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