View Javadoc
1   package org.apache.maven.tools.plugin.extractor.model;
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.File;
23  import java.io.IOException;
24  import java.io.Reader;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.apache.maven.plugin.descriptor.DuplicateParameterException;
30  import org.apache.maven.plugin.descriptor.MojoDescriptor;
31  import org.apache.maven.plugin.descriptor.Parameter;
32  import org.apache.maven.tools.plugin.extractor.model.io.xpp3.PluginMetadataXpp3Reader;
33  import org.codehaus.plexus.component.repository.ComponentRequirement;
34  import org.codehaus.plexus.util.IOUtil;
35  import org.codehaus.plexus.util.ReaderFactory;
36  import org.codehaus.plexus.util.StringUtils;
37  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
38  
39  /**
40   * Parser for plugin metadata.
41   *
42   * @version $Id$
43   */
44  public class PluginMetadataParser
45  {
46      /** Default implementation path which will be replaced in
47       * AbstractScriptedMojoDescriptorExtractor#extractMojoDescriptorsFromMetadata(Map, PluginDescriptor) */
48      public static final String IMPL_BASE_PLACEHOLDER = "<REPLACE-WITH-MOJO-PATH>";
49  
50      /**
51       * @param metadataFile the metadata file to be parse
52       * @return a set of <code>MojoDescriptor</code>
53       * @throws PluginMetadataParseException if any
54       */
55      public Set<MojoDescriptor> parseMojoDescriptors( File metadataFile )
56          throws PluginMetadataParseException
57      {
58          Set<MojoDescriptor> descriptors = new HashSet<MojoDescriptor>();
59  
60          Reader reader = null;
61  
62          try
63          {
64              reader = ReaderFactory.newXmlReader( metadataFile );
65  
66              PluginMetadataXpp3Reader metadataReader = new PluginMetadataXpp3Reader();
67  
68              PluginMetadata pluginMetadata = metadataReader.read( reader );
69  
70              List<Mojo> mojos = pluginMetadata.getMojos();
71  
72              if ( mojos != null && !mojos.isEmpty() )
73              {
74                  for ( Mojo mojo :mojos )
75                  {
76                      MojoDescriptor descriptor = asDescriptor( metadataFile, mojo );
77  
78                      descriptors.add( descriptor );
79                  }
80              }
81  
82              reader.close();
83              reader = null;
84          }
85          catch ( IOException e )
86          {
87              throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
88          }
89          catch ( XmlPullParserException e )
90          {
91              throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e );
92          }
93          finally
94          {
95              IOUtil.close( reader );
96          }
97  
98          return descriptors;
99      }
100 
101     /**
102      * @param metadataFile not null
103      * @param mojo not null
104      * @return a mojo descriptor instance
105      * @throws PluginMetadataParseException if any
106      */
107     private MojoDescriptor asDescriptor( File metadataFile, Mojo mojo )
108         throws PluginMetadataParseException
109     {
110         MojoDescriptor descriptor = new MojoDescriptor();
111 
112         if ( mojo.getCall() != null )
113         {
114             descriptor.setImplementation( IMPL_BASE_PLACEHOLDER + ":" + mojo.getCall() );
115         }
116         else
117         {
118             descriptor.setImplementation( IMPL_BASE_PLACEHOLDER );
119         }
120 
121         descriptor.setGoal( mojo.getGoal() );
122         descriptor.setPhase( mojo.getPhase() );
123         descriptor.setDependencyResolutionRequired( mojo.getRequiresDependencyResolution() );
124         descriptor.setAggregator( mojo.isAggregator() );
125         descriptor.setInheritedByDefault( mojo.isInheritByDefault() );
126         descriptor.setDirectInvocationOnly( mojo.isRequiresDirectInvocation() );
127         descriptor.setOnlineRequired( mojo.isRequiresOnline() );
128         descriptor.setProjectRequired( mojo.isRequiresProject() );
129         descriptor.setRequiresReports( mojo.isRequiresReports() );
130         descriptor.setDescription( mojo.getDescription() );
131         descriptor.setDeprecated( mojo.getDeprecation() );
132         descriptor.setSince( mojo.getSince() );
133 
134         LifecycleExecution le = mojo.getExecution();
135         if ( le != null )
136         {
137             descriptor.setExecuteLifecycle( le.getLifecycle() );
138             descriptor.setExecutePhase( le.getPhase() );
139             descriptor.setExecuteGoal( le.getGoal() );
140         }
141 
142         List<org.apache.maven.tools.plugin.extractor.model.Parameter> parameters = mojo.getParameters();
143 
144         if ( parameters != null && !parameters.isEmpty() )
145         {
146             for ( org.apache.maven.tools.plugin.extractor.model.Parameter param : parameters )
147             {
148                 Parameter dParam = new Parameter();
149                 dParam.setAlias( param.getAlias() );
150                 dParam.setDeprecated( param.getDeprecation() );
151                 dParam.setDescription( param.getDescription() );
152                 dParam.setEditable( !param.isReadonly() );
153                 dParam.setExpression( param.getExpression() );
154                 dParam.setDefaultValue( param.getDefaultValue() );
155                 dParam.setSince( param.getSince() );
156 
157                 String property = param.getProperty();
158                 if ( StringUtils.isNotEmpty( property ) )
159                 {
160                     dParam.setName( property );
161                 }
162                 else
163                 {
164                     dParam.setName( param.getName() );
165                 }
166 
167                 if ( StringUtils.isEmpty( dParam.getName() ) )
168                 {
169                     throw new PluginMetadataParseException( metadataFile, "Mojo: \'" + mojo.getGoal()
170                         + "\' has a parameter without either property or name attributes. Please specify one." );
171                 }
172 
173                 dParam.setRequired( param.isRequired() );
174                 dParam.setType( param.getType() );
175 
176                 try
177                 {
178                     descriptor.addParameter( dParam );
179                 }
180                 catch ( DuplicateParameterException e )
181                 {
182                     throw new PluginMetadataParseException( metadataFile,
183                                                             "Duplicate parameters detected for mojo: "
184                                                                 + mojo.getGoal(), e );
185                 }
186             }
187         }
188 
189         List<Component> components = mojo.getComponents();
190 
191         if ( components != null && !components.isEmpty() )
192         {
193             for ( Component component : components )
194             {
195                 ComponentRequirement cr = new ComponentRequirement();
196                 cr.setRole( component.getRole() );
197                 cr.setRoleHint( component.getHint() );
198 
199                 descriptor.addRequirement( cr );
200             }
201         }
202 
203         return descriptor;
204     }
205 }