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  import java.util.stream.Collectors;
32  
33  import org.apache.maven.execution.ProjectDependencyGraph;
34  import org.apache.maven.project.CycleDetectedException;
35  import org.apache.maven.project.DuplicateProjectException;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.project.ProjectSorter;
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          this(projects, projects);
63      }
64  
65      
66  
67  
68  
69  
70  
71  
72  
73  
74  
75      @Deprecated
76      public DefaultProjectDependencyGraph(List<MavenProject> allProjects, Collection<MavenProject> projects)
77              throws CycleDetectedException, DuplicateProjectException {
78          this((Collection<MavenProject>) allProjects, projects);
79      }
80  
81      
82  
83  
84  
85  
86  
87  
88  
89  
90      public DefaultProjectDependencyGraph(Collection<MavenProject> allProjects, Collection<MavenProject> projects)
91              throws CycleDetectedException, DuplicateProjectException {
92          this.allProjects = Collections.unmodifiableList(new ArrayList<>(allProjects));
93          this.sorter = new ProjectSorter(projects);
94          this.order = new HashMap<>();
95          this.projects = new HashMap<>();
96          List<MavenProject> sorted = this.sorter.getSortedProjects();
97          for (int index = 0; index < sorted.size(); index++) {
98              MavenProject project = sorted.get(index);
99              String id = ProjectSorter.getId(project);
100             this.projects.put(id, project);
101             this.order.put(project, index);
102         }
103     }
104 
105     
106 
107 
108     public List<MavenProject> getAllProjects() {
109         return this.allProjects;
110     }
111 
112     public List<MavenProject> getSortedProjects() {
113         return new ArrayList<>(sorter.getSortedProjects());
114     }
115 
116     public List<MavenProject> getDownstreamProjects(MavenProject project, boolean transitive) {
117         Objects.requireNonNull(project, "project cannot be null");
118 
119         Set<String> projectIds = new HashSet<>();
120 
121         getDownstreamProjects(ProjectSorter.getId(project), projectIds, transitive);
122 
123         return getSortedProjects(projectIds);
124     }
125 
126     private void getDownstreamProjects(String projectId, Set<String> projectIds, boolean transitive) {
127         for (String id : sorter.getDependents(projectId)) {
128             if (projectIds.add(id) && transitive) {
129                 getDownstreamProjects(id, projectIds, transitive);
130             }
131         }
132     }
133 
134     public List<MavenProject> getUpstreamProjects(MavenProject project, boolean transitive) {
135         Objects.requireNonNull(project, "project cannot be null");
136 
137         Set<String> projectIds = new HashSet<>();
138 
139         getUpstreamProjects(ProjectSorter.getId(project), projectIds, transitive);
140 
141         return getSortedProjects(projectIds);
142     }
143 
144     private void getUpstreamProjects(String projectId, Collection<String> projectIds, boolean transitive) {
145         for (String id : sorter.getDependencies(projectId)) {
146             if (projectIds.add(id) && transitive) {
147                 getUpstreamProjects(id, projectIds, transitive);
148             }
149         }
150     }
151 
152     private List<MavenProject> getSortedProjects(Set<String> projectIds) {
153         return projectIds.stream()
154                 .map(projects::get)
155                 .sorted(Comparator.comparingInt(order::get))
156                 .collect(Collectors.toList());
157     }
158 
159     @Override
160     public String toString() {
161         return sorter.getSortedProjects().toString();
162     }
163 }