You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by be...@apache.org on 2009/01/28 22:00:50 UTC

svn commit: r738621 - in /maven/plugins/trunk/maven-invoker-plugin/src: it/project-setup/ main/java/org/apache/maven/plugin/invoker/ main/mdo/ test/java/org/apache/maven/plugin/invoker/

Author: bentmann
Date: Wed Jan 28 21:00:49 2009
New Revision: 738621

URL: http://svn.apache.org/viewvc?rev=738621&view=rev
Log:
o Polished code

Modified:
    maven/plugins/trunk/maven-invoker-plugin/src/it/project-setup/verify.bsh
    maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/BuildFailureException.java
    maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java
    maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerProperties.java
    maven/plugins/trunk/maven-invoker-plugin/src/main/mdo/invocation.mdo
    maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java

Modified: maven/plugins/trunk/maven-invoker-plugin/src/it/project-setup/verify.bsh
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/it/project-setup/verify.bsh?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/it/project-setup/verify.bsh (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/it/project-setup/verify.bsh Wed Jan 28 21:00:49 2009
@@ -32,20 +32,20 @@
         return false;
     }
     
-    File reportFile = new File( basedir, "target/invoker-reports/INVOCATION-project1.xml" );
+    File reportFile = new File( basedir, "target/invoker-reports/BUILD-project1.xml" );
     if ( !reportFile.exists() )
     {
         System.out.println( "reportFile not exists FAILED!" );
         return false;
     }    
-    String report = FileUtils.fileRead( reportFile );
+    String report = FileUtils.fileRead( reportFile, "UTF-8" );
     index = report.indexOf("name=\"Foo\"");
     if ( index < 0 )
     {
         System.out.println( "name missing in the report FAILED!" );
         return false;
     }  
-    index = report.indexOf("<description>good foo</description>");
+    index = report.indexOf("description=\"good foo\"");
     if ( index < 0 )
     {
         System.out.println( "description missing in the report FAILED!" );

Modified: maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/BuildFailureException.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/BuildFailureException.java?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/BuildFailureException.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/BuildFailureException.java Wed Jan 28 21:00:49 2009
@@ -1,7 +1,5 @@
 package org.apache.maven.plugin.invoker;
 
-import org.apache.maven.plugin.invoker.model.Invocation;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -37,18 +35,10 @@
      */
     private static final long serialVersionUID = 236131530635863815L;
 
-    private final String type;
-
     /**
-     * Creates a new exception with the specified detail message.
-     *
-     * @param message The detail message, may be <code>null</code>.
+     * The type of the build failure.
      */
-    public BuildFailureException( String message )
-    {
-        super( message );
-        type = Invocation.FAILURE_BUILD_RESULT;
-    }
+    private final String type;
 
     /**
      * Creates a new exception with the specified detail message.
@@ -59,17 +49,21 @@
     public BuildFailureException( String message, String type )
     {
         super( message );
-        type.getClass(); // throw NPE if null.
+        if ( type == null )
+        {
+            throw new IllegalArgumentException( "missing failure type" );
+        }
         this.type = type;
     }
 
     /**
      * Returns the type of build failure.
      * 
-     * @return The type of build failure.
+     * @return The type of build failure, never <code>null</code>.
      */
     public String getType()
     {
         return type;
     }
+
 }

Modified: maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java Wed Jan 28 21:00:49 2009
@@ -51,8 +51,8 @@
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugin.invoker.model.Invocation;
-import org.apache.maven.plugin.invoker.model.io.xpp3.InvocationXpp3Writer;
+import org.apache.maven.plugin.invoker.model.BuildJob;
+import org.apache.maven.plugin.invoker.model.io.xpp3.BuildJobXpp3Writer;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.settings.Settings;
 import org.apache.maven.shared.invoker.CommandLineConfigurationException;
