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