~ubuntu-branches/ubuntu/wily/maven-antrun-plugin/wily

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/maven/plugin/antrun/AntRunMojo.java

  • Committer: Bazaar Package Importer
  • Author(s): Miguel Landaeta
  • Date: 2011-07-19 19:38:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110719193853-4umqiv4uwqcbrdd0
Tags: 1.6-1
* Team upload.
* New upstream release.
* Bump Standards-Version to 3.9.2. No changes were required.
* Migrate to source package format 3.0 (quilt).
* Allow package to build twice in a row.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
import java.io.File;
 
23
import java.io.IOException;
 
24
import java.io.StringWriter;
 
25
import java.util.ArrayList;
 
26
import java.util.Collection;
 
27
import java.util.Iterator;
23
28
import java.util.List;
 
29
import java.util.Properties;
 
30
import java.util.Set;
24
31
 
 
32
import org.apache.maven.artifact.Artifact;
 
33
import org.apache.maven.artifact.DependencyResolutionRequiredException;
 
34
import org.apache.maven.artifact.repository.ArtifactRepository;
 
35
import org.apache.maven.plugin.AbstractMojo;
25
36
import org.apache.maven.plugin.MojoExecutionException;
26
37
import org.apache.maven.project.MavenProject;
27
 
import org.apache.tools.ant.Target;
 
38
import org.apache.maven.project.MavenProjectHelper;
 
39
import org.apache.tools.ant.BuildException;
 
40
import org.apache.tools.ant.DefaultLogger;
 
41
import org.apache.tools.ant.Project;
 
42
import org.apache.tools.ant.ProjectHelper;
 
43
import org.apache.tools.ant.taskdefs.Typedef;
 
44
import org.apache.tools.ant.types.Path;
 
45
import org.codehaus.plexus.configuration.PlexusConfiguration;
 
46
import org.codehaus.plexus.configuration.PlexusConfigurationException;
 
47
import org.codehaus.plexus.util.FileUtils;
 
48
import org.codehaus.plexus.util.StringUtils;
28
49
 
29
50
/**
30
51
 * Maven AntRun Mojo.
37
58
 *
38
59
 * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
39
60
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
40
 
 * @version $Id: AntRunMojo.java 677381 2008-07-16 19:18:22Z dennisl $
41
 
 * @configurator override
 
61
 * @version $Id: AntRunMojo.java 1005244 2010-10-06 20:53:06Z pgier $
42
62
 * @goal run
 
63
 * @threadSafe
43
64
 * @requiresDependencyResolution test
44
65
 */
45
66
public class AntRunMojo
46
 
    extends AbstractAntMojo
 
67
    extends AbstractMojo