@@ -133,7 +133,7 @@
     private File projectsDirectory;
 
     /**
-     * Base directory where all reports are written to.
+     * Base directory where all build reports are written to.
      *
      * @parameter expression="${invoker.reportsDirectory}" default-value="${project.build.directory}/invoker-reports"
      * @since 1.4
@@ -426,12 +426,11 @@
     private List testClassPath;
 
     /**
-     * The name of an optional test-specific file that contains properties used to configure the invocation of an
-     * integration test. This properties file may be used to specify settings for an individual test invocation. Any
-     * property present in the file will override the corresponding setting from the plugin configuration. The values of
-     * the properties are filtered and may use expressions like <code>${project.version}</code> to reference project
-     * properties or values from the parameter {@link #filterProperties}. The snippet below describes the
-     * supported properties:
+     * The name of an optional project-specific file that contains properties used to specify settings for an individual
+     * Maven invocation. Any property present in the file will override the corresponding setting from the plugin
+     * configuration. The values of the properties are filtered and may use expressions like
+     * <code>${project.version}</code> to reference project properties or values from the parameter
+     * {@link #filterProperties}. The snippet below describes the supported properties:
      * 
      * <pre>
      * # A comma or space separated list of goals/phases to execute, may
@@ -464,6 +463,14 @@
      * # A boolean value controlling the network behavior of Maven, defaults to &quot;false&quot;
      * # Since plugin version 1.4
      * invoker.offline = true
+     * 
+     * # An optional human friendly name for this build job to be included in the build reports. 
+     * # Since plugin version 1.4
+     * invoker.name = Test Build 01
+     * 
+     * # An optional description for this build job to be included in the build reports. 
+     * # Since plugin version 1.4
+     * invoker.description = Checks the support for build reports.
      * </pre>
      * 
      * @parameter expression="${invoker.invokerPropertiesFile}" default-value="invoker.properties"
@@ -495,7 +502,7 @@
     /**
      * The format for elapsed build time.
      */
-    private final DecimalFormat SECS_FORMAT = new DecimalFormat( "(0.0 s)", new DecimalFormatSymbols( Locale.ENGLISH ) );
+    private final DecimalFormat secFormat = new DecimalFormat( "(0.0 s)", new DecimalFormatSymbols( Locale.ENGLISH ) );
 
     /**
      * Invokes Maven on the configured test projects.
@@ -513,8 +520,7 @@
             return;
         }
 
-        reportsDirectory.mkdirs();
-        Invocation[] includedPoms;
+        BuildJob[] buildJobs;
         if ( pom != null )
         {
             try
@@ -527,13 +533,13 @@
                     + " Reason: " + e.getMessage(), e );
             }
 
-            includedPoms = new Invocation[]{ newInvocation( pom.getName(), Invocation.NORMAL_TYPE )};
+            buildJobs = new BuildJob[]{ new BuildJob( pom.getName(), BuildJob.Type.NORMAL )};
         }
         else
         {
             try
             {
-                includedPoms = getPoms();
+                buildJobs = getBuildJobs();
             }
             catch ( final IOException e )
             {
@@ -543,9 +549,9 @@
         }
 
 
-        if ( ( includedPoms == null ) || ( includedPoms.length < 1 ) )
+        if ( ( buildJobs == null ) || ( buildJobs.length < 1 ) )
         {
-            getLog().info( "No test projects were selected for execution." );
+            getLog().info( "No projects were selected for execution." );
             return;
         }
 
@@ -561,9 +567,9 @@
         scriptInterpreters.put( "groovy", new GroovyScriptInterpreter() );
 
         Collection collectedProjects = new LinkedHashSet();
-        for ( int i = 0; i < includedPoms.length; i++ )
+        for ( int i = 0; i < buildJobs.length; i++ )
         {
-            collectProjects( projectsDirectory, includedPoms[i].getProject(), collectedProjects, true );
+            collectProjects( projectsDirectory, buildJobs[i].getProject(), collectedProjects, true );
         }
 
         File projectsDir = projectsDirectory;
@@ -578,13 +584,15 @@
             getLog().warn( "Filtering of parent/child POMs is not supported without cloning the projects" );
         }
 
-        List failures = runBuilds( projectsDir, includedPoms );
+        reportsDirectory.mkdirs();
+
+        List failures = runBuilds( projectsDir, buildJobs );
 
         if ( !suppressSummaries )
         {
             getLog().info( "---------------------------------------" );
             getLog().info( "Execution Summary:" );
-            getLog().info( "  Builds Passing: " + ( includedPoms.length - failures.size() ) );
+            getLog().info( "  Builds Passing: " + ( buildJobs.length - failures.size() ) );
             getLog().info( "  Builds Failing: " + failures.size() );
             getLog().info( "---------------------------------------" );
 
@@ -602,12 +610,8 @@
 
                 for ( final Iterator it = failures.iterator(); it.hasNext(); )
                 {
-                    Invocation invocation = (Invocation) it.next();
-                    String item = "*  " + invocation.getProject();
-                    if ( invocation.getFailureMessage() != null )
-                    {
-                        item += " (" + invocation.getFailureMessage() + ")";
-                    }
+                    BuildJob buildJob = (BuildJob) it.next();
+                    String item = "*  " + buildJob.getProject();
                     if ( ignoreFailures )
                     {
                         getLog().warn( item );
@@ -637,14 +641,6 @@
         }
     }
 
-    private Invocation newInvocation( String project, String type )
-    {
-        Invocation included = new Invocation();
-        included.setProject( project );
-        included.setType( type );
-        return included;
-    }
-
     /**
      * Creates a new reader for the specified file, using the plugin's {@link #encoding} parameter.
      * 
@@ -941,15 +937,14 @@
     }
 
     /**
-     * Runs the specified projects.
+     * Runs the specified build jobs.
      * 
      * @param projectsDir The base directory of all projects, must not be <code>null</code>.
-     * @param invocations The relative paths to the projects, either to their POM file or merely to their base directory,
-     *            must not be <code>null</code> nor contain <code>null</code> elements.
-     * @return The list of projects that failed, can be empty but never <code>null</code>.
-     * @throws MojoExecutionException If any project could not be launched.
+     * @param buildJobs The build jobs to run must not be <code>null</code> nor contain <code>null</code> elements.
+     * @return The list of build jobs that failed, can be empty but never <code>null</code>.
+     * @throws MojoExecutionException If any build could not be launched.
      */
