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