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