-    private List runBuilds( File projectsDir, Invocation[] invocations )
+    private List runBuilds( File projectsDir, BuildJob[] buildJobs )
         throws MojoExecutionException
     {
         List failures = new ArrayList();
@@ -976,9 +971,9 @@
 
         try
         {
-            for ( int i = 0; i < invocations.length; i++ )
+            for ( int i = 0; i < buildJobs.length; i++ )
             {
-                Invocation project = invocations[i];
+                BuildJob project = buildJobs[i];
                 try
                 {
                     runBuild( projectsDir, project, interpolatedSettingsFile );
@@ -1004,17 +999,16 @@
      * Runs the specified project.
      * 
      * @param projectsDir The base directory of all projects, must not be <code>null</code>.
-     * @param invocation The relative path to the project, either to a POM file or merely to a directory, must not be
-     *            <code>null</code>.
+     * @param buildJob The build job to run, must not be <code>null</code>.
      * @param settingsFile The (already interpolated) user settings file for the build, may be <code>null</code> to use
      *            the current user settings.
      * @throws MojoExecutionException If the project could not be launched.
      * @throws BuildFailureException If either a hook script or the build itself failed.
      */
-    private void runBuild( File projectsDir, Invocation invocation, File settingsFile )
+    private void runBuild( File projectsDir, BuildJob buildJob, File settingsFile )
         throws MojoExecutionException, BuildFailureException
     {
-        File pomFile = new File( projectsDir, invocation.getProject() );
+        File pomFile = new File( projectsDir, buildJob.getProject() );
         File basedir;
         if ( pomFile.isDirectory() )
         {
@@ -1026,7 +1020,7 @@
             }
             else
             {
-                invocation.setProject( invocation.getProject() + File.separator + "pom.xml" );
+                buildJob.setProject( buildJob.getProject() + File.separator + "pom.xml" );
             }
         }
         else
@@ -1034,7 +1028,7 @@
             basedir = pomFile.getParentFile();
         }
 
-        getLog().info( "Building: " + invocation.getProject() );
+        getLog().info( "Building: " + buildJob.getProject() );
 
         File interpolatedPomFile = null;
         if ( pomFile != null )
@@ -1053,33 +1047,37 @@
         InvokerProperties invokerProperties = getInvokerProperties( basedir );
 
         // let's set what details we can
-        invocation.setName( invokerProperties.getProperties().getProperty( "invoker.name" ) );
-        invocation.setDescription( invokerProperties.getProperties().getProperty( "invoker.description" ) );
+        buildJob.setName( invokerProperties.getJobName() );
+        buildJob.setDescription( invokerProperties.getJobDescription() );
 
-        long milliseconds = System.currentTimeMillis();
         try
         {
-            runBuild( basedir, interpolatedPomFile, settingsFile, invokerProperties );
+            long milliseconds = System.currentTimeMillis();
+            try
+            {
+                runBuild( basedir, interpolatedPomFile, settingsFile, invokerProperties );
+            }
+            finally
+            {
+                milliseconds = System.currentTimeMillis() - milliseconds;
+                buildJob.setTime( milliseconds / 1000.0 );
+            }
 
-            milliseconds = System.currentTimeMillis() - milliseconds;
-            invocation.setResult( Invocation.SUCCESS_RESULT );
-            invocation.setTime( milliseconds / 1000.0 );
+            buildJob.setResult( BuildJob.Result.SUCCESS );
 
             if ( !suppressSummaries )
             {
-                getLog().info( "..SUCCESS " + formatTime( milliseconds ) );
+                getLog().info( "..SUCCESS " + formatTime( buildJob.getTime() ) );
             }
         }
         catch ( BuildFailureException e )
         {
-            milliseconds = System.currentTimeMillis() - milliseconds;
-            invocation.setResult( Invocation.FAILURE_BUILD_RESULT );
-            invocation.setFailureMessage( e.getMessage() );
-            invocation.setTime( milliseconds / 1000.0 );
+            buildJob.setResult( e.getType() );
+            buildJob.setFailureMessage( e.getMessage() );
 
             if ( !suppressSummaries )
             {
-                getLog().info( "..FAILED " + formatTime( milliseconds ) );
+                getLog().info( "..FAILED " + formatTime( buildJob.getTime() ) );
                 getLog().info( "  " + e.getMessage() );
             }
             throw e;
@@ -1090,45 +1088,56 @@
             {
                 interpolatedPomFile.delete();
             }
-            // now write the invocation summary
+            writeBuildReport( buildJob );
+        }
+    }
 
-            String safeFileName = invocation.getProject().replace( '/', '_' ).replace( '\\', '_' ).replace( ' ', '_' );
-            if ( safeFileName.endsWith( "_pom.xml" ) )
-            {
-                safeFileName = safeFileName.substring( 0, safeFileName.length() - "_pom.xml".length() );
-            }
-            File reportFile = new File( reportsDirectory, "INVOCATION-" + safeFileName + ".xml" );
+    /**
+     * Writes the XML report for the specified build job.
+     * 
+     * @param buildJob The build job whose report should be written, must not be <code>null</code>.
+     * @throws MojoExecutionException If the report could not be written.
+     */
+    private void writeBuildReport( BuildJob buildJob )
+        throws MojoExecutionException
+    {
+        String safeFileName = buildJob.getProject().replace( '/', '_' ).replace( '\\', '_' ).replace( ' ', '_' );
+        if ( safeFileName.endsWith( "_pom.xml" ) )
+        {
+            safeFileName = safeFileName.substring( 0, safeFileName.length() - "_pom.xml".length() );
+        }
+
+        File reportFile = new File( reportsDirectory, "BUILD-" + safeFileName + ".xml" );
+        try
+        {
+            FileOutputStream fos = new FileOutputStream( reportFile );
             try
             {
-                FileOutputStream fos = new FileOutputStream( reportFile );
-                try
-                {
-                    OutputStreamWriter osw = new OutputStreamWriter( fos, invocation.getModelEncoding() );
-                    InvocationXpp3Writer writer = new InvocationXpp3Writer();
-                    writer.write( osw, invocation );
-                    osw.close();
-                }
-                finally
-                {
-                    fos.close();
-                }
+                Writer osw = new OutputStreamWriter( fos, buildJob.getModelEncoding() );
+                BuildJobXpp3Writer writer = new BuildJobXpp3Writer();
+                writer.write( osw, buildJob );
+                osw.close();
             }
-            catch ( IOException e )
+            finally
             {
-                throw new MojoExecutionException( e.getMessage(), e );
+                fos.close();
             }
         }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Failed to write build report " + reportFile, e );
+        }
     }
 
     /**
      * Formats the specified build duration time.
      * 
-     * @param milliseconds The duration of the build.
+     * @param seconds The duration of the build.
      * @return The formatted time, never <code>null</code>.
      */
-    private String formatTime( long milliseconds )
+    private String formatTime( double seconds )
     {
-        return SECS_FORMAT.format( milliseconds / 1000.0 );
+        return secFormat.format( seconds );
     }
 
     /**
@@ -1169,7 +1178,7 @@
         try
         {
             runScript( "pre-build script", basedir, preBuildHookScript, context, logger,
-                       Invocation.FAILURE_PRE_HOOK_RESULT );
+                       BuildJob.Result.FAILURE_PRE_HOOK );
 
             final InvocationRequest request = new DefaultInvocationRequest();
 
@@ -1243,14 +1252,15 @@
                 catch ( final MavenInvocationException e )
                 {
                     getLog().debug( "Error invoking Maven: " + e.getMessage(), e );
-                    throw new BuildFailureException( "Maven invocation failed. " + e.getMessage() );
+                    throw new BuildFailureException( "Maven invocation failed. " + e.getMessage(),
+                                                     BuildJob.Result.FAILURE_BUILD );
                 }
 
                 verify( result, invocationIndex, invokerProperties, logger );
             }
 
             runScript( "post-build script", basedir, postBuildHookScript, context, logger,
-                       Invocation.FAILURE_POST_HOOK_RESULT );
+                       BuildJob.Result.FAILURE_POST_HOOK );
         }
         finally
         {
@@ -1366,7 +1376,7 @@
         if ( result.getExecutionException() != null )
         {
             throw new BuildFailureException( "The Maven invocation failed. "
-                + result.getExecutionException().getMessage(), Invocation.ERROR_RESULT );
+                + result.getExecutionException().getMessage(), BuildJob.Result.ERROR );
         }
         else if ( !invokerProperties.isExpectedResult( result.getExitCode(), invocationIndex ) )
         {
@@ -1382,7 +1392,7 @@
             {
                 buffer.append( "See console output for details." );
             }
-            throw new BuildFailureException( buffer.toString(), Invocation.FAILURE_BUILD_RESULT );
+            throw new BuildFailureException( buffer.toString(), BuildJob.Result.FAILURE_BUILD );
         }
     }
 
@@ -1395,7 +1405,7 @@
      *            to skip the script execution.
      * @param context The key-value storage used to share information between hook scripts, may be <code>null</code>.
      * @param logger The logger to redirect the script output to, may be <code>null</code> to use stdout/stderr.
-     * @param stage
+     * @param stage The stage of the build job the script is invoked in, must not be <code>null</code>.
      * @throws MojoExecutionException If an I/O error occurred while reading the script file.
      * @throws BuildFailureException If the script did not return <code>true</code> of threw an exception.
      */
@@ -1564,21 +1574,19 @@
     }
 
     /**
-     * Gets the paths to the projects that should be build. Each path may either denote a POM file or merely a project
-     * base directory. The returned paths will be relative to the projects directory. Finally note that the order of the
-     * returned project paths is significant.
+     * Gets the build jobs that should be processed. Note that the order of the returned build jobs is significant.
      * 
-     * @return The paths to the projects that should be build, may be empty but never <code>null</code>.
+     * @return The build jobs to process, may be empty but never <code>null</code>.
      * @throws IOException If the projects directory could not be scanned.
      */
