001package org.apache.maven.script.ant;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.artifact.Artifact;
023import org.apache.maven.artifact.DependencyResolutionRequiredException;
024import org.apache.maven.execution.MavenSession;
025import org.apache.maven.plugin.AbstractMojo;
026import org.apache.maven.plugin.ContextEnabled;
027import org.apache.maven.plugin.MojoExecution;
028import org.apache.maven.plugin.MojoExecutionException;
029import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
030import org.apache.maven.plugin.descriptor.PluginDescriptor;
031import org.apache.maven.project.MavenProject;
032import org.apache.maven.project.path.PathTranslator;
033import org.apache.tools.ant.Project;
034import org.apache.tools.ant.PropertyHelper;
035import org.apache.tools.ant.types.Path;
036import org.codehaus.plexus.archiver.ArchiverException;
037import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
038import org.codehaus.plexus.component.MapOrientedComponent;
039import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
040import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
041import org.codehaus.plexus.component.factory.ant.AntComponentExecutionException;
042import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
043import org.codehaus.plexus.component.repository.ComponentRequirement;
044import org.codehaus.plexus.logging.LogEnabled;
045import org.codehaus.plexus.logging.Logger;
046import org.codehaus.plexus.util.StringUtils;
047
048import java.io.File;
049import java.util.ArrayList;
050import java.util.Collection;
051import java.util.HashMap;
052import java.util.List;
053import java.util.Map;
054
055/**
056 *
057 * @deprecated Scripting support for mojos is deprecated and is planned tp be removed in maven 4.0
058 */
059@Deprecated
060public class AntMojoWrapper
061    extends AbstractMojo
062    implements ContextEnabled, MapOrientedComponent, LogEnabled
063{
064
065    private Map<String, Object> pluginContext;
066    
067    private final AntScriptInvoker scriptInvoker;
068
069    private Project antProject;
070
071    private MavenProject mavenProject;
072
073    private MojoExecution mojoExecution;
074
075    private MavenSession session;
076    
077    private PathTranslator pathTranslator;
078
079    private Logger logger;
080    
081    private transient List<String> unconstructedParts = new ArrayList<>();
082
083    public AntMojoWrapper( AntScriptInvoker scriptInvoker )
084    {
085        this.scriptInvoker = scriptInvoker;
086    }
087
088    public void execute()
089        throws MojoExecutionException
090    {
091        if ( antProject == null )
092        {
093            antProject = scriptInvoker.getProject();
094        }
095        
096        Map<String, Object> allConfig = new HashMap<>();
097        if ( pluginContext != null && !pluginContext.isEmpty() )
098        {
099            allConfig.putAll( pluginContext );
100        }
101        
102        @SuppressWarnings( "unchecked" )
103        Map<String, PathTranslator> refs = scriptInvoker.getReferences();
104        if ( refs != null )
105        {
106            allConfig.putAll( refs );
107            
108            for ( Map.Entry<String, PathTranslator> entry : refs.entrySet() )
109            {
110                if ( entry.getKey().startsWith( PathTranslator.class.getName() ) )
111                {
112                    pathTranslator = entry.getValue();
113                }
114            }
115        }
116
117        mavenProject = (MavenProject) allConfig.get( "project" );
118        
119        mojoExecution = (MojoExecution) allConfig.get( "mojoExecution" );
120        
121        session = (MavenSession) allConfig.get( "session" );
122        
123        unpackFileBasedResources();
124
125        addClasspathReferences();
126        
127        if ( logger.isDebugEnabled() && !unconstructedParts.isEmpty() )
128        {
129            StringBuilder buffer = new StringBuilder();
130            
131            buffer.append( "The following standard Maven Ant-mojo support objects could not be created:\n\n" );
132            
133            for ( String part : unconstructedParts )
134            {
135                buffer.append( "\n-  " ).append( part );
136            }
137            
138            buffer.append( "\n\nMaven project, session, mojo-execution, or path-translation parameter "
139                + "information is " );
140            buffer.append( "\nmissing from this mojo's plugin descriptor." );
141            buffer.append( "\n\nPerhaps this Ant-based mojo depends on maven-script-ant < 2.1.0, " );
142            buffer.append( "or used maven-plugin-tools-ant < 2.2 during release?\n\n" );
143            
144            logger.debug( buffer.toString() );
145        }
146
147        try
148        {
149            scriptInvoker.invoke();
150        }
151        catch ( AntComponentExecutionException e )
152        {
153            throw new MojoExecutionException( "Failed to execute: " + e.getMessage(), e );
154        }
155        
156        unconstructedParts.clear();
157    }
158
159    public void setPluginContext( Map pluginContext )
160    {
161        this.pluginContext = pluginContext;
162    }
163
164    public Map getPluginContext()
165    {
166        return pluginContext;
167    }
168
169    public void addComponentRequirement( ComponentRequirement requirementDescriptor, Object requirementValue )
170        throws ComponentConfigurationException
171    {
172        scriptInvoker.addComponentRequirement( requirementDescriptor, requirementValue );
173    }
174
175    public void setComponentConfiguration( Map componentConfiguration )
176        throws ComponentConfigurationException
177    {
178        scriptInvoker.setComponentConfiguration( componentConfiguration );
179        antProject = scriptInvoker.getProject();
180    }
181
182    private void unpackFileBasedResources()
183        throws MojoExecutionException
184    {
185        if ( mojoExecution == null || mavenProject == null )
186        {
187            unconstructedParts.add( "Unpacked Ant build scripts (in Maven build directory)." );
188            
189            return;
190        }
191        
192        // What we need to write out any resources in the plugin to the target directory of the
193        // mavenProject using the Ant-based plugin:
194        //
195        // 1. Need a reference to the plugin JAR itself
196        // 2. Need a reference to the ${basedir} of the mavenProject
197
198        PluginDescriptor pluginDescriptor = mojoExecution.getMojoDescriptor().getPluginDescriptor();
199        
200        File pluginJar = pluginDescriptor.getPluginArtifact().getFile();
201
202        String resourcesPath = pluginDescriptor.getArtifactId();
203
204        File outputDirectory = new File( mavenProject.getBuild().getDirectory() );
205
206        try
207        {
208            ZipUnArchiver ua = new ZipUnArchiver( pluginJar );
209
210            ua.extract( resourcesPath, outputDirectory );
211        }
212        catch ( ArchiverException e )
213        {
214            throw new MojoExecutionException( "Error extracting resources from your Ant-based plugin.", e );
215        }
216    }
217
218    private void addClasspathReferences()
219        throws MojoExecutionException
220    {
221        try
222        {
223            if ( mavenProject != null && session != null && pathTranslator != null )
224            {
225                ExpressionEvaluator exprEvaluator =
226                    new PluginParameterExpressionEvaluator( session, mojoExecution, pathTranslator, logger,
227                                                            mavenProject, mavenProject.getProperties() );
228                
229                PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper( antProject );
230                propertyHelper.setNext( new AntPropertyHelper( exprEvaluator, mavenProject.getArtifacts(), getLog() ) );
231            }
232            else
233            {
234                unconstructedParts.add( "Maven parameter expression evaluator for Ant properties." );
235            }
236
237            @SuppressWarnings( "unchecked" )
238            Map<String, Object> references = scriptInvoker.getReferences();
239
240            if ( mavenProject != null )
241            {
242
243                // Compile classpath
244                Path p = new Path( antProject );
245
246                p.setPath( StringUtils.join( mavenProject.getCompileClasspathElements().iterator(),
247                                             File.pathSeparator ) );
248
249                /* maven.dependency.classpath it's deprecated as it's equal to maven.compile.classpath */
250                references.put( "maven.dependency.classpath", p );
251                antProject.addReference( "maven.dependency.classpath", p );
252                
253                references.put( "maven.compile.classpath", p );
254                antProject.addReference( "maven.compile.classpath", p );
255
256                // Runtime classpath
257                p = new Path( antProject );
258
259                p.setPath( StringUtils.join( mavenProject.getRuntimeClasspathElements().iterator(),
260                                             File.pathSeparator ) );
261
262                references.put( "maven.runtime.classpath", p );
263                antProject.addReference( "maven.runtime.classpath", p );
264
265                // Test classpath
266                p = new Path( antProject );
267
268                p.setPath( StringUtils.join( mavenProject.getTestClasspathElements().iterator(),
269                                             File.pathSeparator ) );
270
271                references.put( "maven.test.classpath", p );
272                antProject.addReference( "maven.test.classpath", p );
273
274            }
275            else
276            {
277                unconstructedParts.add( "Maven standard project-based classpath references." );
278            }
279            
280            if ( mojoExecution != null )
281            {
282                // Plugin dependency classpath
283                Path p =
284                    getPathFromArtifacts( mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifacts(),
285                                          antProject );
286                
287                references.put( "maven.plugin.classpath", p );
288                antProject.addReference( "maven.plugin.classpath", p );
289            }
290            else
291            {
292                unconstructedParts.add( "Maven standard plugin-based classpath references." );
293            }
294        }
295        catch ( DependencyResolutionRequiredException e )
296        {
297            throw new MojoExecutionException( "Error creating classpath references for Ant-based plugin scripts.", e );
298        }
299    }
300
301    public Path getPathFromArtifacts( Collection<Artifact> artifacts, Project antProject )
302        throws DependencyResolutionRequiredException
303    {
304        List<String> list = new ArrayList<>( artifacts.size() );
305
306        for ( Artifact a : artifacts )
307        {
308            File file = a.getFile();
309
310            if ( file == null )
311            {
312                throw new DependencyResolutionRequiredException( a );
313            }
314
315            list.add( file.getPath() );
316        }
317
318        Path p = new Path( antProject );
319
320        p.setPath( StringUtils.join( list.iterator(), File.pathSeparator ) );
321
322        return p;
323    }
324
325    public Project getAntProject()
326    {
327        return antProject;
328    }
329
330    public void setAntProject( Project antProject )
331    {
332        this.antProject = antProject;
333    }
334
335    public MavenProject getMavenProject()
336    {
337        return mavenProject;
338    }
339
340    public void setMavenProject( MavenProject mavenProject )
341    {
342        this.mavenProject = mavenProject;
343    }
344
345    public MojoExecution getMojoExecution()
346    {
347        return mojoExecution;
348    }
349
350    public void setMojoExecution( MojoExecution mojoExecution )
351    {
352        this.mojoExecution = mojoExecution;
353    }
354
355    public MavenSession getSession()
356    {
357        return session;
358    }
359
360    public void setSession( MavenSession session )
361    {
362        this.session = session;
363    }
364
365    public PathTranslator getPathTranslator()
366    {
367        return pathTranslator;
368    }
369
370    public void setPathTranslator( PathTranslator pathTranslator )
371    {
372        this.pathTranslator = pathTranslator;
373    }
374
375    public AntScriptInvoker getScriptInvoker()
376    {
377        return scriptInvoker;
378    }
379
380    public void enableLogging( Logger logger )
381    {
382        this.logger = logger;
383    }
384}