47
68
{
48
69
    /**
 
70
     * The refid used to store the Maven project object in the Ant build.
 
71
     */
 
72
    public final static String DEFAULT_MAVEN_PROJECT_REFID = "maven.project";
 
73
 
 
74
    /**
 
75
     * The refid used to store the Maven project object in the Ant build.
 
76
     */
 
77
    public final static String DEFAULT_MAVEN_PROJECT_HELPER_REFID = "maven.project.helper";
 
78
 
 
79
    /**
 
80
     * The default target name.
 
81
     */
 
82
    public final static String DEFAULT_ANT_TARGET_NAME = "main";
 
83
 
 
84
    /**
 
85
     * The default encoding to use for the generated Ant build.
 
86
     */
 
87
    public final static String UTF_8 = "UTF-8";
 
88
 
 
89
    /**
 
90
     * The name used for the ant target
 
91
     */
 
92
    private String antTargetName;
 
93
 
 
94
    /**
 
95
     * The path to The XML file containing the definition of the Maven tasks.
 
96
     */
 
97
    public final static String ANTLIB = "org/apache/maven/ant/tasks/antlib.xml";
 
98
 
 
99
    /**
 
100
     * The URI which defines the built in Ant tasks
 
101
     */
 
102
    public final static String TASK_URI = "antlib:org.apache.maven.ant.tasks";
 
103
 
 
104
    /**
49
105
     * The Maven project object
50
 
     *
 
106
     * 
51
107
     * @parameter expression="${project}"
52
 
     * @required
53
108
     * @readonly
54
109
     */
55
110
    private MavenProject project;
56
111
 
57
112
    /**
 
113
     * The Maven project helper object
 
114
     * 
 
115
     * @component
 
116
     */
 
117
    private MavenProjectHelper projectHelper;
 
118
 
 
119
    /**
58
120
     * The plugin dependencies.
59
 
     *
 
121
     * 
60
122
     * @parameter expression="${plugin.artifacts}"
61
123
     * @required
62
124
     * @readonly
64
126
    private List pluginArtifacts;
65
127
 
66
128
    /**
67
 
     * The XML for the Ant task. You can add anything you can add
68
 
     * between &lt;target&gt; and &lt;/target&gt; in a build.xml.
69
 
     *
70
 
     * @parameter expression="${tasks}"
71
 
     */
72
 
    private Target tasks;
73
 
 
74
 
    /**
75
 
     * This folder is added to the list of those folders
76
 
     * containing source to be compiled. Use this if your
77
 
     * ant script generates source code.
78
 
     *
 
129
     * The local Maven repository
 
130
     * 
 
131
     * @parameter expression="${localRepository}"
 
132
     * @readonly
 
133
     */
 
134
    protected ArtifactRepository localRepository;
 
135
 
 
136
    /**
 
137
     * String to prepend to project and dependency property names.
 
138
     * 
 
139
     * @parameter default-value=""
 
140
     * @since 1.4
 
141
     */
 
142
    private String propertyPrefix;
 
143
 
 
144
    /**
 
145
     * The xml tag prefix to use for the built in Ant tasks. This prefix needs to be prepended to each task referenced
 
146
     * in the antrun target config. For example, a prefix of "mvn" means that the attachartifact task is referenced by
 
147
     * "&lt;mvn:attachartifact&gt;" The default value of an empty string means that no prefix is used for the tasks.
 
148
     * 
 
149
     * @parameter default-value=""
 
150
     * @since 1.5
 
151
     */
 
152
    private String customTaskPrefix = "";
 
153
 
 
154
    /**
 
155
     * The name of a property containing the list of all dependency versions. This is used for the removing the versions
 
156
     * from the filenames.
 
157
     * 
 
158
     * @parameter default-value="maven.project.dependencies.versions"
 
159
     */
 
160
    private String versionsPropertyName;
 
161
 
 
162
    /**
 
163
     * The XML for the Ant task. You can add anything you can add between &lt;target&gt; and &lt;/target&gt; in a
 
164
     * build.xml.
 
165
     * 
 
166
     * @deprecated Use target instead
 
167
     * @parameter
 
168
     */
 
169
    private PlexusConfiguration tasks;
 
170
 
 
171
    /**
 
172
     * The XML for the Ant target. You can add anything you can add between &lt;target&gt; and &lt;/target&gt; in a
 
173
     * build.xml.
 
174
     * 
 
175
     * @parameter
 
176
     * @since 1.5
 
177
     */
 
178
    private PlexusConfiguration target;
 
179
 
 
180
    /**
 
181
     * This folder is added to the list of those folders containing source to be compiled. Use this if your ant script
 
182
     * generates source code.
 
183
     * 
79
184
     * @parameter expression="${sourceRoot}"
 
185
     * @deprecated Use the build-helper-maven-plugin to bind source directories
80
186
     */
81
187
    private File sourceRoot;
82
188
 
83
189
    /**
84
 
     * This folder is added to the list of those folders
85
 
     * containing source to be compiled for testing. Use this if your
 
190
     * This folder is added to the list of those folders containing source to be compiled for testing. Use this if your
86
191
     * ant script generates test source code.
87
 
     *
 
192
     * 
88
193
     * @parameter expression="${testSourceRoot}"
 
194
     * @deprecated Use the build-helper-maven-plugin to bind test source directories
89
195
     */
90
196
    private File testSourceRoot;
91
197
 
95
201
    public void execute()
96
202
        throws MojoExecutionException
97
203
    {
98
 
        executeTasks( tasks, project, pluginArtifacts );
 
204
        MavenProject mavenProject = getMavenProject();
 
205
 
 
206
        if ( tasks != null )
 
207
        {
 
208
            getLog().warn( "Parameter tasks is deprecated, use target instead" );
 
209
            target = tasks;
 
210
        }
 
211
        
 
212
        if ( target == null )
 
213
        {
 
214
            getLog().info( "No ant target defined - SKIPPED" );
 
215
            return;
 
216
        }
 
217
 
 
218
        if ( propertyPrefix == null )
 
219
        {
 
220
            propertyPrefix = "";
 
221
        }
 
222
 
 
223
        try
 
224
        {
 
225
            Project antProject = new Project();
 
226
            File antBuildFile = this.writeTargetToProjectFile( );
 
227
            ProjectHelper.configureProject( antProject, antBuildFile );
 
228
            antProject.init();
 
229
 
 
230
            DefaultLogger antLogger = new DefaultLogger();
 
231
            antLogger.setOutputPrintStream( System.out );
 
232
            antLogger.setErrorPrintStream( System.err );
 
233
            antLogger.setMessageOutputLevel( getLog().isDebugEnabled() ? Project.MSG_DEBUG : Project.MSG_INFO );
 
234
 
 
235
            antProject.addBuildListener( antLogger );
 
236
            antProject.setBaseDir( mavenProject.getBasedir() );
 
237
 
 
238
            Path p = new Path( antProject );
 
239
            p.setPath( StringUtils.join( mavenProject.getCompileClasspathElements().iterator(), File.pathSeparator ) );
 
240
 
 
241
            /* maven.dependency.classpath it's deprecated as it's equal to maven.compile.classpath */
 
242
            antProject.addReference( "maven.dependency.classpath", p );
 
243
            antProject.addReference( "maven.compile.classpath", p );
 
244
 
 
245
            p = new Path( antProject );
 
246
            p.setPath( StringUtils.join( mavenProject.getRuntimeClasspathElements().iterator(), File.pathSeparator ) );
 
247
            antProject.addReference( "maven.runtime.classpath", p );
 
248
 
 
249
            p = new Path( antProject );
 
250
            p.setPath( StringUtils.join( mavenProject.getTestClasspathElements().iterator(), File.pathSeparator ) );
 
251
            antProject.addReference( "maven.test.classpath", p );
 
252
 
 
253
            /* set maven.plugin.classpath with plugin dependencies */
 
254
            antProject.addReference( "maven.plugin.classpath", getPathFromArtifacts( pluginArtifacts, antProject ) );
 
255
 
 
256
            antProject.addReference( DEFAULT_MAVEN_PROJECT_REFID, getMavenProject() );
 
257
            antProject.addReference( DEFAULT_MAVEN_PROJECT_HELPER_REFID, projectHelper );
 
258
            antProject.addReference( "maven.local.repository", localRepository );
 
259
            initMavenTasks( antProject );
 
260
 
 
261
            // The ant project needs actual properties vs. using expression evaluator when calling an external build
 
262
            // file.
 
263
            copyProperties( mavenProject, antProject );
 
264
 
 
265
            if ( getLog().isInfoEnabled() )
 
266
            {
 
267
                getLog().info( "Executing tasks" );
 
268
            }
 
269
 
 
270
            antProject.executeTarget( antTargetName );
 
271
 
 
272
            if ( getLog().isInfoEnabled() )
 
273
            {
 
274
                getLog().info( "Executed tasks" );
 
275
            }
 
276
        }
 
277
        catch ( DependencyResolutionRequiredException e )
 
278
        {
 
279
            throw new MojoExecutionException( "DependencyResolutionRequiredException: " + e.getMessage(), e );
 
280
        }
 
281
        catch ( BuildException e )
 
282
        {
 
283
            throw new MojoExecutionException( "An Ant BuildException has occured: " + e.getMessage(), e );
 
284
        }
 
285
        catch ( Exception e )
 
286
        {
 
287
            throw new MojoExecutionException( "Error executing ant tasks: " + e.getMessage(), e );
 
288
        }
99
289
 
100
290
        if ( sourceRoot != null )
101
291
        {
102
292
            getLog().info( "Registering compile source root " + sourceRoot );
103
 
            project.addCompileSourceRoot( sourceRoot.toString() );
 
293
            getMavenProject().addCompileSourceRoot( sourceRoot.toString() );
104
294
        }
105
295
 
106
296
        if ( testSourceRoot != null )
107
297
        {
108
298
            getLog().info( "Registering compile test source root " + testSourceRoot );
109
 
            project.addTestCompileSourceRoot( testSourceRoot.toString() );
110
 
        }
111
 
    }
 
299
            getMavenProject().addTestCompileSourceRoot( testSourceRoot.toString() );
 
300
        }
 