-    Invocation[] getPoms()
+    BuildJob[] getBuildJobs()
         throws IOException
     {
-        Invocation[] poms;
+        BuildJob[] buildJobs;
 
         if ( ( pom != null ) && pom.exists() )
         {
-            poms = new Invocation[] { newInvocation( pom.getAbsolutePath(), Invocation.NORMAL_TYPE ) };
+            buildJobs = new BuildJob[] { new BuildJob( pom.getAbsolutePath(), BuildJob.Type.NORMAL ) };
         }
         else if ( invokerTest != null )
         {
@@ -1593,7 +1601,7 @@
 
             // it would be nice if we could figure out what types these are... but perhaps
             // not necessary for the -Dinvoker.test=xxx t
-            poms = scanProjectsDirectory( includes, null, Invocation.DIRECT_TYPE );
+            buildJobs = scanProjectsDirectory( includes, null, BuildJob.Type.DIRECT );
         }
         else
         {
@@ -1608,10 +1616,10 @@
                 }
             }
 
-            Invocation[] setupPoms = scanProjectsDirectory( setupIncludes, excludes, Invocation.SETUP_TYPE );
+            BuildJob[] setupPoms = scanProjectsDirectory( setupIncludes, excludes, BuildJob.Type.SETUP );
             getLog().debug( "Setup projects: " + Arrays.asList( setupPoms ) );
 
