001 package 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
022 import org.apache.maven.artifact.Artifact;
023 import org.apache.maven.artifact.DependencyResolutionRequiredException;
024 import org.apache.maven.execution.MavenSession;
025 import org.apache.maven.plugin.AbstractMojo;
026 import org.apache.maven.plugin.ContextEnabled;
027 import org.apache.maven.plugin.MojoExecution;
028 import org.apache.maven.plugin.MojoExecutionException;
029 import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
030 import org.apache.maven.plugin.descriptor.PluginDescriptor;
031 import org.apache.maven.project.MavenProject;
032 import org.apache.maven.project.path.PathTranslator;
033 import org.apache.tools.ant.Project;
034 import org.apache.tools.ant.PropertyHelper;
035 import org.apache.tools.ant.types.Path;
036 import org.codehaus.plexus.archiver.ArchiverException;
037 import org.codehaus.plexus.archiver.UnArchiver;
038 import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
039 import org.codehaus.plexus.component.MapOrientedComponent;
040 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
041 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
042 import org.codehaus.plexus.component.factory.ant.AntComponentExecutionException;
043 import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
044 import org.codehaus.plexus.component.repository.ComponentRequirement;
045 import org.codehaus.plexus.logging.LogEnabled;
046 import org.codehaus.plexus.logging.Logger;
047 import org.codehaus.plexus.util.StringUtils;
048
049 import java.io.File;
050 import java.util.ArrayList;
051 import java.util.Collection;
052 import java.util.HashMap;
053 import java.util.List;
054 import java.util.Map;
055
056 public class AntMojoWrapper
057 extends AbstractMojo
058 implements ContextEnabled, MapOrientedComponent, LogEnabled
059 {
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<String>();
078
079 public AntMojoWrapper( AntScriptInvoker scriptInvoker )
080 {
081 this.scriptInvoker = scriptInvoker;
082 }
083
084 public void execute()
085 throws MojoExecutionException
086 {
087 if ( antProject == null )
088 {
089 antProject = scriptInvoker.getProject();
090 }
091
092 Map<String, Object> allConfig = new HashMap<String, Object>();
093 if ( pluginContext != null && !pluginContext.isEmpty() )
094 {
095 allConfig.putAll( pluginContext );
096 }
097
098 @SuppressWarnings( "unchecked" )
099 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 }