301
    }
 
302
 
 
303
    /**
 
304
     * @param artifacts
 
305
     * @param antProject
 
306
     * @return a path
 
307
     * @throws DependencyResolutionRequiredException
 
308
     */
 
309
    public Path getPathFromArtifacts( Collection artifacts, Project antProject )
 
310
        throws DependencyResolutionRequiredException
 
311
    {
 
312
        if ( artifacts == null )
 
313
        {
 
314
            return new Path( antProject );
 
315
        }
 
316
 
 
317
        List list = new ArrayList( artifacts.size() );
 
318
        for ( Iterator i = artifacts.iterator(); i.hasNext(); )
 
319
        {
 
320
            Artifact a = (Artifact) i.next();
 
321
            File file = a.getFile();
 
322
            if ( file == null )
 
323
            {
 
324
                throw new DependencyResolutionRequiredException( a );
 
325
            }
 
326
            list.add( file.getPath() );
 
327
        }
 
328
 
 
329
        Path p = new Path( antProject );
 
330
        p.setPath( StringUtils.join( list.iterator(), File.pathSeparator ) );
 
331
 
 
332
        return p;
 
333
    }
 
334
 
 
335
    /**
 
336
     * Copy properties from the maven project to the ant project.
 
337
     * 
 
338
     * @param mavenProject
 
339
     * @param antProject
 
340
     */
 
