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 [4/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/internal/LifecycleExecutionPlanCalculatorImpl.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorImpl.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorImpl.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorImpl.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,673 @@
+/*
+ * 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.artifact.repository.DefaultRepositoryRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.*;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.lifecycle.Execution;
+import org.apache.maven.plugin.lifecycle.Phase;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+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 org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (Extract class)
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecycleExecutionPlanCalculator.class)
+public class LifecycleExecutionPlanCalculatorImpl
+    implements LifecycleExecutionPlanCalculator
+{
+    @Requirement
+    private PluginVersionResolver pluginVersionResolver;
+
+    @Requirement
+    private BuildPluginManager pluginManager;
+
+    @Requirement
+    private DefaultLifecycles defaultLifeCycles;
+
+    @Requirement
+    private MojoDescriptorCreator mojoDescriptorCreator;
+
+    @Requirement
+    private LifecyclePluginResolver lifecyclePluginResolver;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecycleExecutionPlanCalculatorImpl()
+    {
+    }
+
+    public LifecycleExecutionPlanCalculatorImpl( BuildPluginManager pluginManager, DefaultLifecycles defaultLifeCycles,
+                                                 MojoDescriptorCreator mojoDescriptorCreator,
+                                                 LifecyclePluginResolver lifecyclePluginResolver )
+    {
+        this.pluginManager = pluginManager;
+        this.defaultLifeCycles = defaultLifeCycles;
+        this.mojoDescriptorCreator = mojoDescriptorCreator;
+        this.lifecyclePluginResolver = lifecyclePluginResolver;
+    }
+
+    public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
+        throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+        NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        Set<String> requiredDependencyResolutionScopes = new TreeSet<String>();
+        Set<String> requiredDependencyCollectionScopes = new TreeSet<String>();
+
+        final List<MojoExecution> executions =
+            calculateExecutionPlan( session, project, tasks, requiredDependencyResolutionScopes,
+                                    requiredDependencyCollectionScopes );
+        final List<ExecutionPlanItem> planItem = defaultLifeCycles.createExecutionPlanItem( project, executions );
+
+        return new MavenExecutionPlan( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
+                                       planItem );
+
+
+    }
+
+    public List<MojoExecution> calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks,
+                                                       Set<String> requiredDependencyResolutionScopes,
+                                                       Set<String> requiredDependencyCollectionScopes )
+        throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+        NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        lifecyclePluginResolver.resolveMissingPluginVersions( project, session );
+
+        List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+        for ( Object task : tasks )
+        {
+            if ( task instanceof GoalTask )
+            {
+                String pluginGoal = ( (GoalTask) task ).pluginGoal;
+
+                MojoDescriptor mojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( pluginGoal, session, project );
+
+                MojoExecution mojoExecution =
+                    new MojoExecution( mojoDescriptor, "default-cli", MojoExecution.Source.CLI );
+
+                mojoExecutions.add( mojoExecution );
+            }
+            else if ( task instanceof LifecycleTask )
+            {
+                String lifecyclePhase = ( (LifecycleTask) task ).getLifecyclePhase();
+
+                Map<String, List<MojoExecution>> phaseToMojoMapping =
+                    calculateLifecycleMappings( session, project, lifecyclePhase );
+
+                for ( List<MojoExecution> mojoExecutionsFromLifecycle : phaseToMojoMapping.values() )
+                {
+                    mojoExecutions.addAll( mojoExecutionsFromLifecycle );
+                }
+            }
+            else
+            {
+                throw new IllegalStateException( "unexpected task " + task );
+            }
+        }
+
+        for ( MojoExecution mojoExecution : mojoExecutions )
+        {
+            MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+            if ( mojoDescriptor == null )
+            {
+                mojoDescriptor = pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(),
+                                                                  DefaultRepositoryRequest.getRepositoryRequest(
+                                                                      session, project ) );
+
+                mojoExecution.setMojoDescriptor( mojoDescriptor );
+            }
+
+            populateMojoExecutionConfiguration( project, mojoExecution,
+                                                MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) );
+
+            finalizeMojoConfiguration( mojoExecution );
+
+            calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() );
+
+            collectDependencyRequirements( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
+                                           mojoExecution );
+        }
+
+        return mojoExecutions;
+    }
+
+    private static void collectDependencyRequirements( Collection<String> requiredDependencyResolutionScopes,
+                                                       Collection<String> requiredDependencyCollectionScopes,
+                                                       MojoExecution mojoExecution )
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        String requiredDependencyResolutionScope = mojoDescriptor.getDependencyResolutionRequired();
+
+        if ( StringUtils.isNotEmpty( requiredDependencyResolutionScope ) )
+        {
+            requiredDependencyResolutionScopes.add( requiredDependencyResolutionScope );
+        }
+
+        String requiredDependencyCollectionScope = mojoDescriptor.getDependencyCollectionRequired();
+
+        if ( StringUtils.isNotEmpty( requiredDependencyCollectionScope ) )
+        {
+            requiredDependencyCollectionScopes.add( requiredDependencyCollectionScope );
+        }
+
+        for ( List<MojoExecution> forkedExecutions : mojoExecution.getForkedExecutions().values() )
+        {
+            for ( MojoExecution forkedExecution : forkedExecutions )
+            {
+                collectDependencyRequirements( requiredDependencyResolutionScopes, requiredDependencyCollectionScopes,
+                                               forkedExecution );
+            }
+        }
+    }
+
+
+    private Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+                                                                         String lifecyclePhase )
+        throws LifecyclePhaseNotFoundException, PluginNotFoundException, PluginResolutionException,
+        PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException
+    {
+        /*
+         * Determine the lifecycle that corresponds to the given phase.
+         */
+
+        Lifecycle lifecycle = defaultLifeCycles.get( lifecyclePhase );
+
+        if ( lifecycle == null )
+        {
+            throw new LifecyclePhaseNotFoundException(
+                "Unknown lifecycle phase \"" + lifecyclePhase + "\". You must specify a valid lifecycle phase" +
+                    " or a goal in the format <plugin-prefix>:<goal> or" +
+                    " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: " +
+                    defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase );
+        }
+
+        /*
+         * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller
+         * is interested in, i.e. all phases up to and including the specified phase.
+         */
+
+        Map<String, Map<Integer, List<MojoExecution>>> mappings =
+            new LinkedHashMap<String, Map<Integer, List<MojoExecution>>>();
+
+        for ( String phase : lifecycle.getPhases() )
+        {
+            Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<Integer, List<MojoExecution>>();
+
+            mappings.put( phase, phaseBindings );
+
+            if ( phase.equals( lifecyclePhase ) )
+            {
+                break;
+            }
+        }
+
+        /*
+         * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of
+         * the project already contains the plugin executions induced by the project's packaging type. Remember, all
+         * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not
+         * interested in any of the executions bound to it.
+         */
+
+        for ( Plugin plugin : project.getBuild().getPlugins() )
+        {
+            for ( PluginExecution execution : plugin.getExecutions() )
+            {
+                // if the phase is specified then I don't have to go fetch the plugin yet and pull it down
+                // to examine the phase it is associated to.
+                if ( execution.getPhase() != null )
+                {
+                    Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() );
+                    if ( phaseBindings != null )
+                    {
+                        for ( String goal : execution.getGoals() )
+                        {
+                            MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
+                            mojoExecution.setLifecyclePhase( execution.getPhase() );
+                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+                        }
+                    }
+                }
+                // if not then i need to grab the mojo descriptor and look at the phase that is specified
+                else
+                {
+                    for ( String goal : execution.getGoals() )
+                    {
+                        MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal,
+                                                                                         DefaultRepositoryRequest.getRepositoryRequest(
+                                                                                             session, project ) );
+
+                        Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() );
+                        if ( phaseBindings != null )
+                        {
+                            MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
+                            mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() );
+                            addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+                        }
+                    }
+                }
+            }
+        }
+
+        Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>();
+
+        for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() )
+        {
+            List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+            for ( List<MojoExecution> executions : entry.getValue().values() )
+            {
+                mojoExecutions.addAll( executions );
+            }
+
+            lifecycleMappings.put( entry.getKey(), mojoExecutions );
+        }
+
+        return lifecycleMappings;
+    }
+
+    private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution,
+                                   int priority )
+    {
+        List<MojoExecution> mojoExecutions = phaseBindings.get( priority );
+
+        if ( mojoExecutions == null )
+        {
+            mojoExecutions = new ArrayList<MojoExecution>();
+            phaseBindings.put( priority, mojoExecutions );
+        }
+
+        mojoExecutions.add( mojoExecution );
+    }
+
+    private void populateMojoExecutionConfiguration( MavenProject project, MojoExecution mojoExecution,
+                                                     boolean allowPluginLevelConfig )
+    {
+        String g = mojoExecution.getGroupId();
+
+        String a = mojoExecution.getArtifactId();
+
+        Plugin plugin = findPlugin( g, a, project.getBuildPlugins() );
+
+        if ( plugin == null && project.getPluginManagement() != null )
+        {
+            plugin = findPlugin( g, a, project.getPluginManagement().getPlugins() );
+        }
+
+        if ( plugin != null )
+        {
+            PluginExecution pluginExecution =
+                findPluginExecution( mojoExecution.getExecutionId(), plugin.getExecutions() );
+
+            Xpp3Dom pomConfiguration = null;
+
+            if ( pluginExecution != null )
+            {
+                pomConfiguration = (Xpp3Dom) pluginExecution.getConfiguration();
+            }
+            else if ( allowPluginLevelConfig )
+            {
+                pomConfiguration = (Xpp3Dom) plugin.getConfiguration();
+            }
+
+            Xpp3Dom mojoConfiguration = ( pomConfiguration != null ) ? new Xpp3Dom( pomConfiguration ) : null;
+
+            mojoConfiguration = Xpp3Dom.mergeXpp3Dom( mojoExecution.getConfiguration(), mojoConfiguration );
+
+            mojoExecution.setConfiguration( mojoConfiguration );
+        }
+    }
+
+    private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins )
+    {
+        for ( Plugin plugin : plugins )
+        {
+            if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) )
+            {
+                return plugin;
+            }
+        }
+
+        return null;
+    }
+
+    private PluginExecution findPluginExecution( String executionId, Collection<PluginExecution> executions )
+    {
+        if ( StringUtils.isNotEmpty( executionId ) )
+        {
+            for ( PluginExecution execution : executions )
+            {
+                if ( executionId.equals( execution.getId() ) )
+                {
+                    return execution;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Post-processes the effective configuration for the specified mojo execution. This step discards all parameters
+     * from the configuration that are not applicable to the mojo and injects the default values for any missing
+     * parameters.
+     *
+     * @param mojoExecution The mojo execution whose configuration should be finalized, must not be {@code null}.
+     */
+    private void finalizeMojoConfiguration( MojoExecution mojoExecution )
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        Xpp3Dom executionConfiguration = mojoExecution.getConfiguration();
+        if ( executionConfiguration == null )
+        {
+            executionConfiguration = new Xpp3Dom( "configuration" );
+        }
+
+        Xpp3Dom defaultConfiguration = getMojoConfiguration( mojoDescriptor );
+
+        Xpp3Dom finalConfiguration = new Xpp3Dom( "configuration" );
+
+        if ( mojoDescriptor.getParameters() != null )
+        {
+            for ( Parameter parameter : mojoDescriptor.getParameters() )
+            {
+                Xpp3Dom parameterConfiguration = executionConfiguration.getChild( parameter.getName() );
+
+                if ( parameterConfiguration == null )
+                {
+                    parameterConfiguration = executionConfiguration.getChild( parameter.getAlias() );
+                }
+
+                Xpp3Dom parameterDefaults = defaultConfiguration.getChild( parameter.getName() );
+
+                parameterConfiguration =
+                    Xpp3Dom.mergeXpp3Dom( parameterConfiguration, parameterDefaults, Boolean.TRUE );
+
+                if ( parameterConfiguration != null )
+                {
+                    parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() );
+
+                    if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) ) &&
+                        StringUtils.isNotEmpty( parameter.getImplementation() ) )
+                    {
+                        parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() );
+                    }
+
+                    finalConfiguration.addChild( parameterConfiguration );
+                }
+            }
+        }
+
+        mojoExecution.setConfiguration( finalConfiguration );
+    }
+
+    private Xpp3Dom getMojoConfiguration( MojoDescriptor mojoDescriptor )
+    {
+        return MojoDescriptorCreator.convert( mojoDescriptor );
+    }
+
+    private void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session, MavenProject project,
+                                            Collection<MojoDescriptor> alreadyForkedExecutions )
+        throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+        PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        if ( !mojoDescriptor.isForking() )
+        {
+            return;
+        }
+
+        if ( !alreadyForkedExecutions.add( mojoDescriptor ) )
+        {
+            return;
+        }
+
+        List<MavenProject> forkedProjects =
+            LifecycleDependencyResolver.getProjects( project, session, mojoDescriptor.isAggregator() );
+
+        for ( MavenProject forkedProject : forkedProjects )
+        {
+            List<MojoExecution> forkedExecutions;
+
+            if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) )
+            {
+                forkedExecutions =
+                    calculateForkedLifecycle( mojoExecution, session, forkedProject, alreadyForkedExecutions );
+            }
+            else
+            {
+                forkedExecutions =
+                    calculateForkedGoal( mojoExecution, session, forkedProject, alreadyForkedExecutions );
+            }
+
+            mojoExecution.setForkedExecutions( BuilderCommon.getKey( forkedProject ), forkedExecutions );
+        }
+
+        alreadyForkedExecutions.remove( mojoDescriptor );
+    }
+
+    private List<MojoExecution> calculateForkedLifecycle( MojoExecution mojoExecution, MavenSession session,
+                                                          MavenProject project,
+                                                          Collection<MojoDescriptor> alreadyForkedExecutions )
+        throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+        PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        String forkedPhase = mojoDescriptor.getExecutePhase();
+
+        Map<String, List<MojoExecution>> lifecycleMappings =
+            calculateLifecycleMappings( session, project, forkedPhase );
+
+        for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
+        {
+            for ( MojoExecution forkedExecution : forkedExecutions )
+            {
+                if ( forkedExecution.getMojoDescriptor() == null )
+                {
+                    MojoDescriptor forkedMojoDescriptor =
+                        pluginManager.getMojoDescriptor( forkedExecution.getPlugin(), forkedExecution.getGoal(),
+                                                         DefaultRepositoryRequest.getRepositoryRequest( session,
+                                                                                                        project ) );
+
+                    forkedExecution.setMojoDescriptor( forkedMojoDescriptor );
+                }
+
+                populateMojoExecutionConfiguration( project, forkedExecution, false );
+            }
+        }
+
+        injectLifecycleOverlay( lifecycleMappings, mojoExecution, session, project );
+
+        List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+        for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
+        {
+            for ( MojoExecution forkedExecution : forkedExecutions )
+            {
+                if ( !alreadyForkedExecutions.contains( forkedExecution.getMojoDescriptor() ) )
+                {
+                    finalizeMojoConfiguration( forkedExecution );
+
+                    calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
+
+                    mojoExecutions.add( forkedExecution );
+                }
+            }
+        }
+
+        return mojoExecutions;
+    }
+
+    private void injectLifecycleOverlay( Map<String, List<MojoExecution>> lifecycleMappings,
+                                         MojoExecution mojoExecution, MavenSession session, MavenProject project )
+        throws PluginDescriptorParsingException, LifecycleNotFoundException, MojoNotFoundException,
+        PluginNotFoundException, PluginResolutionException, NoPluginFoundForPrefixException,
+        InvalidPluginDescriptorException, PluginVersionResolutionException
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+        String forkedLifecycle = mojoDescriptor.getExecuteLifecycle();
+
+        if ( StringUtils.isEmpty( forkedLifecycle ) )
+        {
+            return;
+        }
+
+        org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
+
+        try
+        {
+            lifecycleOverlay = pluginDescriptor.getLifecycleMapping( forkedLifecycle );
+        }
+        catch ( IOException e )
+        {
+            throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e );
+        }
+
+        if ( lifecycleOverlay == null )
+        {
+            throw new LifecycleNotFoundException( forkedLifecycle );
+        }
+
+        for ( Phase phase : lifecycleOverlay.getPhases() )
+        {
+            List<MojoExecution> forkedExecutions = lifecycleMappings.get( phase.getId() );
+
+            if ( forkedExecutions != null )
+            {
+                for ( Execution execution : phase.getExecutions() )
+                {
+                    for ( String goal : execution.getGoals() )
+                    {
+                        MojoDescriptor forkedMojoDescriptor;
+
+                        if ( goal.indexOf( ':' ) < 0 )
+                        {
+                            forkedMojoDescriptor = pluginDescriptor.getMojo( goal );
+                            if ( forkedMojoDescriptor == null )
+                            {
+                                throw new MojoNotFoundException( goal, pluginDescriptor );
+                            }
+                        }
+                        else
+                        {
+                            forkedMojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( goal, session, project );
+                        }
+
+                        MojoExecution forkedExecution =
+                            new MojoExecution( forkedMojoDescriptor, mojoExecution.getExecutionId() );
+
+                        Xpp3Dom forkedConfiguration = (Xpp3Dom) execution.getConfiguration();
+
+                        forkedExecution.setConfiguration( forkedConfiguration );
+
+                        populateMojoExecutionConfiguration( project, forkedExecution, true );
+
+                        forkedExecutions.add( forkedExecution );
+                    }
+                }
+
+                Xpp3Dom phaseConfiguration = (Xpp3Dom) phase.getConfiguration();
+
+                if ( phaseConfiguration != null )
+                {
+                    for ( MojoExecution forkedExecution : forkedExecutions )
+                    {
+                        Xpp3Dom forkedConfiguration = forkedExecution.getConfiguration();
+
+                        forkedConfiguration = Xpp3Dom.mergeXpp3Dom( phaseConfiguration, forkedConfiguration );
+
+                        forkedExecution.setConfiguration( forkedConfiguration );
+                    }
+                }
+            }
+        }
+    }
+    // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
+    //TODO: take repo mans into account as one may be aggregating prefixes of many
+    //TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing
+    //      or the user forces the issue
+
+    private List<MojoExecution> calculateForkedGoal( MojoExecution mojoExecution, MavenSession session,
+                                                     MavenProject project,
+                                                     Collection<MojoDescriptor> alreadyForkedExecutions )
+        throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+        PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+    {
+        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+        PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+        String forkedGoal = mojoDescriptor.getExecuteGoal();
+
+        MojoDescriptor forkedMojoDescriptor = pluginDescriptor.getMojo( forkedGoal );
+        if ( forkedMojoDescriptor == null )
+        {
+            throw new MojoNotFoundException( forkedGoal, pluginDescriptor );
+        }
+
+        if ( alreadyForkedExecutions.contains( forkedMojoDescriptor ) )
+        {
+            return Collections.emptyList();
+        }
+
+        MojoExecution forkedExecution = new MojoExecution( forkedMojoDescriptor, forkedGoal );
+
+        populateMojoExecutionConfiguration( project, forkedExecution, true );
+
+        finalizeMojoConfiguration( forkedExecution );
+
+        calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
+
+        return Collections.singletonList( forkedExecution );
+    }
+
+
+}

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,96 @@
+/*
+ * 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.BuildSuccess;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.DefaultLifecycleExecutor;
+import org.apache.maven.lifecycle.LifecycleEventCatapult;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Builds one or more lifecycles for a full module
+ *
+ * @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 = LifecycleModuleBuilder.class)
+public class LifecycleModuleBuilder
+{
+    @Requirement
+    private MojoExecutor mojoExecutor;
+
+    @Requirement
+    private BuilderCommon builderCommon;
+
+    public void buildProject( MavenSession session, ReactorContext reactorContext, MavenProject currentProject,
+                              TaskSegment taskSegment )
+    {
+        buildProject( session, session, reactorContext, currentProject, taskSegment );
+    }
+
+    public void buildProject( MavenSession session, MavenSession rootSession, ReactorContext reactorContext,
+                              MavenProject currentProject, TaskSegment taskSegment )
+    {
+        boolean isAggregating = taskSegment.isAggregating();
+
+        session.setCurrentProject( currentProject );
+
+        long buildStartTime = System.currentTimeMillis();
+
+        try
+        {
+
+            if ( reactorContext.getReactorBuildStatus().isHaltedOrBlacklisted( currentProject ) )
+            {
+                DefaultLifecycleExecutor.fireEvent( session, null, LifecycleEventCatapult.PROJECT_SKIPPED );
+                return;
+            }
+
+            DefaultLifecycleExecutor.fireEvent( session, null, LifecycleEventCatapult.PROJECT_STARTED );
+
+            BuilderCommon.attachToThread( currentProject );
+            MavenExecutionPlan executionPlan = builderCommon.resolveBuildPlan( session, currentProject, taskSegment );
+
+            DependencyContext dependencyContext = new DependencyContext( executionPlan, isAggregating );
+            mojoExecutor.execute( session, executionPlan.getMojoExecutions(), reactorContext.getProjectIndex(),
+                                  dependencyContext );
+
+            long buildEndTime = System.currentTimeMillis();
+
+            reactorContext.getResult().addBuildSummary(
+                new BuildSuccess( currentProject, buildEndTime - buildStartTime ) );
+
+            DefaultLifecycleExecutor.fireEvent( session, null, LifecycleEventCatapult.PROJECT_SUCCEEDED );
+        }
+        catch ( Exception e )
+        {
+            BuilderCommon.handleBuildError( reactorContext, rootSession, currentProject, e, buildStartTime );
+        }
+        finally
+        {
+            session.setCurrentProject( null );
+
+            Thread.currentThread().setContextClassLoader( reactorContext.getOriginalContextClassLoader() );
+        }
+    }
+}
\ No newline at end of file

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginAnalyzerImpl.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginAnalyzerImpl.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginAnalyzerImpl.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginAnalyzerImpl.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,161 @@
+/*
+ * 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.DefaultLifecycles;
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.mapping.LifecycleMapping;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+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.StringUtils;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @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 = LifecyclePluginAnalyzerImpl.class)
+public class LifecyclePluginAnalyzerImpl
+    implements LifeCyclePluginAnalyzer
+{
+    @Requirement
+    private Map<String, LifecycleMapping> lifecycleMappings;
+
+    @Requirement
+    private DefaultLifecycles defaultLifeCycles;
+
+    @Requirement
+    private Logger logger;
+
+
+    public LifecyclePluginAnalyzerImpl()
+    {
+    }
+
+    // These methods deal with construction intact Plugin object that look like they come from a standard
+    // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
+    // together and this really shows the problem of constructing a sensible default configuration but
+    // it's all encapsulated here so it appears normalized to the POM builder.
+
+    // We are going to take the project packaging and find all plugin in the default lifecycle and create
+    // fully populated Plugin objects, including executions with goals and default configuration taken
+    // from the plugin.xml inside a plugin.
+    //
+
+    public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+    {
+        if ( logger.isDebugEnabled() )
+        {
+            logger.debug( "Looking up lifecyle mappings for packaging " + packaging + " from " +
+                Thread.currentThread().getContextClassLoader() );
+        }
+
+        LifecycleMapping lifecycleMappingForPackaging = lifecycleMappings.get( packaging );
+
+        if ( lifecycleMappingForPackaging == null )
+        {
+            return null;
+        }
+
+        Map<Plugin, Plugin> plugins = new LinkedHashMap<Plugin, Plugin>();
+
+        for ( Lifecycle lifecycle : defaultLifeCycles.getLifeCycles() )
+        {
+            org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
+                lifecycleMappingForPackaging.getLifecycles().get( lifecycle.getId() );
+
+            Map<String, String> phaseToGoalMapping = null;
+
+            if ( lifecycleConfiguration != null )
+            {
+                phaseToGoalMapping = lifecycleConfiguration.getPhases();
+            }
+            else if ( lifecycle.getDefaultPhases() != null )
+            {
+                phaseToGoalMapping = lifecycle.getDefaultPhases();
+            }
+
+            if ( phaseToGoalMapping != null )
+            {
+                // These are of the form:
+                //
+                // compile -> org.apache.maven.plugins:maven-compiler-plugin:compile[,gid:aid:goal,...]
+                //
+                for ( Map.Entry<String, String> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() )
+                {
+                    String phase = goalsForLifecyclePhase.getKey();
+                    String goals = goalsForLifecyclePhase.getValue();
+                    if ( goals != null )
+                    {
+                        parseLifecyclePhaseDefinitions( plugins, phase, goals );
+                    }
+                }
+            }
+        }
+
+        return plugins.keySet();
+    }
+
+    private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, String goals )
+    {
+        String[] mojos = StringUtils.split( goals, "," );
+
+        for ( int i = 0; i < mojos.length; i++ )
+        {
+            // either <groupId>:<artifactId>:<goal> or <groupId>:<artifactId>:<version>:<goal>
+            String goal = mojos[i].trim();
+            String[] p = StringUtils.split( goal, ":" );
+
+            PluginExecution execution = new PluginExecution();
+            execution.setId( "default-" + p[p.length - 1] );
+            execution.setPhase( phase );
+            execution.setPriority( i - mojos.length );
+            execution.getGoals().add( p[p.length - 1] );
+
+            Plugin plugin = new Plugin();
+            plugin.setGroupId( p[0] );
+            plugin.setArtifactId( p[1] );
+            if ( p.length >= 4 )
+            {
+                plugin.setVersion( p[2] );
+            }
+
+            Plugin existing = plugins.get( plugin );
+            if ( existing != null )
+            {
+                plugin = existing;
+            }
+            else
+            {
+                plugins.put( plugin, plugin );
+            }
+
+            plugin.getExecutions().add( execution );
+        }
+    }
+
+
+}

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,86 @@
+/*
+ * 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.model.Plugin;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (Extract class)
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecyclePluginResolver.class)
+public class LifecyclePluginResolver
+{
+    @Requirement
+    private PluginVersionResolver pluginVersionResolver;
+
+
+    public LifecyclePluginResolver( PluginVersionResolver pluginVersionResolver )
+    {
+        this.pluginVersionResolver = pluginVersionResolver;
+    }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecyclePluginResolver()
+    {
+    }
+
+    public void resolveMissingPluginVersions( MavenProject project, MavenSession session )
+        throws PluginVersionResolutionException
+    {
+        Map<String, String> versions = new HashMap<String, String>();
+
+        for ( Plugin plugin : project.getBuildPlugins() )
+        {
+            if ( plugin.getVersion() == null )
+            {
+                PluginVersionRequest request = new DefaultPluginVersionRequest( plugin, session );
+                plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() );
+            }
+            versions.put( plugin.getKey(), plugin.getVersion() );
+        }
+
+        PluginManagement pluginManagement = project.getPluginManagement();
+        if ( pluginManagement != null )
+        {
+            for ( Plugin plugin : pluginManagement.getPlugins() )
+            {
+                if ( plugin.getVersion() == null )
+                {
+                    plugin.setVersion( versions.get( plugin.getKey() ) );
+                    if ( plugin.getVersion() == null )
+                    {
+                        PluginVersionRequest request = new DefaultPluginVersionRequest( plugin, session );
+                        plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() );
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,45 @@
+/*
+ * 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 lifecycle
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public final class LifecycleTask
+{
+
+    private final String lifecyclePhase;
+
+    public LifecycleTask( String lifecyclePhase )
+    {
+        this.lifecyclePhase = lifecyclePhase;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getLifecyclePhase();
+    }
+
+    public String getLifecyclePhase()
+    {
+        return lifecyclePhase;
+    }
+}

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,44 @@
+/*
+ * 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.plugin.*;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+import java.util.List;
+
+/**
+ * Calculates the task segments in the build
+ *
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @author Kristian Rosenvold (extracted interface)
+ *         <p/>
+ *         NOTE: This interface is not part of any public api and can be changed or deleted without prior notice.
+ */
+
+public interface LifecycleTaskSegmentCalculator
+{
+    List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks )
+        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+        MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        PluginVersionResolutionException;
+
+    public boolean requiresProject( MavenSession session );
+
+}

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImpl.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImpl.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImpl.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImpl.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,122 @@
+/*
+ * 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.plugin.*;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Calculates the task segments in the build
+ *
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @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 = LifecycleTaskSegmentCalculator.class)
+public class LifecycleTaskSegmentCalculatorImpl
+    implements LifecycleTaskSegmentCalculator
+{
+    @Requirement
+    private MojoDescriptorCreator mojoDescriptorCreator;
+
+    @Requirement
+    private LifecyclePluginResolver lifecyclePluginResolver;
+
+    public LifecycleTaskSegmentCalculatorImpl()
+    {
+    }
+
+    public List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks )
+        throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+        MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+        PluginVersionResolutionException
+    {
+        List<TaskSegment> taskSegments = new ArrayList<TaskSegment>( tasks.size() );
+
+        TaskSegment currentSegment = null;
+
+        for ( String task : tasks )
+        {
+            if ( isGoalSpecification( task ) )
+            {
+                // "pluginPrefix:goal" or "groupId:artifactId[:version]:goal"
+
+                lifecyclePluginResolver.resolveMissingPluginVersions( session.getTopLevelProject(), session );
+
+                MojoDescriptor mojoDescriptor =
+                    mojoDescriptorCreator.getMojoDescriptor( task, session, session.getTopLevelProject() );
+
+                boolean aggregating = mojoDescriptor.isAggregator() || !mojoDescriptor.isProjectRequired();
+
+                if ( currentSegment == null || currentSegment.isAggregating() != aggregating )
+                {
+                    currentSegment = new TaskSegment( aggregating );
+                    taskSegments.add( currentSegment );
+                }
+
+                currentSegment.getTasks().add( new GoalTask( task ) );
+            }
+            else
+            {
+                // lifecycle phase
+
+                if ( currentSegment == null || currentSegment.isAggregating() )
+                {
+                    currentSegment = new TaskSegment( false );
+                    taskSegments.add( currentSegment );
+                }
+
+                currentSegment.getTasks().add( new LifecycleTask( task ) );
+            }
+        }
+
+        return taskSegments;
+    }
+
+    public boolean requiresProject( MavenSession session )
+    {
+        List<String> goals = session.getGoals();
+        if ( goals != null )
+        {
+            for ( String goal : goals )
+            {
+                if ( !isGoalSpecification( goal ) )
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    private boolean isGoalSpecification( String task )
+    {
+        return task.indexOf( ':' ) >= 0;
+    }
+
+}
\ No newline at end of file

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleThreadedBuilder.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleThreadedBuilder.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleThreadedBuilder.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleThreadedBuilder.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.internal;
+
+import org.apache.maven.execution.MavenSession;
+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.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * Builds the full lifecycle in weave-mode (phase by phase as opposed to project-by-project)
+ *
+ * @author Kristian Rosenvold
+ *         Builds one or more lifecycles for a full module
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecycleThreadedBuilder.class)
+public class LifecycleThreadedBuilder
+{
+
+
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    private LifecycleModuleBuilder lifecycleModuleBuilder;
+
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecycleThreadedBuilder()
+    {
+    }
+
+    public void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
+                       List<TaskSegment> currentTaskSegment, ConcurrencyDependencyGraph analyzer,
+                       CompletionService<ProjectSegment> service )
+    {
+
+        // Currently disabled
+        ThreadOutputMuxer muxer = null; // new ThreadOutputMuxer( analyzer.getProjectBuilds(), System.out );
+
+        for ( TaskSegment taskSegment : currentTaskSegment )
+        {
+            Map<MavenProject, ProjectSegment> projectBuildMap = projectBuilds.selectSegment( taskSegment );
+                try
+                {
+                    multiThreadedProjectTaskSegmentBuild( analyzer, reactorContext, session, service, taskSegment, projectBuildMap, muxer );
+                    if ( reactorContext.getReactorBuildStatus().isHalted() )
+                    {
+                        break;
+                    }
+
+                    if ( reactorContext.getReactorBuildStatus().isHalted() )
+                    {
+                        break;
+                    }
+                }
+                catch ( Exception e )
+                {
+                    break;  // Why are we just ignoring this exception? Are exceptions are being used for flow control
+                }
+
+        }
+    }
+
+    private void multiThreadedProjectTaskSegmentBuild( ConcurrencyDependencyGraph analyzer,
+                                                       ReactorContext reactorContext, MavenSession rootSession,
+                                                       CompletionService<ProjectSegment> service,
+                                                       TaskSegment taskSegment, Map<MavenProject, ProjectSegment> projectBuildList,
+                                                       ThreadOutputMuxer muxer )
+    {
+
+        // schedule independent projects
+        for ( MavenProject mavenProject : analyzer.getRootSchedulableBuilds() )
+        {
+            ProjectSegment projectSegment = projectBuildList.get( mavenProject );
+            logger.debug( "Scheduling: " + projectSegment.getProject() );
+            Callable<ProjectSegment> cb =
+                createBuildCallable( rootSession, projectSegment, reactorContext, taskSegment, muxer );
+            service.submit( cb );
+        }
+
+        // for each finished project
+        for ( int i = 0; i < analyzer.getNumberOfBuilds(); i++ )
+        {
+            try
+            {
+                ProjectSegment projectBuild = service.take().get();
+                if ( reactorContext.getReactorBuildStatus().isHalted() )
+                {
+                    break;
+                }
+                final List<MavenProject> newItemsThatCanBeBuilt =
+                    analyzer.markAsFinished( projectBuild.getProject() );
+                for ( MavenProject mavenProject : newItemsThatCanBeBuilt )
+                {
+                    ProjectSegment scheduledDependent = projectBuildList.get( mavenProject );
+                    logger.debug( "Scheduling: " + scheduledDependent );
+                    Callable<ProjectSegment> cb =
+                        createBuildCallable( rootSession, scheduledDependent, reactorContext, taskSegment, muxer );
+                    service.submit( cb );
+                }
+            }
+            catch ( InterruptedException e )
+            {
+                break;
+            }
+            catch ( ExecutionException e )
+            {
+                break;
+            }
+        }
+
+        // cancel outstanding builds (if any)  - this can happen if an exception is thrown in above block
+
+        Future<ProjectSegment> unprocessed;
+        while ( ( unprocessed = service.poll() ) != null )
+        {
+            try
+            {
+                unprocessed.get();
+            }
+            catch ( InterruptedException e )
+            {
+                throw new RuntimeException( e );
+            }
+            catch ( ExecutionException e )
+            {
+                throw new RuntimeException( e );
+            }
+        }
+    }
+
+    private Callable<ProjectSegment> createBuildCallable( final MavenSession rootSession,
+                                                          final ProjectSegment projectBuild,
+                                                          final ReactorContext reactorContext,
+                                                          final TaskSegment taskSegment, final ThreadOutputMuxer muxer )
+    {
+        return new Callable<ProjectSegment>()
+        {
+            public ProjectSegment call()
+            {
+                // muxer.associateThreadWithProjectSegment( projectBuild );
+                lifecycleModuleBuilder.buildProject( projectBuild.getSession(), rootSession, reactorContext,
+                                                     projectBuild.getProject(), taskSegment );
+                // muxer.setThisModuleComplete( projectBuild );
+
+                return projectBuild;
+            }
+        };
+    }
+}
\ No newline at end of file

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

Added: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilder.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilder.java?rev=931884&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilder.java (added)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilder.java Thu Apr  8 11:29:07 2010
@@ -0,0 +1,306 @@
+/*
+ * 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.BuildSuccess;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.*;
+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.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * Builds the full lifecycle in weave-mode (phase by phase as opposed to project-by-project)
+ * <p/>
+ * NOTE: Weave mode is still experimental. It may be either promoted to first class citizen
+ * at some later point in time, and it may also be removed entirely. Weave mode has much more aggressive
+ * concurrency behaviour than regular threaded mode, and as such is still under test wrt cross platform stability.
+ * <p/>
+ * To remove weave mode from m3, the following should be removed:
+ * ExecutionPlanItem.schedule w/setters and getters
+ * DefaultLifeCycles.getScheduling() and all its use
+ * ReactorArtifactRepository has a reference to isWeave too.
+ * This class and its usage
+ *
+ * @author Kristian Rosenvold
+ *         Builds one or more lifecycles for a full module
+ *         <p/>
+ *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component(role = LifecycleWeaveBuilder.class)
+public class LifecycleWeaveBuilder
+{
+    @Requirement
+    private MojoExecutor mojoExecutor;
+
+    @Requirement
+    private BuilderCommon builderCommon;
+
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    private LifecycleDependencyResolver lifecycleDependencyResolver;
+
+
+    private final Map<MavenProject, MavenExecutionPlan> executionPlans =
+        Collections.synchronizedMap( new HashMap<MavenProject, MavenExecutionPlan>() );
+
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public LifecycleWeaveBuilder()
+    {
+    }
+
+    public LifecycleWeaveBuilder( MojoExecutor mojoExecutor, BuilderCommon builderCommon, Logger logger,
+                                  LifecycleDependencyResolver lifecycleDependencyResolver )
+    {
+        this.mojoExecutor = mojoExecutor;
+        this.builderCommon = builderCommon;
+        this.logger = logger;
+        this.lifecycleDependencyResolver = lifecycleDependencyResolver;
+    }
+
+    public void build( ProjectBuildList projectBuilds, ReactorContext buildContext, List<TaskSegment> taskSegments,
+                       MavenSession session, CompletionService<ProjectSegment> service, ReactorBuildStatus reactorBuildStatus )
+        throws ExecutionException, InterruptedException
+    {
+        ConcurrentBuildLogger concurrentBuildLogger = new ConcurrentBuildLogger();
+        try
+        {
+            final List<Future<ProjectSegment>> futures = new ArrayList<Future<ProjectSegment>>();
+
+            for ( TaskSegment taskSegment : taskSegments )
+            {
+                ProjectBuildList segmentChunks = projectBuilds.getByTaskSegment(  taskSegment );
+                ThreadOutputMuxer muxer = null;  // new ThreadOutputMuxer( segmentChunks, System.out );
+                for ( ProjectSegment projectBuild : segmentChunks )
+                {
+                    try
+                    {
+                        MavenExecutionPlan executionPlan =
+                            builderCommon.resolveBuildPlan( projectBuild.getSession(), projectBuild.getProject(),
+                                                            projectBuild.getTaskSegment() );
+                        executionPlans.put( projectBuild.getProject(), executionPlan );
+                        DependencyContext dependencyContext =
+                            new DependencyContext( executionPlan, projectBuild.getTaskSegment().isAggregating() );
+
+                        final Callable<ProjectSegment> projectBuilder =
+                            createCallableForBuildingOneFullModule( buildContext, session, reactorBuildStatus,
+                                                                    executionPlan, projectBuild, muxer,
+                                                                    dependencyContext, concurrentBuildLogger,
+                                                                    projectBuilds );
+
+                        futures.add( service.submit( projectBuilder ) );
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new ExecutionException( e );
+                    }
+                }
+
+                for ( Future<ProjectSegment> buildFuture : futures )
+                {
+                    buildFuture.get();  // At this point, this build *is* finished.
+                    // Do not leak threads past here or evil gremlins will get you!
+                }
+                futures.clear();
+            }
+        }
+        finally
+        {
+            projectBuilds.closeAll();
+        }
+        logger.info( concurrentBuildLogger.toString() );
+    }
+
+    private Callable<ProjectSegment> createCallableForBuildingOneFullModule( final ReactorContext reactorContext,
+                                                                           final MavenSession rootSession,
+                                                                           final ReactorBuildStatus reactorBuildStatus,
+                                                                           final MavenExecutionPlan executionPlan,
+                                                                           final ProjectSegment projectBuild,
+                                                                           final ThreadOutputMuxer muxer,
+                                                                           final DependencyContext dependencyContext,
+                                                                           final ConcurrentBuildLogger concurrentBuildLogger,
+                                                                           final ProjectBuildList projectBuilds )
+    {
+        return new Callable<ProjectSegment>()
+        {
+            public ProjectSegment call()
+                throws Exception
+            {
+                Iterator<ExecutionPlanItem> planItems = executionPlan.iterator();
+                ExecutionPlanItem current = planItems.hasNext() ? planItems.next() : null;
+                long buildStartTime = System.currentTimeMillis();
+
+                //muxer.associateThreadWithProjectSegment( projectBuild );
+
+                if ( reactorBuildStatus.isHaltedOrBlacklisted( projectBuild.getProject() ) )
+                {
+                    DefaultLifecycleExecutor.fireEvent( projectBuild.getSession(), null,
+                                                        LifecycleEventCatapult.PROJECT_SKIPPED );
+                    return null;
+                }
+
+                DefaultLifecycleExecutor.fireEvent( projectBuild.getSession(), null,
+                                                    LifecycleEventCatapult.PROJECT_STARTED );
+
+                boolean packagePhaseSeen = false;
+                boolean runBAbyRun = false;
+                try
+                {
+                    while ( current != null && !reactorBuildStatus.isHalted() &&
+                        !reactorBuildStatus.isBlackListed( projectBuild.getProject() ) )
+                    {
+                        final String phase = current.getMojoExecution().getMojoDescriptor().getPhase();
+                        PhaseRecorder phaseRecorder = new PhaseRecorder( projectBuild.getProject() );
+
+                        if ( !packagePhaseSeen && phase != null && phase.equals( "package" ) )
+                        {
+                            // Re-resolve. A bit of a kludge ATM
+                            packagePhaseSeen = true;
+                            lifecycleDependencyResolver.reResolveReactorArtifacts( projectBuilds, false,
+                                                                                   projectBuild.getProject(),
+                                                                                   projectBuild.getSession(),
+                                                                                   executionPlan );
+
+                        }
+
+                        BuiltLogItem builtLogItem =
+                            concurrentBuildLogger.createBuildLogItem( projectBuild.getProject(), current );
+                        final Schedule schedule = current.getSchedule();
+
+                        if ( schedule != null && schedule.isMojoSynchronized() )
+                        {
+                            synchronized ( current.getPlugin() )
+                            {
+                                buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
+                                                        phaseRecorder );
+                            }
+                        }
+                        else
+                        {
+                            buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext,
+                                                    phaseRecorder );
+                        }
+
+                        current.setComplete();
+                        builtLogItem.setComplete();
+
+                        ExecutionPlanItem next = planItems.hasNext() ? planItems.next() : null;
+                        if ( next != null )
+                        {
+                            final Schedule scheduleOfNext = next.getSchedule();
+                            if ( !runBAbyRun && ( scheduleOfNext == null || !scheduleOfNext.isParallel() ) )
+                            {
+                                for ( MavenProject upstreamProject : projectBuild.getImmediateUpstreamProjects() )
+                                {
+                                    final MavenExecutionPlan upstreamPlan = executionPlans.get( upstreamProject );
+                                    final ExecutionPlanItem inSchedule = upstreamPlan.findLastInPhase( next );
+                                    if ( inSchedule != null )
+                                    {
+                                        long startWait = System.currentTimeMillis();
+                                        inSchedule.waitUntilDone();
+                                        builtLogItem.addWait( upstreamProject, inSchedule, startWait );
+                                    }
+                                }
+                            }
+                        }
+                        current = next;
+
+                        if ( packagePhaseSeen && !runBAbyRun )
+                        {
+                            runBAbyRun = true;
+                        }
+                    }
+
+                    final long wallClockTime = System.currentTimeMillis() - buildStartTime;
+                    final BuildSuccess summary =
+                        new BuildSuccess( projectBuild.getProject(), wallClockTime ); // - waitingTime 
+                    reactorContext.getResult().addBuildSummary( summary );
+                    DefaultLifecycleExecutor.fireEvent( projectBuild.getSession(), null,
+                                                        LifecycleEventCatapult.PROJECT_SUCCEEDED );
+
+                }
+                catch ( Exception e )
+                {
+                    BuilderCommon.handleBuildError( reactorContext, rootSession, projectBuild.getProject(), e,
+                                                    buildStartTime );
+                }
+                finally
+                {
+                    if ( current != null )
+                    {
+                        executionPlan.forceAllComplete();
+                    }
+                    // muxer.setThisModuleComplete( projectBuild );
+                }
+                return null;
+            }
+        };
+    }
+
+    private void buildExecutionPlanItem( ReactorContext reactorContext, ExecutionPlanItem node,
+                                         ProjectSegment projectBuild, DependencyContext dependencyContext,
+                                         PhaseRecorder phaseRecorder )
+        throws LifecycleExecutionException
+    {
+
+        MavenProject currentProject = projectBuild.getProject();
+
+        long buildStartTime = System.currentTimeMillis();
+
+        MavenSession sessionForThisModule = projectBuild.getSession();
+        try
+        {
+
+            if ( reactorContext.getReactorBuildStatus().isHaltedOrBlacklisted( currentProject ) )
+            {
+                return;
+            }
+
+            BuilderCommon.attachToThread( currentProject );
+
+            mojoExecutor.execute( sessionForThisModule, node.getMojoExecution(), reactorContext.getProjectIndex(),
+                                  dependencyContext, phaseRecorder );
+
+            final BuildSuccess summary =
+                new BuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
+            reactorContext.getResult().addBuildSummary( summary );
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader( reactorContext.getOriginalContextClassLoader() );
+        }
+    }
+
+    public static boolean isWeaveMode( MavenExecutionRequest request )
+    {
+        return "true".equals( request.getUserProperties().getProperty( "maven3.weaveMode" ) );
+    }
+
+    public static void setWeaveMode( Properties properties )
+    {
+        properties.setProperty( "maven3.weaveMode", "true" );
+    }
+}
\ No newline at end of file

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