View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.tools.plugin.extractor.ant;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.io.File;
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Set;
30  
31  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
32  import org.apache.maven.plugin.descriptor.MojoDescriptor;
33  import org.apache.maven.plugin.descriptor.Parameter;
34  import org.apache.maven.project.MavenProject;
35  import org.apache.maven.project.path.PathTranslator;
36  import org.apache.maven.tools.plugin.PluginToolsRequest;
37  import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor;
38  import org.apache.maven.tools.plugin.extractor.ExtractionException;
39  import org.apache.maven.tools.plugin.extractor.GroupKey;
40  import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParseException;
41  import org.apache.maven.tools.plugin.extractor.model.PluginMetadataParser;
42  import org.codehaus.plexus.component.repository.ComponentRequirement;
43  
44  /**
45   * Extracts Mojo descriptors from <a href="http://ant.apache.org">Ant</a> sources.
46   *
47   * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
48   */
49  @Deprecated
50  @Named(AntMojoDescriptorExtractor.NAME)
51  @Singleton
52  public class AntMojoDescriptorExtractor extends AbstractScriptedMojoDescriptorExtractor {
53      public static final String NAME = "ant";
54  
55      private static final GroupKey GROUP_KEY = new GroupKey("ant", 100);
56  
57      /** Default metadata file extension */
58      private static final String METADATA_FILE_EXTENSION = ".mojos.xml";
59  
60      /** Default Ant build file extension */
61      private static final String SCRIPT_FILE_EXTENSION = ".build.xml";
62  
63      @Override
64      public String getName() {
65          return NAME;
66      }
67  
68      @Override
69      public GroupKey getGroupKey() {
70          return GROUP_KEY;
71      }
72  
73      /** {@inheritDoc} */
74      @Override
75      protected List<MojoDescriptor> extractMojoDescriptorsFromMetadata(
76              Map<String, Set<File>> metadataFilesKeyedByBasedir, PluginToolsRequest request)
77              throws ExtractionException, InvalidPluginDescriptorException {
78          List<MojoDescriptor> descriptors = new ArrayList<>();
79  
80          PluginMetadataParser parser = new PluginMetadataParser();
81  
82          for (Map.Entry<String, Set<File>> entry : metadataFilesKeyedByBasedir.entrySet()) {
83              String basedir = entry.getKey();
84              Set<File> metadataFiles = entry.getValue();
85  
86              for (File metadataFile : metadataFiles) {
87                  String basename = metadataFile.getName();
88                  basename = basename.substring(0, basename.length() - METADATA_FILE_EXTENSION.length());
89  
90                  File scriptFile = new File(metadataFile.getParentFile(), basename + SCRIPT_FILE_EXTENSION);
91  
92                  if (!scriptFile.exists()) {
93                      throw new InvalidPluginDescriptorException("Found orphaned plugin metadata file: " + metadataFile);
94                  }
95  
96                  String relativePath =
97                          scriptFile.getPath().substring(basedir.length()).replace('\\', '/');
98  
99                  if (relativePath.startsWith("/")) {
100                     relativePath = relativePath.substring(1);
101                 }
102 
103                 try {
104                     Set<MojoDescriptor> mojoDescriptors = parser.parseMojoDescriptors(metadataFile);
105 
106                     for (MojoDescriptor descriptor : mojoDescriptors) {
107                         @SuppressWarnings("unchecked")
108                         Map<String, ?> paramMap = descriptor.getParameterMap();
109 
110                         if (!paramMap.containsKey("basedir")) {
111                             Parameter param = new Parameter();
112                             param.setName("basedir");
113                             param.setAlias("ant.basedir");
114                             param.setExpression("${antBasedir}");
115                             param.setDefaultValue("${basedir}");
116                             param.setType("java.io.File");
117                             param.setDescription("The base directory from which to execute the Ant script.");
118                             param.setEditable(true);
119                             param.setRequired(true);
120 
121                             descriptor.addParameter(param);
122                         }
123 
124                         if (!paramMap.containsKey("antMessageLevel")) {
125                             Parameter param = new Parameter();
126                             param.setName("messageLevel");
127                             param.setAlias("ant.messageLevel");
128                             param.setExpression("${antMessageLevel}");
129                             param.setDefaultValue("info");
130                             param.setType("java.lang.String");
131                             param.setDescription("The message-level used to tune the verbosity of Ant logging.");
132                             param.setEditable(true);
133                             param.setRequired(false);
134 
135                             descriptor.addParameter(param);
136                         }
137 
138                         if (!paramMap.containsKey("project")) {
139                             Parameter param = new Parameter();
140                             param.setName("project");
141                             param.setDefaultValue("${project}");
142                             param.setType(MavenProject.class.getName());
143                             param.setDescription(
144                                     "The current MavenProject instance, which contains classpath " + "elements.");
145                             param.setEditable(false);
146                             param.setRequired(true);
147 
148                             descriptor.addParameter(param);
149                         }
150 
151                         if (!paramMap.containsKey("session")) {
152                             Parameter param = new Parameter();
153                             param.setName("session");
154                             param.setDefaultValue("${session}");
155                             param.setType("org.apache.maven.execution.MavenSession");
156                             param.setDescription("The current MavenSession instance, which is used for "
157                                     + "plugin-style expression resolution.");
158                             param.setEditable(false);
159                             param.setRequired(true);
160 
161                             descriptor.addParameter(param);
162                         }
163 
164                         if (!paramMap.containsKey("mojoExecution")) {
165                             Parameter param = new Parameter();
166                             param.setName("mojoExecution");
167                             param.setDefaultValue("${mojoExecution}");
168                             param.setType("org.apache.maven.plugin.MojoExecution");
169                             param.setDescription("The current Maven MojoExecution instance, which contains "
170                                     + "information about the mojo currently executing.");
171                             param.setEditable(false);
172                             param.setRequired(true);
173 
174                             descriptor.addParameter(param);
175                         }
176 
177                         @SuppressWarnings("unchecked")
178                         List<ComponentRequirement> requirements = descriptor.getRequirements();
179                         Map<String, ComponentRequirement> reqMap = new HashMap<>();
180 
181                         if (requirements != null) {
182                             for (ComponentRequirement req : requirements) {
183                                 reqMap.put(req.getRole(), req);
184                             }
185                         }
186 
187                         if (!reqMap.containsKey(PathTranslator.class.getName())) {
188                             ComponentRequirement req = new ComponentRequirement();
189                             req.setRole(PathTranslator.class.getName());
190 
191                             descriptor.addRequirement(req);
192                         }
193 
194                         String implementation = relativePath;
195 
196                         String dImpl = descriptor.getImplementation();
197                         if (dImpl != null && !dImpl.isEmpty()) {
198                             if (PluginMetadataParser.IMPL_BASE_PLACEHOLDER.equals(dImpl)) {
199                                 implementation = relativePath;
200                             } else {
201                                 implementation = relativePath
202                                         + dImpl.substring(PluginMetadataParser.IMPL_BASE_PLACEHOLDER.length());
203                             }
204                         }
205 
206                         descriptor.setImplementation(implementation);
207 
208                         descriptor.setLanguage("ant-mojo");
209                         descriptor.setComponentComposer("map-oriented");
210                         descriptor.setComponentConfigurator("map-oriented");
211 
212                         descriptor.setPluginDescriptor(request.getPluginDescriptor());
213 
214                         descriptors.add(descriptor);
215                     }
216                 } catch (PluginMetadataParseException e) {
217                     throw new ExtractionException("Error extracting mojo descriptor from script: " + metadataFile, e);
218                 }
219             }
220         }
221 
222         return descriptors;
223     }
224 
225     /** {@inheritDoc} */
226     @Override
227     protected String getScriptFileExtension(PluginToolsRequest request) {
228         return SCRIPT_FILE_EXTENSION;
229     }
230 
231     /** {@inheritDoc} */
232     @Override
233     protected String getMetadataFileExtension(PluginToolsRequest request) {
234         return METADATA_FILE_EXTENSION;
235     }
236 }