1 package org.apache.maven.plugin.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.Collection;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27
28 import org.apache.maven.RepositoryUtils;
29 import org.apache.maven.model.Dependency;
30 import org.apache.maven.model.Plugin;
31 import org.apache.maven.plugin.PluginResolutionException;
32 import org.codehaus.plexus.component.annotations.Component;
33 import org.codehaus.plexus.component.annotations.Requirement;
34 import org.codehaus.plexus.logging.Logger;
35 import org.codehaus.plexus.util.StringUtils;
36 import org.eclipse.aether.DefaultRepositorySystemSession;
37 import org.eclipse.aether.RepositorySystem;
38 import org.eclipse.aether.RepositorySystemSession;
39 import org.eclipse.aether.RequestTrace;
40 import org.eclipse.aether.artifact.Artifact;
41 import org.eclipse.aether.artifact.DefaultArtifact;
42 import org.eclipse.aether.collection.CollectRequest;
43 import org.eclipse.aether.collection.DependencyCollectionException;
44 import org.eclipse.aether.collection.DependencyGraphTransformer;
45 import org.eclipse.aether.collection.DependencySelector;
46 import org.eclipse.aether.graph.DependencyFilter;
47 import org.eclipse.aether.graph.DependencyNode;
48 import org.eclipse.aether.graph.DependencyVisitor;
49 import org.eclipse.aether.repository.RemoteRepository;
50 import org.eclipse.aether.resolution.ArtifactDescriptorException;
51 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
52 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
53 import org.eclipse.aether.resolution.ArtifactRequest;
54 import org.eclipse.aether.resolution.ArtifactResolutionException;
55 import org.eclipse.aether.resolution.DependencyRequest;
56 import org.eclipse.aether.resolution.DependencyResolutionException;
57 import org.eclipse.aether.util.artifact.JavaScopes;
58 import org.eclipse.aether.util.filter.AndDependencyFilter;
59 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
60 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
61 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
62 import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
63 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
64
65
66
67
68
69
70
71
72
73 @Component( role = PluginDependenciesResolver.class )
74 public class DefaultPluginDependenciesResolver
75 implements PluginDependenciesResolver
76 {
77
78 private static final String REPOSITORY_CONTEXT = "plugin";
79
80 @Requirement
81 private Logger logger;
82
83 @Requirement
84 private RepositorySystem repoSystem;
85
86 private Artifact toArtifact( Plugin plugin, RepositorySystemSession session )
87 {
88 return new DefaultArtifact( plugin.getGroupId(), plugin.getArtifactId(), null, "jar", plugin.getVersion(),
89 session.getArtifactTypeRegistry().get( "maven-plugin" ) );
90 }
91
92 public Artifact resolve( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
93 throws PluginResolutionException
94 {
95 RequestTrace trace = RequestTrace.newChild( null, plugin );
96
97 Artifact pluginArtifact = toArtifact( plugin, session );
98
99 try
100 {
101 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
102 pluginSession.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, false ) );
103
104 ArtifactDescriptorRequest request =
105 new ArtifactDescriptorRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
106 request.setTrace( trace );
107 ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor( pluginSession, request );
108
109 pluginArtifact = result.getArtifact();
110
111 if ( logger.isWarnEnabled() )
112 {
113 if ( !result.getRelocations().isEmpty() )
114 {
115 String message = pluginArtifact instanceof org.apache.maven.repository.internal.RelocatedArtifact
116 ? ( ( org.apache.maven.repository.internal.RelocatedArtifact ) pluginArtifact ).getMessage()
117 : null;
118 logger.warn( "The artifact " + result.getRelocations().get( 0 ) + " has been relocated to "
119 + pluginArtifact + ( message != null ? ": " + message : "" ) );
120 }
121 }
122
123 String requiredMavenVersion = (String) result.getProperties().get( "prerequisites.maven" );
124 if ( requiredMavenVersion != null )
125 {
126 Map<String, String> props = new LinkedHashMap<>( pluginArtifact.getProperties() );
127 props.put( "requiredMavenVersion", requiredMavenVersion );
128 pluginArtifact = pluginArtifact.setProperties( props );
129 }
130 }
131 catch ( ArtifactDescriptorException e )
132 {
133 throw new PluginResolutionException( plugin, e );
134 }
135
136 try
137 {
138 ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
139 request.setTrace( trace );
140 pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact();
141 }
142 catch ( ArtifactResolutionException e )
143 {
144 throw new PluginResolutionException( plugin, e );
145 }
146
147 return pluginArtifact;
148 }
149
150
151
152
153 public DependencyNode resolveCoreExtension( Plugin plugin, DependencyFilter dependencyFilter,
154 List<RemoteRepository> repositories, RepositorySystemSession session )
155 throws PluginResolutionException
156 {
157 return resolveInternal( plugin, null , dependencyFilter, null ,
158 repositories, session );
159 }
160
161 public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
162 List<RemoteRepository> repositories, RepositorySystemSession session )
163 throws PluginResolutionException
164 {
165 return resolveInternal( plugin, pluginArtifact, dependencyFilter, new PlexusUtilsInjector(), repositories,
166 session );
167 }
168
169 private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
170 DependencyGraphTransformer transformer,
171 List<RemoteRepository> repositories, RepositorySystemSession session )
172 throws PluginResolutionException
173 {
174 RequestTrace trace = RequestTrace.newChild( null, plugin );
175
176 if ( pluginArtifact == null )
177 {
178 pluginArtifact = toArtifact( plugin, session );
179 }
180
181 DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
182 DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
183
184 DependencyNode node;
185
186 try
187 {
188 DependencySelector selector =
189 AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
190
191 transformer =
192 ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), transformer );
193
194 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
195 pluginSession.setDependencySelector( selector );
196 pluginSession.setDependencyGraphTransformer( transformer );
197
198 CollectRequest request = new CollectRequest();
199 request.setRequestContext( REPOSITORY_CONTEXT );
200 request.setRepositories( repositories );
201 request.setRoot( new org.eclipse.aether.graph.Dependency( pluginArtifact, null ) );
202 for ( Dependency dependency : plugin.getDependencies() )
203 {
204 org.eclipse.aether.graph.Dependency pluginDep =
205 RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() );
206 if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) )
207 {
208 pluginDep = pluginDep.setScope( JavaScopes.RUNTIME );
209 }
210 request.addDependency( pluginDep );
211 }
212
213 DependencyRequest depRequest = new DependencyRequest( request, resolutionFilter );
214 depRequest.setTrace( trace );
215
216 request.setTrace( RequestTrace.newChild( trace, depRequest ) );
217
218 node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
219
220 if ( logger.isDebugEnabled() )
221 {
222 node.accept( new GraphLogger() );
223 }
224
225 depRequest.setRoot( node );
226 repoSystem.resolveDependencies( session, depRequest );
227 }
228 catch ( DependencyCollectionException e )
229 {
230 throw new PluginResolutionException( plugin, e );
231 }
232 catch ( DependencyResolutionException e )
233 {
234 throw new PluginResolutionException( plugin, e.getCause() );
235 }
236
237 return node;
238 }
239
240
241 class GraphLogger
242 implements DependencyVisitor
243 {
244
245 private String indent = "";
246
247 public boolean visitEnter( DependencyNode node )
248 {
249 StringBuilder buffer = new StringBuilder( 128 );
250 buffer.append( indent );
251 org.eclipse.aether.graph.Dependency dep = node.getDependency();
252 if ( dep != null )
253 {
254 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
255
256 buffer.append( art );
257 if ( StringUtils.isNotEmpty( dep.getScope() ) )
258 {
259 buffer.append( ':' ).append( dep.getScope() );
260 }
261
262 if ( dep.isOptional() )
263 {
264 buffer.append( " (optional)" );
265 }
266
267
268
269
270 if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) == DependencyNode.MANAGED_SCOPE )
271 {
272 final String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
273 buffer.append( " (scope managed from " );
274 buffer.append( Objects.toString( premanagedScope, "default" ) );
275 buffer.append( ')' );
276 }
277
278 if ( ( node.getManagedBits() & DependencyNode.MANAGED_VERSION ) == DependencyNode.MANAGED_VERSION )
279 {
280 final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
281 buffer.append( " (version managed from " );
282 buffer.append( Objects.toString( premanagedVersion, "default" ) );
283 buffer.append( ')' );
284 }
285
286 if ( ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) == DependencyNode.MANAGED_OPTIONAL )
287 {
288 final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
289 buffer.append( " (optionality managed from " );
290 buffer.append( Objects.toString( premanagedOptional, "default" ) );
291 buffer.append( ')' );
292 }
293
294 if ( ( node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS )
295 == DependencyNode.MANAGED_EXCLUSIONS )
296 {
297 final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
298 DependencyManagerUtils.getPremanagedExclusions( node );
299
300 buffer.append( " (exclusions managed from " );
301 buffer.append( Objects.toString( premanagedExclusions, "default" ) );
302 buffer.append( ')' );
303 }
304
305 if ( ( node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES )
306 == DependencyNode.MANAGED_PROPERTIES )
307 {
308 final Map<String, String> premanagedProperties =
309 DependencyManagerUtils.getPremanagedProperties( node );
310
311 buffer.append( " (properties managed from " );
312 buffer.append( Objects.toString( premanagedProperties, "default" ) );
313 buffer.append( ')' );
314 }
315 }
316
317 logger.debug( buffer.toString() );
318 indent += " ";
319 return true;
320 }
321
322 public boolean visitLeave( DependencyNode node )
323 {
324 indent = indent.substring( 0, indent.length() - 3 );
325 return true;
326 }
327
328 }
329
330 }