341
    public void copyProperties( MavenProject mavenProject, Project antProject )
 
342
    {
 
343
        Properties mavenProps = mavenProject.getProperties();
 
344
        Iterator iter = mavenProps.keySet().iterator();
 
345
        while ( iter.hasNext() )
 
346
        {
 
347
            String key = (String) iter.next();
 
348
            antProject.setProperty( key, mavenProps.getProperty( key ) );
 
349
        }
 
350
 
 
351
        // Set the POM file as the ant.file for the tasks run directly in Maven.
 
352
        antProject.setProperty( "ant.file", mavenProject.getFile().getAbsolutePath() );
 
353
 
 
354
        // Add some of the common maven properties
 
355
        getLog().debug("Setting properties with prefix: " + propertyPrefix );
 
356
        antProject.setProperty( ( propertyPrefix + "project.groupId" ), mavenProject.getGroupId() );
 
357
        antProject.setProperty( ( propertyPrefix + "project.artifactId" ), mavenProject.getArtifactId() );
 
358
        antProject.setProperty( ( propertyPrefix + "project.name" ), mavenProject.getName() );
 
359
        antProject.setProperty( ( propertyPrefix + "project.description" ), mavenProject.getDescription() );
 
360
        antProject.setProperty( ( propertyPrefix + "project.version" ), mavenProject.getVersion() );
 
361
        antProject.setProperty( ( propertyPrefix + "project.packaging" ), mavenProject.getPackaging() );
 
362
        antProject.setProperty( ( propertyPrefix + "project.build.directory" ), mavenProject.getBuild().getDirectory() );
 
363
        antProject.setProperty( ( propertyPrefix + "project.build.outputDirectory" ),
 
364
                                mavenProject.getBuild().getOutputDirectory() );
 
365
        antProject.setProperty( ( propertyPrefix + "project.build.testOutputDirectory" ),
 
366
                                mavenProject.getBuild().getTestOutputDirectory() );
 
367
        antProject.setProperty( ( propertyPrefix + "project.build.sourceDirectory" ),
 
368
                                mavenProject.getBuild().getSourceDirectory() );
 
369
        antProject.setProperty( ( propertyPrefix + "project.build.testSourceDirectory" ),
 
370
                                mavenProject.getBuild().getTestSourceDirectory() );
 
371
        antProject.setProperty( ( propertyPrefix + "localRepository" ), localRepository.toString() );
 
372
        antProject.setProperty( ( propertyPrefix + "settings.localRepository" ), localRepository.getBasedir() );
 
373
 
 
374
        // Add properties for depenedency artifacts
 
375
        Set depArtifacts = mavenProject.getArtifacts();
 
376
        for ( Iterator it = depArtifacts.iterator(); it.hasNext(); )
 
377
        {
 
378
            Artifact artifact = (Artifact) it.next();
 
379
 
 
380
            String propName = artifact.getDependencyConflictId();
 
381
 
 
382
            antProject.setProperty( propertyPrefix + propName, artifact.getFile().getPath() );
 
383
        }
 
384
 
 
385
        // Add a property containing the list of versions for the mapper
 
386
        StringBuffer versionsBuffer = new StringBuffer();
 
387
        for ( Iterator it = depArtifacts.iterator(); it.hasNext(); )
 
388
        {
 
389
            Artifact artifact = (Artifact) it.next();
 
390
 
 
391
            versionsBuffer.append( artifact.getVersion() + File.pathSeparator );
 
392
        }
 
393
        antProject.setProperty( versionsPropertyName, versionsBuffer.toString() );
 
394
 
 
395
        // Add properties in deprecated format to depenedency artifacts
 
396
        // This should be removed in future versions of the antrun plugin.
 
397
        for ( Iterator it = depArtifacts.iterator(); it.hasNext(); )
 
398
        {
 
399
            Artifact artifact = (Artifact) it.next();
 
400
 
 
401
            String propName = getDependencyArtifactPropertyName( artifact );
 
402
 
 
403
            antProject.setProperty( propName, artifact.getFile().getPath() );
 
404
        }
 
405
    }
 
