Coverage Report - org.apache.maven.plugin.gpg.HelpMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
HelpMojo
0%
0/258
0%
0/62
6.167
 
 1  
 package org.apache.maven.plugin.gpg;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.Iterator;
 5  
 import java.util.List;
 6  
 
 7  
 import org.apache.maven.plugin.AbstractMojo;
 8  
 import org.apache.maven.plugin.MojoExecutionException;
 9  
 
 10  
 /**
 11  
  * Display help information on maven-gpg-plugin.<br/> Call <pre>  mvn gpg:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
 12  
  *
 13  
  * @version generated on Mon Aug 22 11:12:48 IST 2011
 14  
  * @author org.apache.maven.tools.plugin.generator.PluginHelpGenerator (version 2.8)
 15  
  * @goal help
 16  
  * @requiresProject false
 17  
  * @threadSafe
 18  
  */
 19  
 @SuppressWarnings( "all" )
 20  0
 public class HelpMojo
 21  
     extends AbstractMojo
 22  
 {
 23  
     /**
 24  
      * If <code>true</code>, display all settable properties for each goal.
 25  
      * 
 26  
      * @parameter expression="${detail}" default-value="false"
 27  
      */
 28  
     private boolean detail;
 29  
 
 30  
     /**
 31  
      * The name of the goal for which to show help. If unspecified, all goals will be displayed.
 32  
      * 
 33  
      * @parameter expression="${goal}"
 34  
      */
 35  
     private java.lang.String goal;
 36  
 
 37  
     /**
 38  
      * The maximum length of a display line, should be positive.
 39  
      * 
 40  
      * @parameter expression="${lineLength}" default-value="80"
 41  
      */
 42  
     private int lineLength;
 43  
 
 44  
     /**
 45  
      * The number of spaces per indentation level, should be positive.
 46  
      * 
 47  
      * @parameter expression="${indentSize}" default-value="2"
 48  
      */
 49  
     private int indentSize;
 50  
 
 51  
 
 52  
     /** {@inheritDoc} */
 53  
     public void execute()
 54  
         throws MojoExecutionException
 55  
     {
 56  0
         if ( lineLength <= 0 )
 57  
         {
 58  0
             getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
 59  0
             lineLength = 80;
 60  
         }
 61  0
         if ( indentSize <= 0 )
 62  
         {
 63  0
             getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
 64  0
             indentSize = 2;
 65  
         }
 66  
 
 67  0
         StringBuffer sb = new StringBuffer();
 68  
 
 69  0
         append( sb, "org.apache.maven.plugins:maven-gpg-plugin:1.4", 0 );
 70  0
         append( sb, "", 0 );
 71  
 
 72  0
         append( sb, "Maven GPG Plugin", 0 );
 73  0
         append( sb, "Signs the project artifacts with GnuPG.", 1 );
 74  0
         append( sb, "", 0 );
 75  
 
 76  0
         if ( goal == null || goal.length() <= 0 )
 77  
         {
 78  0
             append( sb, "This plugin has 3 goals:", 0 );
 79  0
             append( sb, "", 0 );
 80  
         }
 81  
 
 82  0
         if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
 83  
         {
 84  0
             append( sb, "gpg:help", 0 );
 85  0
             append( sb, "Display help information on maven-gpg-plugin.\nCall\n\u00a0\u00a0mvn\u00a0gpg:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
 86  0
             append( sb, "", 0 );
 87  0
             if ( detail )
 88  
             {
 89  0
                 append( sb, "Available parameters:", 1 );
 90  0
                 append( sb, "", 0 );
 91  
 
 92  0
                 append( sb, "detail (Default: false)", 2 );
 93  0
                 append( sb, "If true, display all settable properties for each goal.", 3 );
 94  0
                 append( sb, "Expression: ${detail}", 3 );
 95  0
                 append( sb, "", 0 );
 96  
 
 97  0
                 append( sb, "goal", 2 );
 98  0
                 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
 99  0
                 append( sb, "Expression: ${goal}", 3 );
 100  0
                 append( sb, "", 0 );
 101  
 
 102  0
                 append( sb, "indentSize (Default: 2)", 2 );
 103  0
                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
 104  0
                 append( sb, "Expression: ${indentSize}", 3 );
 105  0
                 append( sb, "", 0 );
 106  
 
 107  0
                 append( sb, "lineLength (Default: 80)", 2 );
 108  0
                 append( sb, "The maximum length of a display line, should be positive.", 3 );
 109  0
                 append( sb, "Expression: ${lineLength}", 3 );
 110  0
                 append( sb, "", 0 );
 111  
             }
 112  
         }
 113  
 
 114  0
         if ( goal == null || goal.length() <= 0 || "sign".equals( goal ) )
 115  
         {
 116  0
             append( sb, "gpg:sign", 0 );
 117  0
             append( sb, "Sign project artifact, the POM, and attached artifacts with GnuPG for deployment.", 1 );
 118  0
             append( sb, "", 0 );
 119  0
             if ( detail )
 120  
             {
 121  0
                 append( sb, "Available parameters:", 1 );
 122  0
                 append( sb, "", 0 );
 123  
 
 124  0
                 append( sb, "ascDirectory (Default: ${project.build.directory}/gpg)", 2 );
 125  0
                 append( sb, "The directory where to store signature files.", 3 );
 126  0
                 append( sb, "", 0 );
 127  
 
 128  0
                 append( sb, "defaultKeyring (Default: true)", 2 );
 129  0
                 append( sb, "Whether to add the default keyrings from gpg\'s home directory to the list of used keyrings.", 3 );
 130  0
                 append( sb, "Expression: ${gpg.defaultKeyring}", 3 );
 131  0
                 append( sb, "", 0 );
 132  
 
 133  0
                 append( sb, "excludes", 2 );
 134  0
                 append( sb, "A list of files to exclude from being signed. Can contain Ant-style wildcards and double wildcards. The default excludes are **/*.md5 **/*.sha1 **/*.asc.", 3 );
 135  0
                 append( sb, "", 0 );
 136  
 
 137  0
                 append( sb, "executable", 2 );
 138  0
                 append( sb, "The path to the GnuPG executable to use for artifact signing. Defaults to either \'gpg\' or \'gpg.exe\' depending on the operating system.", 3 );
 139  0
                 append( sb, "Expression: ${gpg.executable}", 3 );
 140  0
                 append( sb, "", 0 );
 141  
 
 142  0
                 append( sb, "homedir", 2 );
 143  0
                 append( sb, "The directory from which gpg will load keyrings. If not specified, gpg will use the value configured for its installation, e.g. ~/.gnupg or %APPDATA%/gnupg.", 3 );
 144  0
                 append( sb, "Expression: ${gpg.homedir}", 3 );
 145  0
                 append( sb, "", 0 );
 146  
 
 147  0
                 append( sb, "keyname", 2 );
 148  0
                 append( sb, "The \'name\' of the key to sign with. Passed to gpg as --local-user.", 3 );
 149  0
                 append( sb, "Expression: ${gpg.keyname}", 3 );
 150  0
                 append( sb, "", 0 );
 151  
 
 152  0
                 append( sb, "passphrase", 2 );
 153  0
                 append( sb, "The passphrase to use when signing.", 3 );
 154  0
                 append( sb, "Expression: ${gpg.passphrase}", 3 );
 155  0
                 append( sb, "", 0 );
 156  
 
 157  0
                 append( sb, "publicKeyring", 2 );
 158  0
                 append( sb, "The path to a public keyring to add to the list of keyrings. By default, only the pubring.gpg from gpg\'s home directory is considered. Use this option (and defaultKeyring if required) to use a different public key. Note: Relative paths are resolved against gpg\'s home directory, not the project base directory.", 3 );
 159  0
                 append( sb, "Expression: ${gpg.publicKeyring}", 3 );
 160  0
                 append( sb, "", 0 );
 161  
 
 162  0
                 append( sb, "secretKeyring", 2 );
 163  0
                 append( sb, "The path to a secret keyring to add to the list of keyrings. By default, only the secring.gpg from gpg\'s home directory is considered. Use this option (in combination with publicKeyring and defaultKeyring if required) to use a different secret key. Note: Relative paths are resolved against gpg\'s home directory, not the project base directory.", 3 );
 164  0
                 append( sb, "Expression: ${gpg.secretKeyring}", 3 );
 165  0
                 append( sb, "", 0 );
 166  
 
 167  0
                 append( sb, "skip (Default: false)", 2 );
 168  0
                 append( sb, "Skip doing the gpg signing.", 3 );
 169  0
                 append( sb, "Expression: ${gpg.skip}", 3 );
 170  0
                 append( sb, "", 0 );
 171  
 
 172  0
                 append( sb, "useAgent (Default: false)", 2 );
 173  0
                 append( sb, "Passes --use-agent or --no-use-agent to gpg. If using an agent, the passphrase is optional as the agent will provide it. For gpg2, specify true as --no-use-agent was removed in gpg2 and doesn\'t ask for a passphrase anymore.", 3 );
 174  0
                 append( sb, "Expression: ${gpg.useagent}", 3 );
 175  0
                 append( sb, "", 0 );
 176  
             }
 177  
         }
 178  
 
 179  0
         if ( goal == null || goal.length() <= 0 || "sign-and-deploy-file".equals( goal ) )
 180  
         {
 181  0
             append( sb, "gpg:sign-and-deploy-file", 0 );
 182  0
             append( sb, "Signs artifacts and installs the artifact in the remote repository.", 1 );
 183  0
             append( sb, "", 0 );
 184  0
             if ( detail )
 185  
             {
 186  0
                 append( sb, "Available parameters:", 1 );
 187  0
                 append( sb, "", 0 );
 188  
 
 189  0
                 append( sb, "artifactId", 2 );
 190  0
                 append( sb, "ArtifactId of the artifact to be deployed. Retrieved from POM file if specified.", 3 );
 191  0
                 append( sb, "Expression: ${artifactId}", 3 );
 192  0
                 append( sb, "", 0 );
 193  
 
 194  0
                 append( sb, "ascDirectory", 2 );
 195  0
                 append( sb, "The directory where to store signature files.", 3 );
 196  0
                 append( sb, "Expression: ${gpg.ascDirectory}", 3 );
 197  0
                 append( sb, "", 0 );
 198  
 
 199  0
                 append( sb, "classifier", 2 );
 200  0
                 append( sb, "Add classifier to the artifact", 3 );
 201  0
                 append( sb, "Expression: ${classifier}", 3 );
 202  0
                 append( sb, "", 0 );
 203  
 
 204  0
                 append( sb, "classifiers", 2 );
 205  0
                 append( sb, "A comma separated list of classifiers for each of the extra side artifacts to deploy. If there is a mis-match in the number of entries in files or types, then an error will be raised.", 3 );
 206  0
                 append( sb, "Expression: ${classifiers}", 3 );
 207  0
                 append( sb, "", 0 );
 208  
 
 209  0
                 append( sb, "defaultKeyring (Default: true)", 2 );
 210  0
                 append( sb, "Whether to add the default keyrings from gpg\'s home directory to the list of used keyrings.", 3 );
 211  0
                 append( sb, "Expression: ${gpg.defaultKeyring}", 3 );
 212  0
                 append( sb, "", 0 );
 213  
 
 214  0
                 append( sb, "description", 2 );
 215  0
                 append( sb, "Description passed to a generated POM file (in case of generatePom=true).", 3 );
 216  0
                 append( sb, "Expression: ${generatePom.description}", 3 );
 217  0
                 append( sb, "", 0 );
 218  
 
 219  0
                 append( sb, "executable", 2 );
 220  0
                 append( sb, "The path to the GnuPG executable to use for artifact signing. Defaults to either \'gpg\' or \'gpg.exe\' depending on the operating system.", 3 );
 221  0
                 append( sb, "Expression: ${gpg.executable}", 3 );
 222  0
                 append( sb, "", 0 );
 223  
 
 224  0
                 append( sb, "file", 2 );
 225  0
                 append( sb, "File to be deployed.", 3 );
 226  0
                 append( sb, "Required: Yes", 3 );
 227  0
                 append( sb, "Expression: ${file}", 3 );
 228  0
                 append( sb, "", 0 );
 229  
 
 230  0
                 append( sb, "files", 2 );
 231  0
                 append( sb, "A comma separated list of files for each of the extra side artifacts to deploy. If there is a mis-match in the number of entries in types or classifiers, then an error will be raised.", 3 );
 232  0
                 append( sb, "Expression: ${files}", 3 );
 233  0
                 append( sb, "", 0 );
 234  
 
 235  0
                 append( sb, "generatePom (Default: true)", 2 );
 236  0
                 append( sb, "Upload a POM for this artifact. Will generate a default POM if none is supplied with the pomFile argument.", 3 );
 237  0
                 append( sb, "Expression: ${generatePom}", 3 );
 238  0
                 append( sb, "", 0 );
 239  
 
 240  0
                 append( sb, "groupId", 2 );
 241  0
                 append( sb, "GroupId of the artifact to be deployed. Retrieved from POM file if specified.", 3 );
 242  0
                 append( sb, "Expression: ${groupId}", 3 );
 243  0
                 append( sb, "", 0 );
 244  
 
 245  0
                 append( sb, "homedir", 2 );
 246  0
                 append( sb, "The directory from which gpg will load keyrings. If not specified, gpg will use the value configured for its installation, e.g. ~/.gnupg or %APPDATA%/gnupg.", 3 );
 247  0
                 append( sb, "Expression: ${gpg.homedir}", 3 );
 248  0
                 append( sb, "", 0 );
 249  
 
 250  0
                 append( sb, "javadoc", 2 );
 251  0
                 append( sb, "The bundled API docs for the artifact.", 3 );
 252  0
                 append( sb, "Expression: ${javadoc}", 3 );
 253  0
                 append( sb, "", 0 );
 254  
 
 255  0
                 append( sb, "keyname", 2 );
 256  0
                 append( sb, "The \'name\' of the key to sign with. Passed to gpg as --local-user.", 3 );
 257  0
                 append( sb, "Expression: ${gpg.keyname}", 3 );
 258  0
                 append( sb, "", 0 );
 259  
 
 260  0
                 append( sb, "packaging", 2 );
 261  0
                 append( sb, "Type of the artifact to be deployed. Retrieved from POM file if specified. Defaults to file extension if not specified via command line or POM.", 3 );
 262  0
                 append( sb, "Expression: ${packaging}", 3 );
 263  0
                 append( sb, "", 0 );
 264  
 
 265  0
                 append( sb, "passphrase", 2 );
 266  0
                 append( sb, "The passphrase to use when signing.", 3 );
 267  0
                 append( sb, "Expression: ${gpg.passphrase}", 3 );
 268  0
                 append( sb, "", 0 );
 269  
 
 270  0
                 append( sb, "pomFile", 2 );
 271  0
                 append( sb, "Location of an existing POM file to be deployed alongside the main artifact, given by the ${file} parameter.", 3 );
 272  0
                 append( sb, "Expression: ${pomFile}", 3 );
 273  0
                 append( sb, "", 0 );
 274  
 
 275  0
                 append( sb, "publicKeyring", 2 );
 276  0
                 append( sb, "The path to a public keyring to add to the list of keyrings. By default, only the pubring.gpg from gpg\'s home directory is considered. Use this option (and defaultKeyring if required) to use a different public key. Note: Relative paths are resolved against gpg\'s home directory, not the project base directory.", 3 );
 277  0
                 append( sb, "Expression: ${gpg.publicKeyring}", 3 );
 278  0
                 append( sb, "", 0 );
 279  
 
 280  0
                 append( sb, "repositoryId (Default: remote-repository)", 2 );
 281  0
                 append( sb, "Server Id to map on the <id> under <server> section of settings.xml. In most cases, this parameter will be required for authentication.", 3 );
 282  0
                 append( sb, "Required: Yes", 3 );
 283  0
                 append( sb, "Expression: ${repositoryId}", 3 );
 284  0
                 append( sb, "", 0 );
 285  
 
 286  0
                 append( sb, "repositoryLayout (Default: default)", 2 );
 287  0
                 append( sb, "The type of remote repository layout to deploy to. Try legacy for a Maven 1.x-style repository layout.", 3 );
 288  0
                 append( sb, "Expression: ${repositoryLayout}", 3 );
 289  0
                 append( sb, "", 0 );
 290  
 
 291  0
                 append( sb, "retryFailedDeploymentCount (Default: 1)", 2 );
 292  0
                 append( sb, "Parameter used to control how many times a failed deployment will be retried before giving up and failing. If a value outside the range 1-10 is specified it will be pulled to the nearest value within the range 1-10.", 3 );
 293  0
                 append( sb, "Expression: ${retryFailedDeploymentCount}", 3 );
 294  0
                 append( sb, "", 0 );
 295  
 
 296  0
                 append( sb, "secretKeyring", 2 );
 297  0
                 append( sb, "The path to a secret keyring to add to the list of keyrings. By default, only the secring.gpg from gpg\'s home directory is considered. Use this option (in combination with publicKeyring and defaultKeyring if required) to use a different secret key. Note: Relative paths are resolved against gpg\'s home directory, not the project base directory.", 3 );
 298  0
                 append( sb, "Expression: ${gpg.secretKeyring}", 3 );
 299  0
                 append( sb, "", 0 );
 300  
 
 301  0
                 append( sb, "sources", 2 );
 302  0
                 append( sb, "The bundled sources for the artifact.", 3 );
 303  0
                 append( sb, "Expression: ${sources}", 3 );
 304  0
                 append( sb, "", 0 );
 305  
 
 306  0
                 append( sb, "types", 2 );
 307  0
                 append( sb, "A comma separated list of types for each of the extra side artifacts to deploy. If there is a mis-match in the number of entries in files or classifiers, then an error will be raised.", 3 );
 308  0
                 append( sb, "Expression: ${types}", 3 );
 309  0
                 append( sb, "", 0 );
 310  
 
 311  0
                 append( sb, "uniqueVersion (Default: true)", 2 );
 312  0
                 append( sb, "Whether to deploy snapshots with a unique version or not.", 3 );
 313  0
                 append( sb, "Expression: ${uniqueVersion}", 3 );
 314  0
                 append( sb, "", 0 );
 315  
 
 316  0
                 append( sb, "updateReleaseInfo (Default: false)", 2 );
 317  0
                 append( sb, "Parameter used to update the metadata to make the artifact as release.", 3 );
 318  0
                 append( sb, "Expression: ${updateReleaseInfo}", 3 );
 319  0
                 append( sb, "", 0 );
 320  
 
 321  0
                 append( sb, "url", 2 );
 322  0
                 append( sb, "URL where the artifact will be deployed.\nie ( file:///C:/m2-repo or scp://host.com/path/to/repo )", 3 );
 323  0
                 append( sb, "Required: Yes", 3 );
 324  0
                 append( sb, "Expression: ${url}", 3 );
 325  0
                 append( sb, "", 0 );
 326  
 
 327  0
                 append( sb, "useAgent (Default: false)", 2 );
 328  0
                 append( sb, "Passes --use-agent or --no-use-agent to gpg. If using an agent, the passphrase is optional as the agent will provide it. For gpg2, specify true as --no-use-agent was removed in gpg2 and doesn\'t ask for a passphrase anymore.", 3 );
 329  0
                 append( sb, "Expression: ${gpg.useagent}", 3 );
 330  0
                 append( sb, "", 0 );
 331  
 
 332  0
                 append( sb, "version", 2 );
 333  0
                 append( sb, "Version of the artifact to be deployed. Retrieved from POM file if specified.", 3 );
 334  0
                 append( sb, "Expression: ${version}", 3 );
 335  0
                 append( sb, "", 0 );
 336  
             }
 337  
         }
 338  
 
 339  0
         if ( getLog().isInfoEnabled() )
 340  
         {
 341  0
             getLog().info( sb.toString() );
 342  
         }
 343  0
     }
 344  
 
 345  
     /**
 346  
      * <p>Repeat a String <code>n</code> times to form a new string.</p>
 347  
      *
 348  
      * @param str String to repeat
 349  
      * @param repeat number of times to repeat str
 350  
      * @return String with repeated String
 351  
      * @throws NegativeArraySizeException if <code>repeat < 0</code>
 352  
      * @throws NullPointerException if str is <code>null</code>
 353  
      */
 354  
     private static String repeat( String str, int repeat )
 355  
     {
 356  0
         StringBuffer buffer = new StringBuffer( repeat * str.length() );
 357  
 
 358  0
         for ( int i = 0; i < repeat; i++ )
 359  
         {
 360  0
             buffer.append( str );
 361  
         }
 362  
 
 363  0
         return buffer.toString();
 364  
     }
 365  
 
 366  
     /** 
 367  
      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
 368  
      * <b>Note</b>: The last character is always a new line.
 369  
      * 
 370  
      * @param sb The buffer to append the description, not <code>null</code>.
 371  
      * @param description The description, not <code>null</code>.
 372  
      * @param indent The base indentation level of each line, must not be negative.
 373  
      */
 374  
     private void append( StringBuffer sb, String description, int indent )
 375  
     {
 376  0
         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
 377  
         {
 378  0
             sb.append( it.next().toString() ).append( '\n' );
 379  
         }
 380  0
     }
 381  
 
 382  
     /** 
 383  
      * Splits the specified text into lines of convenient display length.
 384  
      * 
 385  
      * @param text The text to split into lines, must not be <code>null</code>.
 386  
      * @param indent The base indentation level of each line, must not be negative.
 387  
      * @param indentSize The size of each indentation, must not be negative.
 388  
      * @param lineLength The length of the line, must not be negative.
 389  
      * @return The sequence of display lines, never <code>null</code>.
 390  
      * @throws NegativeArraySizeException if <code>indent < 0</code>
 391  
      */
 392  
     private static List toLines( String text, int indent, int indentSize, int lineLength )
 393  
     {
 394  0
         List<String> lines = new ArrayList<String>();
 395  
 
 396  0
         String ind = repeat( "\t", indent );
 397  0
         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
 398  0
         for ( int i = 0; i < plainLines.length; i++ )
 399  
         {
 400  0
             toLines( lines, ind + plainLines[i], indentSize, lineLength );
 401  
         }
 402  
 
 403  0
         return lines;
 404  
     }
 405  
 
 406  
     /** 
 407  
      * Adds the specified line to the output sequence, performing line wrapping if necessary.
 408  
      * 
 409  
      * @param lines The sequence of display lines, must not be <code>null</code>.
 410  
      * @param line The line to add, must not be <code>null</code>.
 411  
      * @param indentSize The size of each indentation, must not be negative.
 412  
      * @param lineLength The length of the line, must not be negative.
 413  
      */
 414  
     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
 415  
     {
 416  0
         int lineIndent = getIndentLevel( line );
 417  0
         StringBuffer buf = new StringBuffer( 256 );
 418  0
         String[] tokens = line.split( " +" );
 419  0
         for ( int i = 0; i < tokens.length; i++ )
 420  
         {
 421  0
             String token = tokens[i];
 422  0
             if ( i > 0 )
 423  
             {
 424  0
                 if ( buf.length() + token.length() >= lineLength )
 425  
                 {
 426  0
                     lines.add( buf.toString() );
 427  0
                     buf.setLength( 0 );
 428  0
                     buf.append( repeat( " ", lineIndent * indentSize ) );
 429  
                 }
 430  
                 else
 431  
                 {
 432  0
                     buf.append( ' ' );
 433  
                 }
 434  
             }
 435  0
             for ( int j = 0; j < token.length(); j++ )
 436  
             {
 437  0
                 char c = token.charAt( j );
 438  0
                 if ( c == '\t' )
 439  
                 {
 440  0
                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
 441  
                 }
 442  0
                 else if ( c == '\u00A0' )
 443  
                 {
 444  0
                     buf.append( ' ' );
 445  
                 }
 446  
                 else
 447  
                 {
 448  0
                     buf.append( c );
 449  
                 }
 450  
             }
 451  
         }
 452  0
         lines.add( buf.toString() );
 453  0
     }
 454  
 
 455  
     /** 
 456  
      * Gets the indentation level of the specified line.
 457  
      * 
 458  
      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
 459  
      * @return The indentation level of the line.
 460  
      */
 461  
     private static int getIndentLevel( String line )
 462  
     {
 463  0
         int level = 0;
 464  0
         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
 465  
         {
 466  0
             level++;
 467  
         }
 468  0
         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
 469  
         {
 470  0
             if ( line.charAt( i ) == '\t' )
 471  
             {
 472  0
                 level++;
 473  0
                 break;
 474  
             }
 475  
         }
 476  0
         return level;
 477  
     }
 478  
 }