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 String requiredMavenVersion = (String) result.getProperties().get( "prerequisites.maven" );
112 if ( requiredMavenVersion != null )
113 {
114 Map<String, String> props = new LinkedHashMap<>( pluginArtifact.getProperties() );
115 props.put( "requiredMavenVersion", requiredMavenVersion );
116 pluginArtifact = pluginArtifact.setProperties( props );
117 }
118 }
119 catch ( ArtifactDescriptorException e )
120 {
121 throw new PluginResolutionException( plugin, e );
122 }
123
124 try
125 {
126 ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
127 request.setTrace( trace );
128 pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact();
129 }
130 catch ( ArtifactResolutionException e )
131 {
132 throw new PluginResolutionException( plugin, e );
133 }
134
135 return pluginArtifact;
136 }
137
138
139
140
141 public DependencyNode resolveCoreExtension( Plugin plugin, DependencyFilter dependencyFilter,
142 List<RemoteRepository> repositories, RepositorySystemSession session )
143 throws PluginResolutionException
144 {
145 return resolveInternal( plugin, null , dependencyFilter, null ,
146 repositories, session );
147 }
148
149 public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
150 List<RemoteRepository> repositories, RepositorySystemSession session )
151 throws PluginResolutionException
152 {
153 return resolveInternal( plugin, pluginArtifact, dependencyFilter, new PlexusUtilsInjector(), repositories,
154 session );
155 }
156
157 private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
158 DependencyGraphTransformer transformer,
159 List<RemoteRepository> repositories, RepositorySystemSession session )
160 throws PluginResolutionException
161 {
162 RequestTrace trace = RequestTrace.newChild( null, plugin );
163
164 if ( pluginArtifact == null )
165 {
166 pluginArtifact = toArtifact( plugin, session );
167 }
168
169 DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
170 DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
171
172 DependencyNode node;
173
174 try
175 {
176 DependencySelector selector =
177 AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
178
179 transformer =
180 ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), transformer );
181
182 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
183 pluginSession.setDependencySelector( selector );
184 pluginSession.setDependencyGraphTransformer( transformer );
185
186 CollectRequest request = new CollectRequest();
187 request.setRequestContext( REPOSITORY_CONTEXT );
188 request.setRepositories( repositories );
189 request.setRoot( new org.eclipse.aether.graph.Dependency( pluginArtifact, null ) );
190 for ( Dependency dependency : plugin.getDependencies() )
191 {
192 org.eclipse.aether.graph.Dependency pluginDep =
193 RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() );
194 if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) )
195 {
196 pluginDep = pluginDep.setScope( JavaScopes.RUNTIME );
197 }
198 request.addDependency( pluginDep );
199 }
200
201 DependencyRequest depRequest = new DependencyRequest( request, resolutionFilter );
202 depRequest.setTrace( trace );
203
204 request.setTrace( RequestTrace.newChild( trace, depRequest ) );
205
206 node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
207
208 if ( logger.isDebugEnabled() )
209 {
210 node.accept( new GraphLogger() );
211 }
212
213 depRequest.setRoot( node );
214 repoSystem.resolveDependencies( session, depRequest );
215 }
216 catch ( DependencyCollectionException e )
217 {
218 throw new PluginResolutionException( plugin, e );
219 }
220 catch ( DependencyResolutionException e )
221 {
222 throw new PluginResolutionException( plugin, e.getCause() );
223 }
224
225 return node;
226 }
227
228
229 class GraphLogger
230 implements DependencyVisitor
231 {
232
233 private String indent = "";
234
235 public boolean visitEnter( DependencyNode node )
236 {
237 StringBuilder buffer = new StringBuilder( 128 );
238 buffer.append( indent );
239 org.eclipse.aether.graph.Dependency dep = node.getDependency();
240 if ( dep != null )
241 {
242 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
243
244 buffer.append( art );
245 if ( StringUtils.isNotEmpty( dep.getScope() ) )
246 {
247 buffer.append( ':' ).append( dep.getScope() );
248 }
249
250 if ( dep.isOptional() )
251 {
252 buffer.append( " (optional)" );
253 }
254
255
256
257
258 if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) == DependencyNode.MANAGED_SCOPE )
259 {
260 final String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
261 buffer.append( " (scope managed from " );
262 buffer.append( Objects.toString( premanagedScope, "default" ) );
263 buffer.append( ')' );
264 }
265
266 if ( ( node.getManagedBits() & DependencyNode.MANAGED_VERSION ) == DependencyNode.MANAGED_VERSION )
267 {
268 final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
269 buffer.append( " (version managed from " );
270 buffer.append( Objects.toString( premanagedVersion, "default" ) );
271 buffer.append( ')' );
272 }
273
274 if ( ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) == DependencyNode.MANAGED_OPTIONAL )
275 {
276 final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
277 buffer.append( " (optionality managed from " );
278 buffer.append( Objects.toString( premanagedOptional, "default" ) );
279 buffer.append( ')' );
280 }
281
282 if ( ( node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS )
283 == DependencyNode.MANAGED_EXCLUSIONS )
284 {
285 final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
286 DependencyManagerUtils.getPremanagedExclusions( node );
287
288 buffer.append( " (exclusions managed from " );
289 buffer.append( Objects.toString( premanagedExclusions, "default" ) );
290 buffer.append( ')' );
291 }
292
293 if ( ( node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES )
294 == DependencyNode.MANAGED_PROPERTIES )
295 {
296 final Map<String, String> premanagedProperties =
297 DependencyManagerUtils.getPremanagedProperties( node );
298
299 buffer.append( " (properties managed from " );
300 buffer.append( Objects.toString( premanagedProperties, "default" ) );
301 buffer.append( ')' );
302 }
303 }
304
305 logger.debug( buffer.toString() );
306 indent += " ";
307 return true;
308 }
309
310 public boolean visitLeave( DependencyNode node )
311 {
312 indent = indent.substring( 0, indent.length() - 3 );
313 return true;
314 }
315
316 }
317
318 }