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  public class AntMojoWrapper
57      extends AbstractMojo
58      implements ContextEnabled, MapOrientedComponent, LogEnabled
59  {
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<String>();
78  
79      public AntMojoWrapper( AntScriptInvoker scriptInvoker )
80      {
81          this.scriptInvoker = scriptInvoker;
82      }
83  
84      public void execute()
85          throws MojoExecutionException
86      {
87          if ( antProject == null )
88          {
89              antProject = scriptInvoker.getProject();
90          }
91          
92          Map<String, Object> allConfig = new HashMap<String, Object>();
93          if ( pluginContext != null && !pluginContext.isEmpty() )
94          {
95              allConfig.putAll( pluginContext );
96          }
97          
98          @SuppressWarnings( "unchecked" )
99          Map<String, PathTranslator> refs = scriptInvoker.getReferences();
100         if ( refs != null )
101         {
102             allConfig.putAll( refs );
103             
104             for ( Map.Entry<String, PathTranslator> entry : refs.entrySet() )
105             {
106                 if ( entry.getKey().startsWith( PathTranslator.class.getName() ) )
107                 {
108                     pathTranslator = entry.getValue();
109                 }
110             }
111         }
112 
113         mavenProject = (MavenProject) allConfig.get( "project" );
114         
115         mojoExecution = (MojoExecution) allConfig.get( "mojoExecution" );
116         
117         session = (MavenSession) allConfig.get( "session" );
118         
119         unpackFileBasedResources();
120 
121         addClasspathReferences();
122         
123         if ( logger.isDebugEnabled() && !unconstructedParts.isEmpty() )
124         {
125             StringBuffer buffer = new StringBuffer();
126             
127             buffer.append( "The following standard Maven Ant-mojo support objects could not be created:\n\n" );
128             
129             for ( String part : unconstructedParts )
130             {
131                 buffer.append( "\n-  " ).append( part );
132             }
133             
134             buffer.append( "\n\nMaven project, session, mojo-execution, or path-translation parameter information is " );
135             buffer.append( "\nmissing from this mojo's plugin descriptor." );
136             buffer.append( "\n\nPerhaps this Ant-based mojo depends on maven-script-ant < 2.1.0, " );
137             buffer.append( "or used maven-plugin-tools-ant < 2.2 during release?\n\n" );
138             
139             logger.debug( buffer.toString() );
140         }
141 
142         try
143         {
144             scriptInvoker.invoke();
145         }
146         catch ( AntComponentExecutionException e )
147         {
148             throw new MojoExecutionException( "Failed to execute: " + e.getMessage(), e );
149         }
150         
151         unconstructedParts.clear();
152     }
153 
154     public void setPluginContext( Map pluginContext )
155     {
156         this.pluginContext = pluginContext;
157     }
158 
159     public Map getPluginContext()
160     {
161         return pluginContext;
162     }
163 
164     public void addComponentRequirement( ComponentRequirement requirementDescriptor, Object requirementValue )
165         throws ComponentConfigurationException
166     {
167         scriptInvoker.addComponentRequirement( requirementDescriptor, requirementValue );
168     }
169 
170     public void setComponentConfiguration( Map componentConfiguration )
171         throws ComponentConfigurationException
172     {
173         scriptInvoker.setComponentConfiguration( componentConfiguration );
174         antProject = scriptInvoker.getProject();
175     }
176 
177     private void unpackFileBasedResources()
178         throws MojoExecutionException
179     {
180         if ( mojoExecution == null || mavenProject == null )
181         {
182             unconstructedParts.add( "Unpacked Ant build scripts (in Maven build directory)." );
183             
184             return;
185         }
186         
187         // What we need to write out any resources in the plugin to the target directory of the
188         // mavenProject using the Ant-based plugin:
189         //
190         // 1. Need a reference to the plugin JAR itself
191         // 2. Need a reference to the ${basedir} of the mavenProject
192 
193         PluginDescriptor pluginDescriptor = mojoExecution.getMojoDescriptor().getPluginDescriptor();
194         
195         File pluginJar = pluginDescriptor.getPluginArtifact().getFile();
196 
197         String resourcesPath = pluginDescriptor.getArtifactId();
198 
199         File outputDirectory = new File( mavenProject.getBuild().getDirectory() );
200 
201         try
202         {
203             UnArchiver ua = new ZipUnArchiver( pluginJar );
204 
205             ua.extract( resourcesPath, outputDirectory );
206         }
207         catch ( ArchiverException e )
208         {
209             throw new MojoExecutionException( "Error extracting resources from your Ant-based plugin.", e );
210         }
211     }
212 
213     private void addClasspathReferences()
214         throws MojoExecutionException
215     {
216         try
217         {
218             if ( mavenProject != null && session != null && pathTranslator != null )
219             {
220                 ExpressionEvaluator exprEvaluator =
221                     new PluginParameterExpressionEvaluator( session, mojoExecution, pathTranslator, logger, mavenProject,
222                                                             mavenProject.getProperties() );
223                 
224                 PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper( antProject );
225                 propertyHelper.setNext( new AntPropertyHelper( exprEvaluator, mavenProject.getArtifacts(), getLog() ) );
226             }
227             else
228             {
229                 unconstructedParts.add( "Maven parameter expression evaluator for Ant properties." );
230             }
231 
232             @SuppressWarnings( "unchecked" )
233             Map<String, Object> references = scriptInvoker.getReferences();
234 
235             if ( mavenProject != null )
236             {
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                 references.put( "maven.dependency.classpath", p );
245                 antProject.addReference( "maven.dependency.classpath", p );
246                 
247                 references.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                 references.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                 references.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                 references.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<Artifact> artifacts, Project antProject )
293         throws DependencyResolutionRequiredException
294     {
295         List<String> list = new ArrayList<String>( artifacts.size() );
296 
297         for ( Artifact a : artifacts )
298         {
299             File file = a.getFile();
300 
301             if ( file == null )
302             {
303                 throw new DependencyResolutionRequiredException( a );
304             }
305 
306             list.add( file.getPath() );
307         }
308 
309         Path p = new Path( antProject );
310 
311         p.setPath( StringUtils.join( list.iterator(), File.pathSeparator ) );
312 
313         return p;
314     }
315 
316     public Project getAntProject()
317     {
318         return antProject;
319     }
320 
321     public void setAntProject( Project antProject )
322     {
323         this.antProject = antProject;
324     }
325 
326     public MavenProject getMavenProject()
327     {
328         return mavenProject;
329     }
330 
331     public void setMavenProject( MavenProject mavenProject )
332     {
333         this.mavenProject = mavenProject;
334     }
335 
336     public MojoExecution getMojoExecution()
337     {
338         return mojoExecution;
339     }
340 
341     public void setMojoExecution( MojoExecution mojoExecution )
342     {
343         this.mojoExecution = mojoExecution;
344     }
345 
346     public MavenSession getSession()
347     {
348         return session;
349     }
350 
351     public void setSession( MavenSession session )
352     {
353         this.session = session;
354     }
355 
356     public PathTranslator getPathTranslator()
357     {
358         return pathTranslator;
359     }
360 
361     public void setPathTranslator( PathTranslator pathTranslator )
362     {
363         this.pathTranslator = pathTranslator;
364     }
365 
366     public AntScriptInvoker getScriptInvoker()
367     {
368         return scriptInvoker;
369     }
370 
371     public void enableLogging( Logger logger )
372     {
373         this.logger = logger;
374     }
375 }