406
 
 
407
    /**
 
408
     * Prefix for legacy property format.
 
409
     * @deprecated This should only be used for generating the old property format.
 
410
     */
 
411
    public static final String DEPENDENCY_PREFIX = "maven.dependency.";
 
412
    
 
413
    /**
 
414
     * Returns a property name for a dependency artifact.  The name is in the format
 
415
     * maven.dependency.groupId.artifactId[.classifier].type.path
 
416
     * 
 
417
     * @param artifact
 
418
     * @return property name
 
419
     * @deprecated The dependency conflict ID should be used as the property name.
 
420
     */
 
421
    public static String getDependencyArtifactPropertyName( Artifact artifact )
 
422
    {
 
423
        String key = DEPENDENCY_PREFIX + artifact.getGroupId() + "." + artifact.getArtifactId()
 
424
            + ( artifact.getClassifier() != null ? "." + artifact.getClassifier() : "" )
 
425
            + ( artifact.getType() != null ? "." + artifact.getType() : "" ) + ".path";
 
426
        return key;
 
427
    }
 
428
 
 
429
    /**
 
430
     * Get the current Maven project
 
431
     * 
 
432
     * @return current Maven project
 
433
     */
 
434
    public MavenProject getMavenProject()
 
435
    {
 
436
        return this.project;
 
437
    }
 
438
 
 
439
    public void initMavenTasks( Project antProject )
 
