View Javadoc
1   package org.apache.maven.graph;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Comparator;
26  import java.util.HashMap;
27  import java.util.HashSet;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Objects;
31  import java.util.Set;
32  import java.util.stream.Collectors;
33  
34  import org.apache.maven.execution.ProjectDependencyGraph;
35  import org.apache.maven.project.DuplicateProjectException;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.project.ProjectSorter;
38  import org.codehaus.plexus.util.dag.CycleDetectedException;
39  
40  /**
41   * Describes the interdependencies between projects in the reactor.
42   *
43   * @author Benjamin Bentmann
44   */
45  public class DefaultProjectDependencyGraph
46          implements ProjectDependencyGraph
47  {
48  
49      private final ProjectSorter sorter;
50  
51      private final List<MavenProject> allProjects;
52  
53      private final Map<MavenProject, Integer> order;
54  
55      private final Map<String, MavenProject> projects;
56  
57      /**
58       * Creates a new project dependency graph based on the specified projects.
59       *
60       * @param projects The projects to create the dependency graph with
61       * @throws DuplicateProjectException
62       * @throws CycleDetectedException
63       */
64      public DefaultProjectDependencyGraph( Collection<MavenProject> projects )
65              throws CycleDetectedException, DuplicateProjectException
66      {
67          this( projects, projects );
68      }
69  
70      /**
71       * Creates a new project dependency graph based on the specified projects.
72       *
73       * @param allProjects All collected projects.
74       * @param projects    The projects to create the dependency graph with.
75       * @throws DuplicateProjectException
76       * @throws CycleDetectedException
77       * @since 3.5.0
78       */
79      public DefaultProjectDependencyGraph( Collection<MavenProject> allProjects,
80                                            Collection<MavenProject> projects )
81              throws CycleDetectedException, DuplicateProjectException
82      {
83          this.allProjects = Collections.unmodifiableList( new ArrayList<>( allProjects ) );
84          this.sorter = new ProjectSorter( projects );
85          this.order = new HashMap<>();
86          this.projects = new HashMap<>();
87          List<MavenProject> sorted = this.sorter.getSortedProjects();
88          for ( int index = 0; index < sorted.size(); index++ )
89          {
90              MavenProject project = sorted.get( index );
91              String id = ProjectSorter.getId( project );
92              this.projects.put( id, project );
93              this.order.put( project, index );
94          }
95      }
96  
97      /**
98       * @since 3.5.0
99       */
100     public List<MavenProject> getAllProjects()
101     {
102         return this.allProjects;
103     }
104 
105     public List<MavenProject> getSortedProjects()
106     {
107         return new ArrayList<>( sorter.getSortedProjects() );
108     }
109 
110     public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
111     {
112         Objects.requireNonNull( project, "project cannot be null" );
113 
114         Set<String> projectIds = new HashSet<>();
115 
116         getDownstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
117 
118         return getSortedProjects( projectIds );
119     }
120 
121     private void getDownstreamProjects( String projectId, Set<String> projectIds, boolean transitive )
122     {
123         for ( String id : sorter.getDependents( projectId ) )
124         {
125             if ( projectIds.add( id ) && transitive )
126             {
127                 getDownstreamProjects( id, projectIds, transitive );
128             }
129         }
130     }
131 
132     public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
133     {
134         Objects.requireNonNull( project, "project cannot be null" );
135 
136         Set<String> projectIds = new HashSet<>();
137 
138         getUpstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
139 
140         return getSortedProjects( projectIds );
141     }
142 
143     private void getUpstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
144     {
145         for ( String id : sorter.getDependencies( projectId ) )
146         {
147             if ( projectIds.add( id ) && transitive )
148             {
149                 getUpstreamProjects( id, projectIds, transitive );
150             }
151         }
152     }
153 
154     private List<MavenProject> getSortedProjects( Set<String> projectIds )
155     {
156         return projectIds.stream()
157                 .map( projects::get )
158                 .sorted( Comparator.comparingInt( order::get ) )
159                 .collect( Collectors.toList() );
160     }
161 
162     @Override
163     public String toString()
164     {
165         return sorter.getSortedProjects().toString();
166     }
167 
168 }