-            Invocation[] normalPoms = scanProjectsDirectory( pomIncludes, excludes, Invocation.NORMAL_TYPE );
+            BuildJob[] normalPoms = scanProjectsDirectory( pomIncludes, excludes, BuildJob.Type.NORMAL );
 
             Map uniquePoms = new LinkedHashMap();
             for ( int i = 0; i < setupPoms.length; i++ )
@@ -1626,12 +1634,12 @@
                 }
             }
 
-            poms = (Invocation[]) uniquePoms.values().toArray( new Invocation[uniquePoms.size()] );
+            buildJobs = (BuildJob[]) uniquePoms.values().toArray( new BuildJob[uniquePoms.size()] );
         }
 
-        poms = relativizeProjectPaths( poms );
+        relativizeProjectPaths( buildJobs );
 
-        return poms;
+        return buildJobs;
     }
 
     /**
@@ -1642,15 +1650,16 @@
      * 
      * @param includes The include patterns for the scanner, may be <code>null</code>.
      * @param excludes The exclude patterns for the scanner, may be <code>null</code> to exclude nothing.
-     * @return The relative paths to either POM files or project base directories, never <code>null</code>.
+     * @param type The type to assign to the resulting build jobs, must not be <code>null</code>.
+     * @return The build jobs matching the patterns, never <code>null</code>.
      * @throws IOException If the project directory could not be scanned.
      */
