001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
003 * agreements. See the NOTICE file distributed with this work for additional information regarding
004 * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
005 * "License"); you may not use this file except in compliance with the License. You may obtain a
006 * copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software distributed under the License
011 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012 * or implied. See the License for the specific language governing permissions and limitations under
013 * the License.
014 */
015
016package org.apache.maven.lifecycle.internal.stub;
017
018import org.apache.maven.execution.AbstractExecutionListener;
019import org.apache.maven.execution.DefaultMavenExecutionRequest;
020import org.apache.maven.execution.DefaultMavenExecutionResult;
021import org.apache.maven.execution.MavenExecutionRequest;
022import org.apache.maven.execution.MavenSession;
023import org.apache.maven.execution.ProjectDependencyGraph;
024import org.apache.maven.lifecycle.LifecycleNotFoundException;
025import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
026import org.apache.maven.lifecycle.internal.GoalTask;
027import org.apache.maven.lifecycle.internal.ProjectBuildList;
028import org.apache.maven.lifecycle.internal.ProjectSegment;
029import org.apache.maven.lifecycle.internal.TaskSegment;
030import org.apache.maven.plugin.InvalidPluginDescriptorException;
031import org.apache.maven.plugin.MojoNotFoundException;
032import org.apache.maven.plugin.PluginDescriptorParsingException;
033import org.apache.maven.plugin.PluginNotFoundException;
034import org.apache.maven.plugin.PluginResolutionException;
035import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
036import org.apache.maven.plugin.version.PluginVersionResolutionException;
037import org.apache.maven.project.MavenProject;
038
039import java.util.ArrayList;
040import java.util.Arrays;
041import java.util.List;
042
043/**
044 * A stub dependency graph that is custom made for testing concurrent build graph evaluations.
045 * <p/>
046 * Implements a graph as follows:
047 * A has no dependencies
048 * B depends on A
049 * C depends on A
050 * X depends on B & C
051 * Y depends on B
052 * Z depends on C
053 *
054 * @author Kristian Rosenvold
055 */
056public class ProjectDependencyGraphStub
057    implements ProjectDependencyGraph
058{
059    public static final MavenProject A = new MavenProject();
060
061    public static final MavenProject B = new MavenProject();
062
063    public static final MavenProject C = new MavenProject();
064
065    public static final MavenProject X = new MavenProject();
066
067    public static final MavenProject Y = new MavenProject();
068
069    public static final MavenProject Z = new MavenProject();
070
071    public static final MavenProject UNKNOWN = new MavenProject();
072
073    static
074    {
075        A.setArtifactId( "A" );
076        B.setArtifactId( "B" );
077        C.setArtifactId( "C" );
078        X.setArtifactId( "X" );
079        Y.setArtifactId( "Y" );
080        Z.setArtifactId( "Z" );
081    }
082
083    // This should probably be moved to a separate stub
084
085    public static ProjectBuildList getProjectBuildList( MavenSession session )
086        throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
087        NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
088        LifecyclePhaseNotFoundException, LifecycleNotFoundException
089    {
090        final List<ProjectSegment> list = getProjectBuilds( session );
091        return new ProjectBuildList( list );
092
093    }
094
095    public static List<ProjectSegment> getProjectBuilds( MavenSession session )
096        throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
097        NoPluginFoundForPrefixException, PluginNotFoundException, MojoNotFoundException, PluginResolutionException,
098        LifecyclePhaseNotFoundException, LifecycleNotFoundException
099    {
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        mavenExecutionRequest.setDegreeOfConcurrency( 1 );
220        final MavenSession session = new MavenSession( null, null, mavenExecutionRequest, defaultMavenExecutionResult );
221        final ProjectDependencyGraphStub dependencyGraphStub = new ProjectDependencyGraphStub();
222        session.setProjectDependencyGraph( dependencyGraphStub );
223        session.setProjects( dependencyGraphStub.getSortedProjects() );
224        return session;
225    }
226
227}