Coverage Report - org.apache.maven.plugin.plugin.HelpMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
HelpMojo
0%
0/223
0%
0/94
8.833
 
 1  
 package org.apache.maven.plugin.plugin;
 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-plugin-plugin.<br/> Call <pre>  mvn plugin:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
 12  
  *
 13  
  * @version generated on Mon Sep 05 21:23:22 EDT 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-plugin-plugin:2.9", 0 );
 70  0
         append( sb, "", 0 );
 71  
 
 72  0
         append( sb, "Maven Plugin Plugin", 0 );
 73  0
         append( sb, "The Plugin Plugin is used to create a Maven plugin descriptor for any Mojo\'s found in the source tree, to include in the JAR. It is also used to generate Xdoc files for the Mojos as well as for updating the plugin registry, the artifact metadata and a generic help goal.", 1 );
 74  0
         append( sb, "", 0 );
 75  
 
 76  0
         if ( goal == null || goal.length() <= 0 )
 77  
         {
 78  0
             append( sb, "This plugin has 7 goals:", 0 );
 79  0
             append( sb, "", 0 );
 80  
         }
 81  
 
 82  0
         if ( goal == null || goal.length() <= 0 || "addPluginArtifactMetadata".equals( goal ) )
 83  
         {
 84  0
             append( sb, "plugin:addPluginArtifactMetadata", 0 );
 85  0
             append( sb, "Inject any plugin-specific artifact metadata to the project\'s artifact, for subsequent installation and deployment. The first use-case for this is to add the LATEST metadata (which is plugin-specific) for shipping alongside the plugin\'s artifact.", 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, "goalPrefix", 2 );
 93  0
                 append( sb, "The prefix for the plugin goal.", 3 );
 94  0
                 append( sb, "", 0 );
 95  
 
 96  0
                 append( sb, "skip (Default: false)", 2 );
 97  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 98  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 99  0
                 append( sb, "", 0 );
 100  
             }
 101  
         }
 102  
 
 103  0
         if ( goal == null || goal.length() <= 0 || "descriptor".equals( goal ) )
 104  
         {
 105  0
             append( sb, "plugin:descriptor", 0 );
 106  0
             append( sb, "Generate a plugin descriptor.\nNote: Phase is after the \'compilation\' of any scripts.", 1 );
 107  0
             append( sb, "", 0 );
 108  0
             if ( detail )
 109  
             {
 110  0
                 append( sb, "Available parameters:", 1 );
 111  0
                 append( sb, "", 0 );
 112  
 
 113  0
                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
 114  0
                 append( sb, "The file encoding of the source files.", 3 );
 115  0
                 append( sb, "Expression: ${encoding}", 3 );
 116  0
                 append( sb, "", 0 );
 117  
 
 118  0
                 append( sb, "extractors", 2 );
 119  0
                 append( sb, "The role names of mojo extractors to use. If not set, all mojo extractors will be used. If set to an empty extractor name, no mojo extractors will be used. Example:\n\u00a0<!--\u00a0Use\u00a0all\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors/>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0no\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor/>\n\u00a0</extractors>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0only\u00a0bsh\u00a0mojo\u00a0extractor\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor>bsh</extractor>\n\u00a0</extractors>\n", 3 );
 120  0
                 append( sb, "", 0 );
 121  
 
 122  0
                 append( sb, "goalPrefix", 2 );
 123  0
                 append( sb, "The goal prefix that will appear before the \':\'.", 3 );
 124  0
                 append( sb, "", 0 );
 125  
 
 126  0
                 append( sb, "outputDirectory (Default: ${project.build.outputDirectory}/META-INF/maven)", 2 );
 127  0
                 append( sb, "The directory where the generated plugin.xml file will be put.", 3 );
 128  0
                 append( sb, "", 0 );
 129  
 
 130  0
                 append( sb, "skip (Default: false)", 2 );
 131  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 132  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 133  0
                 append( sb, "", 0 );
 134  
 
 135  0
                 append( sb, "skipDescriptor (Default: false)", 2 );
 136  0
                 append( sb, "A flag to disable generation of the plugin.xml in favor of a hand authored plugin descriptor.", 3 );
 137  0
                 append( sb, "", 0 );
 138  
             }
 139  
         }
 140  
 
 141  0
         if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
 142  
         {
 143  0
             append( sb, "plugin:help", 0 );
 144  0
             append( sb, "Display help information on maven-plugin-plugin.\nCall\n\u00a0\u00a0mvn\u00a0plugin:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
 145  0
             append( sb, "", 0 );
 146  0
             if ( detail )
 147  
             {
 148  0
                 append( sb, "Available parameters:", 1 );
 149  0
                 append( sb, "", 0 );
 150  
 
 151  0
                 append( sb, "detail (Default: false)", 2 );
 152  0
                 append( sb, "If true, display all settable properties for each goal.", 3 );
 153  0
                 append( sb, "Expression: ${detail}", 3 );
 154  0
                 append( sb, "", 0 );
 155  
 
 156  0
                 append( sb, "goal", 2 );
 157  0
                 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
 158  0
                 append( sb, "Expression: ${goal}", 3 );
 159  0
                 append( sb, "", 0 );
 160  
 
 161  0
                 append( sb, "indentSize (Default: 2)", 2 );
 162  0
                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
 163  0
                 append( sb, "Expression: ${indentSize}", 3 );
 164  0
                 append( sb, "", 0 );
 165  
 
 166  0
                 append( sb, "lineLength (Default: 80)", 2 );
 167  0
                 append( sb, "The maximum length of a display line, should be positive.", 3 );
 168  0
                 append( sb, "Expression: ${lineLength}", 3 );
 169  0
                 append( sb, "", 0 );
 170  
             }
 171  
         }
 172  
 
 173  0
         if ( goal == null || goal.length() <= 0 || "helpmojo".equals( goal ) )
 174  
         {
 175  0
             append( sb, "plugin:helpmojo", 0 );
 176  0
             append( sb, "Generates a HelpMojo class.", 1 );
 177  0
             append( sb, "", 0 );
 178  0
             if ( detail )
 179  
             {
 180  0
                 append( sb, "Available parameters:", 1 );
 181  0
                 append( sb, "", 0 );
 182  
 
 183  0
                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
 184  0
                 append( sb, "The file encoding of the source files.", 3 );
 185  0
                 append( sb, "Expression: ${encoding}", 3 );
 186  0
                 append( sb, "", 0 );
 187  
 
 188  0
                 append( sb, "extractors", 2 );
 189  0
                 append( sb, "The role names of mojo extractors to use. If not set, all mojo extractors will be used. If set to an empty extractor name, no mojo extractors will be used. Example:\n\u00a0<!--\u00a0Use\u00a0all\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors/>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0no\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor/>\n\u00a0</extractors>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0only\u00a0bsh\u00a0mojo\u00a0extractor\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor>bsh</extractor>\n\u00a0</extractors>\n", 3 );
 190  0
                 append( sb, "", 0 );
 191  
 
 192  0
                 append( sb, "goalPrefix", 2 );
 193  0
                 append( sb, "The goal prefix that will appear before the \':\'.", 3 );
 194  0
                 append( sb, "", 0 );
 195  
 
 196  0
                 append( sb, "helpPackageName", 2 );
 197  0
                 append( sb, "The name of the package for the generated HelpMojo. By default, the package will be calculated based on the packages of the other plugin goals.", 3 );
 198  0
                 append( sb, "", 0 );
 199  
 
 200  0
                 append( sb, "outputDirectory (Default: ${project.build.directory}/generated-sources/plugin)", 2 );
 201  0
                 append( sb, "The directory where the generated HelpMojo file will be put.", 3 );
 202  0
                 append( sb, "", 0 );
 203  
 
 204  0
                 append( sb, "skip (Default: false)", 2 );
 205  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 206  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 207  0
                 append( sb, "", 0 );
 208  
 
 209  0
                 append( sb, "useJava5 (Default: false)", 2 );
 210  0
                 append( sb, "Generate Java 5 sources.", 3 );
 211  0
                 append( sb, "Expression: ${useJava5}", 3 );
 212  0
                 append( sb, "", 0 );
 213  
             }
 214  
         }
 215  
 
 216  0
         if ( goal == null || goal.length() <= 0 || "report".equals( goal ) )
 217  
         {
 218  0
             append( sb, "plugin:report", 0 );
 219  0
             append( sb, "Generates the Plugin\'s documentation report.", 1 );
 220  0
             append( sb, "", 0 );
 221  0
             if ( detail )
 222  
             {
 223  0
                 append( sb, "Available parameters:", 1 );
 224  0
                 append( sb, "", 0 );
 225  
 
 226  0
                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
 227  0
                 append( sb, "The file encoding of the source files.", 3 );
 228  0
                 append( sb, "Expression: ${encoding}", 3 );
 229  0
                 append( sb, "", 0 );
 230  
 
 231  0
                 append( sb, "goalPrefix", 2 );
 232  0
                 append( sb, "The goal prefix that will appear before the \':\'. By default, this plugin applies a heuristic to derive a heuristic from the plugin\'s artifactId. It removes any occurrences of the regular expression -?maven-?, and then removes any occurrences of -?plugin-?.\nFor example, horsefeature-maven-plugin becomes horsefeather.\n\n(There is a special for maven-plugin-plugin; it is mapped to \'plugin\'.\n", 3 );
 233  0
                 append( sb, "Expression: ${goalPrefix}", 3 );
 234  0
                 append( sb, "", 0 );
 235  
 
 236  0
                 append( sb, "outputDirectory (Default: ${project.build.directory}/generated-site/xdoc)", 2 );
 237  0
                 append( sb, "Report output directory.", 3 );
 238  0
                 append( sb, "", 0 );
 239  
 
 240  0
                 append( sb, "requirements", 2 );
 241  0
                 append( sb, "Specify some requirements to execute this plugin. Example:\n<requirements>\n\u00a0\u00a0<maven>2.0</maven>\n\u00a0\u00a0<jdk>1.4</jdk>\n\u00a0\u00a0<memory>256m</memory>\n\u00a0\u00a0<diskSpace>1m</diskSpace>\n\u00a0\u00a0<others>\n\u00a0\u00a0\u00a0\u00a0<property>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<name>SVN</name>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<value>1.4.6</value>\n\u00a0\u00a0\u00a0\u00a0</property>\n\u00a0\u00a0</others>\n</requirements>\n", 3 );
 242  0
                 append( sb, "", 0 );
 243  
 
 244  0
                 append( sb, "skip (Default: false)", 2 );
 245  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 246  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 247  0
                 append( sb, "", 0 );
 248  
 
 249  0
                 append( sb, "skipReport (Default: false)", 2 );
 250  0
                 append( sb, "Set this to \'true\' to skip generating the report.", 3 );
 251  0
                 append( sb, "Expression: ${maven.plugin.report.skip}", 3 );
 252  0
                 append( sb, "", 0 );
 253  
             }
 254  
         }
 255  
 
 256  0
         if ( goal == null || goal.length() <= 0 || "updateRegistry".equals( goal ) )
 257  
         {
 258  0
             append( sb, "plugin:updateRegistry", 0 );
 259  0
             append( sb, "Update the user plugin registry (if it\'s in use) to reflect the version we\'re installing.", 1 );
 260  0
             append( sb, "", 0 );
 261  0
             if ( detail )
 262  
             {
 263  0
                 append( sb, "Available parameters:", 1 );
 264  0
                 append( sb, "", 0 );
 265  
 
 266  0
                 append( sb, "skip (Default: false)", 2 );
 267  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 268  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 269  0
                 append( sb, "", 0 );
 270  
 
 271  0
                 append( sb, "skipUpdatePluginRegistry (Default: false)", 2 );
 272  0
                 append( sb, "Set this to \'true\' to skip updating the plugin registry.", 3 );
 273  0
                 append( sb, "Expression: ${maven.plugin.update.registry.skip}", 3 );
 274  0
                 append( sb, "", 0 );
 275  
             }
 276  
         }
 277  
 
 278  0
         if ( goal == null || goal.length() <= 0 || "xdoc".equals( goal ) )
 279  
         {
 280  0
             append( sb, "plugin:xdoc", 0 );
 281  0
             append( sb, "Generate Xdoc files for the project mojos or goals.", 1 );
 282  0
             append( sb, "", 0 );
 283  0
             if ( detail )
 284  
             {
 285  0
                 append( sb, "Available parameters:", 1 );
 286  0
                 append( sb, "", 0 );
 287  
 
 288  0
                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
 289  0
                 append( sb, "The file encoding of the source files.", 3 );
 290  0
                 append( sb, "Expression: ${encoding}", 3 );
 291  0
                 append( sb, "", 0 );
 292  
 
 293  0
                 append( sb, "extractors", 2 );
 294  0
                 append( sb, "The role names of mojo extractors to use. If not set, all mojo extractors will be used. If set to an empty extractor name, no mojo extractors will be used. Example:\n\u00a0<!--\u00a0Use\u00a0all\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors/>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0no\u00a0mojo\u00a0extractors\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor/>\n\u00a0</extractors>\n\u00a0\n\u00a0<!--\u00a0Use\u00a0only\u00a0bsh\u00a0mojo\u00a0extractor\u00a0-->\n\u00a0<extractors>\n\u00a0\u00a0\u00a0\u00a0\u00a0<extractor>bsh</extractor>\n\u00a0</extractors>\n", 3 );
 295  0
                 append( sb, "", 0 );
 296  
 
 297  0
                 append( sb, "goalPrefix", 2 );
 298  0
                 append( sb, "The goal prefix that will appear before the \':\'.", 3 );
 299  0
                 append( sb, "", 0 );
 300  
 
 301  0
                 append( sb, "outputDirectory (Default: ${project.build.directory}/generated-site/xdoc)", 2 );
 302  0
                 append( sb, "The directory where the generated Xdoc files will be put.", 3 );
 303  0
                 append( sb, "", 0 );
 304  
 
 305  0
                 append( sb, "skip (Default: false)", 2 );
 306  0
                 append( sb, "Set this to \'true\' to skip invoking any goals or reports of the plugin.", 3 );
 307  0
                 append( sb, "Expression: ${maven.plugin.skip}", 3 );
 308  0
                 append( sb, "", 0 );
 309  
             }
 310  
         }
 311  
 
 312  0
         if ( getLog().isInfoEnabled() )
 313  
         {
 314  0
             getLog().info( sb.toString() );
 315  
         }
 316  0
     }
 317  
 
 318  
     /**
 319  
      * <p>Repeat a String <code>n</code> times to form a new string.</p>
 320  
      *
 321  
      * @param str String to repeat
 322  
      * @param repeat number of times to repeat str
 323  
      * @return String with repeated String
 324  
      * @throws NegativeArraySizeException if <code>repeat < 0</code>
 325  
      * @throws NullPointerException if str is <code>null</code>
 326  
      */
 327  
     private static String repeat( String str, int repeat )
 328  
     {
 329  0
         StringBuffer buffer = new StringBuffer( repeat * str.length() );
 330  
 
 331  0
         for ( int i = 0; i < repeat; i++ )
 332  
         {
 333  0
             buffer.append( str );
 334  
         }
 335  
 
 336  0
         return buffer.toString();
 337  
     }
 338  
 
 339  
     /** 
 340  
      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
 341  
      * <b>Note</b>: The last character is always a new line.
 342  
      * 
 343  
      * @param sb The buffer to append the description, not <code>null</code>.
 344  
      * @param description The description, not <code>null</code>.
 345  
      * @param indent The base indentation level of each line, must not be negative.
 346  
      */
 347  
     private void append( StringBuffer sb, String description, int indent )
 348  
     {
 349  0
         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
 350  
         {
 351  0
             sb.append( it.next().toString() ).append( '\n' );
 352  
         }
 353  0
     }
 354  
 
 355  
     /** 
 356  
      * Splits the specified text into lines of convenient display length.
 357  
      * 
 358  
      * @param text The text to split into lines, must not be <code>null</code>.
 359  
      * @param indent The base indentation level of each line, must not be negative.
 360  
      * @param indentSize The size of each indentation, must not be negative.
 361  
      * @param lineLength The length of the line, must not be negative.
 362  
      * @return The sequence of display lines, never <code>null</code>.
 363  
      * @throws NegativeArraySizeException if <code>indent < 0</code>
 364  
      */
 365  
     private static List toLines( String text, int indent, int indentSize, int lineLength )
 366  
     {
 367  0
         List<String> lines = new ArrayList<String>();
 368  
 
 369  0
         String ind = repeat( "\t", indent );
 370  0
         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
 371  0
         for ( int i = 0; i < plainLines.length; i++ )
 372  
         {
 373  0
             toLines( lines, ind + plainLines[i], indentSize, lineLength );
 374  
         }
 375  
 
 376  0
         return lines;
 377  
     }
 378  
 
 379  
     /** 
 380  
      * Adds the specified line to the output sequence, performing line wrapping if necessary.
 381  
      * 
 382  
      * @param lines The sequence of display lines, must not be <code>null</code>.
 383  
      * @param line The line to add, must not be <code>null</code>.
 384  
      * @param indentSize The size of each indentation, must not be negative.
 385  
      * @param lineLength The length of the line, must not be negative.
 386  
      */
 387  
     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
 388  
     {
 389  0
         int lineIndent = getIndentLevel( line );
 390  0
         StringBuffer buf = new StringBuffer( 256 );
 391  0
         String[] tokens = line.split( " +" );
 392  0
         for ( int i = 0; i < tokens.length; i++ )
 393  
         {
 394  0
             String token = tokens[i];
 395  0
             if ( i > 0 )
 396  
             {
 397  0
                 if ( buf.length() + token.length() >= lineLength )
 398  
                 {
 399  0
                     lines.add( buf.toString() );
 400  0
                     buf.setLength( 0 );
 401  0
                     buf.append( repeat( " ", lineIndent * indentSize ) );
 402  
                 }
 403  
                 else
 404  
                 {
 405  0
                     buf.append( ' ' );
 406  
                 }
 407  
             }
 408  0
             for ( int j = 0; j < token.length(); j++ )
 409  
             {
 410  0
                 char c = token.charAt( j );
 411  0
                 if ( c == '\t' )
 412  
                 {
 413  0
                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
 414  
                 }
 415  0
                 else if ( c == '\u00A0' )
 416  
                 {
 417  0
                     buf.append( ' ' );
 418  
                 }
 419  
                 else
 420  
                 {
 421  0
                     buf.append( c );
 422  
                 }
 423  
             }
 424  
         }
 425  0
         lines.add( buf.toString() );
 426  0
     }
 427  
 
 428  
     /** 
 429  
      * Gets the indentation level of the specified line.
 430  
      * 
 431  
      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
 432  
      * @return The indentation level of the line.
 433  
      */
 434  
     private static int getIndentLevel( String line )
 435  
     {
 436  0
         int level = 0;
 437  0
         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
 438  
         {
 439  0
             level++;
 440  
         }
 441  0
         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
 442  
         {
 443  0
             if ( line.charAt( i ) == '\t' )
 444  
             {
 445  0
                 level++;
 446  0
                 break;
 447  
             }
 448  
         }
 449  0
         return level;
 450  
     }
 451  
 }