-    private Invocation[] scanProjectsDirectory( List includes, List excludes, String type )
+    private BuildJob[] scanProjectsDirectory( List includes, List excludes, String type )
         throws IOException
     {
         if ( !projectsDirectory.isDirectory() )
         {
-            return new Invocation[0];
+            return new BuildJob[0];
         }
 
         DirectoryScanner scanner = new DirectoryScanner();
@@ -1672,7 +1681,7 @@
         String[] includedFiles = scanner.getIncludedFiles();
         for ( int i = 0; i < includedFiles.length; i++ )
         {
-            matches.put( includedFiles[i], newInvocation( includedFiles[i], type ) );
+            matches.put( includedFiles[i], new BuildJob( includedFiles[i], type ) );
         }
 
         String[] includedDirs = scanner.getIncludedDirectories();
@@ -1681,36 +1690,34 @@
             String includedFile = includedDirs[i] + File.separatorChar + "pom.xml";
             if ( new File( scanner.getBasedir(), includedFile ).isFile() )
             {
-                matches.put( includedFile, newInvocation( includedFile, type ) );
+                matches.put( includedFile, new BuildJob( includedFile, type ) );
             }
             else
             {
-                matches.put( includedDirs[i], newInvocation( includedDirs[i], type ) );
+                matches.put( includedDirs[i], new BuildJob( includedDirs[i], type ) );
             }
         }
 
-        return (Invocation[]) matches.values().toArray( new Invocation[matches.size()] );
+        return (BuildJob[]) matches.values().toArray( new BuildJob[matches.size()] );
     }
 
     /**
-     * Relativizes the specified project paths against the directory specified by {@link #projectsDirectory} (if
-     * possible). If a project path does not denote a sub path of the projects directory, it is returned as is.
+     * Relativizes the project paths of the specified build jobs against the directory specified by
+     * {@link #projectsDirectory} (if possible). If a project path does not denote a sub path of the projects directory,
+     * it is returned as is.
      * 
-     * @param invocations The projects to relativize the paths of, must not be <code>null</code> nor contain <code>null</code>
-     *            elements.
-     * @return The relativized projects, never <code>null</code>.
+     * @param buildJobs The build jobs whose project paths should be relativized, must not be <code>null</code> nor
+     *            contain <code>null</code> elements.
      * @throws IOException If any path could not be relativized.
      */
-    private Invocation[] relativizeProjectPaths( Invocation[] invocations )
+    private void relativizeProjectPaths( BuildJob[] buildJobs )
         throws IOException
     {
         String projectsDirPath = projectsDirectory.getCanonicalPath();
 
-        Invocation[] results = new Invocation[invocations.length];
-
-        for ( int i = 0; i < invocations.length; i++ )
+        for ( int i = 0; i < buildJobs.length; i++ )
         {
-            String projectPath = invocations[i].getProject();
+            String projectPath = buildJobs[i].getProject();
 
             File file = new File( projectPath );
 
@@ -1726,12 +1733,8 @@
                 relativizedPath = projectPath;
             }
 
-            results[i] = new Invocation();
-            results[i].setProject( relativizedPath );
-            results[i].setType( invocations[i].getType() );
+            buildJobs[i].setProject( relativizedPath );
         }
