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