Coverage Report - org.apache.maven.plugin.pmd.HelpMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
HelpMojo
0 %
0/287
0 %
0/78
7,5
 
 1  
 package org.apache.maven.plugin.pmd;
 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-pmd-plugin.<br/> Call <pre>  mvn pmd:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
 12  
  *
 13  
  * @version generated on Tue Nov 08 18:57:08 CET 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-pmd-plugin:2.6", 0 );
 70  0
         append( sb, "", 0 );
 71  
 
 72  0
         append( sb, "Maven PMD Plugin", 0 );
 73  0
         append( sb, "A Maven plugin for the PMD toolkit, that produces a report on both code rule violations and detected copy and paste fragments, as well as being able to fail the build based on these metrics.", 1 );
 74  0
         append( sb, "", 0 );
 75  
 
 76  0
         if ( goal == null || goal.length() <= 0 )
 77  
         {
 78  0
             append( sb, "This plugin has 5 goals:", 0 );
 79  0
             append( sb, "", 0 );
 80  
         }
 81  
 
 82  0
         if ( goal == null || goal.length() <= 0 || "check".equals( goal ) )
 83  
         {
 84  0
             append( sb, "pmd:check", 0 );
 85  0
             append( sb, "Fail the build if there were any PMD violations in the source code.", 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, "aggregate (Default: false)", 2 );
 93  0
                 append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 );
 94  0
                 append( sb, "Expression: ${aggregate}", 3 );
 95  0
                 append( sb, "", 0 );
 96  
 
 97  0
                 append( sb, "failOnViolation (Default: true)", 2 );
 98  0
                 append( sb, "Whether to fail the build if the validation check fails.", 3 );
 99  0
                 append( sb, "Required: Yes", 3 );
 100  0
                 append( sb, "Expression: ${pmd.failOnViolation}", 3 );
 101  0
                 append( sb, "", 0 );
 102  
 
 103  0
                 append( sb, "failurePriority (Default: 5)", 2 );
 104  0
                 append( sb, "What priority level to fail the build on. Failures at or above this level will stop the build. Anything below will be warnings and will be displayed in the build output if verbose=true. Note: Minimum Priority = 5 Maximum Priority = 0", 3 );
 105  0
                 append( sb, "Required: Yes", 3 );
 106  0
                 append( sb, "Expression: ${pmd.failurePriority}", 3 );
 107  0
                 append( sb, "", 0 );
 108  
 
 109  0
                 append( sb, "skip (Default: false)", 2 );
 110  0
                 append( sb, "Skip the PMD checks. Most useful on the command line via \'-Dpmd.skip=true\'.", 3 );
 111  0
                 append( sb, "Expression: ${pmd.skip}", 3 );
 112  0
                 append( sb, "", 0 );
 113  
 
 114  0
                 append( sb, "targetDirectory", 2 );
 115  0
                 append( sb, "The location of the XML report to check, as generated by the PMD report.", 3 );
 116  0
                 append( sb, "Required: Yes", 3 );
 117  0
                 append( sb, "Expression: ${project.build.directory}", 3 );
 118  0
                 append( sb, "", 0 );
 119  
 
 120  0
                 append( sb, "verbose (Default: false)", 2 );
 121  0
                 append( sb, "Print details of check failures to build output.", 3 );
 122  0
                 append( sb, "Expression: ${pmd.verbose}", 3 );
 123  0
                 append( sb, "", 0 );
 124  
             }
 125  
         }
 126  
 
 127  0
         if ( goal == null || goal.length() <= 0 || "cpd".equals( goal ) )
 128  
         {
 129  0
             append( sb, "pmd:cpd", 0 );
 130  0
             append( sb, "Creates a report for PMD\'s CPD tool. See http://pmd.sourceforge.net/cpd.html for more detail.", 1 );
 131  0
             append( sb, "", 0 );
 132  0
             if ( detail )
 133  
             {
 134  0
                 append( sb, "Available parameters:", 1 );
 135  0
                 append( sb, "", 0 );
 136  
 
 137  0
                 append( sb, "aggregate (Default: false)", 2 );
 138  0
                 append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 );
 139  0
                 append( sb, "Expression: ${aggregate}", 3 );
 140  0
                 append( sb, "", 0 );
 141  
 
 142  0
                 append( sb, "excludeRoots", 2 );
 143  0
                 append( sb, "The project source directories that should be excluded.", 3 );
 144  0
                 append( sb, "", 0 );
 145  
 
 146  0
                 append( sb, "excludes", 2 );
 147  0
                 append( sb, "A list of files to exclude from checking. Can contain Ant-style wildcards and double wildcards. Note that these exclusion patterns only operate on the path of a source file relative to its source root directory. In other words, files are excluded based on their package and/or class name. If you want to exclude entire source root directories, use the parameter excludeRoots instead.", 3 );
 148  0
                 append( sb, "", 0 );
 149  
 
 150  0
                 append( sb, "format (Default: xml)", 2 );
 151  0
                 append( sb, "Set the output format type, in addition to the HTML report. Must be one of: \'none\', \'csv\', \'xml\', \'txt\' or the full class name of the PMD renderer to use. See the net.sourceforge.pmd.renderers package javadoc for available renderers. XML is required if the pmd:check goal is being used.", 3 );
 152  0
                 append( sb, "Expression: ${format}", 3 );
 153  0
                 append( sb, "", 0 );
 154  
 
 155  0
                 append( sb, "ignoreIdentifiers (Default: false)", 2 );
 156  0
                 append( sb, "Similar to ignoreLiterals but for identifiers; i.e., variable names, methods names, and so forth.", 3 );
 157  0
                 append( sb, "Expression: ${cpd.ignoreIdentifiers}", 3 );
 158  0
                 append( sb, "", 0 );
 159  
 
 160  0
                 append( sb, "ignoreLiterals (Default: false)", 2 );
 161  0
                 append( sb, "If true, CPD ignores literal value differences when evaluating a duplicate block. This means that foo=42; and foo=43; will be seen as equivalent. You may want to run PMD with this option off to start with and then switch it on to see what it turns up.", 3 );
 162  0
                 append( sb, "Expression: ${cpd.ignoreLiterals}", 3 );
 163  0
                 append( sb, "", 0 );
 164  
 
 165  0
                 append( sb, "includes", 2 );
 166  0
                 append( sb, "A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to **\\/*.java.", 3 );
 167  0
                 append( sb, "", 0 );
 168  
 
 169  0
                 append( sb, "includeTests (Default: false)", 2 );
 170  0
                 append( sb, "Run PMD on the tests.", 3 );
 171  0
                 append( sb, "", 0 );
 172  
 
 173  0
                 append( sb, "linkXRef (Default: true)", 2 );
 174  0
                 append( sb, "Link the violation line numbers to the source xref. Links will be created automatically if the jxr plugin is being used.", 3 );
 175  0
                 append( sb, "Expression: ${linkXRef}", 3 );
 176  0
                 append( sb, "", 0 );
 177  
 
 178  0
                 append( sb, "minimumTokens (Default: 100)", 2 );
 179  0
                 append( sb, "The minimum number of tokens that need to be duplicated before it causes a violation.", 3 );
 180  0
                 append( sb, "Expression: ${minimumTokens}", 3 );
 181  0
                 append( sb, "", 0 );
 182  
 
 183  0
                 append( sb, "outputDirectory", 2 );
 184  0
                 append( sb, "The output directory for the final HTML report. Note that this parameter is only evaluated if the goal is run directly from the command line or during the default lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 );
 185  0
                 append( sb, "Required: Yes", 3 );
 186  0
                 append( sb, "Expression: ${project.reporting.outputDirectory}", 3 );
 187  0
                 append( sb, "", 0 );
 188  
 
 189  0
                 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
 190  0
                 append( sb, "The file encoding when writing non-HTML reports.", 3 );
 191  0
                 append( sb, "Expression: ${outputEncoding}", 3 );
 192  0
                 append( sb, "", 0 );
 193  
 
 194  0
                 append( sb, "skip (Default: false)", 2 );
 195  0
                 append( sb, "Skip the CPD report generation. Most useful on the command line via \'-Dcpd.skip=true\'.", 3 );
 196  0
                 append( sb, "Expression: ${cpd.skip}", 3 );
 197  0
                 append( sb, "", 0 );
 198  
 
 199  0
                 append( sb, "sourceEncoding (Default: ${project.build.sourceEncoding})", 2 );
 200  0
                 append( sb, "The file encoding to use when reading the Java sources.", 3 );
 201  0
                 append( sb, "Expression: ${encoding}", 3 );
 202  0
                 append( sb, "", 0 );
 203  
 
 204  0
                 append( sb, "targetDirectory", 2 );
 205  0
                 append( sb, "The output directory for the intermediate XML report.", 3 );
 206  0
                 append( sb, "Required: Yes", 3 );
 207  0
                 append( sb, "Expression: ${project.build.directory}", 3 );
 208  0
                 append( sb, "", 0 );
 209  
 
 210  0
                 append( sb, "xrefLocation (Default: ${project.reporting.outputDirectory}/xref)", 2 );
 211  0
                 append( sb, "Location of the Xrefs to link to.", 3 );
 212  0
                 append( sb, "", 0 );
 213  
 
 214  0
                 append( sb, "xrefTestLocation (Default: ${project.reporting.outputDirectory}/xref-test)", 2 );
 215  0
                 append( sb, "Location of the Test Xrefs to link to.", 3 );
 216  0
                 append( sb, "", 0 );
 217  
             }
 218  
         }
 219  
 
 220  0
         if ( goal == null || goal.length() <= 0 || "cpd-check".equals( goal ) )
 221  
         {
 222  0
             append( sb, "pmd:cpd-check", 0 );
 223  0
             append( sb, "Fail the build if there were any CPD violations in the source code.", 1 );
 224  0
             append( sb, "", 0 );
 225  0
             if ( detail )
 226  
             {
 227  0
                 append( sb, "Available parameters:", 1 );
 228  0
                 append( sb, "", 0 );
 229  
 
 230  0
                 append( sb, "aggregate (Default: false)", 2 );
 231  0
                 append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 );
 232  0
                 append( sb, "Expression: ${aggregate}", 3 );
 233  0
                 append( sb, "", 0 );
 234  
 
 235  0
                 append( sb, "failOnViolation (Default: true)", 2 );
 236  0
                 append( sb, "Whether to fail the build if the validation check fails.", 3 );
 237  0
                 append( sb, "Required: Yes", 3 );
 238  0
                 append( sb, "Expression: ${pmd.failOnViolation}", 3 );
 239  0
                 append( sb, "", 0 );
 240  
 
 241  0
                 append( sb, "skip (Default: false)", 2 );
 242  0
                 append( sb, "Skip the CPD violation checks. Most useful on the command line via \'-Dcpd.skip=true\'.", 3 );
 243  0
                 append( sb, "Expression: ${cpd.skip}", 3 );
 244  0
                 append( sb, "", 0 );
 245  
 
 246  0
                 append( sb, "targetDirectory", 2 );
 247  0
                 append( sb, "The location of the XML report to check, as generated by the PMD report.", 3 );
 248  0
                 append( sb, "Required: Yes", 3 );
 249  0
                 append( sb, "Expression: ${project.build.directory}", 3 );
 250  0
                 append( sb, "", 0 );
 251  
 
 252  0
                 append( sb, "verbose (Default: false)", 2 );
 253  0
                 append( sb, "Print details of check failures to build output.", 3 );
 254  0
                 append( sb, "Expression: ${pmd.verbose}", 3 );
 255  0
                 append( sb, "", 0 );
 256  
             }
 257  
         }
 258  
 
 259  0
         if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
 260  
         {
 261  0
             append( sb, "pmd:help", 0 );
 262  0
             append( sb, "Display help information on maven-pmd-plugin.\nCall\n\u00a0\u00a0mvn\u00a0pmd:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
 263  0
             append( sb, "", 0 );
 264  0
             if ( detail )
 265  
             {
 266  0
                 append( sb, "Available parameters:", 1 );
 267  0
                 append( sb, "", 0 );
 268  
 
 269  0
                 append( sb, "detail (Default: false)", 2 );
 270  0
                 append( sb, "If true, display all settable properties for each goal.", 3 );
 271  0
                 append( sb, "Expression: ${detail}", 3 );
 272  0
                 append( sb, "", 0 );
 273  
 
 274  0
                 append( sb, "goal", 2 );
 275  0
                 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
 276  0
                 append( sb, "Expression: ${goal}", 3 );
 277  0
                 append( sb, "", 0 );
 278  
 
 279  0
                 append( sb, "indentSize (Default: 2)", 2 );
 280  0
                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
 281  0
                 append( sb, "Expression: ${indentSize}", 3 );
 282  0
                 append( sb, "", 0 );
 283  
 
 284  0
                 append( sb, "lineLength (Default: 80)", 2 );
 285  0
                 append( sb, "The maximum length of a display line, should be positive.", 3 );
 286  0
                 append( sb, "Expression: ${lineLength}", 3 );
 287  0
                 append( sb, "", 0 );
 288  
             }
 289  
         }
 290  
 
 291  0
         if ( goal == null || goal.length() <= 0 || "pmd".equals( goal ) )
 292  
         {
 293  0
             append( sb, "pmd:pmd", 0 );
 294  0
             append( sb, "Creates a PMD report.", 1 );
 295  0
             append( sb, "", 0 );
 296  0
             if ( detail )
 297  
             {
 298  0
                 append( sb, "Available parameters:", 1 );
 299  0
                 append( sb, "", 0 );
 300  
 
 301  0
                 append( sb, "aggregate (Default: false)", 2 );
 302  0
                 append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 );
 303  0
                 append( sb, "Expression: ${aggregate}", 3 );
 304  0
                 append( sb, "", 0 );
 305  
 
 306  0
                 append( sb, "excludeRoots", 2 );
 307  0
                 append( sb, "The project source directories that should be excluded.", 3 );
 308  0
                 append( sb, "", 0 );
 309  
 
 310  0
                 append( sb, "excludes", 2 );
 311  0
                 append( sb, "A list of files to exclude from checking. Can contain Ant-style wildcards and double wildcards. Note that these exclusion patterns only operate on the path of a source file relative to its source root directory. In other words, files are excluded based on their package and/or class name. If you want to exclude entire source root directories, use the parameter excludeRoots instead.", 3 );
 312  0
                 append( sb, "", 0 );
 313  
 
 314  0
                 append( sb, "format (Default: xml)", 2 );
 315  0
                 append( sb, "Set the output format type, in addition to the HTML report. Must be one of: \'none\', \'csv\', \'xml\', \'txt\' or the full class name of the PMD renderer to use. See the net.sourceforge.pmd.renderers package javadoc for available renderers. XML is required if the pmd:check goal is being used.", 3 );
 316  0
                 append( sb, "Expression: ${format}", 3 );
 317  0
                 append( sb, "", 0 );
 318  
 
 319  0
                 append( sb, "includes", 2 );
 320  0
                 append( sb, "A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to **\\/*.java.", 3 );
 321  0
                 append( sb, "", 0 );
 322  
 
 323  0
                 append( sb, "includeTests (Default: false)", 2 );
 324  0
                 append( sb, "Run PMD on the tests.", 3 );
 325  0
                 append( sb, "", 0 );
 326  
 
 327  0
                 append( sb, "linkXRef (Default: true)", 2 );
 328  0
                 append( sb, "Link the violation line numbers to the source xref. Links will be created automatically if the jxr plugin is being used.", 3 );
 329  0
                 append( sb, "Expression: ${linkXRef}", 3 );
 330  0
                 append( sb, "", 0 );
 331  
 
 332  0
                 append( sb, "minimumPriority (Default: 5)", 2 );
 333  0
                 append( sb, "The rule priority threshold; rules with lower priority than this will not be evaluated.", 3 );
 334  0
                 append( sb, "Expression: ${minimumPriority}", 3 );
 335  0
                 append( sb, "", 0 );
 336  
 
 337  0
                 append( sb, "outputDirectory", 2 );
 338  0
                 append( sb, "The output directory for the final HTML report. Note that this parameter is only evaluated if the goal is run directly from the command line or during the default lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 );
 339  0
                 append( sb, "Required: Yes", 3 );
 340  0
                 append( sb, "Expression: ${project.reporting.outputDirectory}", 3 );
 341  0
                 append( sb, "", 0 );
 342  
 
 343  0
                 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
 344  0
                 append( sb, "The file encoding when writing non-HTML reports.", 3 );
 345  0
                 append( sb, "Expression: ${outputEncoding}", 3 );
 346  0
                 append( sb, "", 0 );
 347  
 
 348  0
                 append( sb, "rulesets", 2 );
 349  0
                 append( sb, "The PMD rulesets to use. See the Stock Rulesets for a list of some included. Since version 2.5, the ruleset \'rulesets/maven.xml\' is also available. Defaults to the basic, imports and unusedcode rulesets.", 3 );
 350  0
                 append( sb, "", 0 );
 351  
 
 352  0
                 append( sb, "skip (Default: false)", 2 );
 353  0
                 append( sb, "Skip the PMD report generation. Most useful on the command line via \'-Dpmd.skip=true\'.", 3 );
 354  0
                 append( sb, "Expression: ${pmd.skip}", 3 );
 355  0
                 append( sb, "", 0 );
 356  
 
 357  0
                 append( sb, "sourceEncoding (Default: ${project.build.sourceEncoding})", 2 );
 358  0
                 append( sb, "The file encoding to use when reading the Java sources.", 3 );
 359  0
                 append( sb, "Expression: ${encoding}", 3 );
 360  0
                 append( sb, "", 0 );
 361  
 
 362  0
                 append( sb, "targetDirectory", 2 );
 363  0
                 append( sb, "The output directory for the intermediate XML report.", 3 );
 364  0
                 append( sb, "Required: Yes", 3 );
 365  0
                 append( sb, "Expression: ${project.build.directory}", 3 );
 366  0
                 append( sb, "", 0 );
 367  
 
 368  0
                 append( sb, "targetJdk", 2 );
 369  0
                 append( sb, "The target JDK to analyze based on. Should match the target used in the compiler plugin. Valid values are currently 1.3, 1.4, 1.5 and 1.6.\nNote: support for 1.6 was added in version 2.3 of this plugin.\n", 3 );
 370  0
                 append( sb, "Expression: ${targetJdk}", 3 );
 371  0
                 append( sb, "", 0 );
 372  
 
 373  0
                 append( sb, "xrefLocation (Default: ${project.reporting.outputDirectory}/xref)", 2 );
 374  0
                 append( sb, "Location of the Xrefs to link to.", 3 );
 375  0
                 append( sb, "", 0 );
 376  
 
 377  0
                 append( sb, "xrefTestLocation (Default: ${project.reporting.outputDirectory}/xref-test)", 2 );
 378  0
                 append( sb, "Location of the Test Xrefs to link to.", 3 );
 379  0
                 append( sb, "", 0 );
 380  
             }
 381  
         }
 382  
 
 383  0
         if ( getLog().isInfoEnabled() )
 384  
         {
 385  0
             getLog().info( sb.toString() );
 386  
         }
 387  0
     }
 388  
 
 389  
     /**
 390  
      * <p>Repeat a String <code>n</code> times to form a new string.</p>
 391  
      *
 392  
      * @param str String to repeat
 393  
      * @param repeat number of times to repeat str
 394  
      * @return String with repeated String
 395  
      * @throws NegativeArraySizeException if <code>repeat < 0</code>
 396  
      * @throws NullPointerException if str is <code>null</code>
 397  
      */
 398  
     private static String repeat( String str, int repeat )
 399  
     {
 400  0
         StringBuffer buffer = new StringBuffer( repeat * str.length() );
 401  
 
 402  0
         for ( int i = 0; i < repeat; i++ )
 403  
         {
 404  0
             buffer.append( str );
 405  
         }
 406  
 
 407  0
         return buffer.toString();
 408  
     }
 409  
 
 410  
     /** 
 411  
      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
 412  
      * <b>Note</b>: The last character is always a new line.
 413  
      * 
 414  
      * @param sb The buffer to append the description, not <code>null</code>.
 415  
      * @param description The description, not <code>null</code>.
 416  
      * @param indent The base indentation level of each line, must not be negative.
 417  
      */
 418  
     private void append( StringBuffer sb, String description, int indent )
 419  
     {
 420  0
         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
 421  
         {
 422  0
             sb.append( it.next().toString() ).append( '\n' );
 423  
         }
 424  0
     }
 425  
 
 426  
     /** 
 427  
      * Splits the specified text into lines of convenient display length.
 428  
      * 
 429  
      * @param text The text to split into lines, must not be <code>null</code>.
 430  
      * @param indent The base indentation level of each line, must not be negative.
 431  
      * @param indentSize The size of each indentation, must not be negative.
 432  
      * @param lineLength The length of the line, must not be negative.
 433  
      * @return The sequence of display lines, never <code>null</code>.
 434  
      * @throws NegativeArraySizeException if <code>indent < 0</code>
 435  
      */
 436  
     private static List toLines( String text, int indent, int indentSize, int lineLength )
 437  
     {
 438  0
         List<String> lines = new ArrayList<String>();
 439  
 
 440  0
         String ind = repeat( "\t", indent );
 441  0
         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
 442  0
         for ( int i = 0; i < plainLines.length; i++ )
 443  
         {
 444  0
             toLines( lines, ind + plainLines[i], indentSize, lineLength );
 445  
         }
 446  
 
 447  0
         return lines;
 448  
     }
 449  
 
 450  
     /** 
 451  
      * Adds the specified line to the output sequence, performing line wrapping if necessary.
 452  
      * 
 453  
      * @param lines The sequence of display lines, must not be <code>null</code>.
 454  
      * @param line The line to add, must not be <code>null</code>.
 455  
      * @param indentSize The size of each indentation, must not be negative.
 456  
      * @param lineLength The length of the line, must not be negative.
 457  
      */
 458  
     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
 459  
     {
 460  0
         int lineIndent = getIndentLevel( line );
 461  0
         StringBuffer buf = new StringBuffer( 256 );
 462  0
         String[] tokens = line.split( " +" );
 463  0
         for ( int i = 0; i < tokens.length; i++ )
 464  
         {
 465  0
             String token = tokens[i];
 466  0
             if ( i > 0 )
 467  
             {
 468  0
                 if ( buf.length() + token.length() >= lineLength )
 469  
                 {
 470  0
                     lines.add( buf.toString() );
 471  0
                     buf.setLength( 0 );
 472  0
                     buf.append( repeat( " ", lineIndent * indentSize ) );
 473  
                 }
 474  
                 else
 475  
                 {
 476  0
                     buf.append( ' ' );
 477  
                 }
 478  
             }
 479  0
             for ( int j = 0; j < token.length(); j++ )
 480  
             {
 481  0
                 char c = token.charAt( j );
 482  0
                 if ( c == '\t' )
 483  
                 {
 484  0
                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
 485  
                 }
 486  0
                 else if ( c == '\u00A0' )
 487  
                 {
 488  0
                     buf.append( ' ' );
 489  
                 }
 490  
                 else
 491  
                 {
 492  0
                     buf.append( c );
 493  
                 }
 494  
             }
 495  
         }
 496  0
         lines.add( buf.toString() );
 497  0
     }
 498  
 
 499  
     /** 
 500  
      * Gets the indentation level of the specified line.
 501  
      * 
 502  
      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
 503  
      * @return The indentation level of the line.
 504  
      */
 505  
     private static int getIndentLevel( String line )
 506  
     {
 507  0
         int level = 0;
 508  0
         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
 509  
         {
 510  0
             level++;
 511  
         }
 512  0
         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
 513  
         {
 514  0
             if ( line.charAt( i ) == '\t' )
 515  
             {
 516  0
                 level++;
 517  0
                 break;
 518  
             }
 519  
         }
 520  0
         return level;
 521  
     }
 522  
 }