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