001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.script.ant;
020
021import java.io.File;
022import java.util.ArrayList;
023import java.util.Collection;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.apache.maven.artifact.Artifact;
029import org.apache.maven.artifact.DependencyResolutionRequiredException;
030import org.apache.maven.execution.MavenSession;
031import org.apache.maven.plugin.AbstractMojo;
032import org.apache.maven.plugin.ContextEnabled;
033import org.apache.maven.plugin.MojoExecution;
034import org.apache.maven.plugin.MojoExecutionException;
035import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
036import org.apache.maven.plugin.descriptor.PluginDescriptor;
037import org.apache.maven.project.MavenProject;
038import org.apache.maven.project.path.PathTranslator;
039import org.apache.tools.ant.Project;
040import org.apache.tools.ant.PropertyHelper;
041import org.apache.tools.ant.types.Path;
042import org.codehaus.plexus.archiver.ArchiverException;
043import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
044import org.codehaus.plexus.component.MapOrientedComponent;
045import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
046import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
047import org.codehaus.plexus.component.factory.ant.AntComponentExecutionException;
048import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
049import org.codehaus.plexus.component.repository.ComponentRequirement;
050import org.codehaus.plexus.logging.LogEnabled;
051import org.codehaus.plexus.logging.Logger;
052import org.codehaus.plexus.util.StringUtils;
053
054/**
055 *
056 * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
057 */
058@Deprecated
059public class AntMojoWrapper extends AbstractMojo implements ContextEnabled, MapOrientedComponent, LogEnabled {
060
061    private Map<String, Object> pluginContext;
062
063    private final AntScriptInvoker scriptInvoker;
064
065    private Project antProject;
066
067    private MavenProject mavenProject;
068
069    private MojoExecution mojoExecution;
070
071    private MavenSession session;
072
073    private PathTranslator pathTranslator;
074
075    private Logger logger;
076
077    private transient List<String> unconstructedParts = new ArrayList<>();
078
079    public AntMojoWrapper(AntScriptInvoker scriptInvoker) {
080        this.scriptInvoker = scriptInvoker;
081    }
082
083    public void execute() throws MojoExecutionException {
084        if (antProject == null) {
085            antProject = scriptInvoker.getProject();
086        }
087
088        Map<String, Object> allConfig = new HashMap<>();
089        if (pluginContext != null && !pluginContext.isEmpty()) {
090            allConfig.putAll(pluginContext);
091        }
092
093        @SuppressWarnings("unchecked")
094        Map<String, PathTranslator> refs = scriptInvoker.getReferences();
095        if (refs != null) {
096            allConfig.putAll(refs);
097
098            for (Map.Entry<String, PathTranslator> entry : refs.entrySet()) {
099                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}