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