1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.dependency.graph.internal;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.maven.RepositoryUtils;
30 import org.apache.maven.artifact.Artifact;
31 import org.apache.maven.artifact.repository.ArtifactRepository;
32 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
33 import org.apache.maven.model.Dependency;
34 import org.apache.maven.project.MavenProject;
35 import org.apache.maven.project.ProjectBuildingRequest;
36 import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
37 import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException;
38 import org.apache.maven.shared.dependency.graph.DependencyCollectorRequest;
39 import org.apache.maven.shared.dependency.graph.DependencyNode;
40 import org.eclipse.aether.DefaultRepositorySystemSession;
41 import org.eclipse.aether.RepositorySystem;
42 import org.eclipse.aether.RepositorySystemSession;
43 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
44 import org.eclipse.aether.collection.CollectRequest;
45 import org.eclipse.aether.collection.CollectResult;
46 import org.eclipse.aether.collection.DependencyCollectionException;
47 import org.eclipse.aether.graph.DependencyVisitor;
48 import org.eclipse.aether.graph.Exclusion;
49 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
50 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
51 import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
52 import org.eclipse.aether.version.VersionConstraint;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56
57
58
59
60
61
62 @Named
63 public class DefaultDependencyCollectorBuilder implements DependencyCollectorBuilder {
64 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDependencyCollectorBuilder.class);
65
66 private final RepositorySystem repositorySystem;
67
68 @Inject
69 public DefaultDependencyCollectorBuilder(RepositorySystem repositorySystem) {
70 this.repositorySystem = repositorySystem;
71 }
72
73 @Override
74 public DependencyNode collectDependencyGraph(DependencyCollectorRequest dependencyCollectorRequest)
75 throws DependencyCollectorBuilderException {
76 DefaultRepositorySystemSession session = null;
77 try {
78 ProjectBuildingRequest buildingRequest = dependencyCollectorRequest.getBuildingRequest();
79 MavenProject project = buildingRequest.getProject();
80
81 Artifact projectArtifact = project.getArtifact();
82 List<ArtifactRepository> remoteArtifactRepositories = project.getRemoteArtifactRepositories();
83
84 RepositorySystemSession repositorySession = buildingRequest.getRepositorySession();
85
86 session = new DefaultRepositorySystemSession(repositorySession);
87
88 session.setDependencyGraphTransformer(dependencyCollectorRequest.getDependencyGraphTransformer());
89
90 session.setDependencySelector(dependencyCollectorRequest.getDependencySelector());
91
92 for (Map.Entry<String, Object> entry :
93 dependencyCollectorRequest.getConfigProperties().entrySet()) {
94 session.setConfigProperty(entry.getKey(), entry.getValue());
95 }
96
97 org.eclipse.aether.artifact.Artifact aetherArtifact = RepositoryUtils.toArtifact(projectArtifact);
98
99 List<org.eclipse.aether.repository.RemoteRepository> aetherRepos =
100 RepositoryUtils.toRepos(remoteArtifactRepositories);
101
102 CollectRequest collectRequest = new CollectRequest();
103 collectRequest.setRootArtifact(aetherArtifact);
104 collectRequest.setRepositories(aetherRepos);
105
106 org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
107 collectDependencyList(collectRequest, project, stereotypes);
108 collectManagedDependencyList(collectRequest, project, stereotypes);
109
110 CollectResult collectResult = repositorySystem.collectDependencies(session, collectRequest);
111
112 org.eclipse.aether.graph.DependencyNode rootNode = collectResult.getRoot();
113
114 if (LOGGER.isDebugEnabled()) {
115 logTree(rootNode);
116 }
117
118 return buildDependencyNode(null, rootNode, projectArtifact, dependencyCollectorRequest.getFilter());
119 } catch (DependencyCollectionException e) {
120 throw new DependencyCollectorBuilderException("Could not collect dependencies: " + e.getResult(), e);
121 } finally {
122 if (session != null) {
123 session.setReadOnly();
124 }
125 }
126 }
127
128 private void logTree(org.eclipse.aether.graph.DependencyNode rootNode) {
129
130 rootNode.accept(new TreeDependencyVisitor(new DependencyVisitor() {
131 String indent = "";
132
133 @Override
134 public boolean visitEnter(org.eclipse.aether.graph.DependencyNode dependencyNode) {
135 LOGGER.debug("{}Aether node: {} data map: {}", indent, dependencyNode, dependencyNode.getData());
136 indent += " ";
137 return true;
138 }
139
140 @Override
141 public boolean visitLeave(org.eclipse.aether.graph.DependencyNode dependencyNode) {
142 indent = indent.substring(0, indent.length() - 4);
143 return true;
144 }
145 }));
146 }
147
148 private void collectManagedDependencyList(
149 CollectRequest collectRequest, MavenProject project, ArtifactTypeRegistry stereotypes) {
150 if (project.getDependencyManagement() != null) {
151 for (Dependency dependency : project.getDependencyManagement().getDependencies()) {
152 org.eclipse.aether.graph.Dependency aetherDep = RepositoryUtils.toDependency(dependency, stereotypes);
153 collectRequest.addManagedDependency(aetherDep);
154 }
155 }
156 }
157
158 private void collectDependencyList(
159 CollectRequest collectRequest,
160 MavenProject project,
161 org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes) {
162 for (Dependency dependency : project.getDependencies()) {
163 org.eclipse.aether.graph.Dependency aetherDep = RepositoryUtils.toDependency(dependency, stereotypes);
164 collectRequest.addDependency(aetherDep);
165 }
166 }
167
168 private Artifact getDependencyArtifact(org.eclipse.aether.graph.Dependency dep) {
169 org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact();
170
171 Artifact mavenArtifact = RepositoryUtils.toArtifact(artifact);
172 mavenArtifact.setScope(dep.getScope());
173 mavenArtifact.setOptional(dep.isOptional());
174
175 return mavenArtifact;
176 }
177
178 private DependencyNode buildDependencyNode(
179 DependencyNode parent,
180 org.eclipse.aether.graph.DependencyNode node,
181 Artifact artifact,
182 ArtifactFilter filter) {
183 String premanagedVersion = DependencyManagerUtils.getPremanagedVersion(node);
184 String premanagedScope = DependencyManagerUtils.getPremanagedScope(node);
185
186 Boolean optional = null;
187 if (node.getDependency() != null) {
188 optional = node.getDependency().isOptional();
189 }
190
191 List<org.apache.maven.model.Exclusion> exclusions = null;
192 if (node.getDependency() != null) {
193 exclusions = new ArrayList<>(node.getDependency().getExclusions().size());
194 for (Exclusion exclusion : node.getDependency().getExclusions()) {
195 org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion();
196 modelExclusion.setGroupId(exclusion.getGroupId());
197 modelExclusion.setArtifactId(exclusion.getArtifactId());
198 exclusions.add(modelExclusion);
199 }
200 }
201
202 org.eclipse.aether.graph.DependencyNode winner =
203 (org.eclipse.aether.graph.DependencyNode) node.getData().get(ConflictResolver.NODE_DATA_WINNER);
204 String winnerVersion = null;
205 String ignoredScope = null;
206 if (winner != null) {
207 winnerVersion = winner.getArtifact().getBaseVersion();
208 } else {
209 ignoredScope = (String) node.getData().get(VerboseJavaScopeSelector.REDUCED_SCOPE);
210 }
211
212 ConflictData data = new ConflictData(winnerVersion, ignoredScope);
213
214 VerboseDependencyNode current = new VerboseDependencyNode(
215 parent,
216 artifact,
217 premanagedVersion,
218 premanagedScope,
219 getVersionSelectedFromRange(node.getVersionConstraint()),
220 optional,
221 exclusions,
222 data);
223
224 List<DependencyNode> nodes = new ArrayList<>(node.getChildren().size());
225 for (org.eclipse.aether.graph.DependencyNode child : node.getChildren()) {
226 Artifact childArtifact = getDependencyArtifact(child.getDependency());
227
228 if ((filter == null) || filter.include(childArtifact)) {
229 nodes.add(buildDependencyNode(current, child, childArtifact, filter));
230 }
231 }
232
233 current.setChildren(Collections.unmodifiableList(nodes));
234
235 return current;
236 }
237
238 private String getVersionSelectedFromRange(VersionConstraint constraint) {
239 if ((constraint == null) || (constraint.getVersion() != null)) {
240 return null;
241 }
242
243 return constraint.getRange().toString();
244 }
245 }