1   package org.apache.maven.graph;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
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  
42  
43  
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  
59  
60  
61  
62  
63  
64      public DefaultProjectDependencyGraph( Collection<MavenProject> projects )
65              throws CycleDetectedException, DuplicateProjectException
66      {
67          this( projects, projects );
68      }
69  
70      
71  
72  
73  
74  
75  
76  
77  
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  
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 }