440
    {
 
441
        getLog().debug( "Initialize Maven Ant Tasks" );
 
442
        Typedef typedef = new Typedef();
 
443
        typedef.setProject( antProject );
 
444
        typedef.setResource( ANTLIB );
 
445
        if ( ! customTaskPrefix.equals( "" ) )
 
446
        {
 
447
            typedef.setURI( TASK_URI );
 
448
        }
 
449
        typedef.execute();
 
450
    }
 
451
 
 
452
    /**
 
453
     * Write the ant target and surrounding tags to a temporary file
 
454
     * 
 
455
     * @throws PlexusConfigurationException
 
456
     */
 
457
    private File writeTargetToProjectFile()
 
458
        throws IOException, PlexusConfigurationException
 
459
    {
 
460
        // Have to use an XML writer because in Maven 2.x the PlexusConfig toString() method loses XML attributes
 
461
        StringWriter writer = new StringWriter();
 
462
        AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter();
 
463
        xmlWriter.write( target, writer );
 
464
        
 
465
        StringBuffer antProjectConfig = writer.getBuffer();
 
466
 
 
467
        // replace deprecated tasks tag with standard Ant target
 
468
        stringReplace( antProjectConfig, "<tasks", "<target" );
 
469
        stringReplace( antProjectConfig, "</tasks", "</target" );
 
470
 
 
471
        antTargetName = target.getAttribute( "name" );
 
472
 
 
473
        if ( antTargetName == null )
 
474
        {
 
475
            antTargetName = DEFAULT_ANT_TARGET_NAME;
 
476
            stringReplace( antProjectConfig, "<target", "<target name=\"" + antTargetName + "\"" );
 
477
        }
 
478
 
 
479
        String xmlns = "";
 
480
        if ( ! customTaskPrefix.trim().equals( "" ) )
 
481
        {
 
482
            xmlns = "xmlns:" + customTaskPrefix + "=\"" + TASK_URI + "\""; 
 
483
        }
 
484
        
 
485
        final String xmlHeader = "<?xml version=\"1.0\" encoding=\"" + UTF_8 + "\" ?>\n";
 
486
        antProjectConfig.insert( 0, xmlHeader );
 
487
        final String projectOpen = "<project name=\"maven-antrun-\" default=\"" + antTargetName + "\" " + xmlns +" >\n";
 
488
        int index = antProjectConfig.indexOf( "<target" );
 
489
        antProjectConfig.insert( index, projectOpen );
 
490
 
 
491
        final String projectClose = "\n</project>";
 
492
        antProjectConfig.append( projectClose );
 
493
 
 
494
        // The fileName should probably use the plugin executionId instead of the targetName
 
495
        String fileName = "build-" + antTargetName + ".xml";
 
496
        File buildFile = new File( project.getBuild().getDirectory(), "/antrun/" + fileName );
 
497
 
 
498
        buildFile.getParentFile().mkdirs();
 
499
        FileUtils.fileWrite( buildFile.getAbsolutePath(), UTF_8, antProjectConfig.toString() );
 
500
        return buildFile;
 
501
    }
 
502
 
 
503
    /**
 
504
     * Replace text in a StringBuffer.  If the match text is not found, the StringBuffer 
 
505
     * is returned unchanged.
 
506
     * 
 
507
     * @param text The string buffer containing the text
 
508
     * @param match The string to match and remove
 
509
     * @param with The string to insert
 
510
     */
 
511
    public void stringReplace( StringBuffer text, String match, String with )
 
512
    {
 
513
        int index = text.indexOf( match );
 
514
        if ( index != -1 )
 
515
        {
 
516
            text.replace( index, index + match.length(), with );
 
517
        }
 
518
    }
 
519
 
 
520
    public String checkTargetName( PlexusConfiguration antTargetConfig )
 
521
        throws PlexusConfigurationException
 
522
    {
 
523
        String targetName = antTargetConfig.getAttribute( "name" );
 
524
        if ( targetName == null )
 
525
        {
 
526
            targetName = DEFAULT_ANT_TARGET_NAME;
 
527
        }
 
528
        return targetName;
 
529
    }
 
530
 
112
531
}