Coverage Report - org.apache.maven.tools.plugin.generator.PluginDescriptorGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
PluginDescriptorGenerator
58 %
141/241
47 %
58/122
10,125
 
 1  
 package org.apache.maven.tools.plugin.generator;
 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 org.apache.maven.plugin.descriptor.DuplicateMojoDescriptorException;
 23  
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 24  
 import org.apache.maven.plugin.descriptor.Parameter;
 25  
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 26  
 import org.apache.maven.plugin.descriptor.Requirement;
 27  
 import org.apache.maven.project.MavenProject;
 28  
 import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
 29  
 import org.apache.maven.tools.plugin.PluginToolsRequest;
 30  
 import org.apache.maven.tools.plugin.util.PluginUtils;
 31  
 import org.codehaus.plexus.util.IOUtil;
 32  
 import org.codehaus.plexus.util.PropertyUtils;
 33  
 import org.codehaus.plexus.util.StringUtils;
 34  
 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
 35  
 import org.codehaus.plexus.util.xml.XMLWriter;
 36  
 import org.objectweb.asm.ClassReader;
 37  
 import org.objectweb.asm.ClassVisitor;
 38  
 import org.objectweb.asm.ClassWriter;
 39  
 import org.objectweb.asm.commons.RemappingClassAdapter;
 40  
 import org.objectweb.asm.commons.SimpleRemapper;
 41  
 
 42  
 import java.io.File;
 43  
 import java.io.FileInputStream;
 44  
 import java.io.FileOutputStream;
 45  
 import java.io.IOException;
 46  
 import java.io.OutputStreamWriter;
 47  
 import java.io.Writer;
 48  
 import java.text.SimpleDateFormat;
 49  
 import java.util.Date;
 50  
 import java.util.LinkedHashMap;
 51  
 import java.util.LinkedHashSet;
 52  
 import java.util.List;
 53  
 import java.util.Map;
 54  
 import java.util.Properties;
 55  
 import java.util.Set;
 56  
 
 57  
 /**
 58  
  * Generate a <a href="/ref/current/maven-plugin-api/plugin.html">Maven Plugin Descriptor XML file</a> and
 59  
  * corresponding help content.
 60  
  *
 61  
  * @version $Id: PluginDescriptorGenerator.java 1343173 2012-05-28 09:30:23Z hboutemy $
 62  
  * @todo add example usage tag that can be shown in the doco
 63  
  * @todo need to add validation directives so that systems embedding maven2 can
 64  
  * get validation directives to help users in IDEs.
 65  
  */
 66  1
 public class PluginDescriptorGenerator
 67  
     implements Generator
 68  
 {
 69  
 
 70  
     /**
 71  
      * {@inheritDoc}
 72  
      */
 73  
     public void execute( File destinationDirectory, PluginToolsRequest request )
 74  
         throws GeneratorException
 75  
     {
 76  
 
 77  1
         File tmpPropertiesFile =
 78  
             new File( request.getProject().getBuild().getDirectory(), "maven-plugin-help.properties" );
 79  
 
 80  1
         if ( tmpPropertiesFile.exists() )
 81  
         {
 82  1
             Properties properties = PropertyUtils.loadProperties( tmpPropertiesFile );
 83  
 
 84  1
             String helpPackageName = properties.getProperty( "helpPackageName" );
 85  
 
 86  
             // if helpPackageName property is empty we have to rewrite the class with a better package name than empty
 87  1
             if ( StringUtils.isEmpty( helpPackageName ) )
 88  
             {
 89  1
                 String helpMojoImplementation = rewriteHelpClassToMojoPackage( request );
 90  1
                 if ( helpMojoImplementation != null )
 91  
                 {
 92  
                     // rewrite plugin descriptor with new HelpMojo implementation class
 93  0
                     rewriteDescriptor( request.getPluginDescriptor(), helpMojoImplementation );
 94  
                 }
 95  
 
 96  
             }
 97  
         }
 98  
 
 99  
         try
 100  
         {
 101  
             // write complete plugin.xml descriptor
 102  1
             File f = new File( destinationDirectory, "plugin.xml" );
 103  1
             writeDescriptor( f, request, false );
 104  
 
 105  
             // write plugin-help.xml help-descriptor
 106  1
             MavenProject mavenProject = request.getProject();
 107  1
             String pluginHelpFilePath =
 108  
                 "META-INF/maven/" + mavenProject.getGroupId() + "/" + mavenProject.getArtifactId()
 109  
                     + "/plugin-help.xml";
 110  1
             f = new File( request.getProject().getBuild().getOutputDirectory(), pluginHelpFilePath );
 111  1
             writeDescriptor( f, request, true );
 112  
         }
 113  0
         catch ( IOException e )
 114  
         {
 115  0
             throw new GeneratorException( e.getMessage(), e );
 116  
         }
 117  0
         catch ( DuplicateMojoDescriptorException e )
 118  
         {
 119  0
             throw new GeneratorException( e.getMessage(), e );
 120  1
         }
 121  1
     }
 122  
 
 123  
     private String getVersion()
 124  
     {
 125  2
         Package p = this.getClass().getPackage();
 126  2
         String version = ( p == null ) ? null : p.getSpecificationVersion();
 127  2
         return ( version == null ) ? "SNAPSHOT" : version;
 128  
     }
 129  
 
 130  
     public void writeDescriptor( File destinationFile, PluginToolsRequest request, boolean helpDescriptor )
 131  
         throws IOException, DuplicateMojoDescriptorException
 132  
     {
 133  2
         PluginDescriptor pluginDescriptor = request.getPluginDescriptor();
 134  
 
 135  2
         if ( destinationFile.exists() )
 136  
         {
 137  1
             destinationFile.delete();
 138  
         }
 139  
         else
 140  
         {
 141  1
             if ( !destinationFile.getParentFile().exists() )
 142  
             {
 143  0
                 destinationFile.getParentFile().mkdirs();
 144  
             }
 145  
         }
 146  
 
 147  2
         String encoding = "UTF-8";
 148  
 
 149  2
         Writer writer = null;
 150  
         try
 151  
         {
 152  2
             writer = new OutputStreamWriter( new FileOutputStream( destinationFile ), encoding );
 153  
 
 154  2
             XMLWriter w = new PrettyPrintXMLWriter( writer, encoding, null );
 155  
 
 156  2
             w.writeMarkup( "\n<!-- Generated by maven-plugin-tools " + getVersion() + " on "
 157  
                 + new SimpleDateFormat( "yyyy-MM-dd" ).format( new Date() ) + " -->\n\n" );
 158  
 
 159  2
             w.startElement( "plugin" );
 160  
 
 161  2
             GeneratorUtils.element( w, "name", pluginDescriptor.getName() );
 162  
 
 163  2
             GeneratorUtils.element( w, "description", pluginDescriptor.getDescription(), helpDescriptor );
 164  
 
 165  2
             GeneratorUtils.element( w, "groupId", pluginDescriptor.getGroupId() );
 166  
 
 167  2
             GeneratorUtils.element( w, "artifactId", pluginDescriptor.getArtifactId() );
 168  
 
 169  2
             GeneratorUtils.element( w, "version", pluginDescriptor.getVersion() );
 170  
 
 171  2
             GeneratorUtils.element( w, "goalPrefix", pluginDescriptor.getGoalPrefix() );
 172  
 
 173  2
             if ( !helpDescriptor )
 174  
             {
 175  1
                 GeneratorUtils.element( w, "isolatedRealm", String.valueOf( pluginDescriptor.isIsolatedRealm() ) );
 176  
 
 177  1
                 GeneratorUtils.element( w, "inheritedByDefault", String.valueOf( pluginDescriptor.isInheritedByDefault() ) );
 178  
             }
 179  
 
 180  2
             w.startElement( "mojos" );
 181  
 
 182  2
             if ( pluginDescriptor.getMojos() != null )
 183  
             {
 184  2
                 @SuppressWarnings( "unchecked" ) List<MojoDescriptor> descriptors = pluginDescriptor.getMojos();
 185  
 
 186  2
                 if ( helpDescriptor )
 187  
                 {
 188  1
                     PluginUtils.sortMojos( descriptors );
 189  
                 }
 190  
 
 191  2
                 for ( MojoDescriptor descriptor : descriptors )
 192  
                 {
 193  2
                     processMojoDescriptor( descriptor, w, helpDescriptor );
 194  
                 }
 195  
             }
 196  
 
 197  2
             w.endElement();
 198  
 
 199  2
             if ( !helpDescriptor )
 200  
             {
 201  1
                 GeneratorUtils.writeDependencies( w, pluginDescriptor );
 202  
             }
 203  
 
 204  2
             w.endElement();
 205  
 
 206  2
             writer.flush();
 207  
 
 208  
         }
 209  
         finally
 210  
         {
 211  2
             IOUtil.close( writer );
 212  2
         }
 213  2
     }
 214  
 
 215  
     protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w )
 216  
     {
 217  0
         processMojoDescriptor( mojoDescriptor, w, false );
 218  0
     }
 219  
 
 220  
     /**
 221  
      * @param mojoDescriptor   not null
 222  
      * @param w                not null
 223  
      * @param helpDescriptor will clean html content from description fields
 224  
      */
 225  
     protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w, boolean helpDescriptor )
 226  
     {
 227  2
         w.startElement( "mojo" );
 228  
 
 229  
         // ----------------------------------------------------------------------
 230  
         //
 231  
         // ----------------------------------------------------------------------
 232  
 
 233  2
         w.startElement( "goal" );
 234  2
         w.writeText( mojoDescriptor.getGoal() );
 235  2
         w.endElement();
 236  
 
 237  
         // ----------------------------------------------------------------------
 238  
         //
 239  
         // ----------------------------------------------------------------------
 240  
 
 241  2
         String description = mojoDescriptor.getDescription();
 242  
 
 243  2
         if ( description != null )
 244  
         {
 245  0
             w.startElement( "description" );
 246  0
             if ( helpDescriptor )
 247  
             {
 248  0
                 w.writeText( GeneratorUtils.toText( mojoDescriptor.getDescription() ) );
 249  
             }
 250  
             else
 251  
             {
 252  0
                 w.writeText( mojoDescriptor.getDescription() );
 253  
             }
 254  0
             w.endElement();
 255  
         }
 256  
 
 257  
         // ----------------------------------------------------------------------
 258  
         //
 259  
         // ----------------------------------------------------------------------
 260  
 
 261  2
         if ( mojoDescriptor.isDependencyResolutionRequired() != null )
 262  
         {
 263  2
             GeneratorUtils.element( w, "requiresDependencyResolution", mojoDescriptor.isDependencyResolutionRequired() );
 264  
         }
 265  
 
 266  
         // ----------------------------------------------------------------------
 267  
         //
 268  
         // ----------------------------------------------------------------------
 269  
 
 270  2
         GeneratorUtils.element( w, "requiresDirectInvocation", String.valueOf( mojoDescriptor.isDirectInvocationOnly() ) );
 271  
 
 272  
         // ----------------------------------------------------------------------
 273  
         //
 274  
         // ----------------------------------------------------------------------
 275  
 
 276  2
         GeneratorUtils.element( w, "requiresProject", String.valueOf( mojoDescriptor.isProjectRequired() ) );
 277  
 
 278  
         // ----------------------------------------------------------------------
 279  
         //
 280  
         // ----------------------------------------------------------------------
 281  
 
 282  2
         GeneratorUtils.element( w, "requiresReports", String.valueOf( mojoDescriptor.isRequiresReports() ) );
 283  
 
 284  
         // ----------------------------------------------------------------------
 285  
         //
 286  
         // ----------------------------------------------------------------------
 287  
 
 288  2
         GeneratorUtils.element( w, "aggregator", String.valueOf( mojoDescriptor.isAggregator() ) );
 289  
 
 290  
         // ----------------------------------------------------------------------
 291  
         //
 292  
         // ----------------------------------------------------------------------
 293  
 
 294  2
         GeneratorUtils.element( w, "requiresOnline", String.valueOf( mojoDescriptor.isOnlineRequired() ) );
 295  
 
 296  
         // ----------------------------------------------------------------------
 297  
         //
 298  
         // ----------------------------------------------------------------------
 299  
 
 300  2
         GeneratorUtils.element( w, "inheritedByDefault", String.valueOf( mojoDescriptor.isInheritedByDefault() ) );
 301  
 
 302  
         // ----------------------------------------------------------------------
 303  
         //
 304  
         // ----------------------------------------------------------------------
 305  
 
 306  2
         if ( mojoDescriptor.getPhase() != null )
 307  
         {
 308  0
             GeneratorUtils.element( w, "phase", mojoDescriptor.getPhase() );
 309  
         }
 310  
 
 311  
         // ----------------------------------------------------------------------
 312  
         //
 313  
         // ----------------------------------------------------------------------
 314  
 
 315  2
         if ( mojoDescriptor.getExecutePhase() != null )
 316  
         {
 317  0
             GeneratorUtils.element( w, "executePhase", mojoDescriptor.getExecutePhase() );
 318  
         }
 319  
 
 320  2
         if ( mojoDescriptor.getExecuteGoal() != null )
 321  
         {
 322  0
             GeneratorUtils.element( w, "executeGoal", mojoDescriptor.getExecuteGoal() );
 323  
         }
 324  
 
 325  2
         if ( mojoDescriptor.getExecuteLifecycle() != null )
 326  
         {
 327  0
             GeneratorUtils.element( w, "executeLifecycle", mojoDescriptor.getExecuteLifecycle() );
 328  
         }
 329  
 
 330  
         // ----------------------------------------------------------------------
 331  
         //
 332  
         // ----------------------------------------------------------------------
 333  
 
 334  2
         w.startElement( "implementation" );
 335  2
         w.writeText( mojoDescriptor.getImplementation() );
 336  2
         w.endElement();
 337  
 
 338  
         // ----------------------------------------------------------------------
 339  
         //
 340  
         // ----------------------------------------------------------------------
 341  
 
 342  2
         w.startElement( "language" );
 343  2
         w.writeText( mojoDescriptor.getLanguage() );
 344  2
         w.endElement();
 345  
 
 346  
         // ----------------------------------------------------------------------
 347  
         //
 348  
         // ----------------------------------------------------------------------
 349  
 
 350  2
         if ( mojoDescriptor.getComponentConfigurator() != null )
 351  
         {
 352  0
             w.startElement( "configurator" );
 353  0
             w.writeText( mojoDescriptor.getComponentConfigurator() );
 354  0
             w.endElement();
 355  
         }
 356  
 
 357  
         // ----------------------------------------------------------------------
 358  
         //
 359  
         // ----------------------------------------------------------------------
 360  
 
 361  2
         if ( mojoDescriptor.getComponentComposer() != null )
 362  
         {
 363  0
             w.startElement( "composer" );
 364  0
             w.writeText( mojoDescriptor.getComponentComposer() );
 365  0
             w.endElement();
 366  
         }
 367  
 
 368  
         // ----------------------------------------------------------------------
 369  
         //
 370  
         // ----------------------------------------------------------------------
 371  
 
 372  2
         w.startElement( "instantiationStrategy" );
 373  2
         w.writeText( mojoDescriptor.getInstantiationStrategy() );
 374  2
         w.endElement();
 375  
 
 376  
         // ----------------------------------------------------------------------
 377  
         // Strategy for handling repeated reference to mojo in
 378  
         // the calculated (decorated, resolved) execution stack
 379  
         // ----------------------------------------------------------------------
 380  2
         w.startElement( "executionStrategy" );
 381  2
         w.writeText( mojoDescriptor.getExecutionStrategy() );
 382  2
         w.endElement();
 383  
 
 384  
         // ----------------------------------------------------------------------
 385  
         //
 386  
         // ----------------------------------------------------------------------
 387  
 
 388  2
         if ( mojoDescriptor.getSince() != null )
 389  
         {
 390  0
             w.startElement( "since" );
 391  
 
 392  0
             if ( StringUtils.isEmpty( mojoDescriptor.getSince() ) )
 393  
             {
 394  0
                 w.writeText( "No version given" );
 395  
             }
 396  
             else
 397  
             {
 398  0
                 w.writeText( mojoDescriptor.getSince() );
 399  
             }
 400  
 
 401  0
             w.endElement();
 402  
         }
 403  
 
 404  
         // ----------------------------------------------------------------------
 405  
         //
 406  
         // ----------------------------------------------------------------------
 407  
 
 408  2
         if ( mojoDescriptor.getDeprecated() != null )
 409  
         {
 410  0
             w.startElement( "deprecated" );
 411  
 
 412  0
             if ( StringUtils.isEmpty( mojoDescriptor.getDeprecated() ) )
 413  
             {
 414  0
                 w.writeText( "No reason given" );
 415  
             }
 416  
             else
 417  
             {
 418  0
                 w.writeText( mojoDescriptor.getDeprecated() );
 419  
             }
 420  
 
 421  0
             w.endElement();
 422  
         }
 423  
 
 424  
         // ----------------------------------------------------------------------
 425  
         // Extended (3.0) descriptor
 426  
         // ----------------------------------------------------------------------
 427  
 
 428  2
         if ( mojoDescriptor instanceof ExtendedMojoDescriptor )
 429  
         {
 430  0
             ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor;
 431  0
             if ( extendedMojoDescriptor.getDependencyCollectionRequired() != null )
 432  
             {
 433  0
                 GeneratorUtils.element( w, "requiresDependencyCollection",
 434  
                                      extendedMojoDescriptor.getDependencyCollectionRequired() );
 435  
             }
 436  
 
 437  0
             GeneratorUtils.element( w, "threadSafe", String.valueOf( extendedMojoDescriptor.isThreadSafe() ) );
 438  
         }
 439  
 
 440  
         // ----------------------------------------------------------------------
 441  
         // Parameters
 442  
         // ----------------------------------------------------------------------
 443  
 
 444  2
         @SuppressWarnings( "unchecked" ) List<Parameter> parameters = mojoDescriptor.getParameters();
 445  
 
 446  2
         w.startElement( "parameters" );
 447  
 
 448  2
         Map<String, Requirement> requirements = new LinkedHashMap<String, Requirement>();
 449  
 
 450  2
         Set<Parameter> configuration = new LinkedHashSet<Parameter>();
 451  
 
 452  2
         if ( parameters != null )
 453  
         {
 454  2
             if ( helpDescriptor )
 455  
             {
 456  1
                 PluginUtils.sortMojoParameters( parameters );
 457  
             }
 458  
 
 459  2
             for ( Parameter parameter : parameters )
 460  
             {
 461  2
                 String expression = getExpression( parameter );
 462  
 
 463  2
                 if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${component." ) )
 464  
                 {
 465  
                     // treat it as a component...a requirement, in other words.
 466  
 
 467  
                     // remove "component." plus expression delimiters
 468  0
                     String role = expression.substring( "${component.".length(), expression.length() - 1 );
 469  
 
 470  0
                     String roleHint = null;
 471  
 
 472  0
                     int posRoleHintSeparator = role.indexOf( "#" );
 473  0
                     if ( posRoleHintSeparator > 0 )
 474  
                     {
 475  0
                         roleHint = role.substring( posRoleHintSeparator + 1 );
 476  
 
 477  0
                         role = role.substring( 0, posRoleHintSeparator );
 478  
                     }
 479  
 
 480  
                     // TODO: remove deprecated expression
 481  0
                     requirements.put( parameter.getName(), new Requirement( role, roleHint ) );
 482  0
                 }
 483  2
                 else if ( parameter.getRequirement() != null )
 484  
                 {
 485  0
                     requirements.put( parameter.getName(), parameter.getRequirement() );
 486  
                 }
 487  2
                 else if ( !helpDescriptor || parameter.isEditable() ) // don't show readonly parameters in help
 488  
                 {
 489  
                     // treat it as a normal parameter.
 490  
 
 491  2
                     w.startElement( "parameter" );
 492  
 
 493  2
                     GeneratorUtils.element( w, "name", parameter.getName() );
 494  
 
 495  2
                     if ( parameter.getAlias() != null )
 496  
                     {
 497  0
                         GeneratorUtils.element( w, "alias", parameter.getAlias() );
 498  
                     }
 499  
 
 500  2
                     GeneratorUtils.element( w, "type", parameter.getType() );
 501  
 
 502  2
                     if ( parameter.getSince() != null )
 503  
                     {
 504  0
                         w.startElement( "since" );
 505  
 
 506  0
                         if ( StringUtils.isEmpty( parameter.getSince() ) )
 507  
                         {
 508  0
                             w.writeText( "No version given" );
 509  
                         }
 510  
                         else
 511  
                         {
 512  0
                             w.writeText( parameter.getSince() );
 513  
                         }
 514  
 
 515  0
                         w.endElement();
 516  
                     }
 517  
 
 518  2
                     if ( parameter.getDeprecated() != null )
 519  
                     {
 520  0
                         if ( StringUtils.isEmpty( parameter.getDeprecated() ) )
 521  
                         {
 522  0
                             GeneratorUtils.element( w, "deprecated", "No reason given" );
 523  
                         }
 524  
                         else
 525  
                         {
 526  0
                             GeneratorUtils.element( w, "deprecated", parameter.getDeprecated() );
 527  
                         }
 528  
                     }
 529  
 
 530  2
                     if ( parameter.getImplementation() != null )
 531  
                     {
 532  0
                         GeneratorUtils.element( w, "implementation", parameter.getImplementation() );
 533  
                     }
 534  
 
 535  2
                     GeneratorUtils.element( w, "required", Boolean.toString( parameter.isRequired() ) );
 536  
 
 537  2
                     GeneratorUtils.element( w, "editable", Boolean.toString( parameter.isEditable() ) );
 538  
 
 539  2
                     GeneratorUtils.element( w, "description", parameter.getDescription(), helpDescriptor );
 540  
 
 541  2
                     if ( StringUtils.isNotEmpty( parameter.getDefaultValue() )
 542  
                         || StringUtils.isNotEmpty( parameter.getExpression() ) )
 543  
                     {
 544  2
                         configuration.add( parameter );
 545  
                     }
 546  
 
 547  2
                     w.endElement();
 548  
                 }
 549  
 
 550  2
             }
 551  
         }
 552  
 
 553  2
         w.endElement();
 554  
 
 555  
         // ----------------------------------------------------------------------
 556  
         // Configuration
 557  
         // ----------------------------------------------------------------------
 558  
 
 559  2
         if ( !configuration.isEmpty() )
 560  
         {
 561  2
             w.startElement( "configuration" );
 562  
 
 563  2
             for ( Parameter parameter : configuration )
 564  
             {
 565  2
                 if ( helpDescriptor && !parameter.isEditable() )
 566  
                 {
 567  
                     // don't show readonly parameters in help
 568  0
                     continue;
 569  
                 }
 570  
 
 571  2
                 w.startElement( parameter.getName() );
 572  
 
 573  2
                 String type = parameter.getType();
 574  2
                 if ( type != null )
 575  
                 {
 576  2
                     w.addAttribute( "implementation", type );
 577  
                 }
 578  
 
 579  2
                 if ( parameter.getDefaultValue() != null )
 580  
                 {
 581  2
                     w.addAttribute( "default-value", parameter.getDefaultValue() );
 582  
                 }
 583  
 
 584  2
                 if ( parameter.getExpression() != null )
 585  
                 {
 586  2
                     w.writeText( parameter.getExpression() );
 587  
                 }
 588  
 
 589  2
                 w.endElement();
 590  2
             }
 591  
 
 592  2
             w.endElement();
 593  
         }
 594  
 
 595  
         // ----------------------------------------------------------------------
 596  
         // Requirements
 597  
         // ----------------------------------------------------------------------
 598  
 
 599  2
         if ( !requirements.isEmpty() && !helpDescriptor )
 600  
         {
 601  0
             w.startElement( "requirements" );
 602  
 
 603  0
             for ( Map.Entry<String, Requirement> entry : requirements.entrySet() )
 604  
             {
 605  0
                 String key = entry.getKey();
 606  0
                 Requirement requirement = entry.getValue();
 607  
 
 608  0
                 w.startElement( "requirement" );
 609  
 
 610  0
                 GeneratorUtils.element( w, "role", requirement.getRole() );
 611  
 
 612  0
                 if ( requirement.getRoleHint() != null )
 613  
                 {
 614  0
                     GeneratorUtils.element( w, "role-hint", requirement.getRoleHint() );
 615  
                 }
 616  
 
 617  0
                 GeneratorUtils.element( w, "field-name", key );
 618  
 
 619  0
                 w.endElement();
 620  0
             }
 621  
 
 622  0
             w.endElement();
 623  
         }
 624  
 
 625  2
         w.endElement();
 626  2
     }
 627  
 
 628  
     /**
 629  
      * Get the expression value, eventually surrounding it with <code>${ }</code>.
 630  
      * 
 631  
      * @param parameter the parameter
 632  
      * @return the expression value
 633  
      */
 634  
     private String getExpression( Parameter parameter )
 635  
     {
 636  2
         String expression = parameter.getExpression();
 637  2
         if ( StringUtils.isNotBlank( expression ) && !expression.contains( "${" ) )
 638  
         {
 639  0
             expression = "${" + expression.trim() + "}";
 640  0
             parameter.setExpression( expression );
 641  
         }
 642  2
         return expression;
 643  
     }
 644  
 
 645  
     protected String rewriteHelpClassToMojoPackage( PluginToolsRequest request )
 646  
         throws GeneratorException
 647  
     {
 648  1
         String destinationPackage = GeneratorUtils.discoverPackageName( request.getPluginDescriptor() );
 649  1
         if ( StringUtils.isEmpty( destinationPackage ) )
 650  
         {
 651  0
             return null;
 652  
         }
 653  1
         File helpClassFile = new File( request.getProject().getBuild().getOutputDirectory(), "HelpMojo.class" );
 654  1
         if ( !helpClassFile.exists() )
 655  
         {
 656  1
             return null;
 657  
         }
 658  0
         File rewriteHelpClassFile = new File(
 659  
             request.getProject().getBuild().getOutputDirectory() + "/" + StringUtils.replace( destinationPackage, ".",
 660  
                                                                                               "/" ), "HelpMojo.class" );
 661  0
         if ( !rewriteHelpClassFile.getParentFile().exists() )
 662  
         {
 663  0
             rewriteHelpClassFile.getParentFile().mkdirs();
 664  
         }
 665  
 
 666  0
         ClassReader cr = null;
 667  
         try
 668  
         {
 669  0
             cr = new ClassReader( new FileInputStream( helpClassFile ) );
 670  
         }
 671  0
         catch ( IOException e )
 672  
         {
 673  0
             throw new GeneratorException( e.getMessage(), e );
 674  0
         }
 675  
 
 676  0
         ClassWriter cw = new ClassWriter( 0 );
 677  
 
 678  0
         ClassVisitor cv = new RemappingClassAdapter( cw, new SimpleRemapper( "HelpMojo",
 679  
                                                                              StringUtils.replace( destinationPackage,
 680  
                                                                                                   ".", "/" )
 681  
                                                                                  + "/HelpMojo" ) );
 682  
 
 683  
         try
 684  
         {
 685  0
             cr.accept( cv, ClassReader.EXPAND_FRAMES );
 686  
         }
 687  0
         catch ( Throwable e )
 688  
         {
 689  0
             throw new GeneratorException( "ASM issue processing classFile " + helpClassFile.getPath(), e );
 690  0
         }
 691  
 
 692  0
         byte[] renamedClass = cw.toByteArray();
 693  0
         FileOutputStream fos = null;
 694  
         try
 695  
         {
 696  0
             fos = new FileOutputStream( rewriteHelpClassFile );
 697  0
             fos.write( renamedClass );
 698  
         }
 699  0
         catch ( IOException e )
 700  
         {
 701  0
             throw new GeneratorException( "Error rewriting help class: " + e.getMessage(), e );
 702  
         }
 703  
         finally
 704  
         {
 705  0
             IOUtil.close( fos );
 706  0
         }
 707  0
         helpClassFile.delete();
 708  0
         return destinationPackage + ".HelpMojo";
 709  
     }
 710  
 
 711  
 
 712  
     private void rewriteDescriptor( PluginDescriptor pluginDescriptor, String helpMojoImplementation )
 713  
     {
 714  0
         MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( "help" );
 715  0
         if ( mojoDescriptor != null )
 716  
         {
 717  0
             mojoDescriptor.setImplementation( helpMojoImplementation );
 718  
         }
 719  0
     }
 720  
 }