View Javadoc
1   package org.apache.maven.tools.plugin.extractor.ant;
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.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
30  import org.apache.maven.plugin.descriptor.MojoDescriptor;
31  import org.apache.maven.plugin.descriptor.Parameter;
32  import org.apache.maven.project.MavenProject;
33  import org.apache.maven.project.path.PathTranslator;
34  import org.apache.maven.tools.plugin.PluginToolsRequest;
35  import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor;
36  import org.apache.maven.tools.plugin.extractor.ExtractionException;
37  import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
38  import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParseException;
39  import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParser;
40  import org.codehaus.plexus.component.annotations.Component;
41  import org.codehaus.plexus.component.repository.ComponentRequirement;
42  import org.codehaus.plexus.util.StringUtils;
43  
44  /**
45   * Extracts Mojo descriptors from <a href="http://ant.apache.org">Ant</a> sources.
46   *
47   * @version $Id: AntMojoDescriptorExtractor.html 995996 2016-08-26 22:31:42Z rfscholte $
48   */
49  @Component( role = MojoDescriptorExtractor.class, hint = "ant" )
50  public class AntMojoDescriptorExtractor
51      extends AbstractScriptedMojoDescriptorExtractor
52      implements MojoDescriptorExtractor
53  {
54      /** Default metadata file extension */
55      private static final String METADATA_FILE_EXTENSION = ".mojos.xml";
56  
57      /** Default Ant build file extension */
58      private static final String SCRIPT_FILE_EXTENSION = ".build.xml";
59      
60      /** {@inheritDoc} */
61      protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata(
62                                                                    Map<String, Set<File>> metadataFilesKeyedByBasedir,
63                                                                    PluginToolsRequest request )
64          throws ExtractionException, InvalidPluginDescriptorException
65      {
66          List<MojoDescriptor> descriptors = new ArrayList<MojoDescriptor>();
67  
68          PluginMetadataParser parser = new PluginMetadataParser();
69  
70          for ( Map.Entry<String, Set<File>> entry : metadataFilesKeyedByBasedir.entrySet() )
71          {
72              String basedir = entry.getKey();
73              Set<File> metadataFiles = entry.getValue();
74  
75              for ( File metadataFile : metadataFiles )
76              {
77                  String basename = metadataFile.getName();
78                  basename = basename.substring( 0, basename.length() - METADATA_FILE_EXTENSION.length() );
79  
80                  File scriptFile = new File( metadataFile.getParentFile(), basename + SCRIPT_FILE_EXTENSION );
81  
82                  if ( !scriptFile.exists() )
83                  {
84                      throw new InvalidPluginDescriptorException(
85                          "Found orphaned plugin metadata file: " + metadataFile );
86                  }
87  
88                  String relativePath = scriptFile.getPath().substring( basedir.length() ).replace( '\\', '/' );
89                  
90                  if ( relativePath.startsWith( "/" ) )
91                  {
92                      relativePath = relativePath.substring( 1 );
93                  }
94  
95                  try
96                  {
97                      Set<MojoDescriptor> mojoDescriptors = parser.parseMojoDescriptors( metadataFile );
98  
99                      for ( MojoDescriptor descriptor : mojoDescriptors )
100                     {
101                         @SuppressWarnings( "unchecked" )
102                         Map<String, ?> paramMap = descriptor.getParameterMap();
103 
104                         if ( !paramMap.containsKey( "basedir" ) )
105                         {
106                             Parameter param = new Parameter();
107                             param.setName( "basedir" );
108                             param.setAlias( "ant.basedir" );
109                             param.setExpression( "${antBasedir}" );
110                             param.setDefaultValue( "${basedir}" );
111                             param.setType( "java.io.File" );
112                             param.setDescription( "The base directory from which to execute the Ant script." );
113                             param.setEditable( true );
114                             param.setRequired( true );
115 
116                             descriptor.addParameter( param );
117                         }
118 
119                         if ( !paramMap.containsKey( "antMessageLevel" ) )
120                         {
121                             Parameter param = new Parameter();
122                             param.setName( "messageLevel" );
123                             param.setAlias( "ant.messageLevel" );
124                             param.setExpression( "${antMessageLevel}" );
125                             param.setDefaultValue( "info" );
126                             param.setType( "java.lang.String" );
127                             param.setDescription( "The message-level used to tune the verbosity of Ant logging." );
128                             param.setEditable( true );
129                             param.setRequired( false );
130 
131                             descriptor.addParameter( param );
132                         }
133                         
134                         if ( !paramMap.containsKey( "project" ) )
135                         {
136                             Parameter param = new Parameter();
137                             param.setName( "project" );
138                             param.setDefaultValue( "${project}" );
139                             param.setType( MavenProject.class.getName() );
140                             param.setDescription( "The current MavenProject instance, which contains classpath "
141                                 + "elements." );
142                             param.setEditable( false );
143                             param.setRequired( true );
144 
145                             descriptor.addParameter( param );
146                         }
147 
148                         if ( !paramMap.containsKey( "session" ) )
149                         {
150                             Parameter param = new Parameter();
151                             param.setName( "session" );
152                             param.setDefaultValue( "${session}" );
153                             param.setType( "org.apache.maven.execution.MavenSession" );
154                             param.setDescription( "The current MavenSession instance, which is used for "
155                                 + "plugin-style expression resolution." );
156                             param.setEditable( false );
157                             param.setRequired( true );
158 
159                             descriptor.addParameter( param );
160                         }
161 
162                         if ( !paramMap.containsKey( "mojoExecution" ) )
163                         {
164                             Parameter param = new Parameter();
165                             param.setName( "mojoExecution" );
166                             param.setDefaultValue( "${mojoExecution}" );
167                             param.setType( "org.apache.maven.plugin.MojoExecution" );
168                             param.setDescription( "The current Maven MojoExecution instance, which contains "
169                                 + "information about the mojo currently executing." );
170                             param.setEditable( false );
171                             param.setRequired( true );
172 
173                             descriptor.addParameter( param );
174                         }
175                         
176                         @SuppressWarnings( "unchecked" )
177                         List<ComponentRequirement> requirements = descriptor.getRequirements();
178                         Map<String, ComponentRequirement> reqMap = new HashMap<String, ComponentRequirement>();
179 
180                         if ( requirements != null )
181                         {
182                             for ( ComponentRequirement req : requirements )
183                             {
184                                 reqMap.put( req.getRole(), req );
185                             }
186                         }
187                         
188                         if ( !reqMap.containsKey( PathTranslator.class.getName() ) )
189                         {
190                             ComponentRequirement req = new ComponentRequirement();
191                             req.setRole( PathTranslator.class.getName() );
192                             
193                             descriptor.addRequirement( req );
194                         }
195 
196                         String implementation = relativePath;
197 
198                         String dImpl = descriptor.getImplementation();
199                         if ( StringUtils.isNotEmpty( dImpl ) )
200                         {
201                             if ( PluginMetadataParser.IMPL_BASE_PLACEHOLDER.equals( dImpl ) )
202                             {
203                                 implementation = relativePath;
204                             }
205                             else
206                             {
207                                 implementation =
208                                     relativePath
209                                         + dImpl.substring( PluginMetadataParser.IMPL_BASE_PLACEHOLDER.length() );
210                             }
211                         }
212 
213                         descriptor.setImplementation( implementation );
214 
215                         descriptor.setLanguage( "ant-mojo" );
216                         descriptor.setComponentComposer( "map-oriented" );
217                         descriptor.setComponentConfigurator( "map-oriented" );
218 
219                         descriptor.setPluginDescriptor( request.getPluginDescriptor() );
220 
221                         descriptors.add( descriptor );
222                     }
223                 }
224                 catch ( PluginMetadataParseException e )
225                 {
226                     throw new ExtractionException( "Error extracting mojo descriptor from script: " + metadataFile, e );
227                 }
228             }
229         }
230 
231         return descriptors;
232     }
233 
234     /** {@inheritDoc} */
235     protected String getScriptFileExtension( PluginToolsRequest request )
236     {
237         return SCRIPT_FILE_EXTENSION;
238     }
239 
240     /** {@inheritDoc} */
241     protected String getMetadataFileExtension( PluginToolsRequest request )
242     {
243         return METADATA_FILE_EXTENSION;
244     }
245 }