001package org.apache.maven.lifecycle.internal;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.execution.MavenSession;
023import org.apache.maven.execution.ProjectDependencyGraph;
024import org.apache.maven.project.MavenProject;
025
026import java.util.List;
027
028/**
029 * A build context that matches a mavenproject to a given tasksegment, and the session to be used.
030 * <p/>
031 * A note to the reader;
032 * <p/>
033 * There are several issues/discussions regarding how "aggregator" plugins should be handled.
034 * Read for instance http://docs.codehaus.org/display/MAVEN/Deterministic+Lifecycle+Planning
035 * <p/>
036 * In their current implementation they are "bolted" onto the lifecycle by separating them
037 * into TaskSegments. This class represents the execution context of one such task segment.
038 * <p/>
039 * Wise voices have suggested that maybe aggregators shouldn't be bound to the ordinary
040 * lifecycle at all, in which case we wouldn't be needing this class at all ( and
041 * ProjectBuildList.getByTaskSegments). Or maybe they should be introduced in the calculation
042 * of the execution plan instead, which seems much nicer.
043 * <p/>
044 * Additionally this class contains a clone of the MavenSession, which is *only* needed
045 * because it has as notion of a "current" project.
046 * 
047 * @since 3.0
048 * @author Jason van Zyl
049 * @author Benjamin Bentmann
050 * @author Kristian Rosenvold
051 *         <p/>
052 *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
053 */
054public final class ProjectSegment
055{
056    private final MavenProject project;
057
058    private final TaskSegment taskSegment;
059
060    private final MavenSession session;
061
062    private final List<MavenProject> nonTransitiveUpstreamProjects;
063
064    private final List<MavenProject> transitiveUpstreamProjects;
065
066    public ProjectSegment( MavenProject project, TaskSegment taskSegment, MavenSession copiedSession )
067    {
068        this.project = project;
069        this.taskSegment = taskSegment;
070        this.session = copiedSession;
071        final ProjectDependencyGraph dependencyGraph = getSession().getProjectDependencyGraph();
072        nonTransitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), false );
073        transitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), true );
074    }
075
076    public MavenSession getSession()
077    {
078        return session;
079    }
080
081    public MavenProject getProject()
082    {
083        return project;
084    }
085
086    public TaskSegment getTaskSegment()
087    {
088        return taskSegment;
089    }
090
091    public List<MavenProject> getImmediateUpstreamProjects()
092    {
093        return nonTransitiveUpstreamProjects;
094    }
095
096    public List<MavenProject> getTransitiveUpstreamProjects()
097    {
098        return transitiveUpstreamProjects;
099    }
100
101    @Override
102    public String toString()
103    {
104        return getProject().getId() + " -> " + getTaskSegment();
105    }
106}