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