1 package org.apache.maven.plugin.plugin.report_old;
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.IOException;
24 import java.io.Reader;
25 import java.nio.file.Files;
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.ResourceBundle;
32
33 import org.apache.maven.doxia.sink.Sink;
34 import org.apache.maven.model.Plugin;
35 import org.apache.maven.plugin.descriptor.MojoDescriptor;
36 import org.apache.maven.plugin.descriptor.PluginDescriptor;
37 import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
38 import org.apache.maven.plugin.plugin.DescriptorGeneratorMojo;
39 import org.apache.maven.plugins.annotations.Component;
40 import org.apache.maven.plugins.annotations.Execute;
41 import org.apache.maven.plugins.annotations.LifecyclePhase;
42 import org.apache.maven.plugins.annotations.Mojo;
43 import org.apache.maven.plugins.annotations.Parameter;
44 import org.apache.maven.plugins.plugin.descriptor_old.EnhancedPluginDescriptorBuilder;
45 import org.apache.maven.project.MavenProject;
46 import org.apache.maven.reporting.AbstractMavenReport;
47 import org.apache.maven.reporting.AbstractMavenReportRenderer;
48 import org.apache.maven.reporting.MavenReportException;
49 import org.apache.maven.rtinfo.RuntimeInformation;
50 import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
51 import org.apache.maven.tools.plugin.PluginToolsRequest;
52 import org.apache.maven.tools.plugin.generator.GeneratorException;
53 import org.apache.maven.tools.plugin.generator.GeneratorUtils;
54 import org.apache.maven.tools.plugin.generator.PluginXdocGenerator;
55 import org.apache.maven.tools.plugin.util.PluginUtils;
56 import org.codehaus.plexus.configuration.PlexusConfigurationException;
57 import org.codehaus.plexus.util.StringUtils;
58 import org.codehaus.plexus.util.xml.XmlStreamReader;
59 import org.codehaus.plexus.util.xml.Xpp3Dom;
60
61
62
63
64
65
66
67
68
69
70
71 @Deprecated
72 @Mojo( name = "report", threadSafe = true )
73 @Execute( phase = LifecyclePhase.PROCESS_CLASSES )
74 public class PluginReport
75 extends AbstractMavenReport
76 {
77
78
79
80 @Parameter( defaultValue = "${project.build.directory}/generated-site/xdoc" )
81 private File outputDirectory;
82
83
84
85
86
87
88
89
90 @Deprecated
91 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
92 private String encoding;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 @Deprecated
119 @Parameter
120 private Requirements requirements;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 @Deprecated
144 @Parameter( property = "goalPrefix" )
145 protected String goalPrefix;
146
147
148
149
150
151
152
153
154 @Deprecated
155 @Parameter( defaultValue = "false", property = "maven.plugin.skip" )
156 private boolean skipReport;
157
158
159
160
161
162
163 @Parameter( defaultValue = "false", property = "maven.plugin.report.skip" )
164 private boolean skip;
165
166
167
168
169
170
171
172 @Parameter( defaultValue = "false", property = "maven.plugin.report.hasExtensionsToLoad" )
173 private boolean hasExtensionsToLoad;
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 @Parameter
193 private List<RequirementsHistory> requirementsHistories = new ArrayList<>();
194
195
196
197
198 @Component
199 private RuntimeInformation rtInfo;
200
201
202
203
204
205
206
207 @Parameter( defaultValue = "${project.build.outputDirectory}/META-INF/maven/plugin.xml", required = true,
208 readonly = true )
209 @Deprecated
210 private File pluginXmlFile;
211
212
213
214
215
216
217 @Parameter( defaultValue = "${project.build.directory}/plugin-enhanced.xml", required = true,
218 readonly = true )
219 private File enhancedPluginXmlFile;
220
221
222
223
224
225
226
227
228
229
230
231 @Parameter( property = "maven.plugin.report.disableInternalJavadocLinkValidation" )
232 private boolean disableInternalJavadocLinkValidation;
233
234
235
236
237 @Override
238 protected String getOutputDirectory()
239 {
240
241 return project.getReporting().getOutputDirectory();
242 }
243
244
245
246
247 @Override
248 public boolean canGenerateReport()
249 {
250 return enhancedPluginXmlFile != null && enhancedPluginXmlFile.isFile() && enhancedPluginXmlFile.canRead();
251 }
252
253
254
255
256 @Override
257 protected void executeReport( Locale locale )
258 throws MavenReportException
259 {
260 getLog().warn( "The 'report' goal of the maven-plugin-plugin is deprecated, please use "
261 + "the 'report' goal from the maven-plugin-report-plugin instead. This goal will be removed "
262 + "in version 4.0.0." );
263
264 if ( skip || skipReport )
265 {
266 getLog().info( "Maven Plugin Plugin Report generation skipped." );
267 return;
268 }
269
270 PluginDescriptor pluginDescriptor = extractPluginDescriptor();
271
272
273 generateMojosDocumentation( pluginDescriptor, locale );
274
275
276 PluginOverviewRenderer r =
277 new PluginOverviewRenderer( getProject(), requirements, requirementsHistories, getSink(),
278 pluginDescriptor, locale, hasExtensionsToLoad );
279 r.render();
280 }
281
282 private PluginDescriptor extractPluginDescriptor()
283 throws MavenReportException
284 {
285 PluginDescriptorBuilder builder = new EnhancedPluginDescriptorBuilder( rtInfo );
286
287 try ( Reader input = new XmlStreamReader( Files.newInputStream( enhancedPluginXmlFile.toPath() ) ) )
288 {
289 return builder.build( input );
290 }
291 catch ( IOException | PlexusConfigurationException e )
292 {
293 throw new MavenReportException( "Error extracting plugin descriptor from " + enhancedPluginXmlFile, e );
294 }
295
296 }
297
298
299
300
301 @Override
302 public String getDescription( Locale locale )
303 {
304 return getBundle( locale ).getString( "report.plugin.description" );
305 }
306
307
308
309
310 @Override
311 public String getName( Locale locale )
312 {
313 return getBundle( locale ).getString( "report.plugin.name" );
314 }
315
316
317
318
319 @Override
320 public String getOutputName()
321 {
322 return "plugin-info";
323 }
324
325
326
327
328
329
330
331
332 private void generateMojosDocumentation( PluginDescriptor pluginDescriptor, Locale locale )
333 throws MavenReportException
334 {
335 try
336 {
337 File outputDir = outputDirectory;
338 outputDir.mkdirs();
339
340 PluginXdocGenerator generator = new PluginXdocGenerator( getProject(), locale, getReportOutputDirectory(),
341 disableInternalJavadocLinkValidation );
342 PluginToolsRequest pluginToolsRequest = new DefaultPluginToolsRequest( getProject(), pluginDescriptor );
343 generator.execute( outputDir, pluginToolsRequest );
344 }
345 catch ( GeneratorException e )
346 {
347 throw new MavenReportException( "Error writing plugin documentation", e );
348 }
349
350 }
351
352
353
354
355
356 protected static ResourceBundle getBundle( Locale locale )
357 {
358 return ResourceBundle.getBundle( "plugin-report", locale, PluginReport.class.getClassLoader() );
359 }
360
361
362
363
364
365 static class PluginOverviewRenderer
366 extends AbstractMavenReportRenderer
367 {
368 private final MavenProject project;
369
370 private final Requirements requirements;
371
372 private final List<RequirementsHistory> requirementsHistories;
373
374 private final PluginDescriptor pluginDescriptor;
375
376 private final Locale locale;
377
378 private final boolean hasExtensionsToLoad;
379
380
381
382
383
384
385
386
387
388 PluginOverviewRenderer( MavenProject project, Requirements requirements,
389 List<RequirementsHistory> requirementsHistories, Sink sink,
390 PluginDescriptor pluginDescriptor, Locale locale, boolean hasExtensionsToLoad )
391 {
392 super( sink );
393
394 this.project = project;
395
396 this.requirements = ( requirements == null ? new Requirements() : requirements );
397
398 this.requirementsHistories = requirementsHistories;
399
400 this.pluginDescriptor = pluginDescriptor;
401
402 this.locale = locale;
403
404 this.hasExtensionsToLoad = hasExtensionsToLoad;
405 }
406
407
408
409
410 @Override
411 public String getTitle()
412 {
413 return getBundle( locale ).getString( "report.plugin.title" );
414 }
415
416
417
418
419 @Override
420 public void renderBody()
421 {
422 startSection( getTitle() );
423
424 if ( !( pluginDescriptor.getMojos() != null && pluginDescriptor.getMojos().size() > 0 ) )
425 {
426 paragraph( getBundle( locale ).getString( "report.plugin.goals.nogoal" ) );
427 endSection();
428 return;
429 }
430
431 paragraph( getBundle( locale ).getString( "report.plugin.goals.intro" ) );
432
433 boolean hasMavenReport = false;
434 for ( Iterator<MojoDescriptor> i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
435 {
436 MojoDescriptor mojo = i.next();
437
438 if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
439 {
440 hasMavenReport = true;
441 }
442 }
443
444 startTable();
445
446 String goalColumnName = getBundle( locale ).getString( "report.plugin.goals.column.goal" );
447 String isMavenReport = getBundle( locale ).getString( "report.plugin.goals.column.isMavenReport" );
448 String descriptionColumnName = getBundle( locale ).getString( "report.plugin.goals.column.description" );
449 if ( hasMavenReport )
450 {
451 tableHeader( new String[] {goalColumnName, isMavenReport, descriptionColumnName} );
452 }
453 else
454 {
455 tableHeader( new String[] {goalColumnName, descriptionColumnName} );
456 }
457
458 List<MojoDescriptor> mojos = new ArrayList<>();
459 mojos.addAll( pluginDescriptor.getMojos() );
460 PluginUtils.sortMojos( mojos );
461 for ( MojoDescriptor mojo : mojos )
462 {
463 String goalName = mojo.getFullGoalName();
464
465
466
467
468
469 String goalDocumentationLink = "./" + mojo.getGoal() + "-mojo.html";
470
471 String description;
472 if ( StringUtils.isNotEmpty( mojo.getDeprecated() ) )
473 {
474 description =
475 "<strong>" + getBundle( locale ).getString( "report.plugin.goal.deprecated" ) + "</strong> "
476 + mojo.getDeprecated();
477 }
478 else if ( StringUtils.isNotEmpty( mojo.getDescription() ) )
479 {
480 description = mojo.getDescription();
481 }
482 else
483 {
484 description = getBundle( locale ).getString( "report.plugin.goal.nodescription" );
485 }
486
487 sink.tableRow();
488 tableCell( createLinkPatternedText( goalName, goalDocumentationLink ) );
489 if ( hasMavenReport )
490 {
491 if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
492 {
493 sink.tableCell();
494 sink.text( getBundle( locale ).getString( "report.plugin.isReport" ) );
495 sink.tableCell_();
496 }
497 else
498 {
499 sink.tableCell();
500 sink.text( getBundle( locale ).getString( "report.plugin.isNotReport" ) );
501 sink.tableCell_();
502 }
503 }
504 tableCell( description, true );
505 sink.tableRow_();
506 }
507
508 endTable();
509
510 startSection( getBundle( locale ).getString( "report.plugin.systemrequirements" ) );
511
512 paragraph( getBundle( locale ).getString( "report.plugin.systemrequirements.intro" ) );
513
514 startTable();
515
516 String maven = discoverMavenRequirement( project, requirements );
517 sink.tableRow();
518 tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.maven" ) );
519 tableCell( ( maven != null
520 ? maven
521 : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
522 sink.tableRow_();
523
524 String jdk = discoverJdkRequirement( project, requirements );
525 sink.tableRow();
526 tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.jdk" ) );
527 tableCell(
528 ( jdk != null ? jdk : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
529 sink.tableRow_();
530
531 String memory = requirements.getMemory();
532 if ( StringUtils.isNotEmpty( memory ) )
533 {
534 sink.tableRow();
535 tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.memory" ) );
536 tableCell( memory );
537 sink.tableRow_();
538 }
539
540 String diskSpace = requirements.getDiskSpace();
541 if ( StringUtils.isNotEmpty( diskSpace ) )
542 {
543 sink.tableRow();
544 tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.diskspace" ) );
545 tableCell( diskSpace );
546 sink.tableRow_();
547 }
548
549 if ( requirements.getOthers() != null && requirements.getOthers().size() > 0 )
550 {
551 for ( Iterator it = requirements.getOthers().keySet().iterator(); it.hasNext(); )
552 {
553 String key = it.next().toString();
554
555 sink.tableRow();
556 tableCell( key );
557 tableCell( ( StringUtils.isNotEmpty( requirements.getOthers().getProperty( key ) )
558 ? requirements.getOthers().getProperty( key )
559 : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
560 sink.tableRow_();
561 }
562 }
563 endTable();
564
565 endSection();
566
567 renderRequirementsHistories();
568
569 renderUsageSection( hasMavenReport );
570
571 endSection();
572 }
573
574 private void renderRequirementsHistories()
575 {
576 if ( requirementsHistories.isEmpty() )
577 {
578 return;
579 }
580
581 startSection( getBundle( locale ).getString( "report.plugin.systemrequirements.history" ) );
582 paragraph( getBundle( locale ).getString( "report.plugin.systemrequirements.history.intro" ) );
583
584 startTable();
585 tableHeader( new String[] {
586 getBundle( locale ).getString( "report.plugin.systemrequirements.history.version" ),
587 getBundle( locale ).getString( "report.plugin.systemrequirements.history.maven" ),
588 getBundle( locale ).getString( "report.plugin.systemrequirements.history.jdk" )
589 } );
590
591 requirementsHistories.forEach(
592 requirementsHistory ->
593 {
594 sink.tableRow();
595 tableCell( requirementsHistory.getVersion() );
596 tableCell( requirementsHistory.getMaven() );
597 tableCell( requirementsHistory.getJdk() );
598 sink.tableRow_();
599 } );
600 endTable();
601
602 endSection();
603 }
604
605
606
607
608
609
610 private void renderUsageSection( boolean hasMavenReport )
611 {
612 startSection( getBundle( locale ).getString( "report.plugin.usage" ) );
613
614
615 sink.paragraph();
616 text( getBundle( locale ).getString( "report.plugin.usage.intro" ) );
617 sink.paragraph_();
618
619 StringBuilder sb = new StringBuilder();
620 sb.append( "<project>" ).append( '\n' );
621 sb.append( " ..." ).append( '\n' );
622 sb.append( " <build>" ).append( '\n' );
623 sb.append(
624 " <!-- " + getBundle( locale ).getString( "report.plugin.usage.pluginManagement" ) + " -->" ).append(
625 '\n' );
626 sb.append( " <pluginManagement>" ).append( '\n' );
627 sb.append( " <plugins>" ).append( '\n' );
628 sb.append( " <plugin>" ).append( '\n' );
629 sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
630 '\n' );
631 sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
632 "</artifactId>" ).append( '\n' );
633 sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
634 '\n' );
635 if ( hasExtensionsToLoad )
636 {
637 sb.append( " <extensions>true</extensions>" ).append(
638 '\n' );
639 }
640 sb.append( " </plugin>" ).append( '\n' );
641 sb.append( " ..." ).append( '\n' );
642 sb.append( " </plugins>" ).append( '\n' );
643 sb.append( " </pluginManagement>" ).append( '\n' );
644 sb.append( " <!-- " + getBundle( locale ).getString( "report.plugin.usage.plugins" ) + " -->" ).append(
645 '\n' );
646 sb.append( " <plugins>" ).append( '\n' );
647 sb.append( " <plugin>" ).append( '\n' );
648 sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
649 '\n' );
650 sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
651 "</artifactId>" ).append( '\n' );
652 sb.append( " </plugin>" ).append( '\n' );
653 sb.append( " ..." ).append( '\n' );
654 sb.append( " </plugins>" ).append( '\n' );
655 sb.append( " </build>" ).append( '\n' );
656
657 if ( hasMavenReport )
658 {
659 sb.append( " ..." ).append( '\n' );
660 sb.append(
661 " <!-- " + getBundle( locale ).getString( "report.plugin.usage.reporting" ) + " -->" ).append(
662 '\n' );
663 sb.append( " <reporting>" ).append( '\n' );
664 sb.append( " <plugins>" ).append( '\n' );
665 sb.append( " <plugin>" ).append( '\n' );
666 sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
667 '\n' );
668 sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
669 "</artifactId>" ).append( '\n' );
670 sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
671 '\n' );
672 sb.append( " </plugin>" ).append( '\n' );
673 sb.append( " ..." ).append( '\n' );
674 sb.append( " </plugins>" ).append( '\n' );
675 sb.append( " </reporting>" ).append( '\n' );
676 }
677
678 sb.append( " ..." ).append( '\n' );
679 sb.append( "</project>" ).append( '\n' );
680
681 verbatimText( sb.toString() );
682
683 sink.paragraph();
684 linkPatternedText( getBundle( locale ).getString( "report.plugin.configuration.end" ) );
685 sink.paragraph_();
686
687 endSection();
688 }
689
690
691
692
693
694
695
696
697
698 private static String discoverMavenRequirement( MavenProject project, Requirements requirements )
699 {
700 String maven = requirements.getMaven();
701 if ( maven == null )
702 {
703 maven = ( project.getPrerequisites() != null ? project.getPrerequisites().getMaven() : null );
704 }
705 if ( maven == null )
706 {
707 maven = "2.0";
708 }
709
710 return maven;
711 }
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726 private static String discoverJdkRequirement( MavenProject project, Requirements requirements )
727 {
728 String jdk = requirements.getJdk();
729
730 if ( jdk != null )
731 {
732 return jdk;
733 }
734
735 Plugin compiler = getCompilerPlugin( project.getBuild().getPluginsAsMap() );
736 if ( compiler == null )
737 {
738 compiler = getCompilerPlugin( project.getPluginManagement().getPluginsAsMap() );
739 }
740
741 jdk = getPluginParameter( compiler, "release" );
742 if ( jdk != null )
743 {
744 return jdk;
745 }
746
747 jdk = project.getProperties().getProperty( "maven.compiler.release" );
748 if ( jdk != null )
749 {
750 return jdk;
751 }
752
753 jdk = getPluginParameter( compiler, "target" );
754 if ( jdk != null )
755 {
756 return jdk;
757 }
758
759
760 jdk = project.getProperties().getProperty( "maven.compiler.target" );
761 if ( jdk != null )
762 {
763 return jdk;
764 }
765
766
767
768 String version = ( compiler == null ) ? null : compiler.getVersion();
769
770 if ( version != null )
771 {
772 return "Default target for maven-compiler-plugin version " + version;
773 }
774
775 return "Unknown";
776 }
777
778 private static Plugin getCompilerPlugin( Map<String, Plugin> pluginsAsMap )
779 {
780 return pluginsAsMap.get( "org.apache.maven.plugins:maven-compiler-plugin" );
781 }
782
783 private static String getPluginParameter( Plugin plugin, String parameter )
784 {
785 if ( plugin != null )
786 {
787 Xpp3Dom pluginConf = (Xpp3Dom) plugin.getConfiguration();
788
789 if ( pluginConf != null )
790 {
791 Xpp3Dom target = pluginConf.getChild( parameter );
792
793 if ( target != null )
794 {
795 return target.getValue();
796 }
797 }
798 }
799
800 return null;
801 }
802 }
803 }