1 package org.apache.maven.plugin.assembly.artifact;
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.HashSet;
25 import java.util.LinkedHashSet;
26 import java.util.List;
27 import java.util.Set;
28
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.artifact.factory.ArtifactFactory;
31 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.artifact.resolver.ArtifactCollector;
34 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
35 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
36 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
37 import org.apache.maven.artifact.resolver.ArtifactResolver;
38 import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
39 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
40 import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
41 import org.apache.maven.plugin.assembly.AssemblyContext;
42 import org.apache.maven.plugin.assembly.archive.ArchiveCreationException;
43 import org.apache.maven.plugin.assembly.archive.phase.ModuleSetAssemblyPhase;
44 import org.apache.maven.plugin.assembly.model.Assembly;
45 import org.apache.maven.plugin.assembly.model.DependencySet;
46 import org.apache.maven.plugin.assembly.model.ModuleBinaries;
47 import org.apache.maven.plugin.assembly.model.ModuleSet;
48 import org.apache.maven.plugin.assembly.model.Repository;
49 import org.apache.maven.plugin.assembly.utils.FilterUtils;
50 import org.apache.maven.project.MavenProject;
51 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
52 import org.codehaus.plexus.component.annotations.Component;
53 import org.codehaus.plexus.component.annotations.Requirement;
54 import org.codehaus.plexus.logging.AbstractLogEnabled;
55 import org.codehaus.plexus.logging.Logger;
56 import org.codehaus.plexus.util.StringUtils;
57
58
59
60
61
62 @Component( role = DependencyResolver.class )
63 public class DefaultDependencyResolver
64 extends AbstractLogEnabled
65 implements DependencyResolver
66 {
67
68 @Requirement
69 private ArtifactResolver resolver;
70
71 @Requirement
72 private ArtifactMetadataSource metadataSource;
73
74 @Requirement
75 private ArtifactFactory factory;
76
77 @Requirement
78 private ArtifactCollector collector;
79
80 public DefaultDependencyResolver()
81 {
82
83 }
84
85 protected DefaultDependencyResolver( final ArtifactResolver resolver, final ArtifactMetadataSource metadataSource,
86 final ArtifactFactory factory, final ArtifactCollector collector,
87 final Logger logger )
88 {
89 this.resolver = resolver;
90 this.metadataSource = metadataSource;
91 this.factory = factory;
92 this.collector = collector;
93
94 enableLogging( logger );
95 }
96
97 public void resolve( final Assembly assembly, final AssemblerConfigurationSource configSource,
98 final AssemblyContext context )
99 throws DependencyResolutionException
100 {
101 final MavenProject currentProject = configSource.getProject();
102
103 final ResolutionManagementInfo info = new ResolutionManagementInfo( currentProject );
104 getRepositoryResolutionRequirements( assembly, info, currentProject );
105 getDependencySetResolutionRequirements( assembly, assembly.getDependencySets(), info, currentProject );
106 getModuleSetResolutionRequirements( assembly, info, configSource );
107
108 if ( !info.isResolutionRequired() )
109 {
110 context.setResolvedArtifacts( new HashSet<Artifact>() );
111 return;
112 }
113
114 final List<ArtifactRepository> repos =
115 aggregateRemoteArtifactRepositories( configSource.getRemoteRepositories(), info.getEnabledProjects() );
116
117 Set<Artifact> artifacts = info.getArtifacts();
118 if ( info.isResolvedTransitively() )
119 {
120 getLogger().debug( "Resolving project dependencies transitively." );
121 artifacts = resolveTransitively( artifacts, repos, info, configSource );
122 }
123 else
124 {
125 getLogger().debug( "Resolving project dependencies ONLY. Transitive dependencies WILL NOT be included in the results." );
126 artifacts = resolveNonTransitively( assembly, artifacts, configSource, repos );
127 }
128
129 context.setResolvedArtifacts( artifacts );
130 }
131
132 protected Set<Artifact> resolveNonTransitively( final Assembly assembly, final Set<Artifact> dependencyArtifacts,
133 final AssemblerConfigurationSource configSource,
134 final List<ArtifactRepository> repos )
135 throws DependencyResolutionException
136 {
137
138 final List<Artifact> missing = new ArrayList<Artifact>();
139 final Set<Artifact> resolved = new LinkedHashSet<Artifact>();
140 for (final Artifact depArtifact : dependencyArtifacts) {
141 try {
142 resolver.resolve(depArtifact, repos, configSource.getLocalRepository());
143 resolved.add(depArtifact);
144 } catch (final ArtifactResolutionException e) {
145 if (getLogger().isDebugEnabled()) {
146 getLogger().debug("Failed to resolve: " + depArtifact.getId() + " for assembly: "
147 + assembly.getId());
148 }
149 missing.add(depArtifact);
150 } catch (final ArtifactNotFoundException e) {
151 if (getLogger().isDebugEnabled()) {
152 getLogger().debug("Failed to resolve: " + depArtifact.getId() + " for assembly: "
153 + assembly.getId());
154 }
155 missing.add(depArtifact);
156 }
157 }
158
159 if ( !missing.isEmpty() )
160 {
161 final MavenProject project = configSource.getProject();
162 final Artifact rootArtifact = project.getArtifact();
163
164 final Throwable error =
165 new MultipleArtifactsNotFoundException( rootArtifact, new ArrayList<Artifact>( resolved ), missing,
166 repos );
167
168 throw new DependencyResolutionException( "Failed to resolve dependencies for: " + assembly.getId(), error );
169 }
170
171 return resolved;
172 }
173
174 @SuppressWarnings( "unchecked" )
175 private Set<Artifact> resolveTransitively( final Set<Artifact> dependencyArtifacts,
176 final List<ArtifactRepository> repos,
177 final ResolutionManagementInfo info,
178 final AssemblerConfigurationSource configSource )
179 throws DependencyResolutionException
180 {
181 final MavenProject project = configSource.getProject();
182
183 final ArtifactFilter filter = info.getScopeFilter();
184 final ArtifactRepository localRepository = configSource.getLocalRepository();
185
186 ArtifactResolutionResult result;
187 try
188 {
189 result =
190 resolver.resolveTransitively( dependencyArtifacts, project.getArtifact(),
191 project.getManagedVersionMap(), localRepository, repos, metadataSource,
192 filter );
193 }
194 catch ( final ArtifactResolutionException e )
195 {
196 throw new DependencyResolutionException( "Failed to resolve dependencies for assembly: ", e );
197 }
198 catch ( final ArtifactNotFoundException e )
199 {
200 throw new DependencyResolutionException( "Failed to resolve dependencies for assembly: ", e );
201 }
202
203 getLogger().debug( "While resolving dependencies of " + project.getId() + ":" );
204
205 FilterUtils.reportFilteringStatistics( Collections.singleton( filter ), getLogger() );
206
207 return result.getArtifacts();
208 }
209
210 protected void getRepositoryResolutionRequirements( final Assembly assembly,
211 final ResolutionManagementInfo requirements,
212 final MavenProject... project )
213 {
214 final List<Repository> repositories = assembly.getRepositories();
215
216 if ( repositories != null && !repositories.isEmpty() )
217 {
218 requirements.setResolutionRequired( true );
219 for ( final Repository repo : repositories )
220 {
221 enableScope( repo.getScope(), requirements );
222 }
223 }
224 }
225
226 protected void getModuleSetResolutionRequirements( final Assembly assembly,
227 final ResolutionManagementInfo requirements,
228 final AssemblerConfigurationSource configSource )
229 throws DependencyResolutionException
230 {
231 final List<ModuleSet> moduleSets = assembly.getModuleSets();
232
233 if ( moduleSets != null && !moduleSets.isEmpty() )
234 {
235 for ( final ModuleSet set : moduleSets )
236 {
237 final ModuleBinaries binaries = set.getBinaries();
238 if ( binaries != null )
239 {
240 Set<MavenProject> projects;
241 try
242 {
243 projects = ModuleSetAssemblyPhase.getModuleProjects( set, configSource, getLogger() );
244 }
245 catch ( final ArchiveCreationException e )
246 {
247 throw new DependencyResolutionException(
248 "Error determining project-set for moduleSet with binaries.",
249 e );
250 }
251
252 if ( projects != null && !projects.isEmpty() )
253 {
254 for ( final MavenProject p : projects )
255 {
256 requirements.enableProjectResolution( p );
257
258 if ( p.getArtifact() == null )
259 {
260
261
262 final Artifact artifact =
263 factory.createBuildArtifact( p.getGroupId(), p.getArtifactId(), p.getVersion(),
264 p.getPackaging() );
265 p.setArtifact( artifact );
266 }
267 }
268 }
269
270 if ( binaries.isIncludeDependencies() )
271 {
272 getDependencySetResolutionRequirements( assembly,
273 ModuleSetAssemblyPhase.getDependencySets( binaries ),
274 requirements, projects.toArray(new MavenProject[projects.size()]));
275 }
276 }
277 }
278 }
279 }
280
281 @SuppressWarnings( "unchecked" )
282 protected void getDependencySetResolutionRequirements( final Assembly assembly, final List<DependencySet> depSets,
283 final ResolutionManagementInfo requirements,
284 final MavenProject... projects )
285 throws DependencyResolutionException
286 {
287 if ( depSets != null && !depSets.isEmpty() )
288 {
289 requirements.setResolutionRequired( true );
290
291 for ( final DependencySet set : depSets )
292 {
293 requirements.setResolvedTransitively( set.isUseTransitiveDependencies() );
294
295 enableScope( set.getScope(), requirements );
296 }
297
298 for ( final MavenProject project : projects )
299 {
300 if ( project == null )
301 {
302 continue;
303 }
304
305 Set<Artifact> dependencyArtifacts = project.getDependencyArtifacts();
306 if ( dependencyArtifacts == null )
307 {
308 try
309 {
310 dependencyArtifacts = project.createArtifacts( factory, null, requirements.getScopeFilter() );
311 project.setDependencyArtifacts( dependencyArtifacts );
312 }
313 catch ( final InvalidDependencyVersionException e )
314 {
315 throw new DependencyResolutionException(
316 "Failed to create dependency artifacts for resolution. Assembly: "
317 + assembly.getId(), e );
318 }
319 }
320
321 requirements.addArtifacts( dependencyArtifacts );
322 getLogger().debug( "Dependencies for project: " + project.getId() + " are:\n"
323 + StringUtils.join( dependencyArtifacts.iterator(), "\n" ) );
324 }
325 }
326 }
327
328 private void enableScope( final String scope, final ResolutionManagementInfo requirements )
329 {
330 if ( Artifact.SCOPE_COMPILE.equals( scope ) )
331 {
332 requirements.enableCompileScope();
333 }
334 else if ( Artifact.SCOPE_PROVIDED.equals( scope ) )
335 {
336 requirements.enableProvidedScope();
337 }
338 else if ( Artifact.SCOPE_RUNTIME.equals( scope ) )
339 {
340 requirements.enableRuntimeScope();
341 }
342 else if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
343 {
344 requirements.enableSystemScope();
345 }
346 else if ( Artifact.SCOPE_TEST.equals( scope ) )
347 {
348 requirements.enableTestScope();
349 }
350 }
351
352 @SuppressWarnings( "unchecked" )
353 protected List<ArtifactRepository> aggregateRemoteArtifactRepositories( final List<ArtifactRepository> remoteRepositories,
354 final Set<MavenProject> projects )
355 {
356 final List<List<ArtifactRepository>> repoLists = new ArrayList<List<ArtifactRepository>>();
357
358 repoLists.add( remoteRepositories );
359 for ( final MavenProject project : projects )
360 {
361 repoLists.add( project.getRemoteArtifactRepositories() );
362 }
363
364 final List<ArtifactRepository> remoteRepos = new ArrayList<ArtifactRepository>();
365 final Set<String> encounteredUrls = new HashSet<String>();
366
367 for (final List<ArtifactRepository> repositoryList : repoLists) {
368 if ((repositoryList != null) && !repositoryList.isEmpty()) {
369 for (final ArtifactRepository repo : repositoryList) {
370 if (!encounteredUrls.contains(repo.getUrl())) {
371 remoteRepos.add(repo);
372 encounteredUrls.add(repo.getUrl());
373 }
374 }
375 }
376 }
377
378 return remoteRepos;
379 }
380
381 protected ArtifactResolver getArtifactResolver()
382 {
383 return resolver;
384 }
385
386 protected DefaultDependencyResolver setArtifactResolver( final ArtifactResolver resolver )
387 {
388 this.resolver = resolver;
389
390 return this;
391 }
392
393 protected ArtifactMetadataSource getArtifactMetadataSource()
394 {
395 return metadataSource;
396 }
397
398 protected DefaultDependencyResolver setArtifactMetadataSource( final ArtifactMetadataSource metadataSource )
399 {
400 this.metadataSource = metadataSource;
401
402 return this;
403 }
404
405 protected ArtifactFactory getArtifactFactory()
406 {
407 return factory;
408 }
409
410 protected DefaultDependencyResolver setArtifactFactory( final ArtifactFactory factory )
411 {
412 this.factory = factory;
413
414 return this;
415 }
416
417 protected ArtifactCollector getArtifactCollector()
418 {
419 return collector;
420 }
421
422 protected DefaultDependencyResolver setArtifactCollector( final ArtifactCollector collector )
423 {
424 this.collector = collector;
425
426 return this;
427 }
428
429 protected DefaultDependencyResolver setLogger( final Logger logger )
430 {
431 enableLogging( logger );
432
433 return this;
434 }
435
436 }