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 @SuppressWarnings( "all" )
20 public class HelpMojo
21 extends AbstractMojo
22 {
23
24
25
26
27
28 private boolean detail;
29
30
31
32
33
34
35 private java.lang.String goal;
36
37
38
39
40
41
42 private int lineLength;
43
44
45
46
47
48
49 private int indentSize;
50
51
52
53 public void execute()
54 throws MojoExecutionException
55 {
56 if ( lineLength <= 0 )
57 {
58 getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
59 lineLength = 80;
60 }
61 if ( indentSize <= 0 )
62 {
63 getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
64 indentSize = 2;
65 }
66
67 StringBuffer sb = new StringBuffer();
68
69 append( sb, "org.apache.maven.plugins:maven-remote-resources-plugin:1.3", 0 );
70 append( sb, "", 0 );
71
72 append( sb, "Maven Remote Resources Plugin", 0 );
73 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 );
74 append( sb, "", 0 );
75
76 if ( goal == null || goal.length() <= 0 )
77 {
78 append( sb, "This plugin has 3 goals:", 0 );
79 append( sb, "", 0 );
80 }
81
82 if ( goal == null || goal.length() <= 0 || "bundle".equals( goal ) )
83 {
84 append( sb, "remote-resources:bundle", 0 );
85 append( sb, "Bundle up resources that should be considered as a remote-resource.", 1 );
86 append( sb, "", 0 );
87 if ( detail )
88 {
89 append( sb, "Available parameters:", 1 );
90 append( sb, "", 0 );
91
92 append( sb, "excludes", 2 );
93 append( sb, "A list of files to exclude. Can contain ant-style wildcards and double wildcards.", 3 );
94 append( sb, "", 0 );
95
96 append( sb, "includes", 2 );
97 append( sb, "A list of files to include. Can contain ant-style wildcards and double wildcards. The default includes are **/*.txt **/*.vm", 3 );
98 append( sb, "", 0 );
99
100 append( sb, "outputDirectory (Default: ${project.build.outputDirectory})", 2 );
101 append( sb, "The directory where you want the resource bundle manifest written to.", 3 );
102 append( sb, "", 0 );
103
104 append( sb, "resourcesDirectory (Default: ${basedir}/src/main/resources)", 2 );
105 append( sb, "The directory which contains the resources you want packaged up in this resource bundle.", 3 );
106 append( sb, "", 0 );
107
108 append( sb, "sourceEncoding (Default: ${project.build.sourceEncoding})", 2 );
109 append( sb, "Encoding of the bundle.", 3 );
110 append( sb, "", 0 );
111 }
112 }
113
114 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
115 {
116 append( sb, "remote-resources:help", 0 );
117 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 );
118 append( sb, "", 0 );
119 if ( detail )
120 {
121 append( sb, "Available parameters:", 1 );
122 append( sb, "", 0 );
123
124 append( sb, "detail (Default: false)", 2 );
125 append( sb, "If true, display all settable properties for each goal.", 3 );
126 append( sb, "Expression: ${detail}", 3 );
127 append( sb, "", 0 );
128
129 append( sb, "goal", 2 );
130 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
131 append( sb, "Expression: ${goal}", 3 );
132 append( sb, "", 0 );
133
134 append( sb, "indentSize (Default: 2)", 2 );
135 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
136 append( sb, "Expression: ${indentSize}", 3 );
137 append( sb, "", 0 );
138
139 append( sb, "lineLength (Default: 80)", 2 );
140 append( sb, "The maximum length of a display line, should be positive.", 3 );
141 append( sb, "Expression: ${lineLength}", 3 );
142 append( sb, "", 0 );
143 }
144 }
145
146 if ( goal == null || goal.length() <= 0 || "process".equals( goal ) )
147 {
148 append( sb, "remote-resources:process", 0 );
149 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 );
150 append( sb, "", 0 );
151 if ( detail )
152 {
153 append( sb, "Available parameters:", 1 );
154 append( sb, "", 0 );
155
156 append( sb, "appendedResourcesDirectory (Default: ${basedir}/src/main/appended-resources)", 2 );
157 append( sb, "The directory containing extra information appended to the generated resources.", 3 );
158 append( sb, "", 0 );
159
160 append( sb, "attached (Default: true)", 2 );
161 append( sb, "Attaches the resource to the project as a resource directory", 3 );
162 append( sb, "", 0 );
163
164 append( sb, "encoding (Default: ${project.build.sourceEncoding})", 2 );
165 append( sb, "The character encoding scheme to be applied when filtering resources.", 3 );
166 append( sb, "Expression: ${encoding}", 3 );
167 append( sb, "", 0 );
168
169 append( sb, "excludeArtifactIds", 2 );
170 append( sb, "Comma separated list of Artifact names too exclude.", 3 );
171 append( sb, "Expression: ${excludeArtifactIds}", 3 );
172 append( sb, "", 0 );
173
174 append( sb, "excludeGroupIds", 2 );
175 append( sb, "Comma separated list of GroupId Names to exclude.", 3 );
176 append( sb, "Expression: ${excludeGroupIds}", 3 );
177 append( sb, "", 0 );
178
179 append( sb, "excludeScope", 2 );
180 append( sb, "Scope to exclude. An Empty string indicates no scopes (default).", 3 );
181 append( sb, "Expression: ${excludeScope}", 3 );
182 append( sb, "", 0 );
183
184 append( sb, "excludeTransitive (Default: false)", 2 );
185 append( sb, "If we should exclude transitive dependencies", 3 );
186 append( sb, "Expression: ${excludeTransitive}", 3 );
187 append( sb, "", 0 );
188
189 append( sb, "filterDelimiters", 2 );
190 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 );
191 append( sb, "", 0 );
192
193 append( sb, "includeArtifactIds", 2 );
194 append( sb, "Comma separated list of Artifact names to include.", 3 );
195 append( sb, "Expression: ${includeArtifactIds}", 3 );
196 append( sb, "", 0 );
197
198 append( sb, "includeGroupIds", 2 );
199 append( sb, "Comma separated list of GroupIds to include.", 3 );
200 append( sb, "Expression: ${includeGroupIds}", 3 );
201 append( sb, "", 0 );
202
203 append( sb, "includeProjectProperties (Default: false)", 2 );
204 append( sb, "Whether to include properties defined in the project when filtering resources.", 3 );
205 append( sb, "", 0 );
206
207 append( sb, "includeScope (Default: runtime)", 2 );
208 append( sb, "Scope to include. An Empty string indicates all scopes (default).", 3 );
209 append( sb, "Expression: ${includeScope}", 3 );
210 append( sb, "", 0 );
211
212 append( sb, "outputDirectory (Default: ${project.build.directory}/maven-shared-archive-resources)", 2 );
213 append( sb, "The directory where processed resources will be placed for packaging.", 3 );
214 append( sb, "", 0 );
215
216 append( sb, "properties", 2 );
217 append( sb, "Additional properties to be passed to velocity. 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)\nSee the javadoc for MavenProject for information about the properties on the MavenProject.", 3 );
218 append( sb, "", 0 );
219
220 append( sb, "resourceBundles", 2 );
221 append( sb, "The resource bundles that will be retrieved and processed.", 3 );
222 append( sb, "Required: Yes", 3 );
223 append( sb, "", 0 );
224
225 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
226 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 );
227 append( sb, "", 0 );
228
229 append( sb, "skip (Default: false)", 2 );
230 append( sb, "Skip remote-resource processing", 3 );
231 append( sb, "Expression: ${remoteresources.skip}", 3 );
232 append( sb, "", 0 );
233
234 append( sb, "supplementalModelArtifacts", 2 );
235 append( sb, "List of artifacts that are added to the search path when looking for supplementalModels", 3 );
236 append( sb, "", 0 );
237
238 append( sb, "supplementalModels", 2 );
239 append( sb, "Supplemental model data. Useful when processing artifacts with incomplete POM metadata. By default, this Mojo looks for supplemental model data in the file \'${appendedResourcesDirectory}/supplemental-models.xml\'.", 3 );
240 append( sb, "", 0 );
241
242 append( sb, "useDefaultFilterDelimiters (Default: true)", 2 );
243 append( sb, "(no description available)", 3 );
244 append( sb, "", 0 );
245 }
246 }
247
248 if ( getLog().isInfoEnabled() )
249 {
250 getLog().info( sb.toString() );
251 }
252 }
253
254
255
256
257
258
259
260
261
262
263 private static String repeat( String str, int repeat )
264 {
265 StringBuffer buffer = new StringBuffer( repeat * str.length() );
266
267 for ( int i = 0; i < repeat; i++ )
268 {
269 buffer.append( str );
270 }
271
272 return buffer.toString();
273 }
274
275
276
277
278
279
280
281
282
283 private void append( StringBuffer sb, String description, int indent )
284 {
285 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
286 {
287 sb.append( it.next().toString() ).append( '\n' );
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300
301 private static List toLines( String text, int indent, int indentSize, int lineLength )
302 {
303 List<String> lines = new ArrayList<String>();
304
305 String ind = repeat( "\t", indent );
306 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
307 for ( int i = 0; i < plainLines.length; i++ )
308 {
309 toLines( lines, ind + plainLines[i], indentSize, lineLength );
310 }
311
312 return lines;
313 }
314
315
316
317
318
319
320
321
322
323 private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
324 {
325 int lineIndent = getIndentLevel( line );
326 StringBuffer buf = new StringBuffer( 256 );
327 String[] tokens = line.split( " +" );
328 for ( int i = 0; i < tokens.length; i++ )
329 {
330 String token = tokens[i];
331 if ( i > 0 )
332 {
333 if ( buf.length() + token.length() >= lineLength )
334 {
335 lines.add( buf.toString() );
336 buf.setLength( 0 );
337 buf.append( repeat( " ", lineIndent * indentSize ) );
338 }
339 else
340 {
341 buf.append( ' ' );
342 }
343 }
344 for ( int j = 0; j < token.length(); j++ )
345 {
346 char c = token.charAt( j );
347 if ( c == '\t' )
348 {
349 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
350 }
351 else if ( c == '\u00A0' )
352 {
353 buf.append( ' ' );
354 }
355 else
356 {
357 buf.append( c );
358 }
359 }
360 }
361 lines.add( buf.toString() );
362 }
363
364
365
366
367
368
369
370 private static int getIndentLevel( String line )
371 {
372 int level = 0;
373 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
374 {
375 level++;
376 }
377 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
378 {
379 if ( line.charAt( i ) == '\t' )
380 {
381 level++;
382 break;
383 }
384 }
385 return level;
386 }
387 }