You are viewing a plain text version of this content. The canonical link for it is here.
Posted to m2-dev@maven.apache.org by jd...@apache.org on 2004/09/22 01:11:17 UTC

cvs commit: maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/session MavenSession.java

jdcasey     2004/09/21 16:11:16

  Modified:    maven-core/src/main/resources/META-INF/plexus components.xml
               maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase
                        GoalResolutionPhase.java
               maven-core/src/main/java/org/apache/maven/plugin
                        DefaultPluginManager.java PluginManager.java
               maven-core/src/test/java/org/apache/maven/lifecycle
                        MavenLifecycleManagerTest.java
               maven-core/src/main/java/org/apache/maven/lifecycle/session
                        MavenSession.java
  Added:       maven-core/src/test/java/org/apache/maven/lifecycle/goal/phase
                        GoalAssemblySubProcessTest.java
               maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase
                        PluginResolutionPhase.java GoalMappingPhase.java
               maven-core/src/main/java/org/apache/maven/util
                        AbstractGoalVisitor.java
                        GraphTraversalException.java GoalVisitor.java
                        GoalWalker.java
               maven-core/src/site/apt goal-resolution.apt
  Removed:     maven-core/src/test/java/org/apache/maven/lifecycle/goal/phase
                        GoalResolutionPhaseTest.java
  Log:
  o Refactored the goal/plugin resolution part of the lifecycle.
  
  Revision  Changes    Path
  1.4       +11 -0     maven-components/maven-core/src/main/resources/META-INF/plexus/components.xml
  
  Index: components.xml
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/main/resources/META-INF/plexus/components.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- components.xml	26 Aug 2004 04:39:51 -0000	1.3
  +++ components.xml	21 Sep 2004 23:11:16 -0000	1.4
  @@ -39,6 +39,8 @@
         <implementation>org.apache.maven.lifecycle.goal.DefaultMavenGoalPhaseManager</implementation>
         <configuration>
           <lifecycle-phases>
  +          <lifecycle-phase implementation="org.apache.maven.lifecycle.goal.phase.PluginResolutionPhase"/>
  +          <lifecycle-phase implementation="org.apache.maven.lifecycle.goal.phase.GoalMappingPhase"/>
             <lifecycle-phase implementation="org.apache.maven.lifecycle.goal.phase.GoalResolutionPhase"/>
             <lifecycle-phase implementation="org.apache.maven.lifecycle.goal.phase.DependencyResolutionPhase"/>
             <lifecycle-phase implementation="org.apache.maven.lifecycle.goal.phase.DependencyDownloadPhase"/>
  @@ -64,6 +66,15 @@
           </requirement>
           <requirement>
             <role>org.apache.maven.artifact.resolver.ArtifactResolver</role>
  +        </requirement>
  +      </requirements>
  +    </component>
  +    <component>
  +      <role>org.apache.maven.util.GoalWalker</role>
  +      <implementation>org.apache.maven.util.GoalWalker</implementation>
  +      <requirements>
  +        <requirement>
  +          <role>org.apache.maven.plugin.PluginManager</role>
           </requirement>
         </requirements>
       </component>
  
  
  
  1.1                  maven-components/maven-core/src/test/java/org/apache/maven/lifecycle/goal/phase/GoalAssemblySubProcessTest.java
  
  Index: GoalAssemblySubProcessTest.java
  ===================================================================
  /* Created on Jul 14, 2004 */
  package org.apache.maven.lifecycle.goal.phase;
  
  import org.apache.maven.MavenTestCase;
  import org.apache.maven.artifact.repository.ArtifactRepository;
  import org.apache.maven.lifecycle.goal.MavenGoalExecutionContext;
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.model.Model;
  import org.apache.maven.model.PostGoal;
  import org.apache.maven.model.PreGoal;
  import org.apache.maven.project.MavenProject;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.TreeMap;
  
  /** The point of this test class is to check out the functioning of the 
   * plugin resolution, goal mapping, and goal resolution phases. These are 
   * intertwined here to make testing easier, but should be separated into their
   * own unit tests.
   * 
   * @author jdcasey
   */
  public class GoalAssemblySubProcessTest
      extends MavenTestCase
  {
      /*
       * <!-- Test main with preGoal and postGoal --> <mojo>
       * <id>resolveTest:t1-preGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t1-main </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t1-postGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <!-- End of test -->
       */
      public void testT1_ShouldFind_PreGoal_MainGoal_PostGoal() throws Exception
      {
          String mainGoal = "resolveTest:t1-main";
          String preGoal = "resolveTest:t1-preGoal";
          String postGoal = "resolveTest:t1-postGoal";
  
          PreGoal pg = new PreGoal();
          pg.setAttain( preGoal );
          pg.setName( mainGoal );
  
          List preGoals = new LinkedList();
          preGoals.add( pg );
  
          PostGoal pog = new PostGoal();
          pog.setAttain( postGoal );
          pog.setName( mainGoal );
  
          List postGoals = new LinkedList();
          postGoals.add( pog );
  
          Map messages = new TreeMap();
  
          messages.put( mainGoal, "Main goal is missing." );
          messages.put( preGoal, "preGoal is missing" );
          messages.put( postGoal, "postGoal is missing" );
  
          List order = new ArrayList();
  
          order.add( preGoal );
          order.add( mainGoal );
          order.add( postGoal );
  
          runTest( mainGoal, preGoals, postGoals, order, messages );
      }
  
      /*
       * <!-- Test main with prereq --> <mojo> <id>resolveTest:t2-prereq </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t2-main </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> <prereqs> <prereq>resolveTest:t2-prereq
       * </prereq> </prereqs> </mojo> <!-- End of test -->
       */
      public void testT2_ShouldFind_Prereq_MainGoal() throws Exception
      {
          String mainGoal = "resolveTest:t2-main";
          String prereq = "resolveTest:t2-prereq";
  
          Map messages = new TreeMap();
  
          messages.put( mainGoal, "Main goal is missing." );
          messages.put( prereq, "prereq is missing" );
  
          List order = new ArrayList();
  
          order.add( prereq );
          order.add( mainGoal );
  
          runTest( mainGoal, Collections.EMPTY_LIST, Collections.EMPTY_LIST, order, messages );
      }
  
      /*
       * <!-- Test main with prereq, preGoal and postGoal --> <mojo>
       * <id>resolveTest:t3-preGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t3-prereq </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t3-main </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> <prereqs> <prereq>resolveTest:t3-prereq
       * </prereq> </prereqs> </mojo> <mojo> <id>resolveTest:t3-postGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <!-- End of test -->
       */
      public void testT3_ShouldFind_PreGoal_Prereq_MainGoal_PostGoal() throws Exception
      {
          String mainGoal = "resolveTest:t3-main";
          String prereq = "resolveTest:t3-prereq";
          String preGoal = "resolveTest:t3-preGoal";
          String postGoal = "resolveTest:t3-postGoal";
  
          PreGoal pg = new PreGoal();
          pg.setAttain( preGoal );
          pg.setName( mainGoal );
  
          List preGoals = new LinkedList();
          preGoals.add( pg );
  
          PostGoal pog = new PostGoal();
          pog.setAttain( postGoal );
          pog.setName( mainGoal );
  
          List postGoals = new LinkedList();
          postGoals.add( pog );
  
          Map messages = new TreeMap();
  
          messages.put( mainGoal, "Main goal is missing." );
          messages.put( prereq, "prereq is missing" );
          messages.put( preGoal, "preGoal is missing" );
          messages.put( postGoal, "postGoal is missing" );
  
          List order = new ArrayList();
  
          order.add( preGoal );
          order.add( prereq );
          order.add( mainGoal );
          order.add( postGoal );
  
          runTest( mainGoal, preGoals, postGoals, order, messages );
      }
  
      /*
       * <!-- Test main with prereq which has preGoal and postGoal --> <mojo>
       * <id>resolveTest:t4-prereq-preGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t4-prereq </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t4-main </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> <prereqs> <prereq>resolveTest:t4-prereq
       * </prereq> </prereqs> </mojo> <mojo> <id>resolveTest:t4-prereq-postGoal
       * </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <!-- End of test -->
       */
      public void testT4_ShouldFind_PreGoal_Prereq_PostGoal_MainGoal() throws Exception
      {
          String mainGoal = "resolveTest:t4-main";
          String prereq = "resolveTest:t4-prereq";
          String preGoal = "resolveTest:t4-prereq-preGoal";
          String postGoal = "resolveTest:t4-prereq-postGoal";
  
          PreGoal pg = new PreGoal();
          pg.setAttain( preGoal );
          pg.setName( prereq );
  
          List preGoals = new LinkedList();
          preGoals.add( pg );
  
          PostGoal pog = new PostGoal();
          pog.setAttain( postGoal );
          pog.setName( prereq );
  
          List postGoals = new LinkedList();
          postGoals.add( pog );
  
          Map messages = new TreeMap();
  
          messages.put( mainGoal, "Main goal is missing." );
          messages.put( prereq, "prereq is missing" );
          messages.put( preGoal, "preGoal is missing" );
          messages.put( postGoal, "postGoal is missing" );
  
          List order = new ArrayList();
  
          order.add( preGoal );
          order.add( prereq );
          order.add( postGoal );
          order.add( mainGoal );
  
          runTest( mainGoal, preGoals, postGoals, order, messages );
      }
  
      /*
       * <!-- Test main with prereq and preGoal which has the same prereq -->
       * <mojo> <id>resolveTest:t5-prereq </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> </mojo> <mojo> <id>resolveTest:t5-preGoal </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> <prereqs> <prereq>resolveTest:t5-prereq
       * </prereq> </prereqs> </mojo> <mojo> <id>resolveTest:t5-main </id>
       * <implementation>org.apache.maven.plugin.GoalDecorationAndResolutionTestPlugin
       * </implementation> <instantiationStrategy>singleton
       * </instantiationStrategy> <prereqs> <prereq>resolveTest:t5-prereq
       * </prereq> </prereqs> </mojo> <!-- End of test -->
       */
      public void testT5_ShouldFind_Prereq_PreGoal_MainGoal() throws Exception
      {
          String mainGoal = "resolveTest:t5-main";
          String prereq = "resolveTest:t5-prereq";
          String preGoal = "resolveTest:t5-preGoal";
  
          PreGoal pg = new PreGoal();
          pg.setAttain( preGoal );
          pg.setName( mainGoal );
  
          List preGoals = new LinkedList();
          preGoals.add( pg );
  
          Map messages = new TreeMap();
  
          messages.put( mainGoal, "Main goal is missing." );
          messages.put( prereq, "prereq is missing" );
          messages.put( preGoal, "preGoal is missing" );
  
          List order = new ArrayList();
  
          order.add( prereq );
          order.add( preGoal );
          order.add( mainGoal );
  
          runTest( mainGoal, preGoals, Collections.EMPTY_LIST, order, messages );
      }
  
      private void runTest( String mainGoal, List preGoals, List postGoals, List expectedOrder, Map messages )
          throws Exception
      {
          ArtifactRepository localRepository = new ArtifactRepository( "local", getTestRepoURL() );
  
          Model model = new Model();
          model.setPreGoals( preGoals );
          model.setPostGoals( postGoals );
  
          MavenProject project = new MavenProject( model );
  
          MavenGoalExecutionContext context = createGoalExecutionContext( project, localRepository, mainGoal );
          context.setGoalName( mainGoal );
  
          PluginResolutionPhase pluginPhase = new PluginResolutionPhase();
          GoalMappingPhase mappingPhase = new GoalMappingPhase();
          GoalResolutionPhase goalPhase = new GoalResolutionPhase();
  
          pluginPhase.execute( context );
          mappingPhase.execute( context );
          goalPhase.execute( context );
  
          List goals = context.getResolvedGoals();
          
          //System.out.println("Expected chain: " + expectedOrder);
          //System.out.println("Actual chain: " + goals);
  
          assertNotNull( goals );
  
          assertEquals( expectedOrder.size(), goals.size() );
  
          int index = 0;
          
          for ( Iterator it = expectedOrder.iterator(); it.hasNext(); )
          {
              String goal = (String) it.next();
  
              String failureMessage = (String) messages.get( goal );
  
              String resolvedGoal = (String) goals.get( index++ );
  
              assertEquals( failureMessage, goal, resolvedGoal );
          }
      }
  }
  
  
  
  1.5       +55 -85    maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase/GoalResolutionPhase.java
  
  Index: GoalResolutionPhase.java
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase/GoalResolutionPhase.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- GoalResolutionPhase.java	15 Sep 2004 12:34:16 -0000	1.4
  +++ GoalResolutionPhase.java	21 Sep 2004 23:11:16 -0000	1.5
  @@ -19,17 +19,25 @@
   import org.apache.maven.lifecycle.goal.AbstractMavenGoalPhase;
   import org.apache.maven.lifecycle.goal.GoalExecutionException;
   import org.apache.maven.lifecycle.goal.MavenGoalExecutionContext;
  +import org.apache.maven.lifecycle.goal.phase.PluginResolutionPhase.PluginResolutionVisitor;
  +import org.apache.maven.lifecycle.session.MavenSession;
   import org.apache.maven.model.GoalDecorator;
   import org.apache.maven.model.PreGoal;
   import org.apache.maven.plugin.PluginManager;
   import org.apache.maven.plugin.descriptor.MojoDescriptor;
  +import org.apache.maven.util.AbstractGoalVisitor;
  +import org.apache.maven.util.GoalWalker;
  +import org.apache.maven.util.GraphTraversalException;
  +import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
   
   import java.util.Collections;
   import java.util.HashSet;
   import java.util.Iterator;
   import java.util.LinkedList;
   import java.util.List;
  +import java.util.Map;
   import java.util.Set;
  +import java.util.TreeMap;
   
   /**
    * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
  @@ -38,114 +46,76 @@
   public class GoalResolutionPhase
       extends AbstractMavenGoalPhase
   {
  +
       public void execute( MavenGoalExecutionContext context ) throws GoalExecutionException
       {
  -        PluginManager pluginManager = context.getSession().getPluginManager();
  +        GoalResolutionVisitor visitor = new GoalResolutionVisitor( context.getSession().getPluginManager() );
   
           try
           {
  -            // First, start by retrieving the currently-requested goal.
  -            String goal = context.getGoalName();
  -
  -            List resolvedGoals = resolveTopLevel( goal, new HashSet(), new LinkedList(), context, pluginManager );
  -
  -            context.setResolvedGoals( resolvedGoals );
  -
  -            if ( goal.indexOf( ":" ) < 0 )
  -            {
  -                goal = context.getProject().getType() + ":" + goal;
  -            }
  -
  -            MojoDescriptor md = pluginManager.getMojoDescriptor( goal );
  -
  -            context.setMojoDescriptor( md );
  -        }
  -        catch ( Exception e )
  -        {
  -            throw new GoalExecutionException( "Error resolving goals: ", e );
  +            GoalWalker.walk( context.getGoalName(), context.getSession(), visitor );
           }
  -        finally
  +        catch ( GraphTraversalException e )
           {
  -            context.release( pluginManager );
  +            throw new GoalExecutionException("Cannot calculate goal execution chain", e);
           }
  +        
  +        context.setResolvedGoals(visitor.getExecutionChain());
       }
   
  -    private List resolveTopLevel( String goal, Set includedGoals, List results, MavenGoalExecutionContext context,
  -        PluginManager pluginManager ) throws Exception
  +    public static final class GoalResolutionVisitor
  +        extends AbstractGoalVisitor
       {
  +        private PluginManager pluginManager;
   
  -        // Ensure that the plugin for this goal is installed.
  -        pluginManager.verifyPluginForGoal( goal );
  -
  -        // Retrieve the prereqs-driven execution path for this goal, using the
  -        // DAG.
  -        List work = pluginManager.getGoals( goal );
  -
  -        // Reverse the original goals list to preserve encapsulation while
  -        // decorating.
  -        Collections.reverse( work );
  +        private List executionChain = new LinkedList();
  +        
  +        private Map prereqChains = new TreeMap();
   
  -        return resolveWithPrereqs( work, includedGoals, results, context, pluginManager );
  -    }
  -
  -    private List resolveWithPrereqs( List work, Set includedGoals, List results, MavenGoalExecutionContext context,
  -        PluginManager pluginManager ) throws Exception
  -    {
  -        if ( !work.isEmpty() )
  +        GoalResolutionVisitor( PluginManager pluginManager )
           {
  -            String goal = (String) work.remove( 0 );
  -
  -            MojoDescriptor descriptor = context.getMojoDescriptor( goal );
  -
  -            if ( descriptor.alwaysExecute() || !includedGoals.contains( goal ) )
  -            {
  -                List preGoals = new LinkedList();
  -                List allPreGoals = context.getProject().getModel().getPreGoals();
  -                for ( Iterator it = allPreGoals.iterator(); it.hasNext(); )
  -                {
  -                    PreGoal preGoal = (PreGoal) it.next();
  -                    if ( goal.equals( preGoal.getName() ) )
  -                    {
  -                        preGoals.add( preGoal.getAttain() );
  -                    }
  -                }
  -
  -                results = resolveGoalDecorators( goal, true, includedGoals, results, context, pluginManager );
  -
  -                results = resolveWithPrereqs( work, includedGoals, results, context, pluginManager );
  -                includedGoals.add( goal );
  -                results.add( goal );
  +            this.pluginManager = pluginManager;
  +        }
   
  -                results = resolveGoalDecorators( goal, false, includedGoals, results, context, pluginManager );
  -            }
  +        public boolean shouldVisit( String goal, MavenSession session )
  +        {
  +            boolean result = !executionChain.contains( goal );
  +            
  +            return result;
           }
  -        return results;
  -    }
   
  -    private List resolveGoalDecorators( String baseGoal, boolean usePreGoals, Set includedGoals, List results,
  -        MavenGoalExecutionContext context, PluginManager pluginManager ) throws Exception
  -    {
  -        List decorators = null;
  -        if ( usePreGoals )
  +        public void visitGoal( String goal, MavenSession session )
           {
  -            decorators = context.getProject().getModel().getPreGoals();
  +            executionChain.add( goal );
           }
  -        else
  +        
  +        public void visitPostGoal( String goal, String postGoal, MavenSession session ) 
  +        throws GraphTraversalException
           {
  -            decorators = context.getProject().getModel().getPostGoals();
  +            List chain = session.getExecutionChain( postGoal );
  +            
  +            executionChain.addAll( chain );
           }
  -
  -        for ( Iterator it = decorators.iterator(); it.hasNext(); )
  +        
  +        public void visitPreGoal( String goal, String preGoal, MavenSession session ) 
  +        throws GraphTraversalException
  +        {
  +            List chain = session.getExecutionChain( preGoal );
  +            
  +            executionChain.addAll( chain );
  +        }
  +        
  +        public void visitPrereq( String goal, String prereq, MavenSession session)
  +        throws GraphTraversalException
  +        {
  +            GoalWalker.walk( prereq, session, this );
  +        }
  +        
  +        public List getExecutionChain()
           {
  -            GoalDecorator decorator = (GoalDecorator) it.next();
  -            if ( baseGoal.equals( decorator.getName() ) )
  -            {
  -                String goal = decorator.getAttain();
  -                resolveTopLevel( goal, includedGoals, results, context, pluginManager );
  -            }
  +            return executionChain;
           }
   
  -        return results;
       }
   
   }
  
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase/PluginResolutionPhase.java
  
  Index: PluginResolutionPhase.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.lifecycle.goal.phase;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeMap;
  
  import org.apache.maven.lifecycle.goal.AbstractMavenGoalPhase;
  import org.apache.maven.lifecycle.goal.GoalExecutionException;
  import org.apache.maven.lifecycle.goal.MavenGoalExecutionContext;
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.plugin.PluginManager;
  import org.apache.maven.plugin.descriptor.MojoDescriptor;
  import org.apache.maven.util.AbstractGoalVisitor;
  import org.apache.maven.util.GoalWalker;
  import org.apache.maven.util.GraphTraversalException;
  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
  import org.codehaus.plexus.util.dag.CycleDetectedException;
  
  /**
   * @author jdcasey
   */
  public class PluginResolutionPhase
      extends AbstractMavenGoalPhase
  {
  
      public void execute( MavenGoalExecutionContext context ) throws GoalExecutionException
      {
          PluginResolutionVisitor visitor = new PluginResolutionVisitor( context.getSession().getPluginManager() );
  
          try
          {
              GoalWalker.walk( context.getGoalName(), context.getSession(), visitor );
          }
          catch ( GraphTraversalException e )
          {
              throw new GoalExecutionException( "Cannot resolve plugins required for goal execution chain", e );
          }
  
      }
  
      public static final class PluginResolutionVisitor
          extends AbstractGoalVisitor
      {
          private PluginManager pluginManager;
  
          private Set resolved = new HashSet();
  
          PluginResolutionVisitor( PluginManager pluginManager )
          {
              this.pluginManager = pluginManager;
          }
  
          public void preVisit( String goal, MavenSession session ) throws GraphTraversalException
          {
              try
              {
                  pluginManager.verifyPluginForGoal( goal );
              }
              catch ( Exception e )
              {
                  throw new GraphTraversalException( "Cannot resolve plugin for goal", e );
              }
              finally
              {
                  resolved.add( goal );
              }
          }
  
          public boolean shouldVisit( String goal, MavenSession session ) throws GraphTraversalException
          {
              boolean result = !resolved.contains( goal );
  
              return result;
          }
  
          public void visitPostGoal( String goal, String postGoal, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( postGoal, session, this );
          }
  
          public void visitPreGoal( String goal, String preGoal, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( preGoal, session, this );
          }
  
          public void visitPrereq( String goal, String prereq, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( prereq, session, this );
          }
  
      }
  
  }
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/goal/phase/GoalMappingPhase.java
  
  Index: GoalMappingPhase.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.lifecycle.goal.phase;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  
  import org.apache.maven.lifecycle.goal.AbstractMavenGoalPhase;
  import org.apache.maven.lifecycle.goal.GoalExecutionException;
  import org.apache.maven.lifecycle.goal.MavenGoalExecutionContext;
  import org.apache.maven.lifecycle.goal.phase.PluginResolutionPhase.PluginResolutionVisitor;
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.plugin.PluginManager;
  import org.apache.maven.plugin.descriptor.MojoDescriptor;
  import org.apache.maven.util.AbstractGoalVisitor;
  import org.apache.maven.util.GoalWalker;
  import org.apache.maven.util.GraphTraversalException;
  import org.codehaus.plexus.util.dag.CycleDetectedException;
  
  /**
   * @author jdcasey
   */
  public class GoalMappingPhase
      extends AbstractMavenGoalPhase
  {
  
      public void execute( MavenGoalExecutionContext context ) throws GoalExecutionException
      {
          GoalMappingVisitor visitor = new GoalMappingVisitor( context.getSession().getPluginManager() );
  
          try
          {
              GoalWalker.walk( context.getGoalName(), context.getSession(), visitor );
          }
          catch ( GraphTraversalException e )
          {
              throw new GoalExecutionException( "Cannot resolve plugins required for goal execution chain", e );
          }
  
      }
  
      public static final class GoalMappingVisitor
          extends AbstractGoalVisitor
      {
          private PluginManager pluginManager;
  
          private Set visited = new HashSet();
  
          GoalMappingVisitor( PluginManager pluginManager )
          {
              this.pluginManager = pluginManager;
          }
  
          public void visitPrereq( String goal, String prereq, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( prereq, session, this );
              
              try
              {
                  session.addImpliedExecution( goal, prereq );
              }
              catch ( CycleDetectedException e )
              {
                  throw new GraphTraversalException( "Goal prereq causes goal-graph cycle", e );
              }
          }
  
          public void visitPostGoal( String goal, String postGoal, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( postGoal, session, this );
          }
  
          public void visitPreGoal( String goal, String preGoal, MavenSession session ) throws GraphTraversalException
          {
              GoalWalker.walk( preGoal, session, this );
          }
  
          public void visitGoal( String goal, MavenSession session ) throws GraphTraversalException
          {
              session.addSingleExecution( goal );
          }
  
          public boolean shouldVisit( String goal, MavenSession session ) throws GraphTraversalException
          {
              boolean result = !visited.contains( goal );
  
              return result;
          }
  
      }
  }
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/util/AbstractGoalVisitor.java
  
  Index: AbstractGoalVisitor.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.util;
  
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.plugin.descriptor.MojoDescriptor;
  
  /**
   * @author jdcasey
   */
  public abstract class AbstractGoalVisitor
      implements GoalVisitor
  {
  
      protected AbstractGoalVisitor()
      {
      }
  
  
      public boolean shouldVisit( String goal, MavenSession session ) 
      throws GraphTraversalException
      {
          // visit all by default
          return true;
      }
      
      public void visitGoal( String goal, MavenSession session ) 
      throws GraphTraversalException
      {
          // do nothing by default
      }
      
      public void visitPostGoal( String goal, String postGoal, MavenSession session )
      throws GraphTraversalException
      {
          // do nothing by default
      }
  
      public void visitPreGoal( String goal, String preGoal, MavenSession session )
      throws GraphTraversalException
      {
          // do nothing by default
      }
  
      public void visitPrereq( String goal, String prereq, MavenSession session )
      throws GraphTraversalException
      {
          // do nothing by default
      }
      
      public void preVisit( String goal, MavenSession session )
      throws GraphTraversalException
      {
          // do nothing by default
      }
  
      public void postVisit( String goal, MavenSession session ) 
      throws GraphTraversalException
      {
          // do nothing by default
      }
  
  }
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/util/GraphTraversalException.java
  
  Index: GraphTraversalException.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.util;
  
  /**
   * @author jdcasey
   */
  public class GraphTraversalException
      extends Exception
  {
  
      public GraphTraversalException( Throwable cause )
      {
          super( cause );
      }
  
      public GraphTraversalException( String message, Throwable cause )
      {
          super( message, cause );
      }
  
  }
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/util/GoalVisitor.java
  
  Index: GoalVisitor.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.util;
  
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.plugin.descriptor.MojoDescriptor;
  
  /**
   * @author jdcasey
   */
  public interface GoalVisitor
  {
  
      boolean shouldVisit( String goal, MavenSession session ) throws GraphTraversalException;
      
      void preVisit( String goal, MavenSession session ) throws GraphTraversalException;
  
      void visitGoal( String goal, MavenSession session ) throws GraphTraversalException;
  
      void visitPreGoal( String goal, String preGoal, MavenSession session ) throws GraphTraversalException;
  
      void visitPrereq( String goal, String prereq, MavenSession session ) throws GraphTraversalException;
  
      void visitPostGoal( String goal, String postGoal, MavenSession session ) throws GraphTraversalException;
  
      void postVisit( String goal, MavenSession session ) throws GraphTraversalException;
  
  }
  
  
  1.1                  maven-components/maven-core/src/main/java/org/apache/maven/util/GoalWalker.java
  
  Index: GoalWalker.java
  ===================================================================
  /* Created on Sep 21, 2004 */
  package org.apache.maven.util;
  
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.maven.lifecycle.session.MavenSession;
  import org.apache.maven.plugin.PluginManager;
  import org.apache.maven.plugin.descriptor.MojoDescriptor;
  
  /**
   * @author jdcasey
   */
  public final class GoalWalker
  {
  
      public static void walk( String goal, MavenSession session, GoalVisitor visitor ) throws GraphTraversalException
      {
          if ( visitor.shouldVisit( goal, session ) )
          {
              visitor.preVisit( goal, session );
  
              List preGoals = session.getPreGoals( goal );
              if ( preGoals != null )
              {
                  for ( Iterator it = preGoals.iterator(); it.hasNext(); )
                  {
                      String preGoal = (String) it.next();
                      visitor.visitPreGoal( goal, preGoal, session );
                  }
              }
  
              PluginManager pluginManager = session.getPluginManager();
              MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( goal );
              if ( mojoDescriptor != null )
              {
                  List prereqs = mojoDescriptor.getPrereqs();
                  if ( prereqs != null )
                  {
                      for ( Iterator it = prereqs.iterator(); it.hasNext(); )
                      {
                          String prereq = (String) it.next();
                          visitor.visitPrereq( goal, prereq, session );
                      }
                  }
              }
  
              visitor.visitGoal( goal, session );
  
              List postGoals = session.getPostGoals( goal );
              if ( postGoals != null )
              {
                  for ( Iterator it = postGoals.iterator(); it.hasNext(); )
                  {
                      String postGoal = (String) it.next();
                      visitor.visitPostGoal( goal, postGoal, session );
                  }
              }
  
              visitor.postVisit( goal, session );
          }
      }
  
  }
  
  
  1.1                  maven-components/maven-core/src/site/apt/goal-resolution.apt
  
  Index: goal-resolution.apt
  ===================================================================
  ---
  Goal Resolution Discussion
  ---
  The Maven Team
  ---
  21-Sept-2004
  ---
  
    This document is intended to be a working memory of sorts for the goal 
    resolution algorithm used in Maven-2. It is not intended to supplant the 
    living bible of Maven, the lifecycle.apt document. Instead it is meant to 
    add depth to the goal resolution step of the lifecycle and provide a place 
    for discussing the dirty details of its implementation.
    
  *Conceptual Resolution
  
    Conceptually, goal resolution must take place in a particular order in order
    to preserve the encapsulation of the goal and it's implied requirements as a
    single operation. Obviously, since implied requirements are themselves goals, 
    this is a recursive definition. This model is further complicated by the fact
    that such implied requirements can be derived from two sources: a mojo's 
    declared pre-requisites (non-optional, these are required for correct 
    operation of the mojo itself), and any goal decorations which may have been 
    declared in a project-specific manner via the project POM.
    
    In general, the following should be the combined outcome of all implied 
    requirements.
    
  +-----+
  
    [ main-preGoal* ] [ prereq ]* main-goal [ main-postGoal* ]
    
  +-----+
  
    Note that each of the elements in this formula is a goal in its own right, 
    and will therefore be subject to resolution (taking the place of <<<main-goal>>>
    above) and substitution into the parent (replace <<<main-preGoal>>> with the 
    list of goals implied by <<<main-preGoal>>> <in correct order>).
  
  *Functional Resolution
  
    The fact we must merge two sources of implied-goal information in order to 
    construct a complete execution chain complicates goal resolution beyond simple
    use of a directed acyclical graph (DAG). This is especially true because of the 
    differing lifecycle and scope of the two sources. One is the plugin 
    descriptor, which has a lifecycle arguably longer than the JVM lifecycle 
    itself, and system-wide scope (provided plugin versioning is tracked). The
    other is the project's POM, which has an extremely short lifecycle (probably
    roughly equivalent to the maven-session lifecycle, which is <not> the same as
    the JVM lifecycle in some embedded use cases), and only project scope (don't 
    want one POM's decorations polluting the builds of other POMs). While the 
    plugin descriptor information may be cached - even to disk - the POM goal 
    information must be rebuilt for each maven-session.
    
    On the other hand, one very important distinction between information derived
    from plugin descriptors and information from POMs is that POMs lack the 
    ability to declare new goals. This means that in theory we should be able to
    clone a DAG that describes all of the conventional requirements for all of the
    plugins referenced, and simply add inter-goal relationships to account for any
    extra decoration from the POM. When the session is over, we can then discard 
    the modified DAG, retaining the plugin-derived DAG for future use in memory or
    on disk.
    
    <NOTE:> There are other reasons to be very careful when caching the DAG to 
    disk, notably the handling and updating of -SNAPSHOT plugins.
    
  *Algorithm
  
    Here is the current algorithm implemented by the GoalResolutionPhase:
    
    <NOTE:> The separation of the plugin resolution step from the process of 
    actually building the execution chain is new, and has not yet been implemented.
    However, this appears to be a required separation since the DAG cannot 
    function properly until all plugins - and consequently the prereqs implied by 
    them - are resolved. So, we'll take a second pass later to actually build the
    execution list; for now, we'll just resolve plugins.
    
    <<Resolve Plugins:>>
    
      <NOTE:> Can we re-separate this as a plugin-resolution phase, and provide
      some sort of reusable tree-visit logic (akin to the topo sorter) where we
      could pass in some sort of visitation command to execute per visited goal?
      
      [[1]] Initialize recursion
              [[a]] Instantiate Set for caching resolved goals. <resolved>
              [[b]] Set current goal to be resolved. <goal>
              []
      [[2]] If <goal> is contained in <resolved>, Return.
      [[3]] Verify plugin for <goal>.
      [[4]] Add <goal> to resolved.
      [[5]] Foreach <preGoal> of <goal>, 
              [[a]] Set <goal> = <preGoal>
              [[b]] Call [2]
              []
      [[6]] Foreach <prereq> of <goal>,
              [[a]] Set <goal> = <prereq>
              [[b]] Call [2]
              []
      [[7]] Foreach <postGoal> of <goal>,
              [[a]] Set <goal> = <postGoal>
              [[b]] Call [2]
              []
      [[8]] Return.
      []
    
    <<Build Execution Chain:>>
    
      <NOTE:> Visitation logic is eerily similar to the above recursive process.
      Can we create a graph visitation utility and pass in some sort of command
      to be executed per visited node?
      
      [[1]] Initialize recursion
              [[a]] Instantiate LinkedList to hold execution chain. <chain>
              [[b]] Instantiate Set for caching visited goals. <visited>
              [[c]] Set current goal to be executed. <goal>
              []
      [[2]] If <visited> contains <goal>, Return.
      [[3]] Process preGoals of <goal>
              [[a]] Retrieve List of preGoals bound to <goal>
              [[b]] Foreach <preGoal> in <preGoals>
                      [[i]] Set <goal> = <preGoal>
                      [[ii]] Call [1]
                      []
              []
      [[4]] Process prereqs of <goal>
              [[a]] Retrieve List of prereqs bound to <goal>
              [[b]] Foreach <prereq> in <prereqs>
                      [[i]] Set <goal> = <prereq>
                      [[ii]] Call [1]
                      []
              []
      [[5]] Add <goal> to <chain>
      [[6]] Add <goal> to <visited>
      [[7]] Process postGoals of <goal>
              [[a]] Retrieve List of postGoals bound to <goal>
              [[b]] Foreach <postGoal> in <postGoals>
                      [[i]] Set <goal> = <postGoal>
                      [[ii]] Call [1]
                      []
              []
      [[8]] Return.
      []
  
    <NOTE:> Since the user's intent most likely aligned with separate, serial
    execution of all goals listed on the command line <in order>, the above
    algorithm must be repeated for each <goal> in <user-goals>, with the execution
    chains of each being appended to a single list in order to resolve a complete,
    end-to-end picture of the current build session.
    
  
  
  1.10      +1 -61     maven-components/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
  
  Index: DefaultPluginManager.java
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DefaultPluginManager.java	18 Sep 2004 01:52:38 -0000	1.9
  +++ DefaultPluginManager.java	21 Sep 2004 23:11:16 -0000	1.10
  @@ -47,8 +47,6 @@
   {
       static String MAVEN_PLUGIN = "maven-plugin";
   
  -    protected DAG dag;
  -
       protected Map mojoDescriptors;
   
       protected Map pluginDescriptors;
  @@ -67,8 +65,6 @@
   
       public DefaultPluginManager()
       {
  -        dag = new DAG();
  -
           mojoDescriptors = new HashMap();
   
           pluginDescriptors = new HashMap();
  @@ -77,15 +73,6 @@
       }
   
       // ----------------------------------------------------------------------
  -    //
  -    // ----------------------------------------------------------------------
  -
  -    public List getGoals( String goal )
  -    {
  -        return TopologicalSorter.sort( dag.getVertex( goal ) );
  -    }
  -
  -    // ----------------------------------------------------------------------
       // Goal descriptors
       // ----------------------------------------------------------------------
   
  @@ -121,58 +108,11 @@
               MavenMojoDescriptor mavenMojoDescriptor = (MavenMojoDescriptor) it.next();
   
               MojoDescriptor mojoDescriptor = mavenMojoDescriptor.getMojoDescriptor();
  -
  -            if ( mojoDescriptor.getPrereqs() != null )
  -            {
  -                for ( Iterator k = mojoDescriptor.getPrereqs().iterator(); k.hasNext(); )
  -                {
  -                    String prereq = (String) k.next();
  -
  -                    if ( !processEdge( mojoDescriptor.getId(), prereq ) )
  -                    {
  -                        continue;
  -                    }
  -                }
  -            }
  -            else
  -            {
  -                dag.addVertex( mojoDescriptor.getId() );
  -            }
  -
  +            
               mojoDescriptors.put( mojoDescriptor.getId(), mojoDescriptor );
   
               pluginDescriptors.put( pluginDescriptor.getId(), pluginDescriptor );
           }
  -    }
  -
  -    private boolean processEdge( String mojoId, String prereq ) throws CycleDetectedException
  -    {
  -        dag.addEdge( mojoId, prereq );
  -
  -        // We don't want to verify a plugin that we are already in the process
  -        // of verifying.
  -        String prereqPlugin = getPluginId( prereq );
  -
  -        String goalPlugin = getPluginId( mojoId );
  -
  -        if ( isPluginInstalled( prereqPlugin ) )
  -        {
  -            return false;
  -        }
  -
  -        if ( !goalPlugin.equals( prereqPlugin ) )
  -        {
  -            try
  -            {
  -                verifyPluginForGoal( prereq );
  -            }
  -            catch ( Exception e )
  -            {
  -                e.printStackTrace();
  -            }
  -        }
  -
  -        return true;
       }
   
       // ----------------------------------------------------------------------
  
  
  
  1.3       +1 -3      maven-components/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java
  
  Index: PluginManager.java
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PluginManager.java	15 Sep 2004 12:30:04 -0000	1.2
  +++ PluginManager.java	21 Sep 2004 23:11:16 -0000	1.3
  @@ -49,8 +49,6 @@
       //
       // ----------------------------------------------------------------------
   
  -    List getGoals( String goal );
  -
       // ----------------------------------------------------------------------
       //
       // ----------------------------------------------------------------------
  
  
  
  1.4       +1 -1      maven-components/maven-core/src/test/java/org/apache/maven/lifecycle/MavenLifecycleManagerTest.java
  
  Index: MavenLifecycleManagerTest.java
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/test/java/org/apache/maven/lifecycle/MavenLifecycleManagerTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MavenLifecycleManagerTest.java	26 Aug 2004 04:39:54 -0000	1.3
  +++ MavenLifecycleManagerTest.java	21 Sep 2004 23:11:16 -0000	1.4
  @@ -19,6 +19,6 @@
   
           List lifecyclePhases = mlm.getLifecyclePhases();
   
  -        assertEquals( 4, lifecyclePhases.size() );
  +        assertEquals( 6, lifecyclePhases.size() );
       }
   }
  
  
  
  1.4       +100 -12   maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/session/MavenSession.java
  
  Index: MavenSession.java
  ===================================================================
  RCS file: /home/cvs/maven-components/maven-core/src/main/java/org/apache/maven/lifecycle/session/MavenSession.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MavenSession.java	15 Sep 2004 12:30:04 -0000	1.3
  +++ MavenSession.java	21 Sep 2004 23:11:16 -0000	1.4
  @@ -1,14 +1,24 @@
   package org.apache.maven.lifecycle.session;
   
   import org.apache.maven.artifact.repository.ArtifactRepository;
  +import org.apache.maven.model.PostGoal;
  +import org.apache.maven.model.PreGoal;
   import org.apache.maven.plugin.PluginManager;
   import org.apache.maven.project.MavenProject;
   import org.apache.maven.repository.RepositoryUtils;
   import org.codehaus.plexus.PlexusContainer;
   import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
  +import org.codehaus.plexus.util.dag.CycleDetectedException;
  +import org.codehaus.plexus.util.dag.DAG;
  +import org.codehaus.plexus.util.dag.TopologicalSorter;
  +import org.codehaus.plexus.util.dag.Vertex;
   
  +import java.util.Iterator;
  +import java.util.LinkedList;
   import java.util.List;
  +import java.util.Map;
   import java.util.Set;
  +import java.util.TreeMap;
   
   /*
    * Copyright 2001-2004 The Apache Software Foundation.
  @@ -27,7 +37,7 @@
    */
   
   /**
  - * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
  + * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
    * @version $Id$
    */
   public class MavenSession
  @@ -42,13 +52,16 @@
   
       private Set remoteRepositories;
   
  +    private DAG dag;
  +
       private List goals;
   
  -    public MavenSession( PlexusContainer container,
  -                         PluginManager pluginManager,
  -                         MavenProject project,
  -                         ArtifactRepository localRepository,
  -                         List goals )
  +    private Map preGoalMappings;
  +
  +    private Map postGoalMappings;
  +
  +    public MavenSession( PlexusContainer container, PluginManager pluginManager, MavenProject project,
  +        ArtifactRepository localRepository, List goals )
       {
           this.container = container;
   
  @@ -58,7 +71,15 @@
   
           this.localRepository = localRepository;
   
  +        this.dag = new DAG();
  +
           this.goals = goals;
  +
  +        this.preGoalMappings = new TreeMap();
  +
  +        this.postGoalMappings = new TreeMap();
  +
  +        initGoalDecoratorMappings();
       }
   
       public PlexusContainer getContainer()
  @@ -100,14 +121,12 @@
       //
       // ----------------------------------------------------------------------
   
  -    public Object lookup( String role )
  -        throws ComponentLookupException
  +    public Object lookup( String role ) throws ComponentLookupException
       {
           return container.lookup( role );
       }
   
  -    public Object lookup( String role, String roleHint )
  -        throws ComponentLookupException
  +    public Object lookup( String role, String roleHint ) throws ComponentLookupException
       {
           return container.lookup( role, roleHint );
       }
  @@ -126,4 +145,73 @@
               }
           }
       }
  -}
  +
  +    public List getPreGoals( String goal )
  +    {
  +        List result = (List) preGoalMappings.get( goal );
  +        return result;
  +    }
  +
  +    public List getPostGoals( String goal )
  +    {
  +        List result = (List) postGoalMappings.get( goal );
  +        return result;
  +    }
  +
  +    private void initGoalDecoratorMappings()
  +    {
  +        List allPreGoals = project.getModel().getPreGoals();
  +        for ( Iterator it = allPreGoals.iterator(); it.hasNext(); )
  +        {
  +            PreGoal preGoal = (PreGoal) it.next();
  +
  +            List preGoalList = (List) preGoalMappings.get( preGoal.getName() );
  +            if ( preGoalList == null )
  +            {
  +                preGoalList = new LinkedList();
  +                preGoalMappings.put( preGoal.getName(), preGoalList );
  +            }
  +
  +            preGoalList.add( preGoal.getAttain() );
  +        }
  +
  +        List allPostGoals = project.getModel().getPostGoals();
  +        for ( Iterator it = allPostGoals.iterator(); it.hasNext(); )
  +        {
  +            PostGoal postGoal = (PostGoal) it.next();
  +
  +            List postGoalList = (List) postGoalMappings.get( postGoal.getName() );
  +            if ( postGoalList == null )
  +            {
  +                postGoalList = new LinkedList();
  +                postGoalMappings.put( postGoal.getName(), postGoalList );
  +            }
  +
  +            postGoalList.add( postGoal.getAttain() );
  +        }
  +    }
  +
  +    public void addImpliedExecution( String goal, String implied ) throws CycleDetectedException
  +    {
  +        dag.addEdge( goal, implied );
  +    }
  +    
  +    public void addSingleExecution( String goal )
  +    {
  +        dag.addVertex( goal );
  +    }
  +
  +    public List getExecutionChain( String goal )
  +    {
  +        Vertex vertex = dag.getVertex( goal );
  +        
  +        List sorted = TopologicalSorter.sort( vertex );
  +        
  +        int goalIndex = sorted.indexOf( goal );
  +        
  +        List chainToHere = sorted.subList( 0, goalIndex + 1 );
  +        
  +        return chainToHere;
  +    }
  +
  +}
  \ No newline at end of file