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.script.ant;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.DependencyResolutionRequiredException;
30  import org.apache.maven.execution.MavenSession;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.ContextEnabled;
33  import org.apache.maven.plugin.MojoExecution;
34  import org.apache.maven.plugin.MojoExecutionException;
35  import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
36  import org.apache.maven.plugin.descriptor.PluginDescriptor;
37  import org.apache.maven.project.MavenProject;
38  import org.apache.maven.project.path.PathTranslator;
39  import org.apache.tools.ant.Project;
40  import org.apache.tools.ant.PropertyHelper;
41  import org.apache.tools.ant.types.Path;
42  import org.codehaus.plexus.archiver.ArchiverException;
43  import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
44  import org.codehaus.plexus.component.MapOrientedComponent;
45  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
46  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
47  import org.codehaus.plexus.component.factory.ant.AntComponentExecutionException;
48  import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
49  import org.codehaus.plexus.component.repository.ComponentRequirement;
50  import org.codehaus.plexus.logging.LogEnabled;
51  import org.codehaus.plexus.logging.Logger;
52  import org.codehaus.plexus.util.StringUtils;
53  
54  /**
55   *
56   * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
57   */
58  @Deprecated
59  public class AntMojoWrapper extends AbstractMojo implements ContextEnabled, MapOrientedComponent, LogEnabled {
60  
61      private Map<String, Object> pluginContext;
62  
63      private final AntScriptInvoker scriptInvoker;
64  
65      private Project antProject;
66  
67      private MavenProject mavenProject;
68  
69      private MojoExecution mojoExecution;
70  
71      private MavenSession session;
72  
73      private PathTranslator pathTranslator;
74  
75      private Logger logger;
76  
77      private transient List<String> unconstructedParts = new ArrayList<>();
78  
79      public AntMojoWrapper(AntScriptInvoker scriptInvoker) {
80          this.scriptInvoker = scriptInvoker;
81      }
82  
83      public void execute() throws MojoExecutionException {
84          if (antProject == null) {
85              antProject = scriptInvoker.getProject();
86          }
87  
88          Map<String, Object> allConfig = new HashMap<>();
89          if (pluginContext != null && !pluginContext.isEmpty()) {
90              allConfig.putAll(pluginContext);
91          }
92  
93          @SuppressWarnings("unchecked")
94          Map<String, PathTranslator> refs = scriptInvoker.getReferences();
95          if (refs != null) {
96              allConfig.putAll(refs);
97  
98              for (Map.Entry<String, PathTranslator> entry : refs.entrySet()) {
99                  if (entry.getKey().startsWith(PathTranslator.class.getName())) {
100                     pathTranslator = entry.getValue();
101                 }
102             }
103         }
104 
105         mavenProject = (MavenProject) allConfig.get("project");
106 
107         mojoExecution = (MojoExecution) allConfig.get("mojoExecution");
108 
109         session = (MavenSession) allConfig.get("session");
110 
111         unpackFileBasedResources();
112 
113         addClasspathReferences();
114 
115         if (logger.isDebugEnabled() && !unconstructedParts.isEmpty()) {
116             StringBuilder buffer = new StringBuilder();
117 
118             buffer.append("The following standard Maven Ant-mojo support objects could not be created:\n\n");
119 
120             for (String part : unconstructedParts) {
121                 buffer.append("\n-  ").append(part);
122             }
123 
124             buffer.append(
125                     "\n\nMaven project, session, mojo-execution, or path-translation parameter " + "information is ");
126             buffer.append("\nmissing from this mojo's plugin descriptor.");
127             buffer.append("\n\nPerhaps this Ant-based mojo depends on maven-script-ant < 2.1.0, ");
128             buffer.append("or used maven-plugin-tools-ant < 2.2 during release?\n\n");
129 
130             logger.debug(buffer.toString());
131         }
132 
133         try {
134             scriptInvoker.invoke();
135         } catch (AntComponentExecutionException e) {
136             throw new MojoExecutionException("Failed to execute: " + e.getMessage(), e);
137         }
138 
139         unconstructedParts.clear();
140     }
141 
142     public void setPluginContext(Map pluginContext) {
143         this.pluginContext = pluginContext;
144     }
145 
146     public Map getPluginContext() {
147         return pluginContext;
148     }
149 
150     public void addComponentRequirement(ComponentRequirement requirementDescriptor, Object requirementValue)
151             throws ComponentConfigurationException {
152         scriptInvoker.addComponentRequirement(requirementDescriptor, requirementValue);
153     }
154 
155     public void setComponentConfiguration(Map componentConfiguration) throws ComponentConfigurationException {
156         scriptInvoker.setComponentConfiguration(componentConfiguration);
157         antProject = scriptInvoker.getProject();
158     }
159 
160     private void unpackFileBasedResources() throws MojoExecutionException {
161         if (mojoExecution == null || mavenProject == null) {
162             unconstructedParts.add("Unpacked Ant build scripts (in Maven build directory).");
163 
164             return;
165         }
166 
167         // What we need to write out any resources in the plugin to the target directory of the
168         // mavenProject using the Ant-based plugin:
169         //
170         // 1. Need a reference to the plugin JAR itself
171         // 2. Need a reference to the ${basedir} of the mavenProject
172 
173         PluginDescriptor pluginDescriptor = mojoExecution.getMojoDescriptor().getPluginDescriptor();
174 
175         File pluginJar = pluginDescriptor.getPluginArtifact().getFile();
176 
177         String resourcesPath = pluginDescriptor.getArtifactId();
178 
179         File outputDirectory = new File(mavenProject.getBuild().getDirectory());
180 
181         try {
182             ZipUnArchiver ua = new ZipUnArchiver(pluginJar);
183 
184             ua.extract(resourcesPath, outputDirectory);
185         } catch (ArchiverException e) {
186             throw new MojoExecutionException("Error extracting resources from your Ant-based plugin.", e);
187         }
188     }
189 
190     private void addClasspathReferences() throws MojoExecutionException {
191         try {
192             if (mavenProject != null && session != null && pathTranslator != null) {
193                 ExpressionEvaluator exprEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);
194 
195                 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(antProject);
196                 propertyHelper.setNext(new AntPropertyHelper(exprEvaluator, mavenProject.getArtifacts(), getLog()));
197             } else {
198                 unconstructedParts.add("Maven parameter expression evaluator for Ant properties.");
199             }
200 
201             @SuppressWarnings("unchecked")
202             Map<String, Object> references = scriptInvoker.getReferences();
203 
204             if (mavenProject != null) {
205 
206                 // Compile classpath
207                 Path p = new Path(antProject);
208 
209                 p.setPath(StringUtils.join(
210                         mavenProject.getCompileClasspathElements().iterator(), File.pathSeparator));
211 
212                 /* maven.dependency.classpath it's deprecated as it's equal to maven.compile.classpath */
213                 references.put("maven.dependency.classpath", p);
214                 antProject.addReference("maven.dependency.classpath", p);
215 
216                 references.put("maven.compile.classpath", p);
217                 antProject.addReference("maven.compile.classpath", p);
218 
219                 // Runtime classpath
220                 p = new Path(antProject);
221 
222                 p.setPath(StringUtils.join(
223                         mavenProject.getRuntimeClasspathElements().iterator(), File.pathSeparator));
224 
225                 references.put("maven.runtime.classpath", p);
226                 antProject.addReference("maven.runtime.classpath", p);
227 
228                 // Test classpath
229                 p = new Path(antProject);
230 
231                 p.setPath(
232                         StringUtils.join(mavenProject.getTestClasspathElements().iterator(), File.pathSeparator));
233 
234                 references.put("maven.test.classpath", p);
235                 antProject.addReference("maven.test.classpath", p);
236 
237             } else {
238                 unconstructedParts.add("Maven standard project-based classpath references.");
239             }
240 
241             if (mojoExecution != null) {
242                 // Plugin dependency classpath
243                 Path p = getPathFromArtifacts(
244                         mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifacts(), antProject);
245 
246                 references.put("maven.plugin.classpath", p);
247                 antProject.addReference("maven.plugin.classpath", p);
248             } else {
249                 unconstructedParts.add("Maven standard plugin-based classpath references.");
250             }
251         } catch (DependencyResolutionRequiredException e) {
252             throw new MojoExecutionException("Error creating classpath references for Ant-based plugin scripts.", e);
253         }
254     }
255 
256     public Path getPathFromArtifacts(Collection<Artifact> artifacts, Project antProject)
257             throws DependencyResolutionRequiredException {
258         List<String> list = new ArrayList<>(artifacts.size());
259 
260         for (Artifact a : artifacts) {
261             File file = a.getFile();
262 
263             if (file == null) {
264                 throw new DependencyResolutionRequiredException(a);
265             }
266 
267             list.add(file.getPath());
268         }
269 
270         Path p = new Path(antProject);
271 
272         p.setPath(StringUtils.join(list.iterator(), File.pathSeparator));
273 
274         return p;
275     }
276 
277     public Project getAntProject() {
278         return antProject;
279     }
280 
281     public void setAntProject(Project antProject) {
282         this.antProject = antProject;
283     }
284 
285     public MavenProject getMavenProject() {
286         return mavenProject;
287     }
288 
289     public void setMavenProject(MavenProject mavenProject) {
290         this.mavenProject = mavenProject;
291     }
292 
293     public MojoExecution getMojoExecution() {
294         return mojoExecution;
295     }
296 
297     public void setMojoExecution(MojoExecution mojoExecution) {
298         this.mojoExecution = mojoExecution;
299     }
300 
301     public MavenSession getSession() {
302         return session;
303     }
304 
305     public void setSession(MavenSession session) {
306         this.session = session;
307     }
308 
309     public PathTranslator getPathTranslator() {
310         return pathTranslator;
311     }
312 
313     public void setPathTranslator(PathTranslator pathTranslator) {
314         this.pathTranslator = pathTranslator;
315     }
316 
317     public AntScriptInvoker getScriptInvoker() {
318         return scriptInvoker;
319     }
320 
321     public void enableLogging(Logger logger) {
322         this.logger = logger;
323     }
324 }