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