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