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