Coverage Report - org.apache.maven.archetype.mojos.HelpMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
HelpMojo
0 %
0/305
0 %
0/104
9,667
 
 1  
 package org.apache.maven.archetype.mojos;
 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-archetype-plugin.<br/> Call <pre>  mvn archetype:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
 12  
  *
 13  
  * @version generated on Wed Aug 31 21:38:02 CEST 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-archetype-plugin:2.1", 0 );
 70  0
         append( sb, "", 0 );
 71  
 
 72  0
         append( sb, "Maven Archetype Plugin", 0 );
 73  0
         append( sb, "Maven Archetype is a set of tools to deal with archetypes, i.e. an abstract representation of a kind of project that can be instantiated into a concrete customized Maven project. An archetype knows which files will be part of the instantiated project and which properties to fill to properly customize the project.", 1 );
 74  0
         append( sb, "", 0 );
 75  
 
 76  0
         if ( goal == null || goal.length() <= 0 )
 77  
         {
 78  0
             append( sb, "This plugin has 8 goals:", 0 );
 79  0
             append( sb, "", 0 );
 80  
         }
 81  
 
 82  0
         if ( goal == null || goal.length() <= 0 || "crawl".equals( goal ) )
 83  
         {
 84  0
             append( sb, "archetype:crawl", 0 );
 85  0
             append( sb, "Crawl a Maven repository (filesystem, not HTTP) and creates a catalog file.", 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, "catalogFile", 2 );
 93  0
                 append( sb, "The archetype\'s catalog to update.", 3 );
 94  0
                 append( sb, "Expression: ${catalog}", 3 );
 95  0
                 append( sb, "", 0 );
 96  
 
 97  0
                 append( sb, "repository (Default: ${settings.localRepository})", 2 );
 98  0
                 append( sb, "The repository to crawl.", 3 );
 99  0
                 append( sb, "Expression: ${repository}", 3 );
 100  0
                 append( sb, "", 0 );
 101  
             }
 102  
         }
 103  
 
 104  0
         if ( goal == null || goal.length() <= 0 || "create".equals( goal ) )
 105  
         {
 106  0
             append( sb, "archetype:create", 0 );
 107  0
             append( sb, "Deprecated. Please use the generate mojo instead.", 1 );
 108  0
             if ( detail )
 109  
             {
 110  0
                 append( sb, "", 0 );
 111  0
                 append( sb, "The archetype creation goal looks for an archetype with a given groupId, artifactId, and version and retrieves it from the remote repository. Once the archetype is retrieved, it is then processed against a set of user parameters to create a working Maven project.", 1 );
 112  
             }
 113  0
             append( sb, "", 0 );
 114  0
             if ( detail )
 115  
             {
 116  0
                 append( sb, "Available parameters:", 1 );
 117  0
                 append( sb, "", 0 );
 118  
 
 119  0
                 append( sb, "archetypeArtifactId (Default: maven-archetype-quickstart)", 2 );
 120  0
                 append( sb, "The Archetype Artifact Id to be used.", 3 );
 121  0
                 append( sb, "Required: Yes", 3 );
 122  0
                 append( sb, "Expression: ${archetypeArtifactId}", 3 );
 123  0
                 append( sb, "", 0 );
 124  
 
 125  0
                 append( sb, "archetypeGroupId (Default: org.apache.maven.archetypes)", 2 );
 126  0
                 append( sb, "The Archetype Group Id to be used.", 3 );
 127  0
                 append( sb, "Required: Yes", 3 );
 128  0
                 append( sb, "Expression: ${archetypeGroupId}", 3 );
 129  0
                 append( sb, "", 0 );
 130  
 
 131  0
                 append( sb, "archetypeVersion (Default: RELEASE)", 2 );
 132  0
                 append( sb, "The Archetype Version to be used.", 3 );
 133  0
                 append( sb, "Required: Yes", 3 );
 134  0
                 append( sb, "Expression: ${archetypeVersion}", 3 );
 135  0
                 append( sb, "", 0 );
 136  
 
 137  0
                 append( sb, "artifactId", 2 );
 138  0
                 append( sb, "The Artifact Id of the project to be build.", 3 );
 139  0
                 append( sb, "Expression: ${artifactId}", 3 );
 140  0
                 append( sb, "", 0 );
 141  
 
 142  0
                 append( sb, "basedir (Default: ${user.dir})", 2 );
 143  0
                 append( sb, "(no description available)", 3 );
 144  0
                 append( sb, "Expression: ${basedir}", 3 );
 145  0
                 append( sb, "", 0 );
 146  
 
 147  0
                 append( sb, "groupId", 2 );
 148  0
                 append( sb, "The Group Id of the project to be build.", 3 );
 149  0
                 append( sb, "Expression: ${groupId}", 3 );
 150  0
                 append( sb, "", 0 );
 151  
 
 152  0
                 append( sb, "localRepository", 2 );
 153  0
                 append( sb, "Maven\'s local repository.", 3 );
 154  0
                 append( sb, "Required: Yes", 3 );
 155  0
                 append( sb, "Expression: ${localRepository}", 3 );
 156  0
                 append( sb, "", 0 );
 157  
 
 158  0
                 append( sb, "packageName", 2 );
 159  0
                 append( sb, "The Package Name of the project to be build.", 3 );
 160  0
                 append( sb, "Expression: ${packageName}", 3 );
 161  0
                 append( sb, "", 0 );
 162  
 
 163  0
                 append( sb, "pomRemoteRepositories", 2 );
 164  0
                 append( sb, "The remote repositories available for discovering dependencies and extensions as indicated by the POM.", 3 );
 165  0
                 append( sb, "Required: Yes", 3 );
 166  0
                 append( sb, "Expression: ${project.remoteArtifactRepositories}", 3 );
 167  0
                 append( sb, "", 0 );
 168  
 
 169  0
                 append( sb, "project", 2 );
 170  0
                 append( sb, "The project to be created an archetype of.", 3 );
 171  0
                 append( sb, "Expression: ${project}", 3 );
 172  0
                 append( sb, "", 0 );
 173  
 
 174  0
                 append( sb, "remoteRepositories", 2 );
 175  0
                 append( sb, "Other remote repositories available for discovering dependencies and extensions.", 3 );
 176  0
                 append( sb, "Expression: ${remoteRepositories}", 3 );
 177  0
                 append( sb, "", 0 );
 178  
 
 179  0
                 append( sb, "version (Default: 1.0-SNAPSHOT)", 2 );
 180  0
                 append( sb, "The Version of the project to be build.", 3 );
 181  0
                 append( sb, "Required: Yes", 3 );
 182  0
                 append( sb, "Expression: ${version}", 3 );
 183  0
                 append( sb, "", 0 );
 184  
             }
 185  
         }
 186  
 
 187  0
         if ( goal == null || goal.length() <= 0 || "create-from-project".equals( goal ) )
 188  
         {
 189  0
             append( sb, "archetype:create-from-project", 0 );
 190  0
             append( sb, "Creates an archetype project from the current project, with a basic integration-test.", 1 );
 191  0
             append( sb, "", 0 );
 192  0
             if ( detail )
 193  
             {
 194  0
                 append( sb, "Available parameters:", 1 );
 195  0
                 append( sb, "", 0 );
 196  
 
 197  0
                 append( sb, "archetypeFilteredExtentions", 2 );
 198  0
                 append( sb, "File extensions which are checked for project\'s text files (vs binary files).", 3 );
 199  0
                 append( sb, "Expression: ${archetype.filteredExtentions}", 3 );
 200  0
                 append( sb, "", 0 );
 201  
 
 202  0
                 append( sb, "archetypeLanguages", 2 );
 203  0
                 append( sb, "Directory names which are checked for project\'s sources main package.", 3 );
 204  0
                 append( sb, "Expression: ${archetype.languages}", 3 );
 205  0
                 append( sb, "", 0 );
 206  
 
 207  0
                 append( sb, "archetypePostPhase (Default: package)", 2 );
 208  0
                 append( sb, "The property telling which phase to call on the generated archetype. Interesting values are: package, integration-test, install and deploy.", 3 );
 209  0
                 append( sb, "Expression: ${archetype.postPhase}", 3 );
 210  0
                 append( sb, "", 0 );
 211  
 
 212  0
                 append( sb, "archetypeRegistryFile", 2 );
 213  0
                 append( sb, "The location of the registry file.", 3 );
 214  0
                 append( sb, "Expression: ${user.home}/.m2/archetype.xml", 3 );
 215  0
                 append( sb, "", 0 );
 216  
 
 217  0
                 append( sb, "defaultEncoding (Default: UTF-8)", 2 );
 218  0
                 append( sb, "Velocity templates encoding.", 3 );
 219  0
                 append( sb, "Expression: ${archetype.encoding}", 3 );
 220  0
                 append( sb, "", 0 );
 221  
 
 222  0
                 append( sb, "interactive (Default: false)", 2 );
 223  0
                 append( sb, "Enable the interactive mode to define the archetype from the project.", 3 );
 224  0
                 append( sb, "Expression: ${interactive}", 3 );
 225  0
                 append( sb, "", 0 );
 226  
 
 227  0
                 append( sb, "keepParent", 2 );
 228  0
                 append( sb, "POMs in archetype are created with their initial parent. This property is ignored when preserveCData is true.", 3 );
 229  0
                 append( sb, "Expression: ${archetype.keepParent}", 3 );
 230  0
                 append( sb, "", 0 );
 231  
 
 232  0
                 append( sb, "localRepository", 2 );
 233  0
                 append( sb, "(no description available)", 3 );
 234  0
                 append( sb, "Expression: ${localRepository}", 3 );
 235  0
                 append( sb, "", 0 );
 236  
 
 237  0
                 append( sb, "outputDirectory", 2 );
 238  0
                 append( sb, "The directory where the archetype should be created.", 3 );
 239  0
                 append( sb, "Expression: ${project.build.directory}/generated-sources/archetype", 3 );
 240  0
                 append( sb, "", 0 );
 241  
 
 242  0
                 append( sb, "packageName", 2 );
 243  0
                 append( sb, "(no description available)", 3 );
 244  0
                 append( sb, "Expression: ${packageName}", 3 );
 245  0
                 append( sb, "", 0 );
 246  
 
 247  0
                 append( sb, "partialArchetype", 2 );
 248  0
                 append( sb, "Create a partial archetype.", 3 );
 249  0
                 append( sb, "Expression: ${archetype.partialArchetype}", 3 );
 250  0
                 append( sb, "", 0 );
 251  
 
 252  0
                 append( sb, "preserveCData", 2 );
 253  0
                 append( sb, "Create pom\'s velocity templates with CDATA preservation. This uses the String.replaceAll() method and risks to have some overly replacement capabilities (beware of \'1.0\' value).", 3 );
 254  0
                 append( sb, "Expression: ${archetype.preserveCData}", 3 );
 255  0
                 append( sb, "", 0 );
 256  
 
 257  0
                 append( sb, "propertyFile", 2 );
 258  0
                 append( sb, "The property file that holds the plugin configuration.", 3 );
 259  0
                 append( sb, "Expression: ${archetype.properties}", 3 );
 260  0
                 append( sb, "", 0 );
 261  
 
 262  0
                 append( sb, "testMode", 2 );
 263  0
                 append( sb, "(no description available)", 3 );
 264  0
                 append( sb, "Expression: ${testMode}", 3 );
 265  0
                 append( sb, "", 0 );
 266  
             }
 267  
         }
 268  
 
 269  0
         if ( goal == null || goal.length() <= 0 || "generate".equals( goal ) )
 270  
         {
 271  0
             append( sb, "archetype:generate", 0 );
 272  0
             append( sb, "Generates a new project from an archetype, or updated the actual project if using a partial archetype. If the project is fully generated, it is generated in a directory corresponding to its artifactId. If the project is updated with a partial archetype, it is done in the current directory.", 1 );
 273  0
             append( sb, "", 0 );
 274  0
             if ( detail )
 275  
             {
 276  0
                 append( sb, "Available parameters:", 1 );
 277  0
                 append( sb, "", 0 );
 278  
 
 279  0
                 append( sb, "archetypeArtifactId", 2 );
 280  0
                 append( sb, "The archetype\'s artifactId.", 3 );
 281  0
                 append( sb, "Expression: ${archetypeArtifactId}", 3 );
 282  0
                 append( sb, "", 0 );
 283  
 
 284  0
                 append( sb, "archetypeCatalog (Default: remote,local)", 2 );
 285  0
                 append( sb, "The archetype catalogs to use to build a list and let the user choose from. It is a comma separated list of catalogs. Catalogs use following schemes:\n-\t\'file://...\' with archetype-catalog.xml automatically appended when pointing to a directory\n-\t\'http://...\' or \'https://...\' with archetype-catalog.xml always appended\n-\t\'local\' which is the shortcut for \'file://~/.m2/archetype-catalog.xml\'\n-\t\'remote\' which is the shortcut for Maven Central repository, ie \'http://repo1.maven.org/maven2\'\n-\t\'internal\' which is an internal catalog\nSince 2.0-alpha-5, default value is no longer internal,local but remote,local. If Maven Central repository catalog file is empty, internal catalog is used instead.", 3 );
 286  0
                 append( sb, "Expression: ${archetypeCatalog}", 3 );
 287  0
                 append( sb, "", 0 );
 288  
 
 289  0
                 append( sb, "archetypeGroupId", 2 );
 290  0
                 append( sb, "The archetype\'s groupId.", 3 );
 291  0
                 append( sb, "Expression: ${archetypeGroupId}", 3 );
 292  0
                 append( sb, "", 0 );
 293  
 
 294  0
                 append( sb, "archetypeRepository", 2 );
 295  0
                 append( sb, "The archetype\'s repository.", 3 );
 296  0
                 append( sb, "Expression: ${archetypeRepository}", 3 );
 297  0
                 append( sb, "", 0 );
 298  
 
 299  0
                 append( sb, "archetypeVersion", 2 );
 300  0
                 append( sb, "The archetype\'s version.", 3 );
 301  0
                 append( sb, "Expression: ${archetypeVersion}", 3 );
 302  0
                 append( sb, "", 0 );
 303  
 
 304  0
                 append( sb, "basedir", 2 );
 305  0
                 append( sb, "(no description available)", 3 );
 306  0
                 append( sb, "Expression: ${basedir}", 3 );
 307  0
                 append( sb, "", 0 );
 308  
 
 309  0
                 append( sb, "filter", 2 );
 310  0
                 append( sb, "Applying some filter on displayed archetypes list: format is artifactId or groupId:artifactId.\n-\torg.apache: -> displays all archetypes which contain org.apache in groupId\n-\t:jee or jee -> displays all archetypes which contain jee in artifactId\n-\torg.apache:jee -> displays all archetypes which contain org.apache in groupId AND jee in artifactId\n", 3 );
 311  0
                 append( sb, "Expression: ${filter}", 3 );
 312  0
                 append( sb, "", 0 );
 313  
 
 314  0
                 append( sb, "goals", 2 );
 315  0
                 append( sb, "Additional goals to immediately run on the project created from the archetype.", 3 );
 316  0
                 append( sb, "Expression: ${goals}", 3 );
 317  0
                 append( sb, "", 0 );
 318  
 
 319  0
                 append( sb, "interactiveMode (Default: ${settings.interactiveMode})", 2 );
 320  0
                 append( sb, "User settings use to check the interactiveMode.", 3 );
 321  0
                 append( sb, "Required: Yes", 3 );
 322  0
                 append( sb, "Expression: ${interactiveMode}", 3 );
 323  0
                 append( sb, "", 0 );
 324  
             }
 325  
         }
 326  
 
 327  0
         if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
 328  
         {
 329  0
             append( sb, "archetype:help", 0 );
 330  0
             append( sb, "Display help information on maven-archetype-plugin.\nCall\n\u00a0\u00a0mvn\u00a0archetype:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
 331  0
             append( sb, "", 0 );
 332  0
             if ( detail )
 333  
             {
 334  0
                 append( sb, "Available parameters:", 1 );
 335  0
                 append( sb, "", 0 );
 336  
 
 337  0
                 append( sb, "detail (Default: false)", 2 );
 338  0
                 append( sb, "If true, display all settable properties for each goal.", 3 );
 339  0
                 append( sb, "Expression: ${detail}", 3 );
 340  0
                 append( sb, "", 0 );
 341  
 
 342  0
                 append( sb, "goal", 2 );
 343  0
                 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
 344  0
                 append( sb, "Expression: ${goal}", 3 );
 345  0
                 append( sb, "", 0 );
 346  
 
 347  0
                 append( sb, "indentSize (Default: 2)", 2 );
 348  0
                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
 349  0
                 append( sb, "Expression: ${indentSize}", 3 );
 350  0
                 append( sb, "", 0 );
 351  
 
 352  0
                 append( sb, "lineLength (Default: 80)", 2 );
 353  0
                 append( sb, "The maximum length of a display line, should be positive.", 3 );
 354  0
                 append( sb, "Expression: ${lineLength}", 3 );
 355  0
                 append( sb, "", 0 );
 356  
             }
 357  
         }
 358  
 
 359  0
         if ( goal == null || goal.length() <= 0 || "integration-test".equals( goal ) )
 360  
         {
 361  0
             append( sb, "archetype:integration-test", 0 );
 362  0
             append( sb, "Execute the archetype integration tests, consisting in generating projects from the current archetype and optionally comparing generated projects with reference copy.\n\nEach IT consists of a sub-directory in src/test/resources/projects containing:\n\n-\ta goal.txt file, containing a list of goals to run against the generated project (can be empty, content ignored before maven-archetype-plugin 2.1),\n-\tan archetype.properties file, containing properties for project generation,\n-\tan optional reference/ directory containing a reference copy of the expected project created from the IT.\nNotice that it is expected to be run as part as of a build after the package phase and not directly as a goal from CLI.", 1 );
 363  0
             append( sb, "", 0 );
 364  0
             if ( detail )
 365  
             {
 366  0
                 append( sb, "Available parameters:", 1 );
 367  0
                 append( sb, "", 0 );
 368  
             }
 369  
         }
 370  
 
 371  0
         if ( goal == null || goal.length() <= 0 || "jar".equals( goal ) )
 372  
         {
 373  0
             append( sb, "archetype:jar", 0 );
 374  0
             append( sb, "Build a JAR from the current Archetype project.", 1 );
 375  0
             append( sb, "", 0 );
 376  0
             if ( detail )
 377  
             {
 378  0
                 append( sb, "Available parameters:", 1 );
 379  0
                 append( sb, "", 0 );
 380  
 
 381  0
                 append( sb, "archetypeDirectory", 2 );
 382  0
                 append( sb, "Directory containing the classes.", 3 );
 383  0
                 append( sb, "Required: Yes", 3 );
 384  0
                 append( sb, "Expression: ${project.build.outputDirectory}", 3 );
 385  0
                 append( sb, "", 0 );
 386  
 
 387  0
                 append( sb, "finalName", 2 );
 388  0
                 append( sb, "Name of the generated JAR.", 3 );
 389  0
                 append( sb, "Required: Yes", 3 );
 390  0
                 append( sb, "Expression: ${project.build.finalName}", 3 );
 391  0
                 append( sb, "", 0 );
 392  
 
 393  0
                 append( sb, "outputDirectory", 2 );
 394  0
                 append( sb, "Directory containing the generated JAR.", 3 );
 395  0
                 append( sb, "Required: Yes", 3 );
 396  0
                 append( sb, "Expression: ${project.build.directory}", 3 );
 397  0
                 append( sb, "", 0 );
 398  
             }
 399  
         }
 400  
 
 401  0
         if ( goal == null || goal.length() <= 0 || "update-local-catalog".equals( goal ) )
 402  
         {
 403  0
             append( sb, "archetype:update-local-catalog", 0 );
 404  0
             append( sb, "Updates the local catalog", 1 );
 405  0
             append( sb, "", 0 );
 406  0
             if ( detail )
 407  
             {
 408  0
                 append( sb, "Available parameters:", 1 );
 409  0
                 append( sb, "", 0 );
 410  
             }
 411  
         }
 412  
 
 413  0
         if ( getLog().isInfoEnabled() )
 414  
         {
 415  0
             getLog().info( sb.toString() );
 416  
         }
 417  0
     }
 418  
 
 419  
     /**
 420  
      * <p>Repeat a String <code>n</code> times to form a new string.</p>
 421  
      *
 422  
      * @param str String to repeat
 423  
      * @param repeat number of times to repeat str
 424  
      * @return String with repeated String
 425  
      * @throws NegativeArraySizeException if <code>repeat < 0</code>
 426  
      * @throws NullPointerException if str is <code>null</code>
 427  
      */
 428  
     private static String repeat( String str, int repeat )
 429  
     {
 430  0
         StringBuffer buffer = new StringBuffer( repeat * str.length() );
 431  
 
 432  0
         for ( int i = 0; i < repeat; i++ )
 433  
         {
 434  0
             buffer.append( str );
 435  
         }
 436  
 
 437  0
         return buffer.toString();
 438  
     }
 439  
 
 440  
     /** 
 441  
      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
 442  
      * <b>Note</b>: The last character is always a new line.
 443  
      * 
 444  
      * @param sb The buffer to append the description, not <code>null</code>.
 445  
      * @param description The description, not <code>null</code>.
 446  
      * @param indent The base indentation level of each line, must not be negative.
 447  
      */
 448  
     private void append( StringBuffer sb, String description, int indent )
 449  
     {
 450  0
         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
 451  
         {
 452  0
             sb.append( it.next().toString() ).append( '\n' );
 453  
         }
 454  0
     }
 455  
 
 456  
     /** 
 457  
      * Splits the specified text into lines of convenient display length.
 458  
      * 
 459  
      * @param text The text to split into lines, must not be <code>null</code>.
 460  
      * @param indent The base indentation level of each line, must not be negative.
 461  
      * @param indentSize The size of each indentation, must not be negative.
 462  
      * @param lineLength The length of the line, must not be negative.
 463  
      * @return The sequence of display lines, never <code>null</code>.
 464  
      * @throws NegativeArraySizeException if <code>indent < 0</code>
 465  
      */
 466  
     private static List toLines( String text, int indent, int indentSize, int lineLength )
 467  
     {
 468  0
         List<String> lines = new ArrayList<String>();
 469  
 
 470  0
         String ind = repeat( "\t", indent );
 471  0
         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
 472  0
         for ( int i = 0; i < plainLines.length; i++ )
 473  
         {
 474  0
             toLines( lines, ind + plainLines[i], indentSize, lineLength );
 475  
         }
 476  
 
 477  0
         return lines;
 478  
     }
 479  
 
 480  
     /** 
 481  
      * Adds the specified line to the output sequence, performing line wrapping if necessary.
 482  
      * 
 483  
      * @param lines The sequence of display lines, must not be <code>null</code>.
 484  
      * @param line The line to add, must not be <code>null</code>.
 485  
      * @param indentSize The size of each indentation, must not be negative.
 486  
      * @param lineLength The length of the line, must not be negative.
 487  
      */
 488  
     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
 489  
     {
 490  0
         int lineIndent = getIndentLevel( line );
 491  0
         StringBuffer buf = new StringBuffer( 256 );
 492  0
         String[] tokens = line.split( " +" );
 493  0
         for ( int i = 0; i < tokens.length; i++ )
 494  
         {
 495  0
             String token = tokens[i];
 496  0
             if ( i > 0 )
 497  
             {
 498  0
                 if ( buf.length() + token.length() >= lineLength )
 499  
                 {
 500  0
                     lines.add( buf.toString() );
 501  0
                     buf.setLength( 0 );
 502  0
                     buf.append( repeat( " ", lineIndent * indentSize ) );
 503  
                 }
 504  
                 else
 505  
                 {
 506  0
                     buf.append( ' ' );
 507  
                 }
 508  
             }
 509  0
             for ( int j = 0; j < token.length(); j++ )
 510  
             {
 511  0
                 char c = token.charAt( j );
 512  0
                 if ( c == '\t' )
 513  
                 {
 514  0
                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
 515  
                 }
 516  0
                 else if ( c == '\u00A0' )
 517  
                 {
 518  0
                     buf.append( ' ' );
 519  
                 }
 520  
                 else
 521  
                 {
 522  0
                     buf.append( c );
 523  
                 }
 524  
             }
 525  
         }
 526  0
         lines.add( buf.toString() );
 527  0
     }
 528  
 
 529  
     /** 
 530  
      * Gets the indentation level of the specified line.
 531  
      * 
 532  
      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
 533  
      * @return The indentation level of the line.
 534  
      */
 535  
     private static int getIndentLevel( String line )
 536  
     {
 537  0
         int level = 0;
 538  0
         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
 539  
         {
 540  0
             level++;
 541  
         }
 542  0
         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
 543  
         {
 544  0
             if ( line.charAt( i ) == '\t' )
 545  
             {
 546  0
                 level++;
 547  0
                 break;
 548  
             }
 549  
         }
 550  0
         return level;
 551  
     }
 552  
 }