in maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java [72:184]
public ProjectSorter(Collection<MavenProject> projects) throws CycleDetectedException, DuplicateProjectException {
dag = new DAG();
// groupId:artifactId:version -> project
projectMap = new HashMap<>(projects.size() * 2);
// groupId:artifactId -> (version -> vertex)
Map<String, Map<String, Vertex>> vertexMap = new HashMap<>(projects.size() * 2);
for (MavenProject project : projects) {
String projectId = getId(project);
MavenProject conflictingProject = projectMap.put(projectId, project);
if (conflictingProject != null) {
throw new DuplicateProjectException(
projectId,
conflictingProject.getFile(),
project.getFile(),
"Project '" + projectId + "' is duplicated in the reactor");
}
String projectKey = ArtifactUtils.versionlessKey(project.getGroupId(), project.getArtifactId());
Map<String, Vertex> vertices = vertexMap.computeIfAbsent(projectKey, k -> new HashMap<>(2, 1));
vertices.put(project.getVersion(), dag.addVertex(projectId));
}
for (Vertex projectVertex : dag.getVertices()) {
String projectId = projectVertex.getLabel();
MavenProject project = projectMap.get(projectId);
for (Dependency dependency : project.getModel().getDelegate().getDependencies()) {
addEdge(
projectMap,
vertexMap,
project,
projectVertex,
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion(),
false,
false);
}
Parent parent = project.getModel().getDelegate().getParent();
if (parent != null) {
// Parent is added as an edge, but must not cause a cycle - so we remove any other edges it has
// in conflict
addEdge(
projectMap,
vertexMap,
null,
projectVertex,
parent.getGroupId(),
parent.getArtifactId(),
parent.getVersion(),
true,
false);
}
Build build = project.getModel().getDelegate().getBuild();
if (build != null) {
for (Plugin plugin : build.getPlugins()) {
addEdge(
projectMap,
vertexMap,
project,
projectVertex,
plugin.getGroupId(),
plugin.getArtifactId(),
plugin.getVersion(),
false,
true);
for (Dependency dependency : plugin.getDependencies()) {
addEdge(
projectMap,
vertexMap,
project,
projectVertex,
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion(),
false,
true);
}
}
for (Extension extension : build.getExtensions()) {
addEdge(
projectMap,
vertexMap,
project,
projectVertex,
extension.getGroupId(),
extension.getArtifactId(),
extension.getVersion(),
false,
true);
}
}
}
List<String> sortedProjectLabels = TopologicalSorter.sort(dag);
this.sortedProjects = sortedProjectLabels.stream()
.map(id -> projectMap.get(id))
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}