1 package org.apache.maven.tools.plugin.generator;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.OutputStreamWriter;
26 import java.io.Writer;
27 import java.util.LinkedHashMap;
28 import java.util.LinkedHashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import org.apache.maven.plugin.descriptor.DuplicateMojoDescriptorException;
33 import org.apache.maven.plugin.descriptor.MojoDescriptor;
34 import org.apache.maven.plugin.descriptor.Parameter;
35 import org.apache.maven.plugin.descriptor.PluginDescriptor;
36 import org.apache.maven.plugin.descriptor.Requirement;
37 import org.apache.maven.plugin.logging.Log;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
40 import org.apache.maven.tools.plugin.PluginToolsRequest;
41 import org.apache.maven.tools.plugin.util.PluginUtils;
42 import org.codehaus.plexus.util.IOUtil;
43 import org.codehaus.plexus.util.StringUtils;
44 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
45 import org.codehaus.plexus.util.xml.XMLWriter;
46
47
48
49
50
51
52
53 public class PluginDescriptorGenerator
54 implements Generator
55 {
56
57 private final Log log;
58
59 public PluginDescriptorGenerator( Log log )
60 {
61 this.log = log;
62 }
63
64
65
66
67 public void execute( File destinationDirectory, PluginToolsRequest request )
68 throws GeneratorException
69 {
70
71 PluginHelpGenerator.rewriteHelpMojo( request, log );
72
73 try
74 {
75
76 File f = new File( destinationDirectory, "plugin.xml" );
77 writeDescriptor( f, request, false );
78
79
80 MavenProject mavenProject = request.getProject();
81
82 f = new File( mavenProject.getBuild().getOutputDirectory(),
83 PluginHelpGenerator.getPluginHelpPath( mavenProject ) );
84
85 writeDescriptor( f, request, true );
86 }
87 catch ( IOException e )
88 {
89 throw new GeneratorException( e.getMessage(), e );
90 }
91 catch ( DuplicateMojoDescriptorException e )
92 {
93 throw new GeneratorException( e.getMessage(), e );
94 }
95 }
96
97 private String getVersion()
98 {
99 Package p = this.getClass().getPackage();
100 String version = ( p == null ) ? null : p.getSpecificationVersion();
101 return ( version == null ) ? "SNAPSHOT" : version;
102 }
103
104 public void writeDescriptor( File destinationFile, PluginToolsRequest request, boolean helpDescriptor )
105 throws IOException, DuplicateMojoDescriptorException
106 {
107 PluginDescriptor pluginDescriptor = request.getPluginDescriptor();
108
109 if ( destinationFile.exists() )
110 {
111 destinationFile.delete();
112 }
113 else
114 {
115 if ( !destinationFile.getParentFile().exists() )
116 {
117 destinationFile.getParentFile().mkdirs();
118 }
119 }
120
121 String encoding = "UTF-8";
122
123 Writer writer = null;
124 try
125 {
126 writer = new OutputStreamWriter( new FileOutputStream( destinationFile ), encoding );
127
128 XMLWriter w = new PrettyPrintXMLWriter( writer, encoding, null );
129
130 w.writeMarkup( "\n<!-- Generated by maven-plugin-tools " + getVersion() + " -->\n\n" );
131
132 w.startElement( "plugin" );
133
134 GeneratorUtils.element( w, "name", pluginDescriptor.getName() );
135
136 GeneratorUtils.element( w, "description", pluginDescriptor.getDescription(), helpDescriptor );
137
138 GeneratorUtils.element( w, "groupId", pluginDescriptor.getGroupId() );
139
140 GeneratorUtils.element( w, "artifactId", pluginDescriptor.getArtifactId() );
141
142 GeneratorUtils.element( w, "version", pluginDescriptor.getVersion() );
143
144 GeneratorUtils.element( w, "goalPrefix", pluginDescriptor.getGoalPrefix() );
145
146 if ( !helpDescriptor )
147 {
148 GeneratorUtils.element( w, "isolatedRealm", String.valueOf( pluginDescriptor.isIsolatedRealm() ) );
149
150 GeneratorUtils.element( w, "inheritedByDefault",
151 String.valueOf( pluginDescriptor.isInheritedByDefault() ) );
152 }
153
154 w.startElement( "mojos" );
155
156 if ( pluginDescriptor.getMojos() != null )
157 {
158 @SuppressWarnings( "unchecked" ) List<MojoDescriptor> descriptors = pluginDescriptor.getMojos();
159
160 PluginUtils.sortMojos( descriptors );
161
162 for ( MojoDescriptor descriptor : descriptors )
163 {
164 processMojoDescriptor( descriptor, w, helpDescriptor );
165 }
166 }
167
168 w.endElement();
169
170 if ( !helpDescriptor )
171 {
172 GeneratorUtils.writeDependencies( w, pluginDescriptor );
173 }
174
175 w.endElement();
176
177 writer.flush();
178
179 }
180 finally
181 {
182 IOUtil.close( writer );
183 }
184 }
185
186 protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w )
187 {
188 processMojoDescriptor( mojoDescriptor, w, false );
189 }
190
191
192
193
194
195
196 protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w, boolean helpDescriptor )
197 {
198 w.startElement( "mojo" );
199
200
201
202
203
204 w.startElement( "goal" );
205 w.writeText( mojoDescriptor.getGoal() );
206 w.endElement();
207
208
209
210
211
212 String description = mojoDescriptor.getDescription();
213
214 if ( StringUtils.isNotEmpty( description ) )
215 {
216 w.startElement( "description" );
217 if ( helpDescriptor )
218 {
219 w.writeText( GeneratorUtils.toText( mojoDescriptor.getDescription() ) );
220 }
221 else
222 {
223 w.writeText( mojoDescriptor.getDescription() );
224 }
225 w.endElement();
226 }
227
228
229
230
231
232 if ( StringUtils.isNotEmpty( mojoDescriptor.isDependencyResolutionRequired() ) )
233 {
234 GeneratorUtils.element( w, "requiresDependencyResolution",
235 mojoDescriptor.isDependencyResolutionRequired() );
236 }
237
238
239
240
241
242 GeneratorUtils.element( w, "requiresDirectInvocation",
243 String.valueOf( mojoDescriptor.isDirectInvocationOnly() ) );
244
245
246
247
248
249 GeneratorUtils.element( w, "requiresProject", String.valueOf( mojoDescriptor.isProjectRequired() ) );
250
251
252
253
254
255 GeneratorUtils.element( w, "requiresReports", String.valueOf( mojoDescriptor.isRequiresReports() ) );
256
257
258
259
260
261 GeneratorUtils.element( w, "aggregator", String.valueOf( mojoDescriptor.isAggregator() ) );
262
263
264
265
266
267 GeneratorUtils.element( w, "requiresOnline", String.valueOf( mojoDescriptor.isOnlineRequired() ) );
268
269
270
271
272
273 GeneratorUtils.element( w, "inheritedByDefault", String.valueOf( mojoDescriptor.isInheritedByDefault() ) );
274
275
276
277
278
279 if ( StringUtils.isNotEmpty( mojoDescriptor.getPhase() ) )
280 {
281 GeneratorUtils.element( w, "phase", mojoDescriptor.getPhase() );
282 }
283
284
285
286
287
288 if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) )
289 {
290 GeneratorUtils.element( w, "executePhase", mojoDescriptor.getExecutePhase() );
291 }
292
293 if ( StringUtils.isNotEmpty( mojoDescriptor.getExecuteGoal() ) )
294 {
295 GeneratorUtils.element( w, "executeGoal", mojoDescriptor.getExecuteGoal() );
296 }
297
298 if ( StringUtils.isNotEmpty( mojoDescriptor.getExecuteLifecycle() ) )
299 {
300 GeneratorUtils.element( w, "executeLifecycle", mojoDescriptor.getExecuteLifecycle() );
301 }
302
303
304
305
306
307 w.startElement( "implementation" );
308 w.writeText( mojoDescriptor.getImplementation() );
309 w.endElement();
310
311
312
313
314
315 w.startElement( "language" );
316 w.writeText( mojoDescriptor.getLanguage() );
317 w.endElement();
318
319
320
321
322
323 if ( StringUtils.isNotEmpty( mojoDescriptor.getComponentConfigurator() ) )
324 {
325 w.startElement( "configurator" );
326 w.writeText( mojoDescriptor.getComponentConfigurator() );
327 w.endElement();
328 }
329
330
331
332
333
334 if ( StringUtils.isNotEmpty( mojoDescriptor.getComponentComposer() ) )
335 {
336 w.startElement( "composer" );
337 w.writeText( mojoDescriptor.getComponentComposer() );
338 w.endElement();
339 }
340
341
342
343
344
345 w.startElement( "instantiationStrategy" );
346 w.writeText( mojoDescriptor.getInstantiationStrategy() );
347 w.endElement();
348
349
350
351
352
353 w.startElement( "executionStrategy" );
354 w.writeText( mojoDescriptor.getExecutionStrategy() );
355 w.endElement();
356
357
358
359
360
361 if ( mojoDescriptor.getSince() != null )
362 {
363 w.startElement( "since" );
364
365 if ( StringUtils.isEmpty( mojoDescriptor.getSince() ) )
366 {
367 w.writeText( "No version given" );
368 }
369 else
370 {
371 w.writeText( mojoDescriptor.getSince() );
372 }
373
374 w.endElement();
375 }
376
377
378
379
380
381 if ( mojoDescriptor.getDeprecated() != null )
382 {
383 w.startElement( "deprecated" );
384
385 if ( StringUtils.isEmpty( mojoDescriptor.getDeprecated() ) )
386 {
387 w.writeText( "No reason given" );
388 }
389 else
390 {
391 w.writeText( mojoDescriptor.getDeprecated() );
392 }
393
394 w.endElement();
395 }
396
397
398
399
400
401 if ( mojoDescriptor instanceof ExtendedMojoDescriptor )
402 {
403 ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor;
404 if ( extendedMojoDescriptor.getDependencyCollectionRequired() != null )
405 {
406 GeneratorUtils.element( w, "requiresDependencyCollection",
407 extendedMojoDescriptor.getDependencyCollectionRequired() );
408 }
409
410 GeneratorUtils.element( w, "threadSafe", String.valueOf( extendedMojoDescriptor.isThreadSafe() ) );
411 }
412
413
414
415
416
417 @SuppressWarnings( "unchecked" ) List<Parameter> parameters = mojoDescriptor.getParameters();
418
419 w.startElement( "parameters" );
420
421 Map<String, Requirement> requirements = new LinkedHashMap<String, Requirement>();
422
423 Set<Parameter> configuration = new LinkedHashSet<Parameter>();
424
425 if ( parameters != null )
426 {
427 if ( helpDescriptor )
428 {
429 PluginUtils.sortMojoParameters( parameters );
430 }
431
432 for ( Parameter parameter : parameters )
433 {
434 String expression = getExpression( parameter );
435
436 if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${component." ) )
437 {
438
439
440
441 String role = expression.substring( "${component.".length(), expression.length() - 1 );
442
443 String roleHint = null;
444
445 int posRoleHintSeparator = role.indexOf( '#' );
446 if ( posRoleHintSeparator > 0 )
447 {
448 roleHint = role.substring( posRoleHintSeparator + 1 );
449
450 role = role.substring( 0, posRoleHintSeparator );
451 }
452
453
454 requirements.put( parameter.getName(), new Requirement( role, roleHint ) );
455 }
456 else if ( parameter.getRequirement() != null )
457 {
458 requirements.put( parameter.getName(), parameter.getRequirement() );
459 }
460 else if ( !helpDescriptor || parameter.isEditable() )
461 {
462
463
464 w.startElement( "parameter" );
465
466 GeneratorUtils.element( w, "name", parameter.getName() );
467
468 if ( parameter.getAlias() != null )
469 {
470 GeneratorUtils.element( w, "alias", parameter.getAlias() );
471 }
472
473 GeneratorUtils.element( w, "type", parameter.getType() );
474
475 if ( parameter.getSince() != null )
476 {
477 w.startElement( "since" );
478
479 if ( StringUtils.isEmpty( parameter.getSince() ) )
480 {
481 w.writeText( "No version given" );
482 }
483 else
484 {
485 w.writeText( parameter.getSince() );
486 }
487
488 w.endElement();
489 }
490
491 if ( parameter.getDeprecated() != null )
492 {
493 if ( StringUtils.isEmpty( parameter.getDeprecated() ) )
494 {
495 GeneratorUtils.element( w, "deprecated", "No reason given" );
496 }
497 else
498 {
499 GeneratorUtils.element( w, "deprecated", parameter.getDeprecated() );
500 }
501 }
502
503 if ( parameter.getImplementation() != null )
504 {
505 GeneratorUtils.element( w, "implementation", parameter.getImplementation() );
506 }
507
508 GeneratorUtils.element( w, "required", Boolean.toString( parameter.isRequired() ) );
509
510 GeneratorUtils.element( w, "editable", Boolean.toString( parameter.isEditable() ) );
511
512 GeneratorUtils.element( w, "description", parameter.getDescription(), helpDescriptor );
513
514 if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) || StringUtils.isNotEmpty(
515 parameter.getExpression() ) )
516 {
517 configuration.add( parameter );
518 }
519
520 w.endElement();
521 }
522
523 }
524 }
525
526 w.endElement();
527
528
529
530
531
532 if ( !configuration.isEmpty() )
533 {
534 w.startElement( "configuration" );
535
536 for ( Parameter parameter : configuration )
537 {
538 if ( helpDescriptor && !parameter.isEditable() )
539 {
540
541 continue;
542 }
543
544 w.startElement( parameter.getName() );
545
546 String type = parameter.getType();
547 if ( StringUtils.isNotEmpty( type ) )
548 {
549 w.addAttribute( "implementation", type );
550 }
551
552 if ( parameter.getDefaultValue() != null )
553 {
554 w.addAttribute( "default-value", parameter.getDefaultValue() );
555 }
556
557 if ( StringUtils.isNotEmpty( parameter.getExpression() ) )
558 {
559 w.writeText( parameter.getExpression() );
560 }
561
562 w.endElement();
563 }
564
565 w.endElement();
566 }
567
568
569
570
571
572 if ( !requirements.isEmpty() && !helpDescriptor )
573 {
574 w.startElement( "requirements" );
575
576 for ( Map.Entry<String, Requirement> entry : requirements.entrySet() )
577 {
578 String key = entry.getKey();
579 Requirement requirement = entry.getValue();
580
581 w.startElement( "requirement" );
582
583 GeneratorUtils.element( w, "role", requirement.getRole() );
584
585 if ( StringUtils.isNotEmpty( requirement.getRoleHint() ) )
586 {
587 GeneratorUtils.element( w, "role-hint", requirement.getRoleHint() );
588 }
589
590 GeneratorUtils.element( w, "field-name", key );
591
592 w.endElement();
593 }
594
595 w.endElement();
596 }
597
598 w.endElement();
599 }
600
601
602
603
604
605
606
607 private String getExpression( Parameter parameter )
608 {
609 String expression = parameter.getExpression();
610 if ( StringUtils.isNotBlank( expression ) && !expression.contains( "${" ) )
611 {
612 expression = "${" + expression.trim() + "}";
613 parameter.setExpression( expression );
614 }
615 return expression;
616 }
617 }