1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  
16  package org.apache.maven.lifecycle.internal.stub;
17  
18  import org.apache.maven.execution.AbstractExecutionListener;
19  import org.apache.maven.execution.DefaultMavenExecutionRequest;
20  import org.apache.maven.execution.DefaultMavenExecutionResult;
21  import org.apache.maven.execution.MavenExecutionRequest;
22  import org.apache.maven.execution.MavenSession;
23  import org.apache.maven.execution.ProjectDependencyGraph;
24  import org.apache.maven.lifecycle.LifecycleNotFoundException;
25  import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
26  import org.apache.maven.lifecycle.internal.GoalTask;
27  import org.apache.maven.lifecycle.internal.ProjectBuildList;
28  import org.apache.maven.lifecycle.internal.ProjectSegment;
29  import org.apache.maven.lifecycle.internal.TaskSegment;
30  import org.apache.maven.plugin.InvalidPluginDescriptorException;
31  import org.apache.maven.plugin.MojoNotFoundException;
32  import org.apache.maven.plugin.PluginDescriptorParsingException;
33  import org.apache.maven.plugin.PluginNotFoundException;
34  import org.apache.maven.plugin.PluginResolutionException;
35  import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
36  import org.apache.maven.plugin.version.PluginVersionResolutionException;
37  import org.apache.maven.project.MavenProject;
38  
39  import java.util.ArrayList;
40  import java.util.Arrays;
41  import java.util.List;
42  
43  /**
44   * A stub dependency graph that is custom made for testing concurrent build graph evaluations.
45   * <p/>
46   * Implements a graph as follows:
47   * A has no dependencies
48   * B depends on A
49   * C depends on A
50   * X depends on B & C
51   * Y depends on B
52   * Z depends on C
53   *
54   * @author Kristian Rosenvold
55   */
56  public class ProjectDependencyGraphStub
57      implements ProjectDependencyGraph
58  {
59      public static final MavenProject A = new MavenProject();
60  
61      public static final MavenProject B = new MavenProject();
62  
63      public static final MavenProject C = new MavenProject();
64  
65      public static final MavenProject X = new MavenProject();
66  
67      public static final MavenProject Y = new MavenProject();
68  
69      public static final MavenProject Z = new MavenProject();
70  
71      public static final MavenProject UNKNOWN = new MavenProject();
72  
73      static
74      {
75          A.setArtifactId( "A" );
76          B.setArtifactId( "B" );
77          C.setArtifactId( "C" );
78          X.setArtifactId( "X" );
79          Y.setArtifactId( "Y" );
80          Z.setArtifactId( "Z" );
81      }
82  
83      // This should probably be moved to a separate stub
84  
85      public static ProjectBuildList getProjectBuildList( MavenSession session )
86          throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
87          NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
88          LifecyclePhaseNotFoundException, LifecycleNotFoundException
89      {
90          final List<ProjectSegment> list = getProjectBuilds( session );
91          return new ProjectBuildList( list );
92  
93      }
94  
95      public static List<ProjectSegment> getProjectBuilds( MavenSession session )
96          throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
97          NoPluginFoundForPrefixException, PluginNotFoundException, MojoNotFoundException, PluginResolutionException,
98          LifecyclePhaseNotFoundException, LifecycleNotFoundException
99      {
100         List<ProjectSegment> projectBuilds = new ArrayList<ProjectSegment>();
101 
102         TaskSegment segment = createTaskSegment();
103         projectBuilds.add( createProjectBuild( A, session, segment ) );
104         projectBuilds.add( createProjectBuild( B, session, segment ) );
105         projectBuilds.add( createProjectBuild( C, session, segment ) );
106         projectBuilds.add( createProjectBuild( X, session, segment ) );
107         projectBuilds.add( createProjectBuild( Y, session, segment ) );
108         projectBuilds.add( createProjectBuild( Z, session, segment ) );
109         return projectBuilds;
110     }
111 
112     private static ProjectSegment createProjectBuild( MavenProject project, MavenSession session,
113                                                       TaskSegment taskSegment )
114         throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
115         NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
116         LifecyclePhaseNotFoundException, LifecycleNotFoundException
117     {
118         final MavenSession session1 = session.clone();
119         return new ProjectSegment( project, taskSegment, session1 );
120     }
121 
122 
123     private static TaskSegment createTaskSegment()
124     {
125         TaskSegment result = new TaskSegment( false );
126         result.getTasks().add( new GoalTask( "t1" ) );
127         result.getTasks().add( new GoalTask( "t2" ) );
128         return result;
129     }
130 
131     class Dependency
132     {
133         MavenProject dependant;
134 
135         MavenProject dependency;
136 
137         Dependency( MavenProject dependant, MavenProject dependency )
138         {
139             this.dependant = dependant;
140             this.dependency = dependency;
141         }
142 
143         void addIfDownstream( MavenProject mavenProject, List<MavenProject> result )
144         {
145             if ( dependency == mavenProject )
146             {
147                 result.add( dependant );
148             }
149         }
150 
151         void addIfUpstreamOf( MavenProject mavenProject, List<MavenProject> result )
152         {
153             if ( dependant == mavenProject )
154             {
155                 result.add( dependency ); // All projects are the statics from this class
156             }
157         }
158     }
159 
160     private List<Dependency> getDependencies()
161     {
162         List<Dependency> dependencies = new ArrayList<Dependency>();
163         dependencies.add( new Dependency( B, A ) );
164         dependencies.add( new Dependency( C, A ) );
165         dependencies.add( new Dependency( X, B ) );
166         dependencies.add( new Dependency( X, C ) );
167         dependencies.add( new Dependency( Y, B ) );
168         dependencies.add( new Dependency( Z, C ) );
169         return dependencies;
170     }
171 
172     public List<MavenProject> getSortedProjects()
173     {
174         return Arrays.asList( A, B, C, X, Y, Z ); // I'm not entirely sure about the order but this shold do...
175     }
176 
177     public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
178     {
179         if ( transitive )
180         {
181             throw new RuntimeException( "Not implemented yet" );
182         }
183         List<MavenProject> result = new ArrayList<MavenProject>();
184         for ( Dependency dependency : getDependencies() )
185         {
186             dependency.addIfDownstream( project, result );
187         }
188         return result;
189     }
190 
191     public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
192     {
193         /*  if ( transitive )
194         {
195             throw new RuntimeException( "Not implemented yet" );
196         }*/
197         List<MavenProject> result = new ArrayList<MavenProject>();
198         final List<Dependency> dependencies = getDependencies();
199         for ( Dependency dependency : dependencies )
200         {
201             dependency.addIfUpstreamOf( project, result );
202         }
203         return result;
204     }
205 
206     public static MavenSession getMavenSession( MavenProject mavenProject )
207     {
208         final MavenSession session = getMavenSession();
209         session.setCurrentProject( mavenProject );
210         return session;
211     }
212 
213     public static MavenSession getMavenSession()
214     {
215         final DefaultMavenExecutionResult defaultMavenExecutionResult = new DefaultMavenExecutionResult();
216         MavenExecutionRequest mavenExecutionRequest = new DefaultMavenExecutionRequest();
217         mavenExecutionRequest.setExecutionListener( new AbstractExecutionListener() );
218         mavenExecutionRequest.setGoals( Arrays.asList( "clean", "aggr", "install" ) );
219         final MavenSession session = new MavenSession( null, null, mavenExecutionRequest, defaultMavenExecutionResult );
220         final ProjectDependencyGraphStub dependencyGraphStub = new ProjectDependencyGraphStub();
221         session.setProjectDependencyGraph( dependencyGraphStub );
222         session.setProjects( dependencyGraphStub.getSortedProjects() );
223         return session;
224     }
225 
226 }