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