View Javadoc

1   package org.apache.maven.script.ant;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.DependencyResolutionRequiredException;
24  import org.apache.maven.execution.MavenSession;
25  import org.apache.maven.plugin.AbstractMojo;
26  import org.apache.maven.plugin.ContextEnabled;
27  import org.apache.maven.plugin.MojoExecution;
28  import org.apache.maven.plugin.MojoExecutionException;
29  import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
30  import org.apache.maven.plugin.descriptor.PluginDescriptor;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.project.path.PathTranslator;
33  import org.apache.tools.ant.Project;
34  import org.apache.tools.ant.PropertyHelper;
35  import org.apache.tools.ant.types.Path;
36  import org.codehaus.plexus.archiver.ArchiverException;
37  import org.codehaus.plexus.archiver.UnArchiver;
38  import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
39  import org.codehaus.plexus.component.MapOrientedComponent;
40  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
41  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
42  import org.codehaus.plexus.component.factory.ant.AntComponentExecutionException;
43  import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
44  import org.codehaus.plexus.component.repository.ComponentRequirement;
45  import org.codehaus.plexus.logging.LogEnabled;
46  import org.codehaus.plexus.logging.Logger;
47  import org.codehaus.plexus.util.StringUtils;
48  
49  import java.io.File;
50  import java.util.ArrayList;
51  import java.util.Collection;
52  import java.util.HashMap;
53  import java.util.Iterator;
54  import java.util.List;
55  import java.util.Map;
56  
57  
58  public class AntMojoWrapper
59      extends AbstractMojo
60      implements ContextEnabled, MapOrientedComponent, LogEnabled
61  {
62  
63      private Map pluginContext;
64      
65      private final AntScriptInvoker scriptInvoker;
66  
67      private Project antProject;
68  
69      private MavenProject mavenProject;
70  
71      private MojoExecution mojoExecution;
72  
73      private MavenSession session;
74      
75      private PathTranslator pathTranslator;
76  
77      private Logger logger;
78      
79      private transient List unconstructedParts = new ArrayList();
80  
81      public AntMojoWrapper( AntScriptInvoker scriptInvoker )
82      {
83          this.scriptInvoker = scriptInvoker;
84      }
85  
86      public void execute()
87          throws MojoExecutionException
88      {
89          if ( antProject == null )
90          {
91              antProject = scriptInvoker.getProject();
92          }
93          
94          Map allConfig = new HashMap();
95          if ( pluginContext != null && !pluginContext.isEmpty() )
96          {
97              allConfig.putAll( pluginContext );
98          }
99          
100         Map refs = scriptInvoker.getReferences();
101         if ( refs != null )
102         {
103             allConfig.putAll( refs );
104             
105             for ( Iterator it = refs.entrySet().iterator(); it.hasNext(); )
106             {
107                 Map.Entry entry = (Map.Entry) it.next();
108                 String key = (String) entry.getKey();
109                 if ( key.startsWith( PathTranslator.class.getName() ) )
110                 {
111                     pathTranslator = (PathTranslator) entry.getValue();
112                 }
113             }
114         }
115 
116         mavenProject = (MavenProject) allConfig.get( "project" );
117         
118         mojoExecution = (MojoExecution) allConfig.get( "mojoExecution" );
119         
120         session = (MavenSession) allConfig.get( "session" );
121         
122         unpackFileBasedResources();
123 
124         addClasspathReferences();
125         
126         if ( logger.isDebugEnabled() && !unconstructedParts.isEmpty() )
127         {
128             StringBuffer buffer = new StringBuffer();
129             
130             buffer.append( "The following standard Maven Ant-mojo support objects could not be created:\n\n" );
131             
132             for ( Iterator it = unconstructedParts.iterator(); it.hasNext(); )
133             {
134                 String part = (String) it.next();
135                 buffer.append( "\n-  " ).append( part );
136             }
137             
138             buffer.append( "\n\nMaven project, session, mojo-execution, or path-translation parameter information is " );
139             buffer.append( "\nmissing from this mojo's plugin descriptor." );
140             buffer.append( "\n\nPerhaps this Ant-based mojo depends on maven-script-ant < 2.1.0, " );
141             buffer.append( "or used maven-plugin-tools-ant < 2.2 during release?\n\n" );
142             
143             logger.debug( buffer.toString() );
144         }
145 
146         try
147         {
148             scriptInvoker.invoke();
149         }
150         catch ( AntComponentExecutionException e )
151         {
152             throw new MojoExecutionException( "Failed to execute: " + e.getMessage(), e );
153         }
154         
155         unconstructedParts.clear();
156     }
157 
158     public void setPluginContext( Map pluginContext )
159     {
160         this.pluginContext = pluginContext;
161     }
162 
163     public Map getPluginContext()
164     {
165         return pluginContext;
166     }
167 
168     public void addComponentRequirement( ComponentRequirement requirementDescriptor, Object requirementValue )
169         throws ComponentConfigurationException
170     {
171         scriptInvoker.addComponentRequirement( requirementDescriptor, requirementValue );
172     }
173 
174     public void setComponentConfiguration( Map componentConfiguration )
175         throws ComponentConfigurationException
176     {
177         scriptInvoker.setComponentConfiguration( componentConfiguration );
178         antProject = scriptInvoker.getProject();
179     }
180 
181     private void unpackFileBasedResources()
182         throws MojoExecutionException
183     {
184         if ( mojoExecution == null || mavenProject == null )
185         {
186             unconstructedParts.add( "Unpacked Ant build scripts (in Maven build directory)." );
187             
188             return;
189         }
190         
191         // What we need to write out any resources in the plugin to the target directory of the
192         // mavenProject using the Ant-based plugin:
193         //
194         // 1. Need a reference to the plugin JAR itself
195         // 2. Need a reference to the ${basedir} of the mavenProject
196 
197         PluginDescriptor pluginDescriptor = mojoExecution.getMojoDescriptor().getPluginDescriptor();
198         
199         File pluginJar = pluginDescriptor.getPluginArtifact().getFile();
200 
201         String resourcesPath = pluginDescriptor.getArtifactId();
202 
203         File outputDirectory = new File( mavenProject.getBuild().getDirectory() );
204 
205         try
206         {
207             UnArchiver ua = new ZipUnArchiver( pluginJar );
208 
209             ua.extract( resourcesPath, outputDirectory );
210         }
211         catch ( ArchiverException e )
212         {
213             throw new MojoExecutionException( "Error extracting resources from your Ant-based plugin.", e );
214         }
215     }
216 
217     private void addClasspathReferences()
218         throws MojoExecutionException
219     {
220         try
221         {
222             if ( mavenProject != null && session != null && pathTranslator != null )
223             {
224                 ExpressionEvaluator exprEvaluator =
225                     new PluginParameterExpressionEvaluator( session, mojoExecution, pathTranslator, logger, mavenProject,
226                                                             mavenProject.getProperties() );
227                 
228                 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper( antProject );
229                 propertyHelper.setNext( new AntPropertyHelper( exprEvaluator, mavenProject.getArtifacts(), getLog() ) );
230             }
231             else
232             {
233                 unconstructedParts.add( "Maven parameter expression evaluator for Ant properties." );
234             }
235 
236             if ( mavenProject != null )
237             {
238                 // Compile classpath
239                 Path p = new Path( antProject );
240 
241                 p.setPath( StringUtils.join( mavenProject.getCompileClasspathElements().iterator(), File.pathSeparator ) );
242 
243                 /* maven.dependency.classpath it's deprecated as it's equal to maven.compile.classpath */
244                 scriptInvoker.getReferences().put( "maven.dependency.classpath", p );
245                 antProject.addReference( "maven.dependency.classpath", p );
246                 
247                 scriptInvoker.getReferences().put( "maven.compile.classpath", p );
248                 antProject.addReference( "maven.compile.classpath", p );
249 
250                 // Runtime classpath
251                 p = new Path( antProject );
252 
253                 p.setPath( StringUtils.join( mavenProject.getRuntimeClasspathElements().iterator(), File.pathSeparator ) );
254 
255                 scriptInvoker.getReferences().put( "maven.runtime.classpath", p );
256                 antProject.addReference( "maven.runtime.classpath", p );
257 
258                 // Test classpath
259                 p = new Path( antProject );
260 
261                 p.setPath( StringUtils.join( mavenProject.getTestClasspathElements().iterator(), File.pathSeparator ) );
262 
263                 scriptInvoker.getReferences().put( "maven.test.classpath", p );
264                 antProject.addReference( "maven.test.classpath", p );
265 
266             }
267             else
268             {
269                 unconstructedParts.add( "Maven standard project-based classpath references." );
270             }
271             
272             if ( mojoExecution != null )
273             {
274                 // Plugin dependency classpath
275 
276                 Path p = getPathFromArtifacts( mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifacts(), antProject );
277                 
278                 scriptInvoker.getReferences().put( "maven.plugin.classpath", p );
279                 antProject.addReference( "maven.plugin.classpath", p );
280             }
281             else
282             {
283                 unconstructedParts.add( "Maven standard plugin-based classpath references." );
284             }
285         }
286         catch ( DependencyResolutionRequiredException e )
287         {
288             throw new MojoExecutionException( "Error creating classpath references for Ant-based plugin scripts.", e  );
289         }
290     }
291 
292     public Path getPathFromArtifacts( Collection artifacts,
293                                       Project antProject )
294         throws DependencyResolutionRequiredException
295     {
296         List list = new ArrayList( artifacts.size() );
297 
298         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
299         {
300             Artifact a = (Artifact) i.next();
301 
302             File file = a.getFile();
303 
304             if ( file == null )
305             {
306                 throw new DependencyResolutionRequiredException( a );
307             }
308 
309             list.add( file.getPath() );
310         }
311 
312         Path p = new Path( antProject );
313 
314         p.setPath( StringUtils.join( list.iterator(), File.pathSeparator ) );
315 
316         return p;
317     }
318 
319     public Project getAntProject()
320     {
321         return antProject;
322     }
323 
324     public void setAntProject( Project antProject )
325     {
326         this.antProject = antProject;
327     }
328 
329     public MavenProject getMavenProject()
330     {
331         return mavenProject;
332     }
333 
334     public void setMavenProject( MavenProject mavenProject )
335     {
336         this.mavenProject = mavenProject;
337     }
338 
339     public MojoExecution getMojoExecution()
340     {
341         return mojoExecution;
342     }
343 
344     public void setMojoExecution( MojoExecution mojoExecution )
345     {
346         this.mojoExecution = mojoExecution;
347     }
348 
349     public MavenSession getSession()
350     {
351         return session;
352     }
353 
354     public void setSession( MavenSession session )
355     {
356         this.session = session;
357     }
358 
359     public PathTranslator getPathTranslator()
360     {
361         return pathTranslator;
362     }
363 
364     public void setPathTranslator( PathTranslator pathTranslator )
365     {
366         this.pathTranslator = pathTranslator;
367     }
368 
369     public AntScriptInvoker getScriptInvoker()
370     {
371         return scriptInvoker;
372     }
373 
374     public void enableLogging( Logger logger )
375     {
376         this.logger = logger;
377     }
378 }