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/07/27 19:09:52 UTC

svn commit: r798221 - in /maven/components/trunk: maven-core/src/main/java/org/apache/maven/ maven-core/src/main/java/org/apache/maven/project/ maven-model-builder/src/main/java/org/apache/maven/model/building/

Author: bentmann
Date: Mon Jul 27 17:09:51 2009
New Revision: 798221

URL: http://svn.apache.org/viewvc?rev=798221&view=rev
Log:
[MNG-4052] import scope dependencies prefer to download pom rather than find it in the current project

Added:
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java   (with props)
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java   (with props)
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java   (with props)
Modified:
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java
    maven/components/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java Mon Jul 27 17:09:51 2009
@@ -16,7 +16,6 @@
  */
 
 import java.io.File;
-import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,13 +41,13 @@
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuilder;
 import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingResult;
 import org.apache.maven.repository.DelegatingLocalArtifactRepository;
 import org.codehaus.plexus.PlexusContainer;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.util.Os;
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.dag.CycleDetectedException;
 
@@ -288,58 +287,12 @@
     private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
         throws MavenExecutionException, ProjectBuildingException
     {
-        for ( File file : files )
-        {
-            MavenProject project = projectBuilder.build( file, request.getProjectBuildingRequest() );
-
-            projects.add( project );
-            
-            if ( ( project.getModules() != null ) && !project.getModules().isEmpty() && request.isRecursive() )
-            {
-                File basedir = file.getParentFile();
-
-                List<File> moduleFiles = new ArrayList<File>();
-                
-                for ( String name : project.getModules() )
-                {
-                    if ( StringUtils.isEmpty( StringUtils.trim( name ) ) )
-                    {
-                        continue;
-                    }
-
-                    File moduleFile = new File( basedir, name );
-                    
-                    if ( !moduleFile.exists() )
-                    {
-                        throw new MissingModuleException( name, moduleFile, file );
-                    }
-                    else if ( moduleFile.isDirectory() )
-                    {
-                        moduleFile = new File( basedir, name + "/" + Maven.POMv4 );
-                    }
+        List<ProjectBuildingResult> results =
+            projectBuilder.build( files, request.isRecursive(), request.getProjectBuildingRequest() );
 
-                    if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
-                    {
-                        // we don't canonicalize on unix to avoid interfering with symlinks
-                        try
-                        {
-                            moduleFile = moduleFile.getCanonicalFile();
-                        }
-                        catch ( IOException e )
-                        {
-                            throw new MavenExecutionException( "Unable to canonicalize file name " + moduleFile, e );
-                        }
-                    }
-                    else
-                    {
-                        moduleFile = new File( moduleFile.toURI().normalize() );
-                    }
-
-                    moduleFiles.add( moduleFile );
-                }
-
-                collectProjects( projects, moduleFiles, request );
-            }
+        for ( ProjectBuildingResult result : results )
+        {
+            projects.add( result.getProject() );
         }
     }
 

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java Mon Jul 27 17:09:51 2009
@@ -16,13 +16,14 @@
  */
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.maven.Maven;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.ArtifactUtils;
-import org.apache.maven.artifact.InvalidRepositoryException;
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
@@ -46,6 +47,7 @@
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.Os;
 import org.codehaus.plexus.util.StringUtils;
 
 /**
@@ -86,7 +88,7 @@
     private MavenProject build( File pomFile, boolean localProject, ProjectBuildingRequest configuration )
         throws ProjectBuildingException
     {
-        ModelBuildingRequest request = getModelBuildingRequest( configuration );
+        ModelBuildingRequest request = getModelBuildingRequest( configuration, null );
 
         DefaultModelBuildingListener listener = new DefaultModelBuildingListener( projectBuildingHelper, configuration );
         request.setModelBuildingListeners( Arrays.asList( listener ) );
@@ -135,48 +137,7 @@
                 logger.warn( "" );
             }
 
-            File parentPomFile = result.getRawModel( result.getModelIds().get( 1 ) ).getPomFile();
-            MavenProject project = fromModelToMavenProject( model, parentPomFile, configuration, model.getPomFile() );
-
-            project.setOriginalModel( result.getRawModel() );
-
-            project.setRemoteArtifactRepositories( listener.getRemoteRepositories() );
-            project.setPluginArtifactRepositories( listener.getPluginRepositories() );
-
-            project.setClassRealm( listener.getProjectRealm() );
-
-            try
-            {
-                if ( configuration.isProcessPlugins() )
-                {
-                    lifecycle.populateDefaultConfigurationForPlugins( model.getBuild().getPlugins(),
-                                                                      configuration.getLocalRepository(),
-                                                                      project.getPluginArtifactRepositories() );
-                }
-            }
-            catch ( LifecycleExecutionException e )
-            {
-                throw new ProjectBuildingException( project.getId(), e.getMessage(), e );
-            }
-
-            Build build = project.getBuild();
-            // NOTE: setting this script-source root before path translation, because
-            // the plugin tools compose basedir and scriptSourceRoot into a single file.
-            project.addScriptSourceRoot( build.getScriptSourceDirectory() );
-            project.addCompileSourceRoot( build.getSourceDirectory() );
-            project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
-            project.setFile( pomFile );
-
-            List<Profile> activeProfiles = new ArrayList<Profile>();
-            activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) );
-            activeProfiles.addAll( result.getActiveExternalProfiles() );
-            project.setActiveProfiles( activeProfiles );
-
-            project.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
-            for ( String modelId : result.getModelIds() )
-            {
-                project.setInjectedProfileIds( modelId, getProfileIds( result.getActivePomProfiles( modelId ) ) );
-            }
+            MavenProject project = toProject( result, configuration, listener );
 
             return project;
         }
@@ -198,11 +159,12 @@
         return ids;
     }
 
-    private ModelBuildingRequest getModelBuildingRequest( ProjectBuildingRequest configuration )
+    private ModelBuildingRequest getModelBuildingRequest( ProjectBuildingRequest configuration,
+                                                          ReactorModelPool reactorModelPool )
     {
         ModelResolver resolver =
             new RepositoryModelResolver( repositorySystem, resolutionErrorHandler, configuration.getLocalRepository(),
-                                         configuration.getRemoteRepositories() );
+                                         configuration.getRemoteRepositories(), reactorModelPool );
 
         ModelBuildingRequest request = new DefaultModelBuildingRequest();
 
@@ -255,7 +217,7 @@
     public MavenProject buildStandaloneSuperProject( ProjectBuildingRequest config )
         throws ProjectBuildingException
     {
-        ModelBuildingRequest request = getModelBuildingRequest( config );
+        ModelBuildingRequest request = getModelBuildingRequest( config, null );
 
         DefaultModelBuildingListener listener = new DefaultModelBuildingListener( projectBuildingHelper, config );
         request.setModelBuildingListeners( Arrays.asList( listener ) );
@@ -272,16 +234,7 @@
             throw new ProjectBuildingException( "[standalone]", "Failed to build standalone project", e );
         }
 
-        MavenProject standaloneProject;
-
-        try
-        {
-            standaloneProject = new MavenProject( result.getEffectiveModel(), repositorySystem, this, config );
-        }
-        catch ( InvalidRepositoryException e )
-        {
-            throw new IllegalStateException( e );
-        }
+        MavenProject standaloneProject = new MavenProject( result.getEffectiveModel(), repositorySystem, this, config );
 
         standaloneProject.setActiveProfiles( result.getActiveExternalProfiles() );
         standaloneProject.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
@@ -339,24 +292,215 @@
         return new MavenProjectBuildingResult( project, result );
     }
 
-    private MavenProject fromModelToMavenProject( Model model, File parentFile, ProjectBuildingRequest config, File projectDescriptor )
-        throws InvalidProjectModelException
+    public List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest config )
+        throws ProjectBuildingException
     {
-        MavenProject project;
+        List<ProjectBuildingResult> results = new ArrayList<ProjectBuildingResult>();
 
-        try
+        List<InterimResult> interimResults = new ArrayList<InterimResult>();
+
+        ReactorModelPool reactorModelPool = new ReactorModelPool();
+
+        boolean errors = build( results, interimResults, pomFiles, recursive, config, reactorModelPool );
+
+        for ( InterimResult interimResult : interimResults )
         {
-            project = new MavenProject( model, repositorySystem, this, config );
+            Model model = interimResult.result.getEffectiveModel();
+            reactorModelPool.put( model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile() );
+        }
 
-            Artifact projectArtifact = repositorySystem.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null, project.getPackaging() );
-            project.setArtifact( projectArtifact );
+        for ( InterimResult interimResult : interimResults )
+        {
+            try
+            {
+                ModelBuildingResult result = modelBuilder.build( interimResult.request, interimResult.result );
+
+                MavenProject project = toProject( result, config, interimResult.listener );
+
+                results.add( new DefaultProjectBuildingResult( project, result.getProblems() ) );
+            }
+            catch ( ModelBuildingException e )
+            {
+                results.add( new DefaultProjectBuildingResult( interimResult.pomFile, e.getProblems() ) );
 
-            project.setParentFile( parentFile );
+                errors = true;
+            }
         }
-        catch ( InvalidRepositoryException e )
+
+        if ( errors )
         {
-            String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() );
-            throw new InvalidProjectModelException( projectId, e.getMessage(), projectDescriptor, e );
+            throw new ProjectBuildingException( results );
+        }
+
+        return results;
+    }
+
+    private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults, List<File> pomFiles,
+                        boolean recursive, ProjectBuildingRequest config, ReactorModelPool reactorModelPool )
+    {
+        boolean errors = false;
+        
+        for ( File pomFile : pomFiles )
+        {
+            ModelBuildingRequest request = getModelBuildingRequest( config, reactorModelPool );
+
+            request.setPomFile( pomFile );
+            request.setTwoPhaseBuilding( true );
+
+            DefaultModelBuildingListener listener = new DefaultModelBuildingListener( projectBuildingHelper, config );
+            request.setModelBuildingListeners( Arrays.asList( listener ) );
+
+            try
+            {
+                ModelBuildingResult result = modelBuilder.build( request );
+
+                Model model = result.getEffectiveModel();
+
+                interimResults.add( new InterimResult( pomFile, request, result, listener ) );
+
+                if ( recursive && !model.getModules().isEmpty() )
+                {
+                    File basedir = pomFile.getParentFile();
+
+                    List<File> moduleFiles = new ArrayList<File>();
+
+                    for ( String module : model.getModules() )
+                    {
+                        if ( StringUtils.isEmpty( module ) )
+                        {
+                            continue;
+                        }
+
+                        File moduleFile = new File( basedir, module );
+
+                        if ( moduleFile.isDirectory() )
+                        {
+                            moduleFile = new File( moduleFile, Maven.POMv4 );
+                        }
+
+                        if ( !moduleFile.isFile() )
+                        {
+                            String source = toSourceHint( model );
+                            ModelProblem problem =
+                                new ModelProblem( "Child module " + moduleFile + " of " + source + " does not exist",
+                                                  ModelProblem.Severity.ERROR, source );
+                            result.getProblems().add( problem );
+
+                            errors = true;
+
+                            continue;
+                        }
+
+                        if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+                        {
+                            // we don't canonicalize on unix to avoid interfering with symlinks
+                            try
+                            {
+                                moduleFile = moduleFile.getCanonicalFile();
+                            }
+                            catch ( IOException e )
+                            {
+                                moduleFile = moduleFile.getAbsoluteFile();
+                            }
+                        }
+                        else
+                        {
+                            moduleFile = new File( moduleFile.toURI().normalize() );
+                        }
+
+                        moduleFiles.add( moduleFile );
+                    }
+
+                    errors =
+                        build( results, interimResults, moduleFiles, recursive, config, reactorModelPool ) || errors;
+                }
+            }
+            catch ( ModelBuildingException e )
+            {
+                results.add( new DefaultProjectBuildingResult( pomFile, e.getProblems() ) );
+
+                errors = true;
+            }
+        }
+
+        return errors;
+    }
+
+    static class InterimResult
+    {
+
+        File pomFile;
+
+        ModelBuildingRequest request;
+
+        ModelBuildingResult result;
+
+        DefaultModelBuildingListener listener;
+
+        InterimResult( File pomFile, ModelBuildingRequest request, ModelBuildingResult result,
+                       DefaultModelBuildingListener listener )
+        {
+            this.pomFile = pomFile;
+            this.request = request;
+            this.result = result;
+            this.listener = listener;
+        }
+
+    }
+
+    private MavenProject toProject( ModelBuildingResult result, ProjectBuildingRequest configuration,
+                                    DefaultModelBuildingListener listener )
+        throws ProjectBuildingException
+    {
+        Model model = result.getEffectiveModel();
+
+        MavenProject project = new MavenProject( model, repositorySystem, this, configuration );
+
+        project.setFile( model.getPomFile() );
+
+        File parentPomFile = result.getRawModel( result.getModelIds().get( 1 ) ).getPomFile();
+        project.setParentFile( parentPomFile );
+
+        Artifact projectArtifact =
+            repositorySystem.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null,
+                                             project.getPackaging() );
+        project.setArtifact( projectArtifact );
+
+        project.setOriginalModel( result.getRawModel() );
+
+        project.setRemoteArtifactRepositories( listener.getRemoteRepositories() );
+        project.setPluginArtifactRepositories( listener.getPluginRepositories() );
+
+        project.setClassRealm( listener.getProjectRealm() );
+
+        try
+        {
+            if ( configuration.isProcessPlugins() )
+            {
+                lifecycle.populateDefaultConfigurationForPlugins( model.getBuild().getPlugins(),
+                                                                  configuration.getLocalRepository(),
+                                                                  project.getPluginArtifactRepositories() );
+            }
+        }
+        catch ( LifecycleExecutionException e )
+        {
+            throw new ProjectBuildingException( project.getId(), e.getMessage(), e );
+        }
+
+        Build build = project.getBuild();
+        project.addScriptSourceRoot( build.getScriptSourceDirectory() );
+        project.addCompileSourceRoot( build.getSourceDirectory() );
+        project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
+
+        List<Profile> activeProfiles = new ArrayList<Profile>();
+        activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) );
+        activeProfiles.addAll( result.getActiveExternalProfiles() );
+        project.setActiveProfiles( activeProfiles );
+
+        project.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
+        for ( String modelId : result.getModelIds() )
+        {
+            project.setInjectedProfileIds( modelId, getProfileIds( result.getActivePomProfiles( modelId ) ) );
         }
 
         return project;
@@ -381,4 +525,23 @@
         return ArtifactUtils.versionlessKey( gid, aid );
     }
 
-}
\ No newline at end of file
+    private String toSourceHint( Model model )
+    {
+        StringBuilder buffer = new StringBuilder( 192 );
+
+        buffer.append( model.getGroupId() );
+        buffer.append( ':' );
+        buffer.append( model.getArtifactId() );
+        buffer.append( ':' );
+        buffer.append( model.getVersion() );
+
+        File pomFile = model.getPomFile();
+        if ( pomFile != null )
+        {
+            buffer.append( " (" ).append( pomFile ).append( ")" );
+        }
+
+        return buffer.toString();
+    }
+
+}

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java?rev=798221&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java Mon Jul 27 17:09:51 2009
@@ -0,0 +1,88 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblem;
+
+/**
+ * Collects the output of the project builder.
+ * 
+ * @author Benjamin Bentmann
+ */
+class DefaultProjectBuildingResult
+    implements ProjectBuildingResult
+{
+
+    private File pomFile;
+
+    private MavenProject project;
+
+    private List<ModelProblem> problems;
+
+    /**
+     * Creates a new result with the specified contents.
+     * 
+     * @param project The project that was built, may be {@code null}.
+     * @param problems The problems that were encouterned, may be {@code null}.
+     */
+    public DefaultProjectBuildingResult( MavenProject project, List<ModelProblem> problems )
+    {
+        this.pomFile = ( project != null ) ? project.getFile() : null;
+        this.project = project;
+        this.problems = problems;
+    }
+
+    /**
+     * Creates a new result with the specified contents.
+     * 
+     * @param pomFile The POM file from which the project was built, may be {@code null}.
+     * @param problems The problems that were encouterned, may be {@code null}.
+     */
+    public DefaultProjectBuildingResult( File pomFile, List<ModelProblem> problems )
+    {
+        this.pomFile = pomFile;
+        this.problems = problems;
+    }
+
+    public File getPomFile()
+    {
+        return pomFile;
+    }
+
+    public MavenProject getProject()
+    {
+        return project;
+    }
+
+    public List<ModelProblem> getProblems()
+    {
+        if ( problems == null )
+        {
+            problems = new ArrayList<ModelProblem>();
+        }
+
+        return problems;
+    }
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/MavenProject.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/MavenProject.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/MavenProject.java Mon Jul 27 17:09:51 2009
@@ -225,7 +225,6 @@
      * @throws InvalidRepositoryException
      */
     public MavenProject( Model model, RepositorySystem repositorySystem, ProjectBuilder mavenProjectBuilder, ProjectBuildingRequest projectBuilderConfiguration )
-        throws InvalidRepositoryException
     {
         if ( model == null )
         {

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java Mon Jul 27 17:09:51 2009
@@ -16,6 +16,7 @@
  */
 
 import java.io.File;
+import java.util.List;
 
 import org.apache.maven.artifact.Artifact;
 
@@ -40,4 +41,19 @@
     MavenProjectBuildingResult buildProjectWithDependencies( File project, ProjectBuildingRequest request )
         throws ProjectBuildingException;
 
+    /**
+     * Builds the projects for the specified POM files and optionally their children.
+     * 
+     * @param pomFiles The POM files to build, must not be {@code null}.
+     * @param recursive {@code true} to recursively build sub modules referenced by the POM files, {@code false} to
+     *            build only the specified POM files.
+     * @param config The project builder configuration that provides further parameters, must not be {@code null}.
+     * @return The results of the project builder where each result corresponds to one project that was built, never
+     *         {@code null}.
+     * @throws ProjectBuildingException If an error was encountered during building of any project.
+     *             {@link ProjectBuildingException#getResults()} provides access to the details of the problems.
+     */
+    List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest config )
+        throws ProjectBuildingException;
+
 }

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java Mon Jul 27 17:09:51 2009
@@ -2,11 +2,15 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
 
 import org.apache.maven.artifact.InvalidRepositoryException;
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.model.building.ModelProblem;
 import org.apache.maven.profiles.ProfileActivationException;
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@@ -41,9 +45,11 @@
 
     private File pomFile;
 
+    private List<ProjectBuildingResult> results;
+
     public ProjectBuildingException( String projectId, String message, Throwable cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
@@ -55,7 +61,7 @@
      */
     protected ProjectBuildingException( String projectId, String message, String pomLocation )
     {
-        super( message );
+        super( createMessage( message, projectId, new File( pomLocation ) ) );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
@@ -67,7 +73,7 @@
      */
     public ProjectBuildingException( String projectId, String message, File pomFile )
     {
-        super( message );
+        super( createMessage( message, projectId, pomFile ) );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -80,7 +86,7 @@
      */
     protected ProjectBuildingException( String projectId, String message, File pomFile, Throwable cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -91,14 +97,14 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      ProfileActivationException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, ProfileActivationException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -108,14 +114,14 @@
      */
     public ProjectBuildingException( String projectId, String message, String pomLocation, IOException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, IOException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -123,7 +129,7 @@
     // for super-POM building.
     public ProjectBuildingException( String projectId, String message, IOException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
@@ -133,52 +139,52 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      XmlPullParserException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, XmlPullParserException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
 
     protected ProjectBuildingException( String projectId, String message, XmlPullParserException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
     public ProjectBuildingException( String projectId, String message, ArtifactResolutionException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
     public ProjectBuildingException( String projectId, String message, InvalidRepositoryException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, InvalidRepositoryException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
 
     public ProjectBuildingException( String projectId, String message, ArtifactNotFoundException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, null ), cause );
         this.projectId = projectId;
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, ArtifactResolutionException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -189,14 +195,14 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      ArtifactResolutionException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
 
     public ProjectBuildingException( String projectId, String message, File pomFile, ArtifactNotFoundException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -207,7 +213,7 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      ArtifactNotFoundException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
@@ -215,7 +221,7 @@
     public ProjectBuildingException( String projectId, String message, File pomFile,
                                      InvalidVersionSpecificationException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -226,7 +232,7 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      InvalidVersionSpecificationException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
@@ -234,7 +240,7 @@
     public ProjectBuildingException( String projectId, String message, File pomFile,
                                      InvalidDependencyVersionException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, pomFile ), cause );
         this.projectId = projectId;
         this.pomFile = pomFile;
     }
@@ -245,11 +251,17 @@
     public ProjectBuildingException( String projectId, String message, String pomLocation,
                                      InvalidDependencyVersionException cause )
     {
-        super( message, cause );
+        super( createMessage( message, projectId, new File( pomLocation ) ), cause );
         this.projectId = projectId;
         pomFile = new File( pomLocation );
     }
 
+    public ProjectBuildingException( List<ProjectBuildingResult> results )
+    {
+        super( createMessage( results ) );
+        this.projectId = "";
+        this.results = results;
+    }
 
     public File getPomFile()
     {
@@ -276,9 +288,40 @@
         return projectId;
     }
 
-    public String getMessage()
+    public List<ProjectBuildingResult> getResults()
+    {
+        return results;
+    }
+
+    private static String createMessage( String message, String projectId, File pomFile )
+    {
+        StringBuilder buffer = new StringBuilder( 256 );
+        buffer.append( message );
+        buffer.append( " for project " ).append( projectId );
+        if ( pomFile != null )
+        {
+            buffer.append( " at " ).append( pomFile.getAbsolutePath() );
+        }
+        return buffer.toString();
+    }
+
+    private static String createMessage( List<ProjectBuildingResult> results )
     {
-        return super.getMessage() + " for project " + projectId +
-            ( ( getPomFile() == null ? "" : " at " + getPomFile().getAbsolutePath() ) );
+        StringWriter buffer = new StringWriter( 1024 );
+
+        PrintWriter writer = new PrintWriter( buffer );
+        writer.println( "Some problems were encountered while processing the POMs:" );
+        for ( ProjectBuildingResult result : results )
+        {
+            for ( ModelProblem problem : result.getProblems() )
+            {
+                writer.print( "o " );
+                writer.println( problem.getMessage() );
+            }
+        }
+        writer.close();
+
+        return buffer.toString();
     }
+
 }

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java?rev=798221&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java Mon Jul 27 17:09:51 2009
@@ -0,0 +1,56 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblem;
+
+/**
+ * Collects the output of the project builder.
+ * 
+ * @author Benjamin Bentmann
+ */
+public interface ProjectBuildingResult
+{
+
+    /**
+     * Gets the POM file from which the project was built.
+     * 
+     * @return The POM file or {@code null} if unknown.
+     */
+    File getPomFile();
+
+    /**
+     * Gets the project that was built.
+     * 
+     * @return The project that was built or {@code null} if an error occurred.
+     */
+    MavenProject getProject();
+
+    /**
+     * Gets the problems that were encountered during the project building.
+     * 
+     * @return The problems that were encountered during the project building, can be empty but never {@code null}.
+     */
+    List<ModelProblem> getProblems();
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java?rev=798221&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java Mon Jul 27 17:09:51 2009
@@ -0,0 +1,106 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Holds all POM files that are known to the reactor. This allows the project builder to resolve imported POMs from the
+ * reactor when building another project's effective model.
+ * 
+ * @author Benjamin Bentmann
+ */
+class ReactorModelPool
+{
+
+    private final Map<CacheKey, File> pomFiles = new HashMap<CacheKey, File>();
+
+    public File get( String groupId, String artifactId, String version )
+    {
+        return pomFiles.get( new CacheKey( groupId, artifactId, version ) );
+    }
+
+    public void put( String groupId, String artifactId, String version, File pomFile )
+    {
+        pomFiles.put( new CacheKey( groupId, artifactId, version ), pomFile );
+    }
+
+    private static final class CacheKey
+    {
+
+        private final String groupId;
+
+        private final String artifactId;
+
+        private final String version;
+
+        private final int hashCode;
+
+        public CacheKey( String groupId, String artifactId, String version )
+        {
+            this.groupId = ( groupId != null ) ? groupId : "";
+            this.artifactId = ( artifactId != null ) ? artifactId : "";
+            this.version = ( version != null ) ? version : "";
+
+            int hash = 17;
+            hash = hash * 31 + this.groupId.hashCode();
+            hash = hash * 31 + this.artifactId.hashCode();
+            hash = hash * 31 + this.version.hashCode();
+            hashCode = hash;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+            {
+                return true;
+            }
+
+            if ( !( obj instanceof CacheKey ) )
+            {
+                return false;
+            }
+
+            CacheKey that = (CacheKey) obj;
+
+            return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
+                && version.equals( that.version );
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return hashCode;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder buffer = new StringBuilder( 96 );
+            buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
+            return buffer.toString();
+        }
+
+    }
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/project/RepositoryModelResolver.java Mon Jul 27 17:09:51 2009
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -38,7 +39,7 @@
 import org.apache.maven.repository.RepositorySystem;
 
 /**
- * Implements a model resolver backed by the Maven Repository API.
+ * Implements a model resolver backed by the Maven Repository API and the reactor.
  * 
  * @author Benjamin Bentmann
  */
@@ -54,8 +55,11 @@
 
     private List<ArtifactRepository> remoteRepositories;
 
+    private ReactorModelPool reactorModelPool;
+
     public RepositoryModelResolver( RepositorySystem repositorySystem, ResolutionErrorHandler resolutionErrorHandler,
-                                    ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+                                    ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories,
+                                    ReactorModelPool reactorModelPool )
     {
         if ( repositorySystem == null )
         {
@@ -80,12 +84,14 @@
             throw new IllegalArgumentException( "no remote repositories specified" );
         }
         this.remoteRepositories = new ArrayList<ArtifactRepository>( remoteRepositories );
+
+        this.reactorModelPool = reactorModelPool;
     }
 
     public ModelResolver newCopy()
     {
         return new RepositoryModelResolver( repositorySystem, resolutionErrorHandler, localRepository,
-                                            remoteRepositories );
+                                            remoteRepositories, reactorModelPool );
     }
 
     public void addRepository( Repository repository )
@@ -110,26 +116,38 @@
     public ModelSource resolveModel( String groupId, String artifactId, String version )
         throws UnresolvableModelException
     {
-        Artifact artifactParent = repositorySystem.createProjectArtifact( groupId, artifactId, version );
+        File pomFile = null;
 
-        ArtifactResolutionRequest request = new ArtifactResolutionRequest();
-        request.setArtifact( artifactParent );
-        request.setLocalRepository( localRepository );
-        request.setRemoteRepostories( remoteRepositories );
-        // FIXME setTransferListener
-        ArtifactResolutionResult result = repositorySystem.resolve( request );
-
-        try
+        if ( reactorModelPool != null )
         {
-            resolutionErrorHandler.throwErrors( request, result );
+            pomFile = reactorModelPool.get( groupId, artifactId, version );
         }
-        catch ( ArtifactResolutionException e )
+
+        if ( pomFile == null )
         {
-            throw new UnresolvableModelException( "Failed to resolve POM for " + groupId + ":" + artifactId + ":"
-                + version + " due to " + e.getMessage(), groupId, artifactId, version, e );
+            Artifact artifactParent = repositorySystem.createProjectArtifact( groupId, artifactId, version );
+
+            ArtifactResolutionRequest request = new ArtifactResolutionRequest();
+            request.setArtifact( artifactParent );
+            request.setLocalRepository( localRepository );
+            request.setRemoteRepostories( remoteRepositories );
+            // FIXME setTransferListener
+            ArtifactResolutionResult result = repositorySystem.resolve( request );
+
+            try
+            {
+                resolutionErrorHandler.throwErrors( request, result );
+            }
+            catch ( ArtifactResolutionException e )
+            {
+                throw new UnresolvableModelException( "Failed to resolve POM for " + groupId + ":" + artifactId + ":"
+                    + version + " due to " + e.getMessage(), groupId, artifactId, version, e );
+            }
+
+            pomFile = artifactParent.getFile();
         }
 
-        return new FileModelSource( artifactParent.getFile() );
+        return new FileModelSource( pomFile );
     }
 
 }

Modified: maven/components/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java?rev=798221&r1=798220&r2=798221&view=diff
==============================================================================
--- maven/components/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java (original)
+++ maven/components/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java Mon Jul 27 17:09:51 2009
@@ -43,9 +43,9 @@
     List<String> getModelIds();
 
     /**
-     * Gets the fully assembled model.
+     * Gets the assembled model.
      * 
-     * @return The fully assembled model, never {@code null}.
+     * @return The assembled model, never {@code null}.
      */
     Model getEffectiveModel();