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     public DefaultRepositorySystem() {
121         // enables default constructor
122         this.shutdown = new AtomicBoolean(false);
123     }
124 
125     @SuppressWarnings("checkstyle:parameternumber")
126     @Inject
127     DefaultRepositorySystem(
128             VersionResolver versionResolver,
129             VersionRangeResolver versionRangeResolver,
130             ArtifactResolver artifactResolver,
131             MetadataResolver metadataResolver,
132             ArtifactDescriptorReader artifactDescriptorReader,
133             DependencyCollector dependencyCollector,
134             Installer installer,
135             Deployer deployer,
136             LocalRepositoryProvider localRepositoryProvider,
137             SyncContextFactory syncContextFactory,
138             RemoteRepositoryManager remoteRepositoryManager,
139             RepositorySystemLifecycle repositorySystemLifecycle) {
140         this.shutdown = new AtomicBoolean(false);
141         setVersionResolver(versionResolver);
142         setVersionRangeResolver(versionRangeResolver);
143         setArtifactResolver(artifactResolver);
144         setMetadataResolver(metadataResolver);
145         setArtifactDescriptorReader(artifactDescriptorReader);
146         setDependencyCollector(dependencyCollector);
147         setInstaller(installer);
148         setDeployer(deployer);
149         setLocalRepositoryProvider(localRepositoryProvider);
150         setSyncContextFactory(syncContextFactory);
151         setRemoteRepositoryManager(remoteRepositoryManager);
152         setRepositorySystemLifecycle(repositorySystemLifecycle);
153     }
154 
155     @Override
156     public void initService(ServiceLocator locator) {
157         setVersionResolver(locator.getService(VersionResolver.class));
158         setVersionRangeResolver(locator.getService(VersionRangeResolver.class));
159         setArtifactResolver(locator.getService(ArtifactResolver.class));
160         setMetadataResolver(locator.getService(MetadataResolver.class));
161         setArtifactDescriptorReader(locator.getService(ArtifactDescriptorReader.class));
162         setDependencyCollector(locator.getService(DependencyCollector.class));
163         setInstaller(locator.getService(Installer.class));
164         setDeployer(locator.getService(Deployer.class));
165         setLocalRepositoryProvider(locator.getService(LocalRepositoryProvider.class));
166         setRemoteRepositoryManager(locator.getService(RemoteRepositoryManager.class));
167         setSyncContextFactory(locator.getService(SyncContextFactory.class));
168         setRepositorySystemLifecycle(locator.getService(RepositorySystemLifecycle.class));
169     }
170 
171     /**
172      * @deprecated not used any more since MRESOLVER-36 move to slf4j, added back in MRESOLVER-64 for compatibility
173      */
174     @Deprecated
175     public DefaultRepositorySystem setLoggerFactory(org.eclipse.aether.spi.log.LoggerFactory loggerFactory) {
176         // this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
177         return this;
178     }
179 
180     public DefaultRepositorySystem setVersionResolver(VersionResolver versionResolver) {
181         this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
182         return this;
183     }
184 
185     public DefaultRepositorySystem setVersionRangeResolver(VersionRangeResolver versionRangeResolver) {
186         this.versionRangeResolver = requireNonNull(versionRangeResolver, "version range resolver cannot be null");
187         return this;
188     }
189 
190     public DefaultRepositorySystem setArtifactResolver(ArtifactResolver artifactResolver) {
191         this.artifactResolver = requireNonNull(artifactResolver, "artifact resolver cannot be null");
192         return this;
193     }
194 
195     public DefaultRepositorySystem setMetadataResolver(MetadataResolver metadataResolver) {
196         this.metadataResolver = requireNonNull(metadataResolver, "metadata resolver cannot be null");
197         return this;
198     }
199 
200     public DefaultRepositorySystem setArtifactDescriptorReader(ArtifactDescriptorReader artifactDescriptorReader) {
201         this.artifactDescriptorReader =
202                 requireNonNull(artifactDescriptorReader, "artifact descriptor reader cannot be null");
203         return this;
204     }
205 
206     public DefaultRepositorySystem setDependencyCollector(DependencyCollector dependencyCollector) {
207         this.dependencyCollector = requireNonNull(dependencyCollector, "dependency collector cannot be null");
208         return this;
209     }
210 
211     public DefaultRepositorySystem setInstaller(Installer installer) {
212         this.installer = requireNonNull(installer, "installer cannot be null");
213         return this;
214     }
215 
216     public DefaultRepositorySystem setDeployer(Deployer deployer) {
217         this.deployer = requireNonNull(deployer, "deployer cannot be null");
218         return this;
219     }
220 
221     public DefaultRepositorySystem setLocalRepositoryProvider(LocalRepositoryProvider localRepositoryProvider) {
222         this.localRepositoryProvider =
223                 requireNonNull(localRepositoryProvider, "local repository provider cannot be null");
224         return this;
225     }
226 
227     public DefaultRepositorySystem setSyncContextFactory(SyncContextFactory syncContextFactory) {
228         this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
229         return this;
230     }
231 
232     public DefaultRepositorySystem setRemoteRepositoryManager(RemoteRepositoryManager remoteRepositoryManager) {
233         this.remoteRepositoryManager =
234                 requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
235         return this;
236     }
237 
238     public DefaultRepositorySystem setRepositorySystemLifecycle(RepositorySystemLifecycle repositorySystemLifecycle) {
239         this.repositorySystemLifecycle =
240                 requireNonNull(repositorySystemLifecycle, "repository system lifecycle cannot be null");
241         return this;
242     }
243 
244     @Override
245     public VersionResult resolveVersion(RepositorySystemSession session, VersionRequest request)
246             throws VersionResolutionException {
247         validateSession(session);
248         requireNonNull(request, "request cannot be null");
249 
250         return versionResolver.resolveVersion(session, request);
251     }
252 
253     @Override
254     public VersionRangeResult resolveVersionRange(RepositorySystemSession session, VersionRangeRequest request)
255             throws VersionRangeResolutionException {
256         validateSession(session);
257         requireNonNull(request, "request cannot be null");
258 
259         return versionRangeResolver.resolveVersionRange(session, request);
260     }
261 
262     @Override
263     public ArtifactDescriptorResult readArtifactDescriptor(
264             RepositorySystemSession session, ArtifactDescriptorRequest request) throws ArtifactDescriptorException {
265         validateSession(session);
266         requireNonNull(request, "request cannot be null");
267 
268         return artifactDescriptorReader.readArtifactDescriptor(session, request);
269     }
270 
271     @Override
272     public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
273             throws ArtifactResolutionException {
274         validateSession(session);
275         requireNonNull(session, "session cannot be null");
276 
277         return artifactResolver.resolveArtifact(session, request);
278     }
279 
280     @Override
281     public List<ArtifactResult> resolveArtifacts(
282             RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
283             throws ArtifactResolutionException {
284         validateSession(session);
285         requireNonNull(requests, "requests cannot be null");
286 
287         return artifactResolver.resolveArtifacts(session, requests);
288     }
289 
290     @Override
291     public List<MetadataResult> resolveMetadata(
292             RepositorySystemSession session, Collection<? extends MetadataRequest> requests) {
293         validateSession(session);
294         requireNonNull(requests, "requests cannot be null");
295 
296         return metadataResolver.resolveMetadata(session, requests);
297     }
298 
299     @Override
300     public CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request)
301             throws DependencyCollectionException {
302         validateSession(session);
303         requireNonNull(request, "request cannot be null");
304 
305         return dependencyCollector.collectDependencies(session, request);
306     }
307 
308     @Override
309     public DependencyResult resolveDependencies(RepositorySystemSession session, DependencyRequest request)
310             throws DependencyResolutionException {
311         validateSession(session);
312         requireNonNull(request, "request cannot be null");
313 
314         RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
315 
316         DependencyResult result = new DependencyResult(request);
317 
318         DependencyCollectionException dce = null;
319         ArtifactResolutionException are = null;
320 
321         if (request.getRoot() != null) {
322             result.setRoot(request.getRoot());
323         } else if (request.getCollectRequest() != null) {
324             CollectResult collectResult;
325             try {
326                 request.getCollectRequest().setTrace(trace);
327                 collectResult = dependencyCollector.collectDependencies(session, request.getCollectRequest());
328             } catch (DependencyCollectionException e) {
329                 dce = e;
330                 collectResult = e.getResult();
331             }
332             result.setRoot(collectResult.getRoot());
333             result.setCycles(collectResult.getCycles());
334             result.setCollectExceptions(collectResult.getExceptions());
335         } else {
336             throw new NullPointerException("dependency node and collect request cannot be null");
337         }
338 
339         ArtifactRequestBuilder builder = new ArtifactRequestBuilder(trace);
340         DependencyFilter filter = request.getFilter();
341         DependencyVisitor visitor = (filter != null) ? new FilteringDependencyVisitor(builder, filter) : builder;
342         visitor = new TreeDependencyVisitor(visitor);
343 
344         if (result.getRoot() != null) {
345             result.getRoot().accept(visitor);
346         }
347 
348         List<ArtifactRequest> requests = builder.getRequests();
349 
350         List<ArtifactResult> results;
351         try {
352             results = artifactResolver.resolveArtifacts(session, requests);
353         } catch (ArtifactResolutionException e) {
354             are = e;
355             results = e.getResults();
356         }
357         result.setArtifactResults(results);
358 
359         updateNodesWithResolvedArtifacts(results);
360 
361         if (dce != null) {
362             throw new DependencyResolutionException(result, dce);
363         } else if (are != null) {
364             throw new DependencyResolutionException(result, are);
365         }
366 
367         return result;
368     }
369 
370     private void updateNodesWithResolvedArtifacts(List<ArtifactResult> results) {
371         for (ArtifactResult result : results) {
372             Artifact artifact = result.getArtifact();
373             if (artifact != null) {
374                 result.getRequest().getDependencyNode().setArtifact(artifact);
375             }
376         }
377     }
378 
379     @Override
380     public InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException {
381         validateSession(session);
382         requireNonNull(request, "request cannot be null");
383 
384         return installer.install(session, request);
385     }
386 
387     @Override
388     public DeployResult deploy(RepositorySystemSession session, DeployRequest request) throws DeploymentException {
389         validateSession(session);
390         requireNonNull(request, "request cannot be null");
391 
392         return deployer.deploy(session, request);
393     }
394 
395     @Override
396     public LocalRepositoryManager newLocalRepositoryManager(
397             RepositorySystemSession session, LocalRepository localRepository) {
398         requireNonNull(session, "session cannot be null");
399         requireNonNull(localRepository, "localRepository cannot be null");
400 
401         try {
402             return localRepositoryProvider.newLocalRepositoryManager(session, localRepository);
403         } catch (NoLocalRepositoryManagerException e) {
404             throw new IllegalArgumentException(e.getMessage(), e);
405         }
406     }
407 
408     @Override
409     public SyncContext newSyncContext(RepositorySystemSession session, boolean shared) {
410         validateSession(session);
411         return syncContextFactory.newInstance(session, shared);
412     }
413 
414     @Override
415     public List<RemoteRepository> newResolutionRepositories(
416             RepositorySystemSession session, List<RemoteRepository> repositories) {
417         validateSession(session);
418         validateRepositories(repositories);
419 
420         repositories = remoteRepositoryManager.aggregateRepositories(
421                 session, new ArrayList<RemoteRepository>(), 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 }