1 package org.apache.maven.plugins.help;
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.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.net.URL;
27 import java.net.URLClassLoader;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.StringTokenizer;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34
35 import org.apache.maven.RepositoryUtils;
36 import org.apache.maven.lifecycle.DefaultLifecycles;
37 import org.apache.maven.lifecycle.Lifecycle;
38 import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
39 import org.apache.maven.lifecycle.mapping.LifecycleMapping;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.model.building.ModelBuildingRequest;
42 import org.apache.maven.plugin.MojoExecutionException;
43 import org.apache.maven.plugin.MojoFailureException;
44 import org.apache.maven.plugin.descriptor.MojoDescriptor;
45 import org.apache.maven.plugin.descriptor.Parameter;
46 import org.apache.maven.plugin.descriptor.PluginDescriptor;
47 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
48 import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
49 import org.apache.maven.plugin.version.PluginVersionResolutionException;
50 import org.apache.maven.plugin.version.PluginVersionResolver;
51 import org.apache.maven.plugin.version.PluginVersionResult;
52 import org.apache.maven.plugins.annotations.Component;
53 import org.apache.maven.plugins.annotations.Mojo;
54 import org.apache.maven.project.DefaultProjectBuildingRequest;
55 import org.apache.maven.project.MavenProject;
56 import org.apache.maven.project.ProjectBuildingRequest;
57 import org.apache.maven.reporting.MavenReport;
58 import org.apache.maven.reporting.exec.MavenPluginManagerHelper;
59 import org.apache.maven.shared.utils.logging.MessageUtils;
60 import org.apache.maven.tools.plugin.generator.GeneratorUtils;
61 import org.apache.maven.tools.plugin.util.PluginUtils;
62 import org.codehaus.plexus.util.StringUtils;
63 import org.eclipse.aether.artifact.Artifact;
64 import org.eclipse.aether.artifact.DefaultArtifact;
65
66
67
68
69
70
71
72 @Mojo( name = "describe", requiresProject = false, aggregator = true )
73 public class DescribeMojo
74 extends AbstractHelpMojo
75 {
76
77
78
79 private static final int INDENT_SIZE = 2;
80
81
82
83
84 private static final String UNKNOWN = "Unknown";
85
86
87
88
89 private static final String NOT_DEFINED = "Not defined";
90
91
92
93
94 private static final String NO_REASON = "No reason given";
95
96 private static final Pattern EXPRESSION = Pattern.compile( "^\\$\\{([^}]+)\\}$" );
97
98
99
100
101
102
103
104
105 @Component
106 private MavenPluginManagerHelper pluginManager;
107
108
109
110
111 @Component
112 private MojoDescriptorCreator mojoDescriptorCreator;
113
114
115
116
117 @Component
118 private PluginVersionResolver pluginVersionResolver;
119
120
121
122
123 @Component
124 private DefaultLifecycles defaultLifecycles;
125
126
127
128
129 @Component
130 private Map<String, LifecycleMapping> lifecycleMappings;
131
132
133
134
135
136
137
138
139
140
141
142 @org.apache.maven.plugins.annotations.Parameter( defaultValue = "${project}", readonly = true, required = true )
143 private MavenProject project;
144
145
146
147
148
149
150
151
152
153
154 @org.apache.maven.plugins.annotations.Parameter( property = "plugin", alias = "prefix" )
155 private String plugin;
156
157
158
159
160
161
162 @org.apache.maven.plugins.annotations.Parameter( property = "groupId" )
163 private String groupId;
164
165
166
167
168
169
170 @org.apache.maven.plugins.annotations.Parameter( property = "artifactId" )
171 private String artifactId;
172
173
174
175
176
177
178 @org.apache.maven.plugins.annotations.Parameter( property = "version" )
179 private String version;
180
181
182
183
184
185
186
187
188 @org.apache.maven.plugins.annotations.Parameter( property = "goal" )
189 private String goal;
190
191
192
193
194
195
196 @org.apache.maven.plugins.annotations.Parameter( property = "detail", defaultValue = "false" )
197 private boolean detail;
198
199
200
201
202
203
204 @org.apache.maven.plugins.annotations.Parameter( property = "minimal", defaultValue = "false" )
205 private boolean minimal;
206
207
208
209
210
211
212
213
214 @org.apache.maven.plugins.annotations.Parameter( property = "cmd" )
215 private String cmd;
216
217
218
219
220
221
222
223
224 public void execute()
225 throws MojoExecutionException, MojoFailureException
226 {
227 StringBuilder descriptionBuffer = new StringBuilder();
228
229 boolean describePlugin = true;
230 if ( StringUtils.isNotEmpty( cmd ) )
231 {
232 describePlugin = describeCommand( descriptionBuffer );
233 }
234
235 if ( describePlugin )
236 {
237 PluginInfo pi = parsePluginLookupInfo();
238 PluginDescriptor descriptor = lookupPluginDescriptor( pi );
239 if ( StringUtils.isNotEmpty( goal ) )
240 {
241 MojoDescriptor mojo = descriptor.getMojo( goal );
242 if ( mojo == null )
243 {
244 throw new MojoFailureException( "The goal '" + goal + "' does not exist in the plugin '"
245 + pi.getPrefix() + "'" );
246 }
247 describeMojo( mojo, descriptionBuffer );
248 }
249 else
250 {
251 describePlugin( descriptor, descriptionBuffer );
252 }
253 }
254
255 writeDescription( descriptionBuffer );
256 }
257
258
259
260
261
262
263
264
265
266
267
268 private void writeDescription( StringBuilder descriptionBuffer )
269 throws MojoExecutionException
270 {
271 if ( output != null )
272 {
273 try
274 {
275 writeFile( output, descriptionBuffer );
276 }
277 catch ( IOException e )
278 {
279 throw new MojoExecutionException( "Cannot write plugin/goal description to output: " + output, e );
280 }
281
282 getLog().info( "Wrote descriptions to: " + output );
283 }
284 else
285 {
286 getLog().info( descriptionBuffer.toString() );
287 }
288 }
289
290
291
292
293
294
295
296
297
298 private PluginDescriptor lookupPluginDescriptor( PluginInfo pi )
299 throws MojoExecutionException, MojoFailureException
300 {
301 Plugin forLookup = null;
302 if ( StringUtils.isNotEmpty( pi.getPrefix() ) )
303 {
304 try
305 {
306 forLookup = mojoDescriptorCreator.findPluginForPrefix( pi.getPrefix(), session );
307 }
308 catch ( NoPluginFoundForPrefixException e )
309 {
310 throw new MojoExecutionException( "Unable to find the plugin with prefix: " + pi.getPrefix(), e );
311 }
312 }
313 else if ( StringUtils.isNotEmpty( pi.getGroupId() ) && StringUtils.isNotEmpty( pi.getArtifactId() ) )
314 {
315 forLookup = new Plugin();
316 forLookup.setGroupId( pi.getGroupId() );
317 forLookup.setArtifactId( pi.getArtifactId() );
318 }
319 if ( forLookup == null )
320 {
321 String msg =
322 "You must specify either: both 'groupId' and 'artifactId' parameters OR a 'plugin' parameter"
323 + " OR a 'cmd' parameter. For instance:" + LS
324 + " # mvn help:describe -Dcmd=install" + LS
325 + "or" + LS
326 + " # mvn help:describe -Dcmd=help:describe" + LS
327 + "or" + LS
328 + " # mvn help:describe -Dplugin=org.apache.maven.plugins:maven-help-plugin" + LS
329 + "or" + LS
330 + " # mvn help:describe -DgroupId=org.apache.maven.plugins -DartifactId=maven-help-plugin" + LS + LS
331 + "Try 'mvn help:help -Ddetail=true' for more information.";
332 throw new MojoFailureException( msg );
333 }
334
335 if ( StringUtils.isNotEmpty( pi.getVersion() ) )
336 {
337 forLookup.setVersion( pi.getVersion() );
338 }
339 else
340 {
341 try
342 {
343 DefaultPluginVersionRequest versionRequest = new DefaultPluginVersionRequest( forLookup, session );
344 versionRequest.setPom( project.getModel() );
345 PluginVersionResult versionResult = pluginVersionResolver.resolve( versionRequest );
346 forLookup.setVersion( versionResult.getVersion() );
347 }
348 catch ( PluginVersionResolutionException e )
349 {
350 throw new MojoExecutionException( "Unable to resolve the version of the plugin with prefix: "
351 + pi.getPrefix(), e );
352 }
353 }
354
355 try
356 {
357 return pluginManager.getPluginDescriptor( forLookup, session );
358 }
359 catch ( Exception e )
360 {
361 throw new MojoExecutionException( "Error retrieving plugin descriptor for:" + LS + LS + "groupId: '"
362 + groupId + "'" + LS + "artifactId: '" + artifactId + "'" + LS + "version: '" + version + "'" + LS
363 + LS, e );
364 }
365 }
366
367
368
369
370
371
372
373
374 private PluginInfo parsePluginLookupInfo()
375 throws MojoFailureException
376 {
377 PluginInfo pi = new PluginInfo();
378 if ( StringUtils.isNotEmpty( plugin ) )
379 {
380 if ( plugin.indexOf( ':' ) > -1 )
381 {
382 String[] pluginParts = plugin.split( ":" );
383
384 switch ( pluginParts.length )
385 {
386 case 1:
387 pi.setPrefix( pluginParts[0] );
388 break;
389 case 2:
390 pi.setGroupId( pluginParts[0] );
391 pi.setArtifactId( pluginParts[1] );
392 break;
393 case 3:
394 pi.setGroupId( pluginParts[0] );
395 pi.setArtifactId( pluginParts[1] );
396 pi.setVersion( pluginParts[2] );
397 break;
398 default:
399 throw new MojoFailureException( "plugin parameter must be a plugin prefix,"
400 + " or conform to: 'groupId:artifactId[:version]'." );
401 }
402 }
403 else
404 {
405 pi.setPrefix( plugin );
406 }
407 }
408 else
409 {
410 pi.setGroupId( groupId );
411 pi.setArtifactId( artifactId );
412 pi.setVersion( version );
413 }
414 return pi;
415 }
416
417
418
419
420
421
422
423
424
425 private void describePlugin( PluginDescriptor pd, StringBuilder buffer )
426 throws MojoFailureException, MojoExecutionException
427 {
428 append( buffer, pd.getId(), 0 );
429 buffer.append( LS );
430
431 String name = pd.getName();
432 if ( name == null )
433 {
434
435 org.eclipse.aether.artifact.Artifact aetherArtifact = new DefaultArtifact(
436 pd.getGroupId(), pd.getArtifactId(), "jar", pd.getVersion() );
437 ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
438 pbr.setRemoteRepositories( remoteRepositories );
439 pbr.setLocalRepository( localRepository );
440 pbr.setProject( null );
441 pbr.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
442 try
443 {
444 Artifact artifactCopy = resolveArtifact( aetherArtifact ).getArtifact();
445 name = projectBuilder.build( RepositoryUtils.toArtifact( artifactCopy ), pbr ).getProject().getName();
446 }
447 catch ( Exception e )
448 {
449
450 getLog().warn( "Unable to get the name of the plugin " + pd.getId() + ": " + e.getMessage() );
451 name = pd.getId();
452 }
453 }
454 append( buffer, "Name", MessageUtils.buffer().strong( name ).toString(), 0 );
455 appendAsParagraph( buffer, "Description", toDescription( pd.getDescription() ), 0 );
456 append( buffer, "Group Id", pd.getGroupId(), 0 );
457 append( buffer, "Artifact Id", pd.getArtifactId(), 0 );
458 append( buffer, "Version", pd.getVersion(), 0 );
459 append( buffer, "Goal Prefix", MessageUtils.buffer().strong( pd.getGoalPrefix() ).toString(), 0 );
460 buffer.append( LS );
461
462 List<MojoDescriptor> mojos = pd.getMojos();
463
464 if ( mojos == null )
465 {
466 append( buffer, "This plugin has no goals.", 0 );
467 return;
468 }
469
470 if ( !minimal )
471 {
472 append( buffer, "This plugin has " + mojos.size() + " goal" + ( mojos.size() > 1 ? "s" : "" ) + ":", 0 );
473 buffer.append( LS );
474
475 mojos = new ArrayList<>( mojos );
476 PluginUtils.sortMojos( mojos );
477
478 for ( MojoDescriptor md : mojos )
479 {
480 describeMojoGuts( md, buffer, detail );
481 buffer.append( LS );
482 }
483 }
484
485 if ( !detail )
486 {
487 buffer.append( "For more information, run 'mvn help:describe [...] -Ddetail'" );
488 buffer.append( LS );
489 }
490 }
491
492
493
494
495
496
497
498
499
500 private void describeMojo( MojoDescriptor md, StringBuilder buffer )
501 throws MojoFailureException, MojoExecutionException
502 {
503 buffer.append( "Mojo: '" ).append( md.getFullGoalName() ).append( "'" );
504 buffer.append( LS );
505
506 describeMojoGuts( md, buffer, detail );
507 buffer.append( LS );
508
509 if ( !detail )
510 {
511 buffer.append( "For more information, run 'mvn help:describe [...] -Ddetail'" );
512 buffer.append( LS );
513 }
514 }
515
516
517
518
519
520
521
522
523
524
525 private void describeMojoGuts( MojoDescriptor md, StringBuilder buffer, boolean fullDescription )
526 throws MojoFailureException, MojoExecutionException
527 {
528 append( buffer, MessageUtils.buffer().strong( md.getFullGoalName() ).toString(), 0 );
529
530
531 appendAsParagraph( buffer, "Description", toDescription( md.getDescription() ), 1 );
532
533 String deprecation = md.getDeprecated();
534 if ( deprecation != null && deprecation.length() <= 0 )
535 {
536 deprecation = NO_REASON;
537 }
538
539 if ( StringUtils.isNotEmpty( deprecation ) )
540 {
541 append( buffer, MessageUtils.buffer().warning( "Deprecated. " + deprecation ).toString(), 1 );
542 }
543
544 if ( isReportGoal( md ) )
545 {
546 append( buffer, "Note", "This goal should be used as a Maven report.", 1 );
547 }
548
549 if ( !fullDescription )
550 {
551 return;
552 }
553
554 append( buffer, "Implementation", md.getImplementation(), 1 );
555 append( buffer, "Language", md.getLanguage(), 1 );
556
557 String phase = md.getPhase();
558 if ( StringUtils.isNotEmpty( phase ) )
559 {
560 append( buffer, "Bound to phase", phase, 1 );
561 }
562
563 String eGoal = md.getExecuteGoal();
564 String eLife = md.getExecuteLifecycle();
565 String ePhase = md.getExecutePhase();
566
567 if ( StringUtils.isNotEmpty( eGoal ) || StringUtils.isNotEmpty( ePhase ) )
568 {
569 append( buffer, "Before this goal executes, it will call:", 1 );
570
571 if ( StringUtils.isNotEmpty( eGoal ) )
572 {
573 append( buffer, "Single goal", "'" + eGoal + "'", 2 );
574 }
575
576 if ( StringUtils.isNotEmpty( ePhase ) )
577 {
578 String s = "Phase: '" + ePhase + "'";
579
580 if ( StringUtils.isNotEmpty( eLife ) )
581 {
582 s += " in Lifecycle Overlay: '" + eLife + "'";
583 }
584
585 append( buffer, s, 2 );
586 }
587 }
588
589 buffer.append( LS );
590
591 describeMojoParameters( md, buffer );
592 }
593
594
595
596
597
598
599
600
601
602 private void describeMojoParameters( MojoDescriptor md, StringBuilder buffer )
603 throws MojoFailureException, MojoExecutionException
604 {
605 List<Parameter> params = md.getParameters();
606
607 if ( params == null || params.isEmpty() )
608 {
609 append( buffer, "This mojo doesn't use any parameters.", 1 );
610 return;
611 }
612
613 params = new ArrayList<>( params );
614 PluginUtils.sortMojoParameters( params );
615
616 append( buffer, "Available parameters:", 1 );
617
618
619 for ( Parameter parameter : params )
620 {
621 if ( !parameter.isEditable() )
622 {
623 continue;
624 }
625
626 buffer.append( LS );
627
628
629 String defaultVal = parameter.getDefaultValue();
630 if ( defaultVal == null )
631 {
632
633 defaultVal =
634 md.getMojoConfiguration().getChild( parameter.getName() ).getAttribute( "default-value", null );
635 }
636
637 if ( StringUtils.isNotEmpty( defaultVal ) )
638 {
639 defaultVal = " (Default: " + MessageUtils.buffer().strong( defaultVal ) + ")";
640 }
641 else
642 {
643 defaultVal = "";
644 }
645 append( buffer, MessageUtils.buffer().strong( parameter.getName() ) + defaultVal, 2 );
646
647 String alias = parameter.getAlias();
648 if ( !StringUtils.isEmpty( alias ) )
649 {
650 append ( buffer, "Alias", alias, 3 );
651 }
652
653 if ( parameter.isRequired() )
654 {
655 append( buffer, "Required", "true", 3 );
656 }
657
658 String expression = parameter.getExpression();
659 if ( StringUtils.isEmpty( expression ) )
660 {
661
662
663 expression = md.getMojoConfiguration().getChild( parameter.getName() ).getValue( null );
664 }
665 if ( StringUtils.isNotEmpty( expression ) )
666 {
667 Matcher matcher = EXPRESSION.matcher( expression );
668 if ( matcher.matches() )
669 {
670 append( buffer, "User property", matcher.group( 1 ), 3 );
671 }
672 else
673 {
674 append( buffer, "Expression", expression, 3 );
675 }
676 }
677
678 append( buffer, toDescription( parameter.getDescription() ), 3 );
679
680 String deprecation = parameter.getDeprecated();
681 if ( deprecation != null && deprecation.length() <= 0 )
682 {
683 deprecation = NO_REASON;
684 }
685
686 if ( StringUtils.isNotEmpty( deprecation ) )
687 {
688 append( buffer, MessageUtils.buffer().warning( "Deprecated. " + deprecation ).toString(), 3 );
689 }
690 }
691 }
692
693
694
695
696
697
698
699
700 private boolean describeCommand( StringBuilder descriptionBuffer )
701 throws MojoExecutionException
702 {
703 if ( cmd.indexOf( ':' ) == -1 )
704 {
705
706 Lifecycle lifecycle = defaultLifecycles.getPhaseToLifecycleMap().get( cmd );
707 if ( lifecycle == null )
708 {
709 throw new MojoExecutionException( "The given phase '" + cmd + "' is an unknown phase." );
710 }
711
712 Map<String, String> defaultLifecyclePhases =
713 lifecycleMappings.get( project.getPackaging() ).getLifecycles().get( "default" ).getPhases();
714 List<String> phases = lifecycle.getPhases();
715
716 if ( lifecycle.getDefaultPhases() == null )
717 {
718 descriptionBuffer.append( "'" ).append( cmd );
719 descriptionBuffer.append( "' is a phase corresponding to this plugin:" ).append( LS );
720 for ( String key : phases )
721 {
722 if ( !key.equals( cmd ) )
723 {
724 continue;
725 }
726 if ( defaultLifecyclePhases.get( key ) != null )
727 {
728 descriptionBuffer.append( defaultLifecyclePhases.get( key ) );
729 descriptionBuffer.append( LS );
730 }
731 }
732
733 descriptionBuffer.append( LS );
734 descriptionBuffer.append( "It is a part of the lifecycle for the POM packaging '" );
735 descriptionBuffer.append( project.getPackaging() );
736 descriptionBuffer.append( "'. This lifecycle includes the following phases:" );
737 descriptionBuffer.append( LS );
738 for ( String key : phases )
739 {
740 descriptionBuffer.append( "* " ).append( key ).append( ": " );
741 String value = defaultLifecyclePhases.get( key );
742 if ( StringUtils.isNotEmpty( value ) )
743 {
744 for ( StringTokenizer tok = new StringTokenizer( value, "," ); tok.hasMoreTokens(); )
745 {
746 descriptionBuffer.append( tok.nextToken().trim() );
747
748 if ( !tok.hasMoreTokens() )
749 {
750 descriptionBuffer.append( LS );
751 }
752 else
753 {
754 descriptionBuffer.append( ", " );
755 }
756 }
757 }
758 else
759 {
760 descriptionBuffer.append( NOT_DEFINED ).append( LS );
761 }
762 }
763 }
764 else
765 {
766 descriptionBuffer.append( "'" ).append( cmd );
767 descriptionBuffer.append( "' is a phase within the '" ).append( lifecycle.getId() );
768 descriptionBuffer.append( "' lifecycle, which has the following phases: " );
769 descriptionBuffer.append( LS );
770
771 for ( String key : phases )
772 {
773 descriptionBuffer.append( "* " ).append( key ).append( ": " );
774 if ( lifecycle.getDefaultPhases().get( key ) != null )
775 {
776 descriptionBuffer.append( lifecycle.getDefaultPhases().get( key ) ).append( LS );
777 }
778 else
779 {
780 descriptionBuffer.append( NOT_DEFINED ).append( LS );
781 }
782 }
783 }
784 return false;
785 }
786
787
788 MojoDescriptor mojoDescriptor;
789 try
790 {
791 mojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( cmd, session, project );
792 }
793 catch ( Exception e )
794 {
795 throw new MojoExecutionException( "Unable to get descriptor for " + cmd, e );
796 }
797 descriptionBuffer.append( "'" ).append( cmd ).append( "' is a plugin goal (aka mojo)" ).append( "." );
798 descriptionBuffer.append( LS );
799 plugin = mojoDescriptor.getPluginDescriptor().getId();
800 goal = mojoDescriptor.getGoal();
801
802 return true;
803 }
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818 private static List<String> toLines( String text, int indent, int indentSize, int lineLength )
819 throws MojoFailureException, MojoExecutionException
820 {
821 try
822 {
823 Method m = HelpMojo.class.getDeclaredMethod( "toLines", String.class, Integer.TYPE, Integer.TYPE,
824 Integer.TYPE );
825 m.setAccessible( true );
826 @SuppressWarnings( "unchecked" )
827 List<String> output = (List<String>) m.invoke( HelpMojo.class, text, indent, indentSize, lineLength );
828
829 if ( output == null )
830 {
831 throw new MojoExecutionException( "No output was specified." );
832 }
833
834 return output;
835 }
836 catch ( SecurityException e )
837 {
838 throw new MojoFailureException( "SecurityException: " + e.getMessage() );
839 }
840 catch ( IllegalArgumentException e )
841 {
842 throw new MojoFailureException( "IllegalArgumentException: " + e.getMessage() );
843 }
844 catch ( NoSuchMethodException e )
845 {
846 throw new MojoFailureException( "NoSuchMethodException: " + e.getMessage() );
847 }
848 catch ( IllegalAccessException e )
849 {
850 throw new MojoFailureException( "IllegalAccessException: " + e.getMessage() );
851 }
852 catch ( InvocationTargetException e )
853 {
854 Throwable cause = e.getCause();
855
856 if ( cause instanceof NegativeArraySizeException )
857 {
858 throw new MojoFailureException( "NegativeArraySizeException: " + cause.getMessage() );
859 }
860
861 throw new MojoFailureException( "InvocationTargetException: " + e.getMessage() );
862 }
863 }
864
865
866
867
868
869
870
871
872
873
874
875
876 private static void append( StringBuilder sb, String description, int indent )
877 throws MojoFailureException, MojoExecutionException
878 {
879 if ( StringUtils.isEmpty( description ) )
880 {
881 sb.append( UNKNOWN ).append( LS );
882 return;
883 }
884
885 for ( String line : toLines( description, indent, INDENT_SIZE, LINE_LENGTH ) )
886 {
887 sb.append( line ).append( LS );
888 }
889 }
890
891
892
893
894
895
896
897
898
899
900
901
902
903 private static void append( StringBuilder sb, String key, String value, int indent )
904 throws MojoFailureException, MojoExecutionException
905 {
906 if ( StringUtils.isEmpty( key ) )
907 {
908 throw new IllegalArgumentException( "Key is required!" );
909 }
910
911 if ( StringUtils.isEmpty( value ) )
912 {
913 value = UNKNOWN;
914 }
915
916 String description = key + ": " + value;
917 for ( String line : toLines( description, indent, INDENT_SIZE, LINE_LENGTH ) )
918 {
919 sb.append( line ).append( LS );
920 }
921 }
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936 private static void appendAsParagraph( StringBuilder sb, String key, String value, int indent )
937 throws MojoFailureException, MojoExecutionException
938 {
939 if ( StringUtils.isEmpty( value ) )
940 {
941 value = UNKNOWN;
942 }
943
944 String description;
945 if ( key == null )
946 {
947 description = value;
948 }
949 else
950 {
951 description = key + ": " + value;
952 }
953
954 List<String> l1 = toLines( description, indent, INDENT_SIZE, LINE_LENGTH - INDENT_SIZE );
955 List<String> l2 = toLines( description, indent + 1, INDENT_SIZE, LINE_LENGTH );
956 l2.set( 0, l1.get( 0 ) );
957 for ( String line : l2 )
958 {
959 sb.append( line ).append( LS );
960 }
961 }
962
963
964
965
966
967
968
969
970 private boolean isReportGoal( MojoDescriptor md )
971 {
972 PluginDescriptor pd = md.getPluginDescriptor();
973 List<URL> urls = new ArrayList<>();
974 ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
975 pbr.setRemoteRepositories( remoteRepositories );
976 pbr.setResolveDependencies( true );
977 pbr.setProject( null );
978 pbr.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
979 try
980 {
981 org.eclipse.aether.artifact.Artifact jar = resolveArtifact(
982 new DefaultArtifact( pd.getGroupId(), pd.getArtifactId(), "jar", pd.getVersion() ) ).getArtifact();
983 org.eclipse.aether.artifact.Artifact pom = resolveArtifact(
984 new DefaultArtifact( pd.getGroupId(), pd.getArtifactId(), "pom", pd.getVersion() ) ).getArtifact();
985 MavenProject mavenProject = projectBuilder.build( pom.getFile(), pbr ).getProject();
986 urls.add( jar.getFile().toURI().toURL() );
987 for ( String artifact : mavenProject.getCompileClasspathElements() )
988 {
989 urls.add( new File( artifact ).toURI().toURL() );
990 }
991 try ( URLClassLoader classLoader = new URLClassLoader( urls.toArray( new URL[0] ),
992 getClass().getClassLoader() ) )
993 {
994 return MavenReport.class.isAssignableFrom(
995 Class.forName( md.getImplementation(), false, classLoader ) );
996 }
997 }
998 catch ( Exception e )
999 {
1000 getLog().warn( "Couldn't identify if this goal is a report goal: " + e.getMessage() );
1001 return false;
1002 }
1003 }
1004
1005
1006
1007
1008
1009
1010
1011 private static String toDescription( String description )
1012 {
1013 if ( StringUtils.isNotEmpty( description ) )
1014 {
1015 return GeneratorUtils.toText( description );
1016 }
1017
1018 return "(no description available)";
1019 }
1020
1021
1022
1023
1024 static class PluginInfo
1025 {
1026 private String prefix;
1027
1028 private String groupId;
1029
1030 private String artifactId;
1031
1032 private String version;
1033
1034
1035
1036
1037 public String getPrefix()
1038 {
1039 return prefix;
1040 }
1041
1042
1043
1044
1045 public void setPrefix( String prefix )
1046 {
1047 this.prefix = prefix;
1048 }
1049
1050
1051
1052
1053 public String getGroupId()
1054 {
1055 return groupId;
1056 }
1057
1058
1059
1060
1061 public void setGroupId( String groupId )
1062 {
1063 this.groupId = groupId;
1064 }
1065
1066
1067
1068
1069 public String getArtifactId()
1070 {
1071 return artifactId;
1072 }
1073
1074
1075
1076
1077 public void setArtifactId( String artifactId )
1078 {
1079 this.artifactId = artifactId;
1080 }
1081
1082
1083
1084
1085 public String getVersion()
1086 {
1087 return version;
1088 }
1089
1090
1091
1092
1093 public void setVersion( String version )
1094 {
1095 this.version = version;
1096 }
1097
1098 }
1099 }