1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.impl.model;
20
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Objects;
28 import java.util.Set;
29
30 import org.apache.maven.api.di.Named;
31 import org.apache.maven.api.di.Singleton;
32 import org.apache.maven.api.model.Dependency;
33 import org.apache.maven.api.model.DependencyManagement;
34 import org.apache.maven.api.model.Exclusion;
35 import org.apache.maven.api.model.Model;
36 import org.apache.maven.api.services.BuilderProblem.Severity;
37 import org.apache.maven.api.services.ModelBuilderRequest;
38 import org.apache.maven.api.services.ModelProblem.Version;
39 import org.apache.maven.api.services.ModelProblemCollector;
40 import org.apache.maven.api.services.model.*;
41
42
43
44
45
46 @Named
47 @Singleton
48 public class DefaultDependencyManagementImporter implements DependencyManagementImporter {
49
50 @Override
51 public Model importManagement(
52 Model target,
53 List<? extends DependencyManagement> sources,
54 ModelBuilderRequest request,
55 ModelProblemCollector problems) {
56 if (sources != null && !sources.isEmpty()) {
57 Map<String, Dependency> dependencies = new LinkedHashMap<>();
58
59 DependencyManagement depMgmt = target.getDependencyManagement();
60
61 if (depMgmt != null) {
62 for (Dependency dependency : depMgmt.getDependencies()) {
63 dependencies.put(dependency.getManagementKey(), dependency);
64 }
65 } else {
66 depMgmt = DependencyManagement.newInstance();
67 }
68
69 Set<String> directDependencies = new HashSet<>(dependencies.keySet());
70
71 for (DependencyManagement source : sources) {
72 for (Dependency dependency : source.getDependencies()) {
73 String key = dependency.getManagementKey();
74 Dependency present = dependencies.putIfAbsent(key, dependency);
75 if (present != null && !equals(dependency, present) && !directDependencies.contains(key)) {
76
77 problems.add(
78 Severity.WARNING,
79 Version.V40,
80 "Ignored POM import for: " + toString(dependency) + " as already imported "
81 + toString(present) + ". Add a the conflicting managed dependency directly "
82 + "to the dependencyManagement section of the POM.");
83 }
84 }
85 }
86
87 return target.withDependencyManagement(depMgmt.withDependencies(dependencies.values()));
88 }
89 return target;
90 }
91
92 private String toString(Dependency dependency) {
93 StringBuilder stringBuilder = new StringBuilder();
94 stringBuilder
95 .append(dependency.getGroupId())
96 .append(":")
97 .append(dependency.getArtifactId())
98 .append(":")
99 .append(dependency.getType());
100 if (dependency.getClassifier() != null && !dependency.getClassifier().isEmpty()) {
101 stringBuilder.append(":").append(dependency.getClassifier());
102 }
103 stringBuilder
104 .append(":")
105 .append(dependency.getVersion())
106 .append("@")
107 .append(dependency.getScope() == null ? "compile" : dependency.getScope());
108 if (dependency.isOptional()) {
109 stringBuilder.append("[optional]");
110 }
111 if (!dependency.getExclusions().isEmpty()) {
112 stringBuilder.append("[").append(dependency.getExclusions().size()).append(" exclusions]");
113 }
114 return stringBuilder.toString();
115 }
116
117 private boolean equals(Dependency d1, Dependency d2) {
118 return Objects.equals(d1.getGroupId(), d2.getGroupId())
119 && Objects.equals(d1.getArtifactId(), d2.getArtifactId())
120 && Objects.equals(d1.getVersion(), d2.getVersion())
121 && Objects.equals(d1.getType(), d2.getType())
122 && Objects.equals(d1.getClassifier(), d2.getClassifier())
123 && Objects.equals(d1.getScope(), d2.getScope())
124 && Objects.equals(d1.getSystemPath(), d2.getSystemPath())
125 && Objects.equals(d1.getOptional(), d2.getOptional())
126 && equals(d1.getExclusions(), d2.getExclusions());
127 }
128
129 private boolean equals(Collection<Exclusion> ce1, Collection<Exclusion> ce2) {
130 if (ce1.size() == ce2.size()) {
131 Iterator<Exclusion> i1 = ce1.iterator();
132 Iterator<Exclusion> i2 = ce2.iterator();
133 while (i1.hasNext() && i2.hasNext()) {
134 if (!equals(i1.next(), i2.next())) {
135 return false;
136 }
137 }
138 return !i1.hasNext() && !i2.hasNext();
139 }
140 return false;
141 }
142
143 private boolean equals(Exclusion e1, Exclusion e2) {
144 return Objects.equals(e1.getGroupId(), e2.getGroupId())
145 && Objects.equals(e1.getArtifactId(), e2.getArtifactId());
146 }
147 }