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