-
-        return results;
     }
 
     /**

Modified: maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerProperties.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerProperties.java?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerProperties.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerProperties.java Wed Jan 28 21:00:49 2009
@@ -98,6 +98,26 @@
     }
 
     /**
+     * Gets the name of the corresponding build job.
+     * 
+     * @return The name of the build job or an empty string if not set.
+     */
+    public String getJobName()
+    {
+        return this.properties.getProperty( "invoker.name", "" );
+    }
+
+    /**
+     * Gets the description of the corresponding build job.
+     * 
+     * @return The description of the build job or an empty string if not set.
+     */
+    public String getJobDescription()
+    {
+        return this.properties.getProperty( "invoker.description", "" );
+    }
+
+    /**
      * Determines whether these invoker properties contain a build definition for the specified invocation index.
      * 
      * @param index The one-based index of the invocation to check for, must not be negative.

Modified: maven/plugins/trunk/maven-invoker-plugin/src/main/mdo/invocation.mdo
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/main/mdo/invocation.mdo?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/main/mdo/invocation.mdo (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/main/mdo/invocation.mdo Wed Jan 28 21:00:49 2009
@@ -19,10 +19,13 @@
 under the License.
 -->
 
-<model xsd.namespace="http://maven.apache.org/invoker/1.0.0" xsd.target-namespace="http://maven.apache.org/invoker/1.0.0">
-  <id>invocation</id>
-  <name>Invocation</name>
-  <description><![CDATA[An invocation of Maven by maven-invoker-plugin.]]></description>
+<model xsd.namespace="http://maven.apache.org/plugins/maven-invoker-plugin/build-job/1.0.0"
+       xsd.target-namespace="http://maven.apache.org/plugins/maven-invoker-plugin/build-job/1.0.0">
+  <id>build-job</id>
+  <name>BuildJob</name>
+  <description>
+    A build job processed by the Maven Invoker Plugin.
+  </description>
   <defaults>
     <default>
       <key>package</key>
@@ -33,9 +36,12 @@
     <type>namespace</type>
   </versionDefinition>
   <classes>
-    <class rootElement="true" xml.tagName="invocation">
-      <name>Invocation</name>
-      <description>Describes an invocation of Maven by maven-invoker-plugin.</description>
+    <class rootElement="true" xml.tagName="build-job">
+      <name>BuildJob</name>
+      <description>
+        Describes a build job processed by the Maven Invoker Plugin. A build job can consist of a pre-build hook script,
+        one ore more invocations of Maven and a post-build hook script.
+      </description>
       <version>1.0.0</version>
       <fields>
         <field xml.attribute="true">
@@ -43,49 +49,49 @@
           <version>1.0.0</version>
           <required>true</required>
           <type>String</type>
-          <description>The invoked project.</description>
+          <description>The path to the project to build. This path is usually relative and can denote both a POM file or a project directory.</description>
         </field>
         <field xml.attribute="true">
           <name>name</name>
           <version>1.0.0</version>
           <required>false</required>
           <type>String</type>
-          <description>The name of the invocation.</description>
+          <description>The name of this build job.</description>
         </field>
-        <field>
+        <field xml.attribute="true">
           <name>description</name>
           <version>1.0.0</version>
           <required>false</required>
           <type>String</type>
-          <description>The description of the invocation.</description>
+          <description>The description of this build job.</description>
         </field>
         <field xml.attribute="true">
           <name>result</name>
           <version>1.0.0</version>
           <required>true</required>
           <type>String</type>
-          <description>The result of the invocation.</description>
+          <description>The result of this build job.</description>
         </field>
         <field>
           <name>failureMessage</name>
           <version>1.0.0</version>
           <required>false</required>
           <type>String</type>
-          <description>Any failure message(s) for a failed invocation.</description>
+          <description>Any failure message(s) in case this build job failed.</description>
         </field>
         <field xml.attribute="true">
           <name>time</name>
           <version>1.0.0</version>
           <required>true</required>
           <type>double</type>
-          <description>The number of seconds that invocation too to complete.</description>
+          <description>The number of seconds that this build job took to complete.</description>
         </field>
         <field xml.attribute="true">
           <name>type</name>
           <version>1.0.0</version>
           <required>true</required>
           <type>String</type>
-          <description>The type of the invocation.</description>
+          <description>The type of the build job.</description>
         </field>
       </fields>
       <codeSegments>
@@ -93,54 +99,93 @@
           <version>1.0.0+</version>
           <code><![CDATA[
     /**
-     * The result value corresponding with a successful invocation of Maven and completion of all post-hook
-     * scripts.
+     * Creates a new empty build job.
      */
-    public static final String SUCCESS_RESULT = "success";
-
-    /**
-     * The result value corresponding with an invocation that was skipped.
-     */
-    public static final String SKIPPED_RESULT = "skipped";
+    public BuildJob()
+    {
+        // enables no-arg construction
+    }
 
     /**
-     * The result value corresponding with an invocation that failed before Maven was be invoked.
+     * Creates a new build job with the specified project path and type.
+     * 
+     * @param project The path to the project.
+     * @param type The type of the build job.
      */
