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.List;
54  import java.util.Map;
55  
56  /**
57   * 
58   */
59  public class AntMojoWrapper
60      extends AbstractMojo
61      implements ContextEnabled, MapOrientedComponent, LogEnabled
62  {
63  
64      private Map<String, Object> pluginContext;
65      
66      private final AntScriptInvoker scriptInvoker;
67  
68      private Project antProject;
69  
70      private MavenProject mavenProject;
71  
72      private MojoExecution mojoExecution;
73  
74      private MavenSession session;
75      
76      private PathTranslator pathTranslator;
77  
78      private Logger logger;
79      
80      private transient List<String> unconstructedParts = new ArrayList<String>();
81  
82      public AntMojoWrapper( AntScriptInvoker scriptInvoker )
83      {
84          this.scriptInvoker = scriptInvoker;
85      }
86  
87      public void execute()
88          throws MojoExecutionException
89      {
90          if ( antProject == null )
91          {
92              antProject = scriptInvoker.getProject();
93          }
94          
95          Map<String, Object> allConfig = new HashMap<String, Object>();
96          if ( pluginContext != null && !pluginContext.isEmpty() )
97          {
98              allConfig.putAll( pluginContext );
99          }
100         
101         @SuppressWarnings( "unchecked" )
102         Map<String, PathTranslator> refs = scriptInvoker.getReferences();
103         if ( refs != null )
104         {
105             allConfig.putAll( refs );
106             
107             for ( Map.Entry<String, PathTranslator> entry : refs.entrySet() )
108             {
109                 if ( entry.getKey().startsWith( PathTranslator.class.getName() ) )
110                 {
111                     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 ( String part : unconstructedParts )
133             {
134                 buffer.append( "\n-  " ).append( part );
135             }
136             
137             buffer.append( "\n\nMaven project, session, mojo-execution, or path-translation parameter "
138                 + "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,
226                                                             mavenProject, 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             @SuppressWarnings( "unchecked" )
237             Map<String, Object> references = scriptInvoker.getReferences();
238 
239             if ( mavenProject != null )
240             {
241 
242                 // Compile classpath
243                 Path p = new Path( antProject );
244 
245                 p.setPath( StringUtils.join( mavenProject.getCompileClasspathElements().iterator(),
246                                              File.pathSeparator ) );
247 
248                 /* maven.dependency.classpath it's deprecated as it's equal to maven.compile.classpath */
249                 references.put( "maven.dependency.classpath", p );
250                 antProject.addReference( "maven.dependency.classpath", p );
251                 
252                 references.put( "maven.compile.classpath", p );
253                 antProject.addReference( "maven.compile.classpath", p );
254 
255                 // Runtime classpath
256                 p = new Path( antProject );
257 
258                 p.setPath( StringUtils.join( mavenProject.getRuntimeClasspathElements().iterator(),
259                                              File.pathSeparator ) );
260 
261                 references.put( "maven.runtime.classpath", p );
262                 antProject.addReference( "maven.runtime.classpath", p );
263 
264                 // Test classpath
265                 p = new Path( antProject );
266 
267                 p.setPath( StringUtils.join( mavenProject.getTestClasspathElements().iterator(),
268                                              File.pathSeparator ) );
269 
270                 references.put( "maven.test.classpath", p );
271                 antProject.addReference( "maven.test.classpath", p );
272 
273             }
274             else
275             {
276                 unconstructedParts.add( "Maven standard project-based classpath references." );
277             }
278             
279             if ( mojoExecution != null )
280             {
281                 // Plugin dependency classpath
282                 Path p =
283                     getPathFromArtifacts( mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifacts(),
284                                           antProject );
285                 
286                 references.put( "maven.plugin.classpath", p );
287                 antProject.addReference( "maven.plugin.classpath", p );
288             }
289             else
290             {
291                 unconstructedParts.add( "Maven standard plugin-based classpath references." );
292             }
293         }
294         catch ( DependencyResolutionRequiredException e )
295         {
296             throw new MojoExecutionException( "Error creating classpath references for Ant-based plugin scripts.", e );
297         }
298     }
299 
300     public Path getPathFromArtifacts( Collection<Artifact> artifacts, Project antProject )
301         throws DependencyResolutionRequiredException
302     {
303         List<String> list = new ArrayList<String>( artifacts.size() );
304 
305         for ( Artifact a : artifacts )
306         {
307             File file = a.getFile();
308 
309             if ( file == null )
310             {
311                 throw new DependencyResolutionRequiredException( a );
312             }
313 
314             list.add( file.getPath() );
315         }
316 
317         Path p = new Path( antProject );
318 
319         p.setPath( StringUtils.join( list.iterator(), File.pathSeparator ) );
320 
321         return p;
322     }
323 
324     public Project getAntProject()
325     {
326         return antProject;
327     }
328 
329     public void setAntProject( Project antProject )
330     {
331         this.antProject = antProject;
332     }
333 
334     public MavenProject getMavenProject()
335     {
336         return mavenProject;
337     }
338 
339     public void setMavenProject( MavenProject mavenProject )
340     {
341         this.mavenProject = mavenProject;
342     }
343 
344     public MojoExecution getMojoExecution()
345     {
346         return mojoExecution;
347     }
348 
349     public void setMojoExecution( MojoExecution mojoExecution )
350     {
351         this.mojoExecution = mojoExecution;
352     }
353 
354     public MavenSession getSession()
355     {
356         return session;
357     }
358 
359     public void setSession( MavenSession session )
360     {
361         this.session = session;
362     }
363 
364     public PathTranslator getPathTranslator()
365     {
366         return pathTranslator;
367     }
368 
369     public void setPathTranslator( PathTranslator pathTranslator )
370     {
371         this.pathTranslator = pathTranslator;
372     }
373 
374     public AntScriptInvoker getScriptInvoker()
375     {
376         return scriptInvoker;
377     }
378 
379     public void enableLogging( Logger logger )
380     {
381         this.logger = logger;
382     }
383 }