View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.List;
28  import java.util.concurrent.atomic.AtomicBoolean;
29  
30  import org.eclipse.aether.RepositorySystem;
31  import org.eclipse.aether.RepositorySystemSession;
32  import org.eclipse.aether.RequestTrace;
33  import org.eclipse.aether.SyncContext;
34  import org.eclipse.aether.artifact.Artifact;
35  import org.eclipse.aether.collection.CollectRequest;
36  import org.eclipse.aether.collection.CollectResult;
37  import org.eclipse.aether.collection.DependencyCollectionException;
38  import org.eclipse.aether.deployment.DeployRequest;
39  import org.eclipse.aether.deployment.DeployResult;
40  import org.eclipse.aether.deployment.DeploymentException;
41  import org.eclipse.aether.graph.DependencyFilter;
42  import org.eclipse.aether.graph.DependencyVisitor;
43  import org.eclipse.aether.impl.ArtifactDescriptorReader;
44  import org.eclipse.aether.impl.ArtifactResolver;
45  import org.eclipse.aether.impl.DependencyCollector;
46  import org.eclipse.aether.impl.Deployer;
47  import org.eclipse.aether.impl.Installer;
48  import org.eclipse.aether.impl.LocalRepositoryProvider;
49  import org.eclipse.aether.impl.MetadataResolver;
50  import org.eclipse.aether.impl.RemoteRepositoryManager;
51  import org.eclipse.aether.impl.RepositorySystemLifecycle;
52  import org.eclipse.aether.impl.VersionRangeResolver;
53  import org.eclipse.aether.impl.VersionResolver;
54  import org.eclipse.aether.installation.InstallRequest;
55  import org.eclipse.aether.installation.InstallResult;
56  import org.eclipse.aether.installation.InstallationException;
57  import org.eclipse.aether.repository.Authentication;
58  import org.eclipse.aether.repository.LocalRepository;
59  import org.eclipse.aether.repository.LocalRepositoryManager;
60  import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
61  import org.eclipse.aether.repository.Proxy;
62  import org.eclipse.aether.repository.RemoteRepository;
63  import org.eclipse.aether.resolution.ArtifactDescriptorException;
64  import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
65  import org.eclipse.aether.resolution.ArtifactDescriptorResult;
66  import org.eclipse.aether.resolution.ArtifactRequest;
67  import org.eclipse.aether.resolution.ArtifactResolutionException;
68  import org.eclipse.aether.resolution.ArtifactResult;
69  import org.eclipse.aether.resolution.DependencyRequest;
70  import org.eclipse.aether.resolution.DependencyResolutionException;
71  import org.eclipse.aether.resolution.DependencyResult;
72  import org.eclipse.aether.resolution.MetadataRequest;
73  import org.eclipse.aether.resolution.MetadataResult;
74  import org.eclipse.aether.resolution.VersionRangeRequest;
75  import org.eclipse.aether.resolution.VersionRangeResolutionException;
76  import org.eclipse.aether.resolution.VersionRangeResult;
77  import org.eclipse.aether.resolution.VersionRequest;
78  import org.eclipse.aether.resolution.VersionResolutionException;
79  import org.eclipse.aether.resolution.VersionResult;
80  import org.eclipse.aether.spi.locator.Service;
81  import org.eclipse.aether.spi.locator.ServiceLocator;
82  import org.eclipse.aether.spi.synccontext.SyncContextFactory;
83  import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
84  import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
85  
86  import static java.util.Objects.requireNonNull;
87  
88  /**
89   *
90   */
91  @Singleton
92  @Named
93  public class DefaultRepositorySystem implements RepositorySystem, Service {
94      private final AtomicBoolean shutdown;
95  
96      private VersionResolver versionResolver;
97  
98      private VersionRangeResolver versionRangeResolver;
99  
100     private ArtifactResolver artifactResolver;
101 
102     private MetadataResolver metadataResolver;
103 
104     private ArtifactDescriptorReader artifactDescriptorReader;
105 
106     private DependencyCollector dependencyCollector;
107 
108     private Installer installer;
109 
110     private Deployer deployer;
111 
112     private LocalRepositoryProvider localRepositoryProvider;
113 
114     private SyncContextFactory syncContextFactory;
115 
116     private RemoteRepositoryManager remoteRepositoryManager;
117 
118     private RepositorySystemLifecycle repositorySystemLifecycle;
119 
120     @Deprecated
121     public DefaultRepositorySystem() {
122         // enables default constructor
123         this.shutdown = new AtomicBoolean(false);
124     }
125 
126     @SuppressWarnings("checkstyle:parameternumber")
127     @Inject
128     public DefaultRepositorySystem(
129             VersionResolver versionResolver,
130             VersionRangeResolver versionRangeResolver,
131             ArtifactResolver artifactResolver,
132             MetadataResolver metadataResolver,
133             ArtifactDescriptorReader artifactDescriptorReader,
134             DependencyCollector dependencyCollector,
135             Installer installer,
136             Deployer deployer,
137             LocalRepositoryProvider localRepositoryProvider,
138             SyncContextFactory syncContextFactory,
139             RemoteRepositoryManager remoteRepositoryManager,
140             RepositorySystemLifecycle repositorySystemLifecycle) {
141         this.shutdown = new AtomicBoolean(false);
142         setVersionResolver(versionResolver);
143         setVersionRangeResolver(versionRangeResolver);
144         setArtifactResolver(artifactResolver);
145         setMetadataResolver(metadataResolver);
146         setArtifactDescriptorReader(artifactDescriptorReader);
147         setDependencyCollector(dependencyCollector);
148         setInstaller(installer);
149         setDeployer(deployer);
150         setLocalRepositoryProvider(localRepositoryProvider);
151         setSyncContextFactory(syncContextFactory);
152         setRemoteRepositoryManager(remoteRepositoryManager);
153         setRepositorySystemLifecycle(repositorySystemLifecycle);
154     }
155 
156     @Override
157     public void initService(ServiceLocator locator) {
158         setVersionResolver(locator.getService(VersionResolver.class));
159         setVersionRangeResolver(locator.getService(VersionRangeResolver.class));
160         setArtifactResolver(locator.getService(ArtifactResolver.class));
161         setMetadataResolver(locator.getService(MetadataResolver.class));
162         setArtifactDescriptorReader(locator.getService(ArtifactDescriptorReader.class));
163         setDependencyCollector(locator.getService(DependencyCollector.class));
164         setInstaller(locator.getService(Installer.class));
165         setDeployer(locator.getService(Deployer.class));
166         setLocalRepositoryProvider(locator.getService(LocalRepositoryProvider.class));
167         setRemoteRepositoryManager(locator.getService(RemoteRepositoryManager.class));
168         setSyncContextFactory(locator.getService(SyncContextFactory.class));
169         setRepositorySystemLifecycle(locator.getService(RepositorySystemLifecycle.class));
170     }
171 
172     /**
173      * @deprecated not used any more since MRESOLVER-36 move to slf4j, added back in MRESOLVER-64 for compatibility
174      */
175     @Deprecated
176     public DefaultRepositorySystem setLoggerFactory(org.eclipse.aether.spi.log.LoggerFactory loggerFactory) {
177         // this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
178         return this;
179     }
180 
181     public DefaultRepositorySystem setVersionResolver(VersionResolver versionResolver) {
182         this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
183         return this;
184     }
185 
186     public DefaultRepositorySystem setVersionRangeResolver(VersionRangeResolver versionRangeResolver) {
187         this.versionRangeResolver = requireNonNull(versionRangeResolver, "version range resolver cannot be null");
188         return this;
189     }
190 
191     public DefaultRepositorySystem setArtifactResolver(ArtifactResolver artifactResolver) {
192         this.artifactResolver = requireNonNull(artifactResolver, "artifact resolver cannot be null");
193         return this;
194     }
195 
196     public DefaultRepositorySystem setMetadataResolver(MetadataResolver metadataResolver) {
197         this.metadataResolver = requireNonNull(metadataResolver, "metadata resolver cannot be null");
198         return this;
199     }
200 
201     public DefaultRepositorySystem setArtifactDescriptorReader(ArtifactDescriptorReader artifactDescriptorReader) {
202         this.artifactDescriptorReader =
203                 requireNonNull(artifactDescriptorReader, "artifact descriptor reader cannot be null");
204         return this;
205     }
206 
207     public DefaultRepositorySystem setDependencyCollector(DependencyCollector dependencyCollector) {
208         this.dependencyCollector = requireNonNull(dependencyCollector, "dependency collector cannot be null");
209         return this;
210     }
211 
212     public DefaultRepositorySystem setInstaller(Installer installer) {
213         this.installer = requireNonNull(installer, "installer cannot be null");
214         return this;
215     }
216 
217     public DefaultRepositorySystem setDeployer(Deployer deployer) {
218         this.deployer = requireNonNull(deployer, "deployer cannot be null");
219         return this;
220     }
221 
222     public DefaultRepositorySystem setLocalRepositoryProvider(LocalRepositoryProvider localRepositoryProvider) {
223         this.localRepositoryProvider =
224                 requireNonNull(localRepositoryProvider, "local repository provider cannot be null");
225         return this;
226     }
227 
228     public DefaultRepositorySystem setSyncContextFactory(SyncContextFactory syncContextFactory) {
229         this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
230         return this;
231     }
232 
233     public DefaultRepositorySystem setRemoteRepositoryManager(RemoteRepositoryManager remoteRepositoryManager) {
234         this.remoteRepositoryManager =
235                 requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
236         return this;
237     }
238 
239     public DefaultRepositorySystem setRepositorySystemLifecycle(RepositorySystemLifecycle repositorySystemLifecycle) {
240         this.repositorySystemLifecycle =
241                 requireNonNull(repositorySystemLifecycle, "repository system lifecycle cannot be null");
242         return this;
243     }
244 
245     @Override
246     public VersionResult resolveVersion(RepositorySystemSession session, VersionRequest request)
247             throws VersionResolutionException {
248         validateSession(session);
249         requireNonNull(request, "request cannot be null");
250 
251         return versionResolver.resolveVersion(session, request);
252     }
253 
254     @Override
255     public VersionRangeResult resolveVersionRange(RepositorySystemSession session, VersionRangeRequest request)
256             throws VersionRangeResolutionException {
257         validateSession(session);
258         requireNonNull(request, "request cannot be null");
259 
260         return versionRangeResolver.resolveVersionRange(session, request);
261     }
262 
263     @Override
264     public ArtifactDescriptorResult readArtifactDescriptor(
265             RepositorySystemSession session, ArtifactDescriptorRequest request) throws ArtifactDescriptorException {
266         validateSession(session);
267         requireNonNull(request, "request cannot be null");
268 
269         return artifactDescriptorReader.readArtifactDescriptor(session, request);
270     }
271 
272     @Override
273     public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
274             throws ArtifactResolutionException {
275         validateSession(session);
276         requireNonNull(request, "request cannot be null");
277 
278         return artifactResolver.resolveArtifact(session, request);
279     }
280 
281     @Override
282     public List<ArtifactResult> resolveArtifacts(
283             RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
284             throws ArtifactResolutionException {
285         validateSession(session);
286         requireNonNull(requests, "requests cannot be null");
287 
288         return artifactResolver.resolveArtifacts(session, requests);
289     }
290 
291     @Override
292     public List<MetadataResult> resolveMetadata(
293             RepositorySystemSession session, Collection<? extends MetadataRequest> requests) {
294         validateSession(session);
295         requireNonNull(requests, "requests cannot be null");
296 
297         return metadataResolver.resolveMetadata(session, requests);
298     }
299 
300     @Override
301     public CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request)
302             throws DependencyCollectionException {
303         validateSession(session);
304         requireNonNull(request, "request cannot be null");
305 
306         return dependencyCollector.collectDependencies(session, request);
307     }
308 
309     @Override
310     public DependencyResult resolveDependencies(RepositorySystemSession session, DependencyRequest request)
311             throws DependencyResolutionException {
312         validateSession(session);
313         requireNonNull(request, "request cannot be null");
314 
315         RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
316 
317         DependencyResult result = new DependencyResult(request);
318 
319         DependencyCollectionException dce = null;
320         ArtifactResolutionException are = null;
321 
322         if (request.getRoot() != null) {
323             result.setRoot(request.getRoot());
324         } else if (request.getCollectRequest() != null) {
325             CollectResult collectResult;
326             try {
327                 request.getCollectRequest().setTrace(trace);
328                 collectResult = dependencyCollector.collectDependencies(session, request.getCollectRequest());
329             } catch (DependencyCollectionException e) {
330                 dce = e;
331                 collectResult = e.getResult();
332             }
333             result.setRoot(collectResult.getRoot());
334             result.setCycles(collectResult.getCycles());
335             result.setCollectExceptions(collectResult.getExceptions());
336         } else {
337             throw new NullPointerException("dependency node and collect request cannot be null");
338         }
339 
340         ArtifactRequestBuilder builder = new ArtifactRequestBuilder(trace);
341         DependencyFilter filter = request.getFilter();
342         DependencyVisitor visitor = (filter != null) ? new FilteringDependencyVisitor(builder, filter) : builder;
343         visitor = new TreeDependencyVisitor(visitor);
344 
345         if (result.getRoot() != null) {
346             result.getRoot().accept(visitor);
347         }
348 
349         List<ArtifactRequest> requests = builder.getRequests();
350 
351         List<ArtifactResult> results;
352         try {
353             results = artifactResolver.resolveArtifacts(session, requests);
354         } catch (ArtifactResolutionException e) {
355             are = e;
356             results = e.getResults();
357         }
358         result.setArtifactResults(results);
359 
360         updateNodesWithResolvedArtifacts(results);
361 
362         if (dce != null) {
363             throw new DependencyResolutionException(result, dce);
364         } else if (are != null) {
365             throw new DependencyResolutionException(result, are);
366         }
367 
368         return result;
369     }
370 
371     private void updateNodesWithResolvedArtifacts(List<ArtifactResult> results) {
372         for (ArtifactResult result : results) {
373             Artifact artifact = result.getArtifact();
374             if (artifact != null) {
375                 result.getRequest().getDependencyNode().setArtifact(artifact);
376             }
377         }
378     }
379 
380     @Override
381     public InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException {
382         validateSession(session);
383         requireNonNull(request, "request cannot be null");
384 
385         return installer.install(session, request);
386     }
387 
388     @Override
389     public DeployResult deploy(RepositorySystemSession session, DeployRequest request) throws DeploymentException {
390         validateSession(session);
391         requireNonNull(request, "request cannot be null");
392 
393         return deployer.deploy(session, request);
394     }
395 
396     @Override
397     public LocalRepositoryManager newLocalRepositoryManager(
398             RepositorySystemSession session, LocalRepository localRepository) {
399         requireNonNull(session, "session cannot be null");
400         requireNonNull(localRepository, "localRepository cannot be null");
401 
402         try {
403             return localRepositoryProvider.newLocalRepositoryManager(session, localRepository);
404         } catch (NoLocalRepositoryManagerException e) {
405             throw new IllegalArgumentException(e.getMessage(), e);
406         }
407     }
408 
409     @Override
410     public SyncContext newSyncContext(RepositorySystemSession session, boolean shared) {
411         validateSession(session);
412         return syncContextFactory.newInstance(session, shared);
413     }
414 
415     @Override
416     public List<RemoteRepository> newResolutionRepositories(
417             RepositorySystemSession session, List<RemoteRepository> repositories) {
418         validateSession(session);
419         validateRepositories(repositories);
420 
421         repositories = remoteRepositoryManager.aggregateRepositories(session, new ArrayList<>(), repositories, true);
422         return repositories;
423     }
424 
425     @Override
426     public RemoteRepository newDeploymentRepository(RepositorySystemSession session, RemoteRepository repository) {
427         validateSession(session);
428         requireNonNull(repository, "repository cannot be null");
429 
430         RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
431         Authentication auth = session.getAuthenticationSelector().getAuthentication(repository);
432         builder.setAuthentication(auth);
433         Proxy proxy = session.getProxySelector().getProxy(repository);
434         builder.setProxy(proxy);
435         return builder.build();
436     }
437 
438     @Override
439     public void addOnSystemEndedHandler(Runnable handler) {
440         repositorySystemLifecycle.addOnSystemEndedHandler(handler);
441     }
442 
443     @Override
444     public void shutdown() {
445         if (shutdown.compareAndSet(false, true)) {
446             repositorySystemLifecycle.systemEnded();
447         }
448     }
449 
450     private void validateSession(RepositorySystemSession session) {
451         requireNonNull(session, "repository system session cannot be null");
452         invalidSession(session.getLocalRepositoryManager(), "local repository manager");
453         invalidSession(session.getSystemProperties(), "system properties");
454         invalidSession(session.getUserProperties(), "user properties");
455         invalidSession(session.getConfigProperties(), "config properties");
456         invalidSession(session.getMirrorSelector(), "mirror selector");
457         invalidSession(session.getProxySelector(), "proxy selector");
458         invalidSession(session.getAuthenticationSelector(), "authentication selector");
459         invalidSession(session.getArtifactTypeRegistry(), "artifact type registry");
460         invalidSession(session.getData(), "data");
461         if (shutdown.get()) {
462             throw new IllegalStateException("repository system is already shut down");
463         }
464     }
465 
466     private void validateRepositories(List<RemoteRepository> repositories) {
467         requireNonNull(repositories, "repositories cannot be null");
468         for (RemoteRepository repository : repositories) {
469             requireNonNull(repository, "repository cannot be null");
470         }
471     }
472 
473     private void invalidSession(Object obj, String name) {
474         requireNonNull(obj, "repository system session's " + name + " cannot be null");
475     }
476 }