-    public static final String FAILURE_PRE_HOOK_RESULT = "failure-pre-hook";
-
+    public BuildJob( String project, String type )
+    {
+        this.project = project;
+        this.type = type;
+    }
+          ]]></code>
+        </codeSegment>
+        <codeSegment>
+          <version>1.0.0+</version>
+          <code><![CDATA[
     /**
-     * The result value corresponding with an unexpected error trying to invoke Maven.
+     * The various results with which a build job can complete.
      */
-    public static final String ERROR_RESULT = "error";
+    public static class Result
+    {
 
-    /**
-     * The result value corresponding with an invocation that failed while invoking of Maven.
-     */
-    public static final String FAILURE_BUILD_RESULT = "failure-build";
+        /**
+         * The result value corresponding with a successful invocation of Maven and completion of all post-hook scripts.
+         */
+        public static final String SUCCESS = "success";
+
+        /**
+         * The result value corresponding with an invocation that failed before Maven was be invoked.
+         */
+        public static final String FAILURE_PRE_HOOK = "failure-pre-hook";
+
+        /**
+         * The result value corresponding with an invocation that failed while invoking of Maven.
+         */
+        public static final String FAILURE_BUILD = "failure-build";
+
+        /**
+         * The result value corresponding with an invocation that failed after the invocation of Maven.
+         */
+        public static final String FAILURE_POST_HOOK = "failure-post-hook";
+
+        /**
+         * The result value corresponding with an invocation that was skipped.
+         */
+        public static final String SKIPPED = "skipped";
+
+        /**
+         * The result value corresponding with an unexpected error trying to invoke Maven.
+         */
+        public static final String ERROR = "error";
 
-    /**
-     * The result value corresponding with an invocation that failed after the invoking of Maven.
-     */
-    public static final String FAILURE_POST_HOOK_RESULT = "failure-post-hook";
+    }
           ]]></code>
         </codeSegment>
         <codeSegment>
           <version>1.0.0+</version>
           <code><![CDATA[
     /**
-     * An invocation that should be invoked before any non-setup invocations.
+     * The various types of a build job.
      */
-    public static final String SETUP_TYPE = "setup";
+    public static class Type
+    {
 
-    /**
-     * A normal invocation.
-     */
-    public static final String NORMAL_TYPE = "normal";
+        /**
+         * A build job that should be invoked before any non-setup build jobs.
+         */
+        public static final String SETUP = "setup";
+
+        /**
+         * A normal build job.
+         */
+        public static final String NORMAL = "normal";
+
+        /**
+         * A build job that was directly selected via the <code>-Dinvoker.test=xxx,yyy</code> parameter.
+         */
+        public static final String DIRECT = "direct";
 
-    /**
-     * A direct invocation via the <code>-Dinvoker.test=xxx,yyy</code> parameter.
-     */
-    public static final String DIRECT_TYPE = "direct";
+    }
           ]]></code>
         </codeSegment>
         <codeSegment>
@@ -148,8 +193,8 @@
           <code><![CDATA[
     public String toString()
     {
-        StringBuffer buf = new StringBuffer( "Invocation" );
-        buf.append( "[project = \"" );
+        StringBuffer buf = new StringBuffer( 128 );
+        buf.append( "BuildJob[project = \"" );
         buf.append( project );
         buf.append( "\", type = " );
         buf.append( type );

Modified: maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java?rev=738621&r1=738620&r2=738621&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java Wed Jan 28 21:00:49 2009
@@ -26,7 +26,7 @@
 
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
-import org.apache.maven.plugin.invoker.model.Invocation;
+import org.apache.maven.plugin.invoker.model.BuildJob;
 import org.apache.maven.settings.Settings;
 
 /**
@@ -66,7 +66,7 @@
         assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerTest", "*dummy*" );
-        Invocation[] poms = invokerMojo.getPoms();
+        BuildJob[] poms = invokerMojo.getBuildJobs();
         System.out.println( Arrays.asList( poms ) );
         assertEquals( 1, poms.length );
     }
@@ -81,7 +81,7 @@
         assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerTest", "*dummy*,*terpolatio*" );
-        Invocation[] poms = invokerMojo.getPoms();
+        BuildJob[] poms = invokerMojo.getBuildJobs();
         System.out.println( Arrays.asList( poms ) );
         assertEquals( 2, poms.length );
     }
@@ -96,7 +96,7 @@
         assertEquals( 1, goals.size() );
         setVariableValueToObject( invokerMojo, "projectsDirectory", new File( dirPath ) );
         setVariableValueToObject( invokerMojo, "invokerTest", "*" );
-        Invocation[] poms = invokerMojo.getPoms();
+        BuildJob[] poms = invokerMojo.getBuildJobs();
         System.out.println( Arrays.asList( poms ) );
         assertEquals( 4, poms.length );
     }