You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kr...@apache.org on 2010/04/08 13:29:09 UTC

svn commit: r931884 [3/7] - in /maven/maven-3/trunk: maven-compat/src/test/java/org/apache/maven/project/ maven-core/src/main/java/org/apache/maven/ maven-core/src/main/java/org/apache/maven/artifact/repository/ maven-core/src/main/java/org/apache/mave...

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle;
+
+import org.apache.maven.lifecycle.internal.BuilderCommon;
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
+import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.*;
+
+/**
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold
+ */
+//TODO: The configuration for the lifecycle needs to be externalized so that I can use the annotations properly for the wiring and reference and external source for the lifecycle configuration.
+public class DefaultLifecycles
+    implements Initializable
+{
+    // @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml")
+
+    private List<Lifecycle> lifecycles;
+
+    private List<Scheduling> schedules;
+
+    /**
+     * We use this to display all the lifecycles available and their phases to users. Currently this is primarily
+     * used in the IDE integrations where a UI is presented to the user and they can select the lifecycle phase
+     * they would like to execute.
+     */
+    private Map<String, Lifecycle> lifecycleMap;
+
+    /**
+     * We use this to map all phases to the lifecycle that contains it. This is used so that a user can specify the
+     * phase they want to execute and we can easily determine what lifecycle we need to run.
+     */
+    private Map<String, Lifecycle> phaseToLifecycleMap;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public DefaultLifecycles()
+    {
+    }
+
+    public DefaultLifecycles( List<Lifecycle> lifecycles, List<Scheduling> schedules )
+    {
+        this.lifecycles = lifecycles;
+        this.schedules = schedules;
+    }
+
+    public void initialize()
+        throws InitializationException
+    {
+        lifecycleMap = new HashMap<String, Lifecycle>();
+
+        // If people are going to make their own lifecycles then we need to tell people how to namespace them correctly so
+        // that they don't interfere with internally defined lifecycles.
+
+        phaseToLifecycleMap = new HashMap<String, Lifecycle>();
+
+        for ( Lifecycle lifecycle : lifecycles )
+        {
+            for ( String phase : lifecycle.getPhases() )
+            {
+                // The first definition wins.
+                if ( !phaseToLifecycleMap.containsKey( phase ) )
+                {
+                    phaseToLifecycleMap.put( phase, lifecycle );
+                }
+            }
+
+            lifecycleMap.put( lifecycle.getId(), lifecycle );
+        }
+    }
+
+
+    public List<ExecutionPlanItem> createExecutionPlanItem( MavenProject mavenProject, List<MojoExecution> executions )
+        throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+        NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        BuilderCommon.attachToThread( mavenProject );
+
+        List<ExecutionPlanItem> result = new ArrayList<ExecutionPlanItem>();
+        for ( MojoExecution mojoExecution : executions )
+        {
+            String lifeCyclePhase = mojoExecution.getMojoDescriptor().getPhase();
+            final Scheduling scheduling = getScheduling( "default" );
+            Schedule schedule = null;
+            if ( scheduling != null )
+            {
+                schedule = scheduling.getSchedule( mojoExecution.getPlugin() );
+                if ( schedule == null )
+                {
+                    schedule = scheduling.getSchedule( lifeCyclePhase );
+                }
+            }
+            result.add( new ExecutionPlanItem( mojoExecution, schedule ) );
+
+        }
+        return result;
+    }
+
+    /**
+     * Gets scheduling associated with a given phase.
+     * <p/>
+     * This is part of the experimental weave mode and therefore not part of the public api.
+     *
+     * @param lifecyclePhaseName
+     * @return
+     */
+
+    private Scheduling getScheduling( String lifecyclePhaseName )
+    {
+        for ( Scheduling schedule : schedules )
+        {
+            if ( lifecyclePhaseName.equals( schedule.getLifecycle() ) )
+            {
+                return schedule;
+            }
+        }
+        return null;
+    }
+
+    public Lifecycle get( String key )
+    {
+        return phaseToLifecycleMap.get( key );
+    }
+
+    public Map<String, Lifecycle> getPhaseToLifecycleMap()
+    {
+        return phaseToLifecycleMap;
+    }
+
+    public List<Lifecycle> getLifeCycles()
+    {
+        return lifecycles;
+    }
+
+    public List<Scheduling> getSchedules()
+    {
+        return schedules;
+    }
+
+    public String getLifecyclePhaseList()
+    {
+        Set<String> phases = new LinkedHashSet<String>();
+
+        for ( Lifecycle lifecycle : lifecycles )
+        {
+            phases.addAll( lifecycle.getPhases() );
+        }
+
+        return StringUtils.join( phases.iterator(), ", " );
+    }
+
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,28 @@
+
+/*
+ * 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.
+ */
+
+package org.apache.maven.lifecycle;
+
+import java.util.Set;
+import org.apache.maven.model.Plugin;
+
+
+/**
+ * @author Kristian Rosenvold
+ */
+public interface LifeCyclePluginAnalyzer {
+    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles(String packaging);
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java?rev=931884&r1=931883&r2=931884&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java Thu Apr  8 11:29:07 2010
@@ -27,6 +27,14 @@ import java.util.Map;
  */
 public class Lifecycle
 {
+    public Lifecycle() {
+    }
+
+    public Lifecycle(String id, List<String> phases, Map<String, String> defaultPhases) {
+        this.id = id;
+        this.phases = phases;
+        this.defaultPhases = defaultPhases;
+    }
 
     // <lifecycle>
     //   <id>clean</id>

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleEventCatapult.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleEventCatapult.java?rev=931884&r1=931883&r2=931884&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleEventCatapult.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleEventCatapult.java Thu Apr  8 11:29:07 2010
@@ -28,7 +28,7 @@ import org.apache.maven.execution.Execut
  * 
  * @author Benjamin Bentmann
  */
-interface LifecycleEventCatapult
+public interface LifecycleEventCatapult
 {
 
     /**

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java?rev=931884&r1=931883&r2=931884&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java Thu Apr  8 11:29:07 2010
@@ -1,4 +1,18 @@
 package org.apache.maven.lifecycle;
+/*
+ * 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.
+ */
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -52,19 +66,19 @@ public class LifecycleExecutionException
         this.project = project;
     }
 
-    LifecycleExecutionException( String message, MojoExecution execution, MavenProject project )
+    public LifecycleExecutionException( String message, MojoExecution execution, MavenProject project )
     {
         super( message );
         this.project = project;
     }
 
-    LifecycleExecutionException( String message, MojoExecution execution, MavenProject project, Throwable cause )
+    public LifecycleExecutionException( String message, MojoExecution execution, MavenProject project, Throwable cause )
     {
         super( message, cause );
         this.project = project;
     }
 
-    LifecycleExecutionException( MojoExecution execution, MavenProject project, Throwable cause )
+    public LifecycleExecutionException( MojoExecution execution, MavenProject project, Throwable cause )
     {
         this( createMessage( execution, project, cause ), execution, project, cause );
     }

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java?rev=931884&r1=931883&r2=931884&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java Thu Apr  8 11:29:07 2010
@@ -19,21 +19,10 @@ package org.apache.maven.lifecycle;
  * under the License.
  */
 
-import java.util.List;
 import java.util.Set;
 
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Plugin;
-import org.apache.maven.plugin.InvalidPluginDescriptorException;
-import org.apache.maven.plugin.MojoExecution;
-import org.apache.maven.plugin.MojoNotFoundException;
-import org.apache.maven.plugin.PluginDescriptorParsingException;
-import org.apache.maven.plugin.PluginManagerException;
-import org.apache.maven.plugin.PluginNotFoundException;
-import org.apache.maven.plugin.PluginResolutionException;
-import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
-import org.apache.maven.plugin.version.PluginVersionResolutionException;
-import org.apache.maven.project.MavenProject;
 
 /**
  * @author Jason van  Zyl
@@ -45,25 +34,10 @@ public interface LifecycleExecutor
     @Deprecated
     String ROLE = LifecycleExecutor.class.getName();
 
-    /**
-     * Calculate the list of {@link org.apache.maven.plugin.descriptor.MojoDescriptor} objects to run for the selected lifecycle phase.
-     * 
-     * @param phase
-     * @param session
-     * @return
-     * @throws InvalidPluginDescriptorException 
-     * @throws LifecycleExecutionException
-     */
-    MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
-        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
-        MojoNotFoundException, NoPluginFoundForPrefixException,
-        InvalidPluginDescriptorException, PluginManagerException, LifecyclePhaseNotFoundException,
-        LifecycleNotFoundException, PluginVersionResolutionException;
-        
     // For a given project packaging find all the plugins that are bound to any registered
     // lifecycles. The project builder needs to now what default plugin information needs to be
     // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned
-    // by the POM builder because they will have to be defined in plugin management. Once this is done then it
+    // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it
     // can be passed back so that the default configuraiton information can be populated.
     //
     // We need to know the specific version so that we can lookup the right version of the plugin descriptor
@@ -77,33 +51,4 @@ public interface LifecycleExecutor
 
     void execute( MavenSession session );
 
-    /**
-     * Calculates the forked mojo executions requested by the mojo associated with the specified mojo execution.
-     * 
-     * @param mojoExecution The mojo execution for which to calculate the forked mojo executions, must not be {@code
-     *            null}.
-     * @param session The current build session that holds the projects and further settings, must not be {@code null}.
-     */
-    void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
-        throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
-        PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
-        LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
-
-    /**
-     * Executes the previously calculated forked mojo executions of the given mojo execution. If the specified mojo
-     * execution requires no forking, this method does nothing. The return value denotes a subset of the projects from
-     * the session that have been forked. The method {@link MavenProject#getExecutionProject()} of those projects
-     * returns the project clone on which the forked execution were performed. It is the responsibility of the caller to
-     * reset those execution projects to {@code null} once they are no longer needed to free memory and to avoid
-     * accidental usage by unrelated mojos.
-     * 
-     * @param mojoExecution The mojo execution whose forked mojo executions should be processed, must not be {@code
-     *            null}.
-     * @param session The current build session that holds the projects and further settings, must not be {@code null}.
-     * @return The (unmodifiable) list of projects that have been forked, can be empty if no forking was required but
-     *         will never be {@code null}.
-     */
-    List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
-        throws LifecycleExecutionException;
-
 }

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java?rev=931884&r1=931883&r2=931884&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java Thu Apr  8 11:29:07 2010
@@ -19,10 +19,11 @@ package org.apache.maven.lifecycle;
  * under the License.
  */
 
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
 import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
 
 //TODO: lifecycles being executed
 //TODO: what runs in each phase
@@ -30,30 +31,78 @@ import org.apache.maven.plugin.MojoExecu
 //TODO: project dependencies that need downloading
 //TODO: unfortunately the plugins need to be downloaded in order to get the plugin.xml file. need to externalize this from the plugin archive.
 //TODO: this will be the class that people get in IDEs to modify
-public class MavenExecutionPlan
+public class MavenExecutionPlan  implements Iterable<ExecutionPlanItem>
 {
-    /** Individual executions that must be performed. */
-    private List<MojoExecution> executions;
-    
+
+    /*
+       At the moment, this class is totally immutable, and this is in line with thoughts about the
+       pre-calculated execution plan that stays the same during the execution.
+
+       If deciding to add mutable state to this class, it should be at least considered to
+       separate this into a separate mutable structure.
+
+     */
     /** For project dependency resolution, the scopes of resolution required if any. */
-    private Set<String> requiredDependencyResolutionScopes;
+    private final Set<String> requiredDependencyResolutionScopes;
 
     /** For project dependency collection, the scopes of collection required if any. */
-    private Set<String> requiredDependencyCollectionScopes;
+    private final Set<String> requiredDependencyCollectionScopes;
 
-    public MavenExecutionPlan( List<MojoExecution> executions, Set<String> requiredDependencyResolutionScopes,
-                               Set<String> requiredDependencyCollectionScopes )
-    {
-        this.executions = executions;
+    private final List<ExecutionPlanItem> planItem;
+
+    private final Map<String, ExecutionPlanItem> lastInPhase;
+    private final List<String> phasesInOrder;
+
+    public MavenExecutionPlan(Set<String> requiredDependencyResolutionScopes, Set<String> requiredDependencyCollectionScopes, List<ExecutionPlanItem> planItem) {
         this.requiredDependencyResolutionScopes = requiredDependencyResolutionScopes;
         this.requiredDependencyCollectionScopes = requiredDependencyCollectionScopes;
+        this.planItem = planItem;
+        lastInPhase = new HashMap<String, ExecutionPlanItem>();
+        phasesInOrder = new ArrayList<String>();
+        for (ExecutionPlanItem executionPlanItem : getExecutionPlanItems()) {
+            final String phaseName = getPhase( executionPlanItem );
+            if (!lastInPhase.containsKey(  phaseName )){
+                phasesInOrder.add( phaseName );
+            }
+            lastInPhase.put( phaseName, executionPlanItem );
+        }
+
+
     }
 
-    public List<MojoExecution> getExecutions()
-    {
-        return executions;
+    private String getPhase( ExecutionPlanItem executionPlanItem){
+        final MojoExecution mojoExecution = executionPlanItem.getMojoExecution();
+        final MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+        return mojoDescriptor.getPhase();
+
+    }
+    public Iterator<ExecutionPlanItem> iterator() {
+        return getExecutionPlanItems().iterator();
+    }
+
+    /**
+     * Returns the last ExecutionPlanItem in the supplied phase. If no items are in the specified phase,
+     * the closest upstream item will be returned.
+     * @param executionPlanItem The execution plan item
+     * @return The ExecutionPlanItem or null if none can be found
+     */
+    public ExecutionPlanItem findLastInPhase( ExecutionPlanItem executionPlanItem){
+        ExecutionPlanItem executionPlanItem1 = lastInPhase.get( getPhase( executionPlanItem ) );
+        return executionPlanItem1;
+    }
+
+    private List<ExecutionPlanItem> getExecutionPlanItems()
+     {
+         return planItem;
+     }
+
+    public void forceAllComplete(){
+        for (ExecutionPlanItem executionPlanItem : getExecutionPlanItems()) {
+             executionPlanItem.forceComplete();
+        }
     }
 
+
     public Set<String> getRequiredResolutionScopes()
     {
         return requiredDependencyResolutionScopes;
@@ -64,4 +113,17 @@ public class MavenExecutionPlan
         return requiredDependencyCollectionScopes;
     }
 
+
+    public List<MojoExecution> getMojoExecutions(){
+        List<MojoExecution> result = new ArrayList<MojoExecution>();
+        for ( ExecutionPlanItem executionPlanItem : planItem )
+        {
+            result.add( executionPlanItem.getMojoExecution());
+        }
+        return result;
+    }
+
+    public int size() {
+        return planItem.size();
+    }
 }

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Schedule.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Schedule.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Schedule.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Schedule.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.maven.lifecycle;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class Schedule {
+    private String phase;
+    private String mojoClass;
+    private boolean mojoSynchronized;
+    // Indicates that this phase/mojo does not need to respect the reactor-dependency graph
+    // (Module lifecycle order still must be respected )
+    private boolean parallel;
+
+    public Schedule() {
+    }
+
+    public Schedule( String phase, boolean mojoSynchronized, boolean parallel ) {
+        this.phase = phase;
+        this.mojoSynchronized = mojoSynchronized;
+        this.parallel = parallel;
+    }
+
+
+    public boolean isMissingPhase(){
+        return null == phase;
+    }
+    public String getPhase() {
+        return phase;
+    }
+
+    public void setPhase(String phase) {
+        this.phase = phase;
+    }
+
+    public String getMojoClass() {
+        return mojoClass;
+    }
+
+    public void setMojoClass(String mojoClass) {
+        this.mojoClass = mojoClass;
+    }
+
+    public boolean isMojoSynchronized() {
+        return mojoSynchronized;
+    }
+
+    public void setMojoSynchronized(boolean mojoSynchronized) {
+        this.mojoSynchronized = mojoSynchronized;
+    }
+
+
+    public boolean isParallel()
+    {
+        return parallel;
+    }
+
+    public void setParallel( boolean parallel )
+    {
+        this.parallel = parallel;
+    }
+
+
+    @Override
+    public String toString() {
+        return "Schedule{" +
+                "phase='" + phase + '\'' +
+                ", mojoClass='" + mojoClass + '\'' +
+                ", mojoSynchronized=" + mojoSynchronized +
+                ", parallel=" + parallel +
+                '}';
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Schedule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Scheduling.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Scheduling.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Scheduling.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Scheduling.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package org.apache.maven.lifecycle;
+
+import org.apache.maven.model.Plugin;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class Scheduling.
+ */
+public class Scheduling
+{
+    private String lifecycle;
+
+    private List<Schedule> schedules;
+
+    public Scheduling() {
+    }
+
+    public Scheduling(String lifecycle, List<Schedule> schedules) {
+        this.lifecycle = lifecycle;
+        this.schedules = schedules;
+    }
+
+    public String getLifecycle() {
+        return lifecycle;
+    }
+
+    public void setLifecycle(String lifecycle) {
+        this.lifecycle = lifecycle;
+    }
+
+    public List<Schedule> getSchedules() {
+        return schedules;
+    }
+
+
+    public Schedule getSchedule(String phaseName){
+        if (phaseName == null) return null;
+        for (Schedule schedule : schedules) {
+            if (phaseName.equals(schedule.getPhase()) )
+                return schedule;
+        }
+        return null;
+    }
+    
+    public Schedule getSchedule(Plugin mojoClass){
+        if (mojoClass == null) return null;
+        for (Schedule schedule : schedules) {
+            if (mojoClass.getKey().equals(schedule.getMojoClass()) )
+                return schedule;
+        }
+        return null;
+    }
+
+    public void setSchedules(List<Schedule> schedules) {
+        this.schedules = schedules;
+    }
+}
\ No newline at end of file

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/Scheduling.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ *         This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = BuildListCalculator.class)
+public class BuildListCalculator
+{
+    @Requirement
+    private LifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public BuildListCalculator()
+    {
+    }
+
+    public BuildListCalculator( LifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator )
+    {
+        this.lifeCycleTaskSegmentCalculator = lifeCycleTaskSegmentCalculator;
+    }
+
+    public List<TaskSegment> calculateTaskSegments( MavenSession session )
+        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+        MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException
+    {
+
+        MavenProject rootProject = session.getTopLevelProject();
+
+        List<String> tasks = session.getGoals();
+
+        if ( tasks == null || tasks.isEmpty() )
+        {
+            if ( !StringUtils.isEmpty( rootProject.getDefaultGoal() ) )
+            {
+                tasks = Arrays.asList( StringUtils.split( rootProject.getDefaultGoal() ) );
+            }
+        }
+
+        return lifeCycleTaskSegmentCalculator.calculateTaskSegments( session, tasks );
+    }
+
+    public ProjectBuildList calculateProjectBuilds( MavenSession session, List<TaskSegment> taskSegments )
+    {
+        List<ProjectSegment> projectBuilds = new ArrayList<ProjectSegment>();
+
+        MavenProject rootProject = session.getTopLevelProject();
+
+        for ( TaskSegment taskSegment : taskSegments )
+        {
+            List<MavenProject> projects;
+
+            if ( taskSegment.isAggregating() )
+            {
+                projects = Collections.singletonList( rootProject );
+            }
+            else
+            {
+                projects = session.getProjects();
+            }
+            for ( MavenProject project : projects )
+            {
+                BuilderCommon.attachToThread( project ); // Not totally sure if this is needed for anything
+                MavenSession copiedSession = session.clone();
+                copiedSession.setCurrentProject( project );
+                projectBuilds.add( new ProjectSegment( project, taskSegment, copiedSession ) );
+            }
+        }
+        return new ProjectBuildList( projectBuilds );
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuilderCommon.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuilderCommon.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuilderCommon.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuilderCommon.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.BuildFailure;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.*;
+import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Common code that is shared by the LifecycleModuleBuilder and the LifeCycleWeaveBuilder
+ *
+ * @author Kristian Rosenvold
+ *         Builds one or more lifecycles for a full module
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = BuilderCommon.class)
+public class BuilderCommon
+{
+    @Requirement
+    private LifecycleDebugLogger lifecycleDebugLogger;
+
+    @Requirement
+    private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
+
+    @Requirement
+    private LifecycleDependencyResolver lifecycleDependencyResolver;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public BuilderCommon()
+    {
+    }
+
+    public BuilderCommon( LifecycleDebugLogger lifecycleDebugLogger,
+                          LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator,
+                          LifecycleDependencyResolver lifecycleDependencyResolver )
+    {
+        this.lifecycleDebugLogger = lifecycleDebugLogger;
+        this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
+        this.lifecycleDependencyResolver = lifecycleDependencyResolver;
+    }
+
+    public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject project, TaskSegment taskSegment )
+        throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+        NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
+        LifecycleExecutionException
+    {
+        MavenExecutionPlan executionPlan =
+            lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, project, taskSegment.getTasks() );
+        lifecycleDebugLogger.debugProjectPlan( project, executionPlan );
+
+        // TODO: once we have calculated the build plan then we should accurately be able to download
+        // the project dependencies. Having it happen in the plugin manager is a tangled mess. We can optimize
+        // this later by looking at the build plan. Would be better to just batch download everything required
+        // by the reactor.
+
+        lifecycleDependencyResolver.resolveDependencies( taskSegment.isAggregating(), project, session, executionPlan );
+        return executionPlan;
+    }
+
+
+    public static void handleBuildError( final ReactorContext buildContext, final MavenSession rootSession,
+                                         final MavenProject mavenProject, final Exception e, final long buildStartTime )
+    {
+        buildContext.getResult().addException( e );
+
+        long buildEndTime = System.currentTimeMillis();
+
+        buildContext.getResult().addBuildSummary( new BuildFailure( mavenProject, buildEndTime - buildStartTime, e ) );
+
+        DefaultLifecycleExecutor.fireEvent( rootSession, null, LifecycleEventCatapult.PROJECT_FAILED );
+
+        if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( rootSession.getReactorFailureBehavior() ) )
+        {
+            // continue the build
+        }
+        else if ( MavenExecutionRequest.REACTOR_FAIL_AT_END.equals( rootSession.getReactorFailureBehavior() ) )
+        {
+            // continue the build but ban all projects that depend on the failed one
+            buildContext.getReactorBuildStatus().blackList( mavenProject );
+        }
+        else if ( MavenExecutionRequest.REACTOR_FAIL_FAST.equals( rootSession.getReactorFailureBehavior() ) )
+        {
+            buildContext.getReactorBuildStatus().halt();
+        }
+        else
+        {
+            throw new IllegalArgumentException(
+                "invalid reactor failure behavior " + rootSession.getReactorFailureBehavior() );
+        }
+    }
+
+    public static void attachToThread( MavenProject currentProject )
+    {
+        ClassRealm projectRealm = currentProject.getClassRealm();
+        if ( projectRealm != null )
+        {
+            Thread.currentThread().setContextClassLoader( projectRealm );
+        }
+    }
+
+    // Todo: I'm really wondering where this method belongs; smells like it should be on MavenProject, but for some reason it isn't ?
+    // This localization is kind-of a code smell.
+
+    public static String getKey( MavenProject project )
+    {
+        return project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion();
+    }
+
+
+}
\ No newline at end of file

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuilderCommon.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuiltLogItem.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuiltLogItem.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuiltLogItem.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuiltLogItem.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class BuiltLogItem
+{
+    private final ExecutionPlanItem executionPlanItem;
+
+    private final MavenProject project;
+
+    private final long startTime;
+
+    private long endTime;
+
+    private final List<WaitLogEntry> waits = new ArrayList<WaitLogEntry>();
+
+    public BuiltLogItem( MavenProject project, ExecutionPlanItem executionPlanItem )
+    {
+        this.executionPlanItem = executionPlanItem;
+        this.project = project;
+        startTime = System.currentTimeMillis();
+
+    }
+
+    public void setComplete()
+    {
+        endTime = System.currentTimeMillis();
+    }
+
+    public void addWait( MavenProject upstreamProject, ExecutionPlanItem inSchedule, long startWait )
+    {
+        long now = System.currentTimeMillis();
+        if ( ( now - startWait ) > 1 )
+        {
+            waits.add( new WaitLogEntry( upstreamProject, inSchedule, startWait, now ) );
+        }
+    }
+
+    public String toString( long rootStart )
+    {
+        StringBuilder result = new StringBuilder();
+        result.append( String.format( "%1d  %2d ", startTime - rootStart, endTime - rootStart ) );
+        result.append( project.getName() );
+        result.append( " " );
+        result.append( executionPlanItem.getMojoExecution().getArtifactId() );
+        for ( WaitLogEntry waitLogEntry : waits )
+        {
+            result.append( waitLogEntry.toString() );
+        }
+        return result.toString();
+    }
+
+    class WaitLogEntry
+    {
+        private final ExecutionPlanItem executionPlanItem;
+
+        private final MavenProject upstreamProject;
+
+        private final long start;
+
+        private final long stop;
+
+        WaitLogEntry( MavenProject upstreamProject, ExecutionPlanItem executionPlanItem, long start, long stop )
+        {
+            this.upstreamProject = upstreamProject;
+            this.executionPlanItem = executionPlanItem;
+            this.start = start;
+            this.stop = stop;
+        }
+
+        public String toString()
+        {
+            return upstreamProject.getName() + " " + executionPlanItem.getMojoExecution().getArtifactId() + ", wait=" +
+                ( stop - start );
+        }
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuiltLogItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraph.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraph.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraph.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraph.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Presents a view of the Dependency Graph that is suited for concurrent building.
+ *
+ * @author Kristian Rosenvold
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class ConcurrencyDependencyGraph
+{
+
+    private final ProjectBuildList projectBuilds;
+
+    private final ProjectDependencyGraph projectDependencyGraph;
+
+    private final HashSet<MavenProject> finishedProjects = new HashSet<MavenProject>();
+
+
+    public ConcurrencyDependencyGraph( ProjectBuildList projectBuilds, ProjectDependencyGraph projectDependencyGraph )
+    {
+        this.projectDependencyGraph = projectDependencyGraph;
+        this.projectBuilds = projectBuilds;
+    }
+
+
+    public int getNumberOfBuilds()
+    {
+        return projectBuilds.size();
+    }
+
+    /**
+     * Gets all the builds that have no reactor-dependencies
+     *
+     * @return A list of all the initial builds
+     */
+
+    public List<MavenProject> getRootSchedulableBuilds()
+    {
+        List<MavenProject> result = new ArrayList<MavenProject>();
+        for ( ProjectSegment projectBuild : projectBuilds )
+        {
+            if ( projectDependencyGraph.getUpstreamProjects( projectBuild.getProject(), false ).size() == 0 )
+            {
+                result.add( projectBuild.getProject() );
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Marks the provided project as finished. Returns a list of
+     *
+     * @param mavenProject The project
+     * @return The list of builds that are eligible for starting now that the provided project is done
+     */
+    public List<MavenProject> markAsFinished( MavenProject mavenProject )
+    {
+        finishedProjects.add( mavenProject );
+        return getSchedulableNewProcesses( mavenProject );
+    }
+
+    private List<MavenProject> getSchedulableNewProcesses( MavenProject finishedProject )
+    {
+        List<MavenProject> result = new ArrayList<MavenProject>();
+        // schedule dependent projects, if all of their requirements are met
+        for ( MavenProject dependentProject : projectDependencyGraph.getDownstreamProjects( finishedProject, false ) )
+        {
+            final List<MavenProject> upstreamProjects =
+                projectDependencyGraph.getUpstreamProjects( dependentProject, false );
+            if ( finishedProjects.containsAll( upstreamProjects ) )
+            {
+                result.add( dependentProject );
+            }
+        }
+        return result;
+    }
+
+    public ProjectBuildList getProjectBuilds()
+    {
+        return projectBuilds;
+    }
+}
\ No newline at end of file

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraph.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLogger.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLogger.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLogger.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLogger.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Handles all concurrency-related logging.
+ * <p/>
+ * The logging/diagnostic needs of a concurrent build are different from a linear build. This
+ * delta required to analyze a concurrent build is located here.
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ *
+ * @author Kristian Rosenvold
+ */
+public class ConcurrentBuildLogger
+{
+    private final long startTime;
+
+    private final Map<MavenProject, Thread> threadMap = new ConcurrentHashMap<MavenProject, Thread>();
+
+    public ConcurrentBuildLogger()
+    {
+        startTime = System.currentTimeMillis();
+    }
+
+
+    List<BuiltLogItem> items = Collections.synchronizedList( new ArrayList<BuiltLogItem>() );
+
+    public BuiltLogItem createBuildLogItem( MavenProject project, ExecutionPlanItem current )
+    {
+        threadMap.put( project, Thread.currentThread() );
+        BuiltLogItem result = new BuiltLogItem( project, current );
+        items.add( result );
+        return result;
+    }
+
+    public String toString()
+    {
+        StringBuilder result = new StringBuilder();
+        for ( Map.Entry<MavenProject, Thread> mavenProjectThreadEntry : threadMap.entrySet() )
+        {
+            result.append( mavenProjectThreadEntry.getKey().getName() );
+            result.append( " ran on " );
+            result.append( mavenProjectThreadEntry.getValue().getName() );
+            result.append( "\n" );
+        }
+
+        for ( BuiltLogItem builtLogItem : items )
+        {
+            result.append( builtLogItem.toString( startTime ) );
+            result.append( "\n" );
+        }
+        return result.toString();
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.project.MavenProject;
+
+import java.util.Collection;
+
+/**
+ * Context of dependency artifacts for the entire build.
+ *
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (class extract only)
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+// TODO: From a concurrecy perspective, this class is not good. The combination of mutable/immutable state is not nice
+public class DependencyContext
+{
+
+    private final Collection<String> scopesToCollect;
+
+    private final Collection<String> scopesToResolve;
+
+    private final boolean aggregating;
+
+    private volatile MavenProject lastProject;
+
+    private volatile Collection<?> lastDependencyArtifacts;
+
+    private volatile int lastDependencyArtifactCount;
+
+    private DependencyContext( Collection<String> scopesToCollect, Collection<String> scopesToResolve,
+                               boolean aggregating )
+    {
+        this.scopesToCollect = scopesToCollect;
+        this.scopesToResolve = scopesToResolve;
+        this.aggregating = aggregating;
+    }
+
+    public DependencyContext( MavenExecutionPlan executionPlan, boolean aggregating )
+    {
+        this( executionPlan.getRequiredCollectionScopes(), executionPlan.getRequiredResolutionScopes(), aggregating );
+    }
+
+    public void setLastDependencyArtifacts( Collection<?> lastDependencyArtifacts )
+    {
+        this.lastDependencyArtifacts = lastDependencyArtifacts;
+        lastDependencyArtifactCount = ( lastDependencyArtifacts != null ) ? lastDependencyArtifacts.size() : 0;
+    }
+
+    public MavenProject getLastProject()
+    {
+        return lastProject;
+    }
+
+    public void setLastProject( MavenProject lastProject )
+    {
+        this.lastProject = lastProject;
+    }
+
+    public Collection<String> getScopesToCollect()
+    {
+        return scopesToCollect;
+    }
+
+    public Collection<String> getScopesToResolve()
+    {
+        return scopesToResolve;
+    }
+
+    public boolean isAggregating()
+    {
+        return aggregating;
+    }
+
+    public DependencyContext clone()
+    {
+        return new DependencyContext( scopesToCollect, scopesToResolve, aggregating );
+    }
+
+    public boolean isSameProject( MavenSession session )
+    {
+        return ( lastProject == session.getCurrentProject() );
+    }
+
+    public boolean isSameButUpdatedProject( MavenSession session )
+    {
+        if ( isSameProject( session ) )
+        {
+            if ( lastDependencyArtifacts != lastProject.getDependencyArtifacts() ||
+                ( lastDependencyArtifacts != null && lastDependencyArtifactCount != lastDependencyArtifacts.size() ) )
+            {
+                return true;
+
+            }
+        }
+        return false;
+    }
+
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.lifecycle.Schedule;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Wraps individual MojoExecutions, containing information about completion status and scheduling.
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ *
+ * @author Kristian Rosenvold
+ */
+public class ExecutionPlanItem
+{
+    private final MojoExecution mojoExecution;
+
+    private final Schedule schedule;
+    // Completeness just indicates that it has been run or failed
+
+    private final AtomicBoolean complete = new AtomicBoolean( false );
+
+    private final Object monitor = new Object();
+
+    public ExecutionPlanItem( MojoExecution mojoExecution, Schedule schedule )
+    {
+        this.mojoExecution = mojoExecution;
+        this.schedule = schedule;
+    }
+
+    public MojoExecution getMojoExecution()
+    {
+        return mojoExecution;
+    }
+
+    public void setComplete()
+    {
+        boolean transitionSuccessful = ensureComplete();
+        if ( !transitionSuccessful )
+        {
+            throw new IllegalStateException( "Expected to be able to setComplete node, but was complete already" );
+        }
+    }
+
+    public boolean ensureComplete()
+    {
+        boolean f = complete.compareAndSet( false, true );
+        notifyListeners();
+        return f;
+    }
+
+    private void notifyListeners()
+    {
+        synchronized ( monitor )
+        {
+            monitor.notifyAll();
+        }
+    }
+
+    public void forceComplete()
+    {
+        final boolean b = complete.getAndSet( true );
+        if ( !b )
+        {
+            notifyListeners();
+        } // Release anyone waiting for us
+    }
+
+    public void waitUntilDone()
+        throws InterruptedException
+    {
+        synchronized ( monitor )
+        {
+            while ( !complete.get() )
+            {
+                monitor.wait( 100 );
+            }
+        }
+    }
+
+    public Schedule getSchedule()
+    {
+        return schedule;
+    }
+
+    public boolean hasSchedule( Schedule other )
+    {
+        if ( getSchedule() != null && !getSchedule().isMissingPhase() )
+        {
+            if ( other.getPhase().equals( getSchedule().getPhase() ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Plugin getPlugin()
+    {
+        final MojoDescriptor mojoDescriptor = getMojoExecution().getMojoDescriptor();
+        return mojoDescriptor.getPluginDescriptor().getPlugin();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "ExecutionPlanItem{" + ", mojoExecution=" + mojoExecution + ", schedule=" + schedule + '}' +
+            super.toString();
+    }
+
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+/**
+ * A task that is a goal
+ * <p/>
+ * TODO: From a concurrecy perspective, this class is not good. The combination of mutable/immutable state is not nice
+ *
+ * @author Benjamin Bentmann
+ */
+public final class GoalTask
+{
+
+    final String pluginGoal;
+
+    public GoalTask( String pluginGoal )
+    {
+        this.pluginGoal = pluginGoal;
+    }
+
+    @Override
+    public String toString()
+    {
+        return pluginGoal;
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Logs debug output from the various lifecycle phases.
+ *
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold (extracted class only)
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecycleDebugLogger.class)
+public class LifecycleDebugLogger
+{
+    @Requirement
+    private Logger logger;
+
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecycleDebugLogger()
+    {
+    }
+
+    public LifecycleDebugLogger( Logger logger )
+    {
+        this.logger = logger;
+    }
+
+
+    public void debug( String s )
+    {
+        logger.debug( s );
+    }
+
+    public void info( String s )
+    {
+        logger.info( s );
+    }
+
+    public void debugReactorPlan( ProjectBuildList projectBuilds )
+    {
+        if ( !logger.isDebugEnabled() )
+        {
+            return;
+        }
+        logger.debug( "=== REACTOR BUILD PLAN ================================================" );
+
+        for ( Iterator<ProjectSegment> it = projectBuilds.iterator(); it.hasNext(); )
+        {
+            ProjectSegment projectBuild = it.next();
+
+            logger.debug( "Project: " + projectBuild.getProject().getId() );
+            logger.debug( "Tasks:   " + projectBuild.getTaskSegment().getTasks() );
+            logger.debug( "Style:   " + ( projectBuild.getTaskSegment().isAggregating() ? "Aggregating" : "Regular" ) );
+
+            if ( it.hasNext() )
+            {
+                logger.debug( "-----------------------------------------------------------------------" );
+            }
+        }
+
+        logger.debug( "=======================================================================" );
+    }
+
+
+    public void debugProjectPlan( MavenProject currentProject, MavenExecutionPlan executionPlan )
+    {
+        logger.debug( "=== PROJECT BUILD PLAN ================================================" );
+        logger.debug( "Project:       " + BuilderCommon.getKey( currentProject ) );
+        logger.debug( "Dependencies (collect): " + executionPlan.getRequiredCollectionScopes() );
+        logger.debug( "Dependencies (resolve): " + executionPlan.getRequiredResolutionScopes() );
+
+        for ( ExecutionPlanItem mojoExecution : executionPlan )
+        {
+            debugMojoExecution( mojoExecution.getMojoExecution() );
+        }
+
+        logger.debug( "=======================================================================" );
+    }
+
+    private void debugMojoExecution( MojoExecution mojoExecution )
+    {
+        String mojoExecId =
+            mojoExecution.getGroupId() + ':' + mojoExecution.getArtifactId() + ':' + mojoExecution.getVersion() + ':' +
+                mojoExecution.getGoal() + " (" + mojoExecution.getExecutionId() + ')';
+
+        Map<String, List<MojoExecution>> forkedExecutions = mojoExecution.getForkedExecutions();
+        if ( !forkedExecutions.isEmpty() )
+        {
+            for ( Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet() )
+            {
+                logger.debug( "--- init fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
+
+                for ( MojoExecution forkedExecution : fork.getValue() )
+                {
+                    debugMojoExecution( forkedExecution );
+                }
+
+                logger.debug( "--- exit fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
+            }
+        }
+
+        logger.debug( "-----------------------------------------------------------------------" );
+        logger.debug( "Goal:          " + mojoExecId );
+        logger.debug(
+            "Style:         " + ( mojoExecution.getMojoDescriptor().isAggregator() ? "Aggregating" : "Regular" ) );
+        logger.debug( "Configuration: " + mojoExecution.getConfiguration() );
+    }
+
+    public void logWeavePlan( MavenSession session )
+    {
+        if ( !logger.isInfoEnabled() )
+        {
+            return;
+        }
+
+        final ProjectDependencyGraph dependencyGraph = session.getProjectDependencyGraph();
+        logger.info( "=== WEAVE CONCURRENCY BUILD PLAN ================================================" );
+        for ( MavenProject mavenProject : dependencyGraph.getSortedProjects() )
+        {
+
+            StringBuilder item = new StringBuilder();
+            item.append( "Project: " );
+            item.append( mavenProject.getArtifactId() );
+            final List<MavenProject> upstreamProjects = dependencyGraph.getUpstreamProjects( mavenProject, false );
+            if ( upstreamProjects.size() > 0 )
+            {
+                item.append( " ( " );
+                for ( Iterator<MavenProject> it = upstreamProjects.iterator(); it.hasNext(); )
+                {
+                    final MavenProject kid = it.next();
+                    item.append( kid.getArtifactId() );
+                    if ( it.hasNext() )
+                    {
+                        item.append( ", " );
+                    }
+                }
+                item.append( ")" );
+            }
+            logger.info( item.toString() );
+
+        }
+        logger.info( "=======================================================================" );
+    }
+}
\ No newline at end of file

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.ProjectDependenciesResolver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+import java.util.*;
+
+/**
+ * Resolves dependencies for the artifacts in context of the lifecycle build
+ *
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold (extracted class)
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecycleDependencyResolver.class)
+public class LifecycleDependencyResolver
+{
+    @Requirement
+    private ProjectDependenciesResolver projectDependenciesResolver;
+
+    @Requirement
+    private Logger logger;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecycleDependencyResolver()
+    {
+    }
+
+    public LifecycleDependencyResolver( ProjectDependenciesResolver projectDependenciesResolver, Logger logger )
+    {
+        this.projectDependenciesResolver = projectDependenciesResolver;
+        this.logger = logger;
+    }
+
+    public void resolveDependencies( boolean aggregating, MavenProject currentProject,
+                                     MavenSession sessionForThisModule, MavenExecutionPlan executionPlan )
+        throws LifecycleExecutionException
+    {
+        List<MavenProject> projectsToResolve = getProjects( currentProject, sessionForThisModule, aggregating );
+        resolveDependencies( aggregating, sessionForThisModule, executionPlan, projectsToResolve );
+    }
+
+    public static List<MavenProject> getProjects( MavenProject project, MavenSession session, boolean aggregator )
+    {
+        if ( aggregator )
+        {
+            return session.getProjects();
+        }
+        else
+        {
+            return Collections.singletonList( project );
+        }
+    }
+
+    public void checkForUpdate( MavenSession session, DependencyContext dependenctContext )
+        throws LifecycleExecutionException
+    {
+
+        if ( dependenctContext.isSameButUpdatedProject( session ) )
+        {
+            resolveProjectDependencies( dependenctContext.getLastProject(), dependenctContext.getScopesToCollect(),
+                                        dependenctContext.getScopesToResolve(), session,
+                                        dependenctContext.isAggregating() );
+        }
+
+        dependenctContext.setLastProject( session.getCurrentProject() );
+        dependenctContext.setLastDependencyArtifacts( session.getCurrentProject().getDependencyArtifacts() );
+    }
+
+    private void resolveDependencies( boolean aggregating, MavenSession session, MavenExecutionPlan executionPlan,
+                                      List<MavenProject> projectsToResolve )
+        throws LifecycleExecutionException
+    {
+        for ( MavenProject project : projectsToResolve )
+        {
+            resolveDependencies( project, aggregating, session, executionPlan );
+        }
+    }
+
+    private void resolveDependencies( MavenProject project, boolean aggregating, MavenSession session,
+                                      MavenExecutionPlan executionPlan )
+        throws LifecycleExecutionException
+    {
+        resolveProjectDependencies( project, executionPlan.getRequiredCollectionScopes(),
+                                    executionPlan.getRequiredResolutionScopes(), session, aggregating );
+    }
+
+    private void resolveProjectDependencies( MavenProject project, Collection<String> scopesToCollect,
+                                             Collection<String> scopesToResolve, MavenSession session,
+                                             boolean aggregating )
+        throws LifecycleExecutionException
+    {
+        Set<Artifact> artifacts =
+            getProjectDependencies( project, scopesToCollect, scopesToResolve, session, aggregating );
+        updateProjectArtifacts( project, artifacts );
+    }
+
+    private void updateProjectArtifacts( MavenProject project, Set<Artifact> artifacts )
+    {
+        project.setResolvedArtifacts( artifacts );
+
+        if ( project.getDependencyArtifacts() == null )
+        {
+            project.setDependencyArtifacts( getDependencyArtifacts( project, artifacts ) );
+        }
+    }
+
+    private Set<Artifact> getProjectDependencies( MavenProject project, Collection<String> scopesToCollect,
+                                                  Collection<String> scopesToResolve, MavenSession session,
+                                                  boolean aggregating )
+        throws LifecycleExecutionException
+    {
+        Set<Artifact> artifacts;
+        try
+        {
+            try
+            {
+                artifacts = projectDependenciesResolver.resolve( project, scopesToCollect, scopesToResolve, session );
+            }
+            catch ( MultipleArtifactsNotFoundException e )
+            {
+                /*
+                * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator
+                * plugins that require dependency resolution although they usually run in phases of the build where project
+                * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare".
+                */
+                if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) )
+                {
+                    logger.warn( "The following artifacts could not be resolved at this point of the build" +
+                        " but seem to be part of the reactor:" );
+
+                    for ( Artifact artifact : e.getMissingArtifacts() )
+                    {
+                        logger.warn( "o " + artifact.getId() );
+                    }
+
+                    logger.warn( "Try running the build up to the lifecycle phase \"package\"" );
+
+                    artifacts = new LinkedHashSet<Artifact>( e.getResolvedArtifacts() );
+                }
+                else
+                {
+                    throw e;
+                }
+            }
+
+            return artifacts;
+        }
+        catch ( ArtifactResolutionException e )
+        {
+            throw new LifecycleExecutionException( null, project, e );
+        }
+        catch ( ArtifactNotFoundException e )
+        {
+            throw new LifecycleExecutionException( null, project, e );
+        }
+
+    }
+
+
+    private Set<Artifact> getDependencyArtifacts( MavenProject project, Set<Artifact> artifacts )
+    {
+        Set<String> directDependencies = new HashSet<String>( project.getDependencies().size() * 2 );
+        for ( Dependency dependency : project.getDependencies() )
+        {
+            directDependencies.add( dependency.getManagementKey() );
+        }
+
+        Set<Artifact> dependencyArtifacts = new LinkedHashSet<Artifact>( project.getDependencies().size() * 2 );
+        for ( Artifact artifact : artifacts )
+        {
+            if ( directDependencies.contains( artifact.getDependencyConflictId() ) )
+            {
+                dependencyArtifacts.add( artifact );
+            }
+        }
+        return dependencyArtifacts;
+    }
+
+    private boolean areAllArtifactsInReactor( Collection<MavenProject> projects, Collection<Artifact> artifacts )
+    {
+        Set<String> projectKeys = getReactorProjectKeys( projects );
+
+        for ( Artifact artifact : artifacts )
+        {
+            String key = ArtifactUtils.key( artifact );
+            if ( !projectKeys.contains( key ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private Set<String> getReactorProjectKeys( Collection<MavenProject> projects )
+    {
+        Set<String> projectKeys = new HashSet<String>( projects.size() * 2 );
+        for ( MavenProject project : projects )
+        {
+            String key = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+            projectKeys.add( key );
+        }
+        return projectKeys;
+    }
+
+
+    public void reResolveReactorArtifacts( ProjectBuildList projectBuilds, boolean aggregating, MavenProject project,
+                                           MavenSession session, MavenExecutionPlan executionPlan )
+        throws LifecycleExecutionException
+    {
+        final Set<String> reactorProjectKeys = projectBuilds.getReactorProjectKeys();
+        final Set<Artifact> artifactSet = project.getArtifacts();
+        for ( Artifact artifact : artifactSet )
+        {
+            String key = ArtifactUtils.key( artifact );
+            if ( reactorProjectKeys.contains( key ) )
+            {
+                artifact.setResolved( false );
+            }
+
+        }
+        resolveDependencies( aggregating, project, session, executionPlan );
+    }
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package org.apache.maven.lifecycle.internal;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+/**
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold  (extract interface only)
+ *         <p/>
+ *         NOTE: interface is not part of any public api and can be changed or deleted without prior notice.
+ */
+public interface LifecycleExecutionPlanCalculator
+{
+    MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
+        throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+        NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+}

Propchange: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java
------------------------------------------------------------------------------
    svn:eol-style = native