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