1 package org.apache.maven.plugin.resources.remote;
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
12
13
14
15
16
17
18
19 public class HelpMojo
20 extends AbstractMojo
21 {
22
23
24
25
26
27 private boolean detail;
28
29
30
31
32
33
34 private java.lang.String goal;
35
36
37
38
39
40
41 private int lineLength;
42
43
44
45
46
47
48 private int indentSize;
49
50
51
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.apache.maven.plugins:maven-remote-resources-plugin:1.2", 0 );
69 append( sb, "", 0 );
70
71 append( sb, "Maven Remote Resources Plugin", 0 );
72 append( sb, "Process resources packaged in JARs that have been deployed to a remote repository. The primary use case being satisfied is the consistent inclusion of common resources in a large set of projects. Maven projects at Apache use this plug-in to satisfy licensing requirements at Apache where each project must include license and notice files for each release.", 1 );
73 append( sb, "", 0 );
74
75 if ( goal == null || goal.length() <= 0 )
76 {
77 append( sb, "This plugin has 3 goals:", 0 );
78 append( sb, "", 0 );
79 }
80
81 if ( goal == null || goal.length() <= 0 || "bundle".equals( goal ) )
82 {
83 append( sb, "remote-resources:bundle", 0 );
84 append( sb, "Bundle up resources that should be considered as a remote-resource.", 1 );
85 append( sb, "", 0 );
86 if ( detail )
87 {
88 append( sb, "Available parameters:", 1 );
89 append( sb, "", 0 );
90
91 append( sb, "excludes", 2 );
92 append( sb, "A list of files to exclude. Can contain ant-style wildcards and double wildcards.", 3 );
93 append( sb, "", 0 );
94
95 append( sb, "includes", 2 );
96 append( sb, "A list of files to include. Can contain ant-style wildcards and double wildcards. The default includes are **/*.txt **/*.vm", 3 );
97 append( sb, "", 0 );
98
99 append( sb, "outputDirectory", 2 );
100 append( sb, "The directory where you want the resource bundle manifest written to.", 3 );
101 append( sb, "Expression: ${project.build.outputDirectory}", 3 );
102 append( sb, "", 0 );
103
104 append( sb, "resourcesDirectory", 2 );
105 append( sb, "The directory which contains the resources you want packaged up in this resource bundle.", 3 );
106 append( sb, "Expression: ${basedir}/src/main/resources", 3 );
107 append( sb, "", 0 );
108
109 append( sb, "sourceEncoding", 2 );
110 append( sb, "Encoding of the bundle.", 3 );
111 append( sb, "Expression: ${project.build.sourceEncoding}", 3 );
112 append( sb, "", 0 );
113 }
114 }
115
116 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
117 {
118 append( sb, "remote-resources:help", 0 );
119 append( sb, "Display help information on maven-remote-resources-plugin.\nCall\n\u00a0\u00a0mvn\u00a0remote-resources:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
120 append( sb, "", 0 );
121 if ( detail )
122 {
123 append( sb, "Available parameters:", 1 );
124 append( sb, "", 0 );
125
126 append( sb, "detail (Default: false)", 2 );
127 append( sb, "If true, display all settable properties for each goal.", 3 );
128 append( sb, "Expression: ${detail}", 3 );
129 append( sb, "", 0 );
130
131 append( sb, "goal", 2 );
132 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
133 append( sb, "Expression: ${goal}", 3 );
134 append( sb, "", 0 );
135
136 append( sb, "indentSize (Default: 2)", 2 );
137 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
138 append( sb, "Expression: ${indentSize}", 3 );
139 append( sb, "", 0 );
140
141 append( sb, "lineLength (Default: 80)", 2 );
142 append( sb, "The maximum length of a display line, should be positive.", 3 );
143 append( sb, "Expression: ${lineLength}", 3 );
144 append( sb, "", 0 );
145 }
146 }
147
148 if ( goal == null || goal.length() <= 0 || "process".equals( goal ) )
149 {
150 append( sb, "remote-resources:process", 0 );
151 append( sb, "Pull down resourceBundles containing remote resources and process the resources contained inside. When that is done the resources are injected into the current (in-memory) Maven project, making them available to the process-resources phase.\n\nResources that end in \'.vm\' are treated as velocity templates. For those, the \'.vm\' is stripped off for the final artifact name and it\'s fed through velocity to have properties expanded, conditions processed, etc...\n\nResources that don\'t end in \'.vm\' are copied \'as is\'.\n", 1 );
152 append( sb, "", 0 );
153 if ( detail )
154 {
155 append( sb, "Available parameters:", 1 );
156 append( sb, "", 0 );
157
158 append( sb, "appendedResourcesDirectory", 2 );
159 append( sb, "The directory containing extra information appended to the generated resources.", 3 );
160 append( sb, "Expression: ${basedir}/src/main/appended-resources", 3 );
161 append( sb, "", 0 );
162
163 append( sb, "attached (Default: true)", 2 );
164 append( sb, "Attaches the resource to the project as a resource directory", 3 );
165 append( sb, "", 0 );
166
167 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
168 append( sb, "The character encoding scheme to be applied when filtering resources.", 3 );
169 append( sb, "Expression: ${encoding}", 3 );
170 append( sb, "", 0 );
171
172 append( sb, "excludeArtifactIds", 2 );
173 append( sb, "Comma separated list of Artifact names too exclude.", 3 );
174 append( sb, "Expression: ${excludeArtifactIds}", 3 );
175 append( sb, "", 0 );
176
177 append( sb, "excludeGroupIds", 2 );
178 append( sb, "Comma separated list of GroupId Names to exclude.", 3 );
179 append( sb, "Expression: ${excludeGroupIds}", 3 );
180 append( sb, "", 0 );
181
182 append( sb, "excludeScope", 2 );
183 append( sb, "Scope to exclude. An Empty string indicates no scopes (default).", 3 );
184 append( sb, "Expression: ${excludeScope}", 3 );
185 append( sb, "", 0 );
186
187 append( sb, "excludeTransitive (Default: false)", 2 );
188 append( sb, "If we should exclude transitive dependencies", 3 );
189 append( sb, "Expression: ${excludeTransitive}", 3 );
190 append( sb, "", 0 );
191
192 append( sb, "filterDelimiters", 2 );
193 append( sb, "In cases where a local resource overrides one from a remote resource bundle, that resource should be filtered if the resource set specifies it. In those cases, this parameter defines the list of delimiters for filterable expressions. These delimiters are specified in the form \'beginToken*endToken\'. If no \'*\' is given, the delimiter is assumed to be the same for start and end.\n\nSo, the default filtering delimiters might be specified as:\n\n<delimiters>\n\u00a0\u00a0<delimiter>${*}</delimiter>\n\u00a0\u00a0<delimiter>@</delimiter>\n</delimiters>\n\nSince the \'@\' delimiter is the same on both ends, we don\'t need to specify \'@*@\' (though we can).\n", 3 );
194 append( sb, "", 0 );
195
196 append( sb, "includeArtifactIds", 2 );
197 append( sb, "Comma separated list of Artifact names to include.", 3 );
198 append( sb, "Expression: ${includeArtifactIds}", 3 );
199 append( sb, "", 0 );
200
201 append( sb, "includeGroupIds", 2 );
202 append( sb, "Comma separated list of GroupIds to include.", 3 );
203 append( sb, "Expression: ${includeGroupIds}", 3 );
204 append( sb, "", 0 );
205
206 append( sb, "includeProjectProperties (Default: false)", 2 );
207 append( sb, "Whether to include properties defined in the project when filtering resources.", 3 );
208 append( sb, "", 0 );
209
210 append( sb, "includeScope (Default: runtime)", 2 );
211 append( sb, "Scope to include. An Empty string indicates all scopes (default).", 3 );
212 append( sb, "Expression: ${includeScope}", 3 );
213 append( sb, "", 0 );
214
215 append( sb, "outputDirectory", 2 );
216 append( sb, "The directory where processed resources will be placed for packaging.", 3 );
217 append( sb, "Expression: ${project.build.directory}/maven-shared-archive-resources", 3 );
218 append( sb, "", 0 );
219
220 append( sb, "properties", 2 );
221 append( sb, "Additional properties to be passed to velocity.\n>Several properties are automatically added:\nproject - the current MavenProject\nprojects - the list of dependency projects\nprojectTimespan - the timespan of the current project (requires inceptionYear in pom)\n\n\n>See the javadoc for MavenProject for information about the properties on the MavenProject.\n", 3 );
222 append( sb, "", 0 );
223
224 append( sb, "resourceBundles", 2 );
225 append( sb, "The resource bundles that will be retrieved and processed.", 3 );
226 append( sb, "Required: Yes", 3 );
227 append( sb, "", 0 );
228
229 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
230 append( sb, "If true, only generate resources in the directory of the root project in a multimodule build. Dependencies from all modules will be aggregated before resource-generation takes place.", 3 );
231 append( sb, "", 0 );
232
233 append( sb, "skip (Default: false)", 2 );
234 append( sb, "Skip remote-resource processing", 3 );
235 append( sb, "Expression: ${remoteresources.skip}", 3 );
236 append( sb, "", 0 );
237
238 append( sb, "supplementalModelArtifacts", 2 );
239 append( sb, "List of artifacts that are added to the search path when looking for supplementalModels", 3 );
240 append( sb, "", 0 );
241
242 append( sb, "supplementalModels", 2 );
243 append( sb, "Supplemental model data. Useful when processing artifacts with incomplete POM metadata.\n>By default, this Mojo looks for supplemental model data in the file \'${appendedResourcesDirectory}\nsupplemental-models.xml\'.", 3 );
244 append( sb, "", 0 );
245
246 append( sb, "useDefaultFilterDelimiters (Default: true)", 2 );
247 append( sb, "(no description available)", 3 );
248 append( sb, "", 0 );
249 }
250 }
251
252 if ( getLog().isInfoEnabled() )
253 {
254 getLog().info( sb.toString() );
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267 private static String repeat( String str, int repeat )
268 {
269 StringBuffer buffer = new StringBuffer( repeat * str.length() );
270
271 for ( int i = 0; i < repeat; i++ )
272 {
273 buffer.append( str );
274 }
275
276 return buffer.toString();
277 }
278
279
280
281
282
283
284
285
286
287 private void append( StringBuffer sb, String description, int indent )
288 {
289 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
290 {
291 sb.append( it.next().toString() ).append( '\n' );
292 }
293 }
294
295
296
297
298
299
300
301
302
303
304
305 private static List toLines( String text, int indent, int indentSize, int lineLength )
306 {
307 List lines = new ArrayList();
308
309 String ind = repeat( "\t", indent );
310 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
311 for ( int i = 0; i < plainLines.length; i++ )
312 {
313 toLines( lines, ind + plainLines[i], indentSize, lineLength );
314 }
315
316 return lines;
317 }
318
319
320
321
322
323
324
325
326
327 private static void toLines( List lines, String line, int indentSize, int lineLength )
328 {
329 int lineIndent = getIndentLevel( line );
330 StringBuffer buf = new StringBuffer( 256 );
331 String[] tokens = line.split( " +" );
332 for ( int i = 0; i < tokens.length; i++ )
333 {
334 String token = tokens[i];
335 if ( i > 0 )
336 {
337 if ( buf.length() + token.length() >= lineLength )
338 {
339 lines.add( buf.toString() );
340 buf.setLength( 0 );
341 buf.append( repeat( " ", lineIndent * indentSize ) );
342 }
343 else
344 {
345 buf.append( ' ' );
346 }
347 }
348 for ( int j = 0; j < token.length(); j++ )
349 {
350 char c = token.charAt( j );
351 if ( c == '\t' )
352 {
353 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
354 }
355 else if ( c == '\u00A0' )
356 {
357 buf.append( ' ' );
358 }
359 else
360 {
361 buf.append( c );
362 }
363 }
364 }
365 lines.add( buf.toString() );
366 }
367
368
369
370
371
372
373
374 private static int getIndentLevel( String line )
375 {
376 int level = 0;
377 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
378 {
379 level++;
380 }
381 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
382 {
383 if ( line.charAt( i ) == '\t' )
384 {
385 level++;
386 break;
387 }
388 }
389 return level;
390 }
391 }