1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.graph;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.Comparator;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Objects;
30  import java.util.Set;
31  
32  import org.apache.maven.execution.ProjectDependencyGraph;
33  import org.apache.maven.project.DuplicateProjectException;
34  import org.apache.maven.project.MavenProject;
35  import org.apache.maven.project.ProjectSorter;
36  import org.codehaus.plexus.util.dag.CycleDetectedException;
37  
38  
39  
40  
41  
42  
43  public class DefaultProjectDependencyGraph implements ProjectDependencyGraph {
44  
45      private final ProjectSorter sorter;
46  
47      private final List<MavenProject> allProjects;
48  
49      private final Map<MavenProject, Integer> order;
50  
51      private final Map<String, MavenProject> projects;
52  
53      
54  
55  
56  
57  
58  
59  
60      public DefaultProjectDependencyGraph(Collection<MavenProject> projects)
61              throws CycleDetectedException, DuplicateProjectException {
62          super();
63          this.allProjects = Collections.unmodifiableList(new ArrayList<>(projects));
64          this.sorter = new ProjectSorter(projects);
65          List<MavenProject> sorted = this.sorter.getSortedProjects();
66          this.order = new HashMap<>(sorted.size());
67          this.projects = new HashMap<>(sorted.size());
68          int index = 0;
69          for (MavenProject project : sorted) {
70              String id = ProjectSorter.getId(project);
71              this.projects.put(id, project);
72              this.order.put(project, index++);
73          }
74      }
75  
76      
77  
78  
79  
80  
81  
82  
83  
84  
85  
86      public DefaultProjectDependencyGraph(final List<MavenProject> allProjects, final Collection<MavenProject> projects)
87              throws CycleDetectedException, DuplicateProjectException {
88          super();
89          this.allProjects = Collections.unmodifiableList(new ArrayList<>(allProjects));
90          this.sorter = new ProjectSorter(projects);
91          List<MavenProject> sorted = this.sorter.getSortedProjects();
92          this.order = new HashMap<>(sorted.size());
93          this.projects = new HashMap<>(sorted.size());
94          int index = 0;
95          for (MavenProject project : sorted) {
96              String id = ProjectSorter.getId(project);
97              this.projects.put(id, project);
98              this.order.put(project, index++);
99          }
100     }
101 
102     
103 
104 
105     public List<MavenProject> getAllProjects() {
106         return this.allProjects;
107     }
108 
109     public List<MavenProject> getSortedProjects() {
110         return new ArrayList<>(sorter.getSortedProjects());
111     }
112 
113     public List<MavenProject> getDownstreamProjects(MavenProject project, boolean transitive) {
114         Objects.requireNonNull(project, "project cannot be null");
115 
116         Set<String> projectIds = new HashSet<>();
117 
118         getDownstreamProjects(ProjectSorter.getId(project), projectIds, transitive);
119 
120         return getSortedProjects(projectIds);
121     }
122 
123     private void getDownstreamProjects(String projectId, Set<String> projectIds, boolean transitive) {
124         for (String id : sorter.getDependents(projectId)) {
125             if (projectIds.add(id) && transitive) {
126                 getDownstreamProjects(id, projectIds, transitive);
127             }
128         }
129     }
130 
131     public List<MavenProject> getUpstreamProjects(MavenProject project, boolean transitive) {
132         Objects.requireNonNull(project, "project cannot be null");
133 
134         Set<String> projectIds = new HashSet<>();
135 
136         getUpstreamProjects(ProjectSorter.getId(project), projectIds, transitive);
137 
138         return getSortedProjects(projectIds);
139     }
140 
141     private void getUpstreamProjects(String projectId, Collection<String> projectIds, boolean transitive) {
142         for (String id : sorter.getDependencies(projectId)) {
143             if (projectIds.add(id) && transitive) {
144                 getUpstreamProjects(id, projectIds, transitive);
145             }
146         }
147     }
148 
149     private List<MavenProject> getSortedProjects(Set<String> projectIds) {
150         List<MavenProject> result = new ArrayList<>(projectIds.size());
151         for (String projectId : projectIds) {
152             result.add(projects.get(projectId));
153         }
154 
155         Collections.sort(result, new MavenProjectComparator());
156 
157         return result;
158     }
159 
160     @Override
161     public String toString() {
162         return sorter.getSortedProjects().toString();
163     }
164 
165     private class MavenProjectComparator implements Comparator<MavenProject> {
166         @Override
167         public int compare(MavenProject o1, MavenProject o2) {
168             return order.get(o1) - order.get(o2);
169         }
170     }
171 }