View Javadoc

1   package org.codehaus.mojo.license;
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 license-maven-plugin.<br/> Call <pre>  mvn license:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
12   *
13   * @version generated on Thu Jan 19 13:13:54 UTC 2012
14   * @author org.apache.maven.tools.plugin.generator.PluginHelpGenerator (version 2.7)
15   * @goal help
16   * @requiresProject false
17   * @threadSafe
18   */
19  public class HelpMojo
20      extends AbstractMojo
21  {
22      /**
23       * If <code>true</code>, display all settable properties for each goal.
24       * 
25       * @parameter expression="${detail}" default-value="false"
26       */
27      private boolean detail;
28  
29      /**
30       * The name of the goal for which to show help. If unspecified, all goals will be displayed.
31       * 
32       * @parameter expression="${goal}"
33       */
34      private java.lang.String goal;
35  
36      /**
37       * The maximum length of a display line, should be positive.
38       * 
39       * @parameter expression="${lineLength}" default-value="80"
40       */
41      private int lineLength;
42  
43      /**
44       * The number of spaces per indentation level, should be positive.
45       * 
46       * @parameter expression="${indentSize}" default-value="2"
47       */
48      private int indentSize;
49  
50  
51      /** {@inheritDoc} */
52      public void execute()
53          throws MojoExecutionException
54      {
55          if ( lineLength <= 0 )
56          {
57              getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
58              lineLength = 80;
59          }
60          if ( indentSize <= 0 )
61          {
62              getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
63              indentSize = 2;
64          }
65  
66          StringBuffer sb = new StringBuffer();
67  
68          append( sb, "org.kuali.maven.plugins:license-maven-plugin:1.6.0", 0 );
69          append( sb, "", 0 );
70  
71          append( sb, "License Maven Plugin", 0 );
72          append( sb, "Maven plugin to download and collect license files from project dependencies.", 1 );
73          append( sb, "", 0 );
74  
75          if ( goal == null || goal.length() <= 0 )
76          {
77              append( sb, "This plugin has 8 goals:", 0 );
78              append( sb, "", 0 );
79          }
80  
81          if ( goal == null || goal.length() <= 0 || "add-third-party".equals( goal ) )
82          {
83              append( sb, "license:add-third-party", 0 );
84              append( sb, "Goal to generate the third-party license file.\nThis file contains a list of the dependencies and their licenses. Each dependency and it\'s license is displayed on a single line in the format\n\n\n\u00a0\u00a0(<license-name>)\u00a0<project-name>\u00a0<groupId>:<artifactId>:<version>\u00a0-\u00a0<project-url>\nIt will also copy it in the class-path (says add the generated directory as a resource of the build).", 1 );
85              append( sb, "", 0 );
86              if ( detail )
87              {
88                  append( sb, "Available parameters:", 1 );
89                  append( sb, "", 0 );
90  
91                  append( sb, "artifactLicenseMapping (Default: classpath:THIRD-PARTY.properties)", 2 );
92                  append( sb, "Location of a properties file mapping artifacts without a license to the license that should be used for them. This supports classpath notation and any other type of URL Spring 3.1 resource loading can understand.", 3 );
93                  append( sb, "Expression: ${license.artifactLicenseMapping}", 3 );
94                  append( sb, "", 0 );
95  
96                  append( sb, "bundleThirdPartyPath (Default: META-INF/${project.artifactId}-THIRD-PARTY.txt)", 2 );
97                  append( sb, "The path of the bundled third party file to produce when generateBundle is on.\nNote: This option is not available for pom module types.\n", 3 );
98                  append( sb, "Expression: ${license.bundleThirdPartyPath}", 3 );
99                  append( sb, "", 0 );
100 
101                 append( sb, "deployMissingFile (Default: true)", 2 );
102                 append( sb, "Deploy the third party missing file in maven repository.", 3 );
103                 append( sb, "Expression: ${license.deployMissingFile}", 3 );
104                 append( sb, "", 0 );
105 
106                 append( sb, "doGenerateMissing (Default: false)", 2 );
107                 append( sb, "Controls if THIRD-PARTY.properties gets created or not", 3 );
108                 append( sb, "Expression: ${license.doGenerateMissing}", 3 );
109                 append( sb, "", 0 );
110 
111                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
112                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
113                 append( sb, "Expression: ${license.encoding}", 3 );
114                 append( sb, "", 0 );
115 
116                 append( sb, "excludedArtifacts", 2 );
117                 append( sb, "A filter to exclude some ArtifactsIds", 3 );
118                 append( sb, "Expression: ${license.excludedArtifacts}", 3 );
119                 append( sb, "", 0 );
120 
121                 append( sb, "excludedGroups", 2 );
122                 append( sb, "A filter to exclude some GroupIds", 3 );
123                 append( sb, "Expression: ${license.excludedGroups}", 3 );
124                 append( sb, "", 0 );
125 
126                 append( sb, "excludedScopes (Default: system)", 2 );
127                 append( sb, "A filter to exclude some scopes.", 3 );
128                 append( sb, "Expression: ${license.excludedScopes}", 3 );
129                 append( sb, "", 0 );
130 
131                 append( sb, "failIfWarning (Default: false)", 2 );
132                 append( sb, "A flag to fail the build if at least one dependency was detected without a license.", 3 );
133                 append( sb, "Expression: ${license.failIfWarning}", 3 );
134                 append( sb, "", 0 );
135 
136                 append( sb, "force (Default: false)", 2 );
137                 append( sb, "To force generation of the third-party file even if every thing is up to date.", 3 );
138                 append( sb, "Expression: ${license.force}", 3 );
139                 append( sb, "", 0 );
140 
141                 append( sb, "generateBundle (Default: false)", 2 );
142                 append( sb, "A flag to copy a bundled version of the third-party file. This is usefull to avoid for a final application collision name of third party file.\nThe file will be copied at the bundleThirdPartyPath location.\n", 3 );
143                 append( sb, "Expression: ${license.generateBundle}", 3 );
144                 append( sb, "", 0 );
145 
146                 append( sb, "groupByLicense (Default: false)", 2 );
147                 append( sb, "A flag to change the grouping of the generated THIRD-PARTY file.\nBy default, group by dependencies.\n\nIf sets to true, the it will group by license type.\n", 3 );
148                 append( sb, "Expression: ${license.groupByLicense}", 3 );
149                 append( sb, "", 0 );
150 
151                 append( sb, "includedArtifacts", 2 );
152                 append( sb, "A filter to include only some ArtifactsIds", 3 );
153                 append( sb, "Expression: ${license.includedArtifacts}", 3 );
154                 append( sb, "", 0 );
155 
156                 append( sb, "includedGroups", 2 );
157                 append( sb, "A filter to include only some GroupIds", 3 );
158                 append( sb, "Expression: ${license.includedGroups}", 3 );
159                 append( sb, "", 0 );
160 
161                 append( sb, "includedScopes", 2 );
162                 append( sb, "A filter to include only some scopes, if let empty then all scopes will be used (no filter).", 3 );
163                 append( sb, "Expression: ${license.includedScopes}", 3 );
164                 append( sb, "", 0 );
165 
166                 append( sb, "includeTransitiveDependencies (Default: true)", 2 );
167                 append( sb, "Include transitive dependencies when downloading license files.", 3 );
168                 append( sb, "", 0 );
169 
170                 append( sb, "licenseMerges", 2 );
171                 append( sb, "To merge licenses in final file.\nEach entry represents a merge (first license is main license to keep), licenses are separated by |.\n\nExample :\n\n\n<licenseMerges>\n<licenseMerge>The\u00a0Apache\u00a0Software\u00a0License|Version\u00a02.0,Apache\u00a0License,\u00a0Version\u00a02.0</licenseMerge>\n</licenseMerges>\n</pre>\n", 3 );
172                 append( sb, "", 0 );
173 
174                 append( sb, "missingFile (Default: src/license/THIRD-PARTY.properties)", 2 );
175                 append( sb, "The file where to fill the license for dependencies with unknown license.", 3 );
176                 append( sb, "Expression: ${license.missingFile}", 3 );
177                 append( sb, "", 0 );
178 
179                 append( sb, "outputDirectory (Default: ${project.build.directory}/generated-sources/license)", 2 );
180                 append( sb, "Directory where to generate files.", 3 );
181                 append( sb, "Required: Yes", 3 );
182                 append( sb, "Expression: ${license.outputDirectory}", 3 );
183                 append( sb, "", 0 );
184 
185                 append( sb, "project (Default: ${project})", 2 );
186                 append( sb, "The reacted project.", 3 );
187                 append( sb, "Required: Yes", 3 );
188                 append( sb, "", 0 );
189 
190                 append( sb, "thirdPartyFilename (Default: THIRD-PARTY.txt)", 2 );
191                 append( sb, "File where license information for third party dependencies gets stored", 3 );
192                 append( sb, "Required: Yes", 3 );
193                 append( sb, "Expression: ${license.thirdPartyFilename}", 3 );
194                 append( sb, "", 0 );
195 
196                 append( sb, "useMissingFile (Default: false)", 2 );
197                 append( sb, "A flag to use the missing licenses file to consolidate the THID-PARTY file.", 3 );
198                 append( sb, "Expression: ${license.useMissingFile}", 3 );
199                 append( sb, "", 0 );
200 
201                 append( sb, "useRepositoryMissingFiles (Default: true)", 2 );
202                 append( sb, "Load from repositories third party missing files.", 3 );
203                 append( sb, "Expression: ${license.useRepositoryMissingFiles}", 3 );
204                 append( sb, "", 0 );
205 
206                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
207                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
208                 append( sb, "Expression: ${license.verbose}", 3 );
209                 append( sb, "", 0 );
210             }
211         }
212 
213         if ( goal == null || goal.length() <= 0 || "aggregate-add-third-party".equals( goal ) )
214         {
215             append( sb, "license:aggregate-add-third-party", 0 );
216             append( sb, "This aggregator goal (will be executed only once and only on pom projects) executed the add-third-party on all his modules (in a parellel build cycle) then aggreates all the third-party files in final one in the pom project.", 1 );
217             append( sb, "", 0 );
218             if ( detail )
219             {
220                 append( sb, "Available parameters:", 1 );
221                 append( sb, "", 0 );
222 
223                 append( sb, "artifactLicenseMapping (Default: classpath:THIRD-PARTY.properties)", 2 );
224                 append( sb, "Location of a properties file mapping artifacts without a license to the license that should be used for them. This supports classpath notation and any other type of URL Spring 3.1 resource loading can understand.", 3 );
225                 append( sb, "Expression: ${license.artifactLicenseMapping}", 3 );
226                 append( sb, "", 0 );
227 
228                 append( sb, "bundleThirdPartyPath (Default: META-INF/${project.artifactId}-THIRD-PARTY.txt)", 2 );
229                 append( sb, "The path of the bundled third party file to produce when generateBundle is on.\nNote: This option is not available for pom module types.\n", 3 );
230                 append( sb, "Expression: ${license.bundleThirdPartyPath}", 3 );
231                 append( sb, "", 0 );
232 
233                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
234                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
235                 append( sb, "Expression: ${license.encoding}", 3 );
236                 append( sb, "", 0 );
237 
238                 append( sb, "excludedArtifacts", 2 );
239                 append( sb, "A filter to exclude some ArtifactsIds", 3 );
240                 append( sb, "Expression: ${license.excludedArtifacts}", 3 );
241                 append( sb, "", 0 );
242 
243                 append( sb, "excludedGroups", 2 );
244                 append( sb, "A filter to exclude some GroupIds", 3 );
245                 append( sb, "Expression: ${license.excludedGroups}", 3 );
246                 append( sb, "", 0 );
247 
248                 append( sb, "excludedScopes (Default: system)", 2 );
249                 append( sb, "A filter to exclude some scopes.", 3 );
250                 append( sb, "Expression: ${license.excludedScopes}", 3 );
251                 append( sb, "", 0 );
252 
253                 append( sb, "failIfWarning (Default: false)", 2 );
254                 append( sb, "A flag to fail the build if at least one dependency was detected without a license.", 3 );
255                 append( sb, "Expression: ${license.failIfWarning}", 3 );
256                 append( sb, "", 0 );
257 
258                 append( sb, "force (Default: false)", 2 );
259                 append( sb, "To force generation of the third-party file even if every thing is up to date.", 3 );
260                 append( sb, "Expression: ${license.force}", 3 );
261                 append( sb, "", 0 );
262 
263                 append( sb, "generateBundle (Default: false)", 2 );
264                 append( sb, "A flag to copy a bundled version of the third-party file. This is usefull to avoid for a final application collision name of third party file.\nThe file will be copied at the bundleThirdPartyPath location.\n", 3 );
265                 append( sb, "Expression: ${license.generateBundle}", 3 );
266                 append( sb, "", 0 );
267 
268                 append( sb, "groupByLicense (Default: false)", 2 );
269                 append( sb, "A flag to change the grouping of the generated THIRD-PARTY file.\nBy default, group by dependencies.\n\nIf sets to true, the it will group by license type.\n", 3 );
270                 append( sb, "Expression: ${license.groupByLicense}", 3 );
271                 append( sb, "", 0 );
272 
273                 append( sb, "includedArtifacts", 2 );
274                 append( sb, "A filter to include only some ArtifactsIds", 3 );
275                 append( sb, "Expression: ${license.includedArtifacts}", 3 );
276                 append( sb, "", 0 );
277 
278                 append( sb, "includedGroups", 2 );
279                 append( sb, "A filter to include only some GroupIds", 3 );
280                 append( sb, "Expression: ${license.includedGroups}", 3 );
281                 append( sb, "", 0 );
282 
283                 append( sb, "includedScopes", 2 );
284                 append( sb, "A filter to include only some scopes, if let empty then all scopes will be used (no filter).", 3 );
285                 append( sb, "Expression: ${license.includedScopes}", 3 );
286                 append( sb, "", 0 );
287 
288                 append( sb, "includeTransitiveDependencies (Default: true)", 2 );
289                 append( sb, "Include transitive dependencies when downloading license files.", 3 );
290                 append( sb, "", 0 );
291 
292                 append( sb, "licenseMerges", 2 );
293                 append( sb, "To merge licenses in final file.\nEach entry represents a merge (first license is main license to keep), licenses are separated by |.\n\nExample :\n\n\n<licenseMerges>\n<licenseMerge>The\u00a0Apache\u00a0Software\u00a0License|Version\u00a02.0,Apache\u00a0License,\u00a0Version\u00a02.0</licenseMerge>\n</licenseMerges>\n</pre>\n", 3 );
294                 append( sb, "", 0 );
295 
296                 append( sb, "missingFile (Default: src/license/THIRD-PARTY.properties)", 2 );
297                 append( sb, "The file where to fill the license for dependencies with unknown license.", 3 );
298                 append( sb, "Expression: ${license.missingFile}", 3 );
299                 append( sb, "", 0 );
300 
301                 append( sb, "outputDirectory (Default: ${project.build.directory}/generated-sources/license)", 2 );
302                 append( sb, "Directory where to generate files.", 3 );
303                 append( sb, "Required: Yes", 3 );
304                 append( sb, "Expression: ${license.outputDirectory}", 3 );
305                 append( sb, "", 0 );
306 
307                 append( sb, "project (Default: ${project})", 2 );
308                 append( sb, "The reacted project.", 3 );
309                 append( sb, "Required: Yes", 3 );
310                 append( sb, "", 0 );
311 
312                 append( sb, "thirdPartyFilename (Default: THIRD-PARTY.txt)", 2 );
313                 append( sb, "File where license information for third party dependencies gets stored", 3 );
314                 append( sb, "Required: Yes", 3 );
315                 append( sb, "Expression: ${license.thirdPartyFilename}", 3 );
316                 append( sb, "", 0 );
317 
318                 append( sb, "useMissingFile (Default: false)", 2 );
319                 append( sb, "A flag to use the missing licenses file to consolidate the THID-PARTY file.", 3 );
320                 append( sb, "Expression: ${license.useMissingFile}", 3 );
321                 append( sb, "", 0 );
322 
323                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
324                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
325                 append( sb, "Expression: ${license.verbose}", 3 );
326                 append( sb, "", 0 );
327             }
328         }
329 
330         if ( goal == null || goal.length() <= 0 || "comment-style-list".equals( goal ) )
331         {
332             append( sb, "license:comment-style-list", 0 );
333             append( sb, "Displays all the available comment style to box file headers.", 1 );
334             append( sb, "", 0 );
335             if ( detail )
336             {
337                 append( sb, "Available parameters:", 1 );
338                 append( sb, "", 0 );
339 
340                 append( sb, "detail", 2 );
341                 append( sb, "A flag to display also the content of each license.", 3 );
342                 append( sb, "Expression: ${detail}", 3 );
343                 append( sb, "", 0 );
344 
345                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
346                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
347                 append( sb, "Expression: ${license.encoding}", 3 );
348                 append( sb, "", 0 );
349 
350                 append( sb, "project (Default: ${project})", 2 );
351                 append( sb, "The reacted project.", 3 );
352                 append( sb, "Required: Yes", 3 );
353                 append( sb, "", 0 );
354 
355                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
356                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
357                 append( sb, "Expression: ${license.verbose}", 3 );
358                 append( sb, "", 0 );
359             }
360         }
361 
362         if ( goal == null || goal.length() <= 0 || "download-licenses".equals( goal ) )
363         {
364             append( sb, "license:download-licenses", 0 );
365             append( sb, "Download the license files of all the current project\'s dependencies, and generate a summary file containing a list of all dependencies and their licenses.", 1 );
366             append( sb, "", 0 );
367             if ( detail )
368             {
369                 append( sb, "Available parameters:", 1 );
370                 append( sb, "", 0 );
371 
372                 append( sb, "excludedScopes (Default: system)", 2 );
373                 append( sb, "A filter to exclude some scopes.", 3 );
374                 append( sb, "Expression: ${license.excludedScopes}", 3 );
375                 append( sb, "", 0 );
376 
377                 append( sb, "includedScopes", 2 );
378                 append( sb, "A filter to include only some scopes, if let empty then all scopes will be used (no filter).", 3 );
379                 append( sb, "Expression: ${license.includedScopes}", 3 );
380                 append( sb, "", 0 );
381 
382                 append( sb, "includeTransitiveDependencies (Default: true)", 2 );
383                 append( sb, "Include transitive dependencies when downloading license files.", 3 );
384                 append( sb, "", 0 );
385 
386                 append( sb, "licensesConfigFile (Default: ${project.basedir}/src/license/licenses.xml)", 2 );
387                 append( sb, "Input file containing a mapping between each dependency and it\'s license information.", 3 );
388                 append( sb, "Expression: ${licensesConfigFile}", 3 );
389                 append( sb, "", 0 );
390 
391                 append( sb, "licensesOutputDirectory (Default: ${project.build.directory}/generated-resources/licenses)", 2 );
392                 append( sb, "The directory to which the dependency licenses should be written.", 3 );
393                 append( sb, "Expression: ${licensesOutputDirectory}", 3 );
394                 append( sb, "", 0 );
395 
396                 append( sb, "licensesOutputFile (Default: ${project.build.directory}/generated-resources/licenses.xml)", 2 );
397                 append( sb, "The output file containing a mapping between each dependency and it\'s license information.", 3 );
398                 append( sb, "Expression: ${licensesOutputFile}", 3 );
399                 append( sb, "", 0 );
400 
401                 append( sb, "offline (Default: ${settings.offline})", 2 );
402                 append( sb, "Settings offline flag (will not download anything if setted to true).", 3 );
403                 append( sb, "", 0 );
404 
405                 append( sb, "quiet (Default: false)", 2 );
406                 append( sb, "Don\'t show warnings about bad or missing license files.", 3 );
407                 append( sb, "", 0 );
408             }
409         }
410 
411         if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
412         {
413             append( sb, "license:help", 0 );
414             append( sb, "Display help information on license-maven-plugin.\nCall\n\u00a0\u00a0mvn\u00a0license:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
415             append( sb, "", 0 );
416             if ( detail )
417             {
418                 append( sb, "Available parameters:", 1 );
419                 append( sb, "", 0 );
420 
421                 append( sb, "detail (Default: false)", 2 );
422                 append( sb, "If true, display all settable properties for each goal.", 3 );
423                 append( sb, "Expression: ${detail}", 3 );
424                 append( sb, "", 0 );
425 
426                 append( sb, "goal", 2 );
427                 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
428                 append( sb, "Expression: ${goal}", 3 );
429                 append( sb, "", 0 );
430 
431                 append( sb, "indentSize (Default: 2)", 2 );
432                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
433                 append( sb, "Expression: ${indentSize}", 3 );
434                 append( sb, "", 0 );
435 
436                 append( sb, "lineLength (Default: 80)", 2 );
437                 append( sb, "The maximum length of a display line, should be positive.", 3 );
438                 append( sb, "Expression: ${lineLength}", 3 );
439                 append( sb, "", 0 );
440             }
441         }
442 
443         if ( goal == null || goal.length() <= 0 || "license-list".equals( goal ) )
444         {
445             append( sb, "license:license-list", 0 );
446             append( sb, "Display all available licenses.", 1 );
447             append( sb, "", 0 );
448             if ( detail )
449             {
450                 append( sb, "Available parameters:", 1 );
451                 append( sb, "", 0 );
452 
453                 append( sb, "detail", 2 );
454                 append( sb, "A flag to display also the content of each license.", 3 );
455                 append( sb, "Expression: ${detail}", 3 );
456                 append( sb, "", 0 );
457 
458                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
459                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
460                 append( sb, "Expression: ${license.encoding}", 3 );
461                 append( sb, "", 0 );
462 
463                 append( sb, "extraResolver", 2 );
464                 append( sb, "the url of an extra license repository.", 3 );
465                 append( sb, "Expression: ${extraResolver}", 3 );
466                 append( sb, "", 0 );
467 
468                 append( sb, "project (Default: ${project})", 2 );
469                 append( sb, "The reacted project.", 3 );
470                 append( sb, "Required: Yes", 3 );
471                 append( sb, "", 0 );
472 
473                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
474                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
475                 append( sb, "Expression: ${license.verbose}", 3 );
476                 append( sb, "", 0 );
477             }
478         }
479 
480         if ( goal == null || goal.length() <= 0 || "update-file-header".equals( goal ) )
481         {
482             append( sb, "license:update-file-header", 0 );
483             append( sb, "The goal to update (or add) the header on project source files.\nThis goal replace the update-header goal which can not deal with Copyright.\n\nThis goal use a specific project file descriptor project.xml to describe all files to update for a whole project.\n", 1 );
484             append( sb, "", 0 );
485             if ( detail )
486             {
487                 append( sb, "Available parameters:", 1 );
488                 append( sb, "", 0 );
489 
490                 append( sb, "addSvnKeyWords (Default: false)", 2 );
491                 append( sb, "A flag to add svn:keywords on new header.\nWill add svn keywords :\n\nAuthor,\u00a0Id,\u00a0Rev,\u00a0URL\u00a0and\u00a0Date\n", 3 );
492                 append( sb, "Expression: ${license.addSvnKeyWords}", 3 );
493                 append( sb, "", 0 );
494 
495                 append( sb, "canUpdateCopyright (Default: false)", 2 );
496                 append( sb, "A flag to authorize update of the copyright part of the header.\nNote: By default, do NOT authorize it since copyright part should be handled by developpers (holder can change on each file for example).\n", 3 );
497                 append( sb, "Expression: ${license.canUpdateCopyright}", 3 );
498                 append( sb, "", 0 );
499 
500                 append( sb, "canUpdateDescription (Default: false)", 2 );
501                 append( sb, "A flag to authorize update of the description part of the header.\nNote: By default, do NOT authorize it since description can change on each file).\n", 3 );
502                 append( sb, "Expression: ${license.canUpdateDescription}", 3 );
503                 append( sb, "", 0 );
504 
505                 append( sb, "canUpdateLicense (Default: true)", 2 );
506                 append( sb, "A flag to authorize update of the license part of the header.\nNote: By default, authorize it since license part should always be generated by the plugin.\n", 3 );
507                 append( sb, "Expression: ${license.canUpdateLicense}", 3 );
508                 append( sb, "", 0 );
509 
510                 append( sb, "clearAfterOperation (Default: true)", 2 );
511                 append( sb, "A flag to clear everything after execution.\nNote: This property should ONLY be used for test purpose.\n", 3 );
512                 append( sb, "Expression: ${license.clearAfterOperation}", 3 );
513                 append( sb, "", 0 );
514 
515                 append( sb, "dryRun (Default: false)", 2 );
516                 append( sb, "A flag to test plugin but modify no file.", 3 );
517                 append( sb, "Expression: ${dryRun}", 3 );
518                 append( sb, "", 0 );
519 
520                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
521                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
522                 append( sb, "Expression: ${license.encoding}", 3 );
523                 append( sb, "", 0 );
524 
525                 append( sb, "excludes", 2 );
526                 append( sb, "Specific files to excludes, separated by a comma. By default, thoses file type are excluded:\n-\tmodelisation\n-\timages\n\nNote: This parameter is not useable if you are still using a project file descriptor.\n", 3 );
527                 append( sb, "Expression: ${license.excludes}", 3 );
528                 append( sb, "", 0 );
529 
530                 append( sb, "extraExtensions", 2 );
531                 append( sb, "To associate extra extension files to an existing comment style.\nKeys of the map are the extension of extra files to treate, and the value is the comment style you want to associate.\n\nFor example, to treate file with extensions java2 and jdata as java files (says using the java comment style, declare this in your plugin configuration :\n\n<extraExtensions>\n<java2>java</java2>\n<jdata>java</jdata>\n</extraExtensions>\n\nNote: This parameter is not useable if you are still using a project file descriptor.\n", 3 );
532                 append( sb, "", 0 );
533 
534                 append( sb, "ignoreTag", 2 );
535                 append( sb, "A tag to place on files that will be ignored by the plugin.\nSometimes, it is necessary to do this when file is under a specific license.\n\nNote: If no sets, will use the default tag %%Ignore-License\n", 3 );
536                 append( sb, "Expression: ${license.ignoreTag}", 3 );
537                 append( sb, "", 0 );
538 
539                 append( sb, "inceptionYear (Default: ${project.inceptionYear})", 2 );
540                 append( sb, "Inception year of the project.\nWill be used as first year of copyright section in new header.\n", 3 );
541                 append( sb, "Required: Yes", 3 );
542                 append( sb, "Expression: ${license.inceptionYear}", 3 );
543                 append( sb, "", 0 );
544 
545                 append( sb, "includes", 2 );
546                 append( sb, "Specific files to includes, separated by a comma. By default, it is \'** /*\'.\nNote: This parameter is not useable if you are still using a project file descriptor.\n", 3 );
547                 append( sb, "Expression: ${license.includes}", 3 );
548                 append( sb, "", 0 );
549 
550                 append( sb, "keepBackup (Default: false)", 2 );
551                 append( sb, "A flag to keep a backup of every modified file.", 3 );
552                 append( sb, "Expression: ${license.keepBackup}", 3 );
553                 append( sb, "", 0 );
554 
555                 append( sb, "licenseName", 2 );
556                 append( sb, "Name of the license to use in the project.", 3 );
557                 append( sb, "Expression: ${license.licenseName}", 3 );
558                 append( sb, "", 0 );
559 
560                 append( sb, "licenseResolver", 2 );
561                 append( sb, "To specify an external extra licenses repository resolver (says the base url of the repository where the license.properties is present).", 3 );
562                 append( sb, "Expression: ${license.licenseResolver}", 3 );
563                 append( sb, "", 0 );
564 
565                 append( sb, "organizationName (Default: ${project.organization.name})", 2 );
566                 append( sb, "Name of project\'s organization.\nWill be used as copyrigth\'s holder in new header.\n", 3 );
567                 append( sb, "Required: Yes", 3 );
568                 append( sb, "Expression: ${license.organizationName}", 3 );
569                 append( sb, "", 0 );
570 
571                 append( sb, "project (Default: ${project})", 2 );
572                 append( sb, "The reacted project.", 3 );
573                 append( sb, "Required: Yes", 3 );
574                 append( sb, "", 0 );
575 
576                 append( sb, "projectName (Default: ${project.name})", 2 );
577                 append( sb, "Name of project (or module).\nWill be used as description section of new header.\n", 3 );
578                 append( sb, "Required: Yes", 3 );
579                 append( sb, "Expression: ${license.projectName}", 3 );
580                 append( sb, "", 0 );
581 
582                 append( sb, "roots", 2 );
583                 append( sb, "To specify the base dir from which we apply the license.\nShould be on form \'root1,root2,rootn\'.\n\nBy default, the main roots are \'src, target\ngenerated-sources, target/processed-sources\'.\nNote: If some of these roots do not exist, they will be simply ignored.\n\nNote: This parameter is not useable if you are still using a project file descriptor.\n", 3 );
584                 append( sb, "Expression: ${license.roots}", 3 );
585                 append( sb, "", 0 );
586 
587                 append( sb, "skipUpdateLicense (Default: false)", 2 );
588                 append( sb, "A flag to skip the goal.", 3 );
589                 append( sb, "Expression: ${license.skipUpdateLicense}", 3 );
590                 append( sb, "", 0 );
591 
592                 append( sb, "updateCopyright (Default: false)", 2 );
593                 append( sb, "A flag to update copyright application time (change copyright last year if required) according to the last commit made on the processed file.\nNote that this functionnality is still not effective.\n", 3 );
594                 append( sb, "Expression: ${license.updateCopyright}", 3 );
595                 append( sb, "", 0 );
596 
597                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
598                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
599                 append( sb, "Expression: ${license.verbose}", 3 );
600                 append( sb, "", 0 );
601             }
602         }
603 
604         if ( goal == null || goal.length() <= 0 || "update-project-license".equals( goal ) )
605         {
606             append( sb, "license:update-project-license", 0 );
607             append( sb, "Updates (or creates) the main project license file according to the given license defines as licenseName.\nCan also generate a bundled license file (to avoid collision names in class-path). This file is by default generated in META-INF class-path directory.\n", 1 );
608             append( sb, "", 0 );
609             if ( detail )
610             {
611                 append( sb, "Available parameters:", 1 );
612                 append( sb, "", 0 );
613 
614                 append( sb, "bundleLicensePath (Default: META-INF/${project.artifactId}-LICENSE.txt)", 2 );
615                 append( sb, "The path of the bundled license file to produce when generateBundle is on.\nNote: This option is not available for pom module types.\n", 3 );
616                 append( sb, "Expression: ${license.bundleLicensePath}", 3 );
617                 append( sb, "", 0 );
618 
619                 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
620                 append( sb, "Encoding used to read and writes files.\nNote: If nothing is filled here, we will use the system property file.encoding.\n", 3 );
621                 append( sb, "Expression: ${license.encoding}", 3 );
622                 append( sb, "", 0 );
623 
624                 append( sb, "force (Default: false)", 2 );
625                 append( sb, "A flag to force to generate project license file even if it is up-to-date.", 3 );
626                 append( sb, "Expression: ${license.force}", 3 );
627                 append( sb, "", 0 );
628 
629                 append( sb, "generateBundle (Default: false)", 2 );
630                 append( sb, "A flag to copy the main license file in a bundled place.\nThis is usefull for final application to have a none confusing location to seek for the application license.\n\nIf Sets to true, will copy the license file to the bundleLicensePath to outputDirectory.\n\nNote: This option is not available for pom module types.\n", 3 );
631                 append( sb, "Expression: ${license.generateBundle}", 3 );
632                 append( sb, "", 0 );
633 
634                 append( sb, "keepBackup (Default: false)", 2 );
635                 append( sb, "A flag to keep a backup of every modified file.", 3 );
636                 append( sb, "Expression: ${license.keepBackup}", 3 );
637                 append( sb, "", 0 );
638 
639                 append( sb, "licenseFile (Default: ${basedir}/LICENSE.txt)", 2 );
640                 append( sb, "Project license file to synchronize with main license defined in descriptor file.", 3 );
641                 append( sb, "Required: Yes", 3 );
642                 append( sb, "Expression: ${license.licenceFile}", 3 );
643                 append( sb, "", 0 );
644 
645                 append( sb, "licenseName", 2 );
646                 append( sb, "Name of the license to use in the project.", 3 );
647                 append( sb, "Expression: ${license.licenseName}", 3 );
648                 append( sb, "", 0 );
649 
650                 append( sb, "licenseResolver", 2 );
651                 append( sb, "To specify an external extra licenses repository resolver (says the base url of the repository where the license.properties is present).", 3 );
652                 append( sb, "Expression: ${license.licenseResolver}", 3 );
653                 append( sb, "", 0 );
654 
655                 append( sb, "outputDirectory (Default: target/generated-sources/license)", 2 );
656                 append( sb, "The directory where to generate license resources.\nNote: This option is not available for pom module types.\n", 3 );
657                 append( sb, "Expression: ${license.outputDirectory}", 3 );
658                 append( sb, "", 0 );
659 
660                 append( sb, "project (Default: ${project})", 2 );
661                 append( sb, "The reacted project.", 3 );
662                 append( sb, "Required: Yes", 3 );
663                 append( sb, "", 0 );
664 
665                 append( sb, "skipUpdateProjectLicense (Default: false)", 2 );
666                 append( sb, "A flag to skip the goal.", 3 );
667                 append( sb, "Expression: ${license.skipUpdateProjectLicense}", 3 );
668                 append( sb, "", 0 );
669 
670                 append( sb, "verbose (Default: ${maven.verbose})", 2 );
671                 append( sb, "Flag to activate verbose mode.\nNote: Verbose mode is always on if you starts a debug maven instance (says via -X).\n", 3 );
672                 append( sb, "Expression: ${license.verbose}", 3 );
673                 append( sb, "", 0 );
674             }
675         }
676 
677         if ( getLog().isInfoEnabled() )
678         {
679             getLog().info( sb.toString() );
680         }
681     }
682 
683     /**
684      * <p>Repeat a String <code>n</code> times to form a new string.</p>
685      *
686      * @param str String to repeat
687      * @param repeat number of times to repeat str
688      * @return String with repeated String
689      * @throws NegativeArraySizeException if <code>repeat < 0</code>
690      * @throws NullPointerException if str is <code>null</code>
691      */
692     private static String repeat( String str, int repeat )
693     {
694         StringBuffer buffer = new StringBuffer( repeat * str.length() );
695 
696         for ( int i = 0; i < repeat; i++ )
697         {
698             buffer.append( str );
699         }
700 
701         return buffer.toString();
702     }
703 
704     /** 
705      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
706      * <b>Note</b>: The last character is always a new line.
707      * 
708      * @param sb The buffer to append the description, not <code>null</code>.
709      * @param description The description, not <code>null</code>.
710      * @param indent The base indentation level of each line, must not be negative.
711      */
712     private void append( StringBuffer sb, String description, int indent )
713     {
714         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
715         {
716             sb.append( it.next().toString() ).append( '\n' );
717         }
718     }
719 
720     /** 
721      * Splits the specified text into lines of convenient display length.
722      * 
723      * @param text The text to split into lines, must not be <code>null</code>.
724      * @param indent The base indentation level of each line, must not be negative.
725      * @param indentSize The size of each indentation, must not be negative.
726      * @param lineLength The length of the line, must not be negative.
727      * @return The sequence of display lines, never <code>null</code>.
728      * @throws NegativeArraySizeException if <code>indent < 0</code>
729      */
730     private static List toLines( String text, int indent, int indentSize, int lineLength )
731     {
732         List lines = new ArrayList();
733 
734         String ind = repeat( "\t", indent );
735         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
736         for ( int i = 0; i < plainLines.length; i++ )
737         {
738             toLines( lines, ind + plainLines[i], indentSize, lineLength );
739         }
740 
741         return lines;
742     }
743 
744     /** 
745      * Adds the specified line to the output sequence, performing line wrapping if necessary.
746      * 
747      * @param lines The sequence of display lines, must not be <code>null</code>.
748      * @param line The line to add, must not be <code>null</code>.
749      * @param indentSize The size of each indentation, must not be negative.
750      * @param lineLength The length of the line, must not be negative.
751      */
752     private static void toLines( List lines, String line, int indentSize, int lineLength )
753     {
754         int lineIndent = getIndentLevel( line );
755         StringBuffer buf = new StringBuffer( 256 );
756         String[] tokens = line.split( " +" );
757         for ( int i = 0; i < tokens.length; i++ )
758         {
759             String token = tokens[i];
760             if ( i > 0 )
761             {
762                 if ( buf.length() + token.length() >= lineLength )
763                 {
764                     lines.add( buf.toString() );
765                     buf.setLength( 0 );
766                     buf.append( repeat( " ", lineIndent * indentSize ) );
767                 }
768                 else
769                 {
770                     buf.append( ' ' );
771                 }
772             }
773             for ( int j = 0; j < token.length(); j++ )
774             {
775                 char c = token.charAt( j );
776                 if ( c == '\t' )
777                 {
778                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
779                 }
780                 else if ( c == '\u00A0' )
781                 {
782                     buf.append( ' ' );
783                 }
784                 else
785                 {
786                     buf.append( c );
787                 }
788             }
789         }
790         lines.add( buf.toString() );
791     }
792 
793     /** 
794      * Gets the indentation level of the specified line.
795      * 
796      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
797      * @return The indentation level of the line.
798      */
799     private static int getIndentLevel( String line )
800     {
801         int level = 0;
802         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
803         {
804             level++;
805         }
806         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
807         {
808             if ( line.charAt( i ) == '\t' )
809             {
810                 level++;
811                 break;
812             }
813         }
814         return level;
815     }
816 }