1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.Objects;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import java.util.function.Consumer;
31 import java.util.stream.Collectors;
32
33 import org.eclipse.aether.ConfigurationProperties;
34 import org.eclipse.aether.RepositorySystem;
35 import org.eclipse.aether.RepositorySystemSession;
36 import org.eclipse.aether.RequestTrace;
37 import org.eclipse.aether.SyncContext;
38 import org.eclipse.aether.artifact.Artifact;
39 import org.eclipse.aether.collection.CollectRequest;
40 import org.eclipse.aether.collection.CollectResult;
41 import org.eclipse.aether.collection.DependencyCollectionException;
42 import org.eclipse.aether.deployment.DeployRequest;
43 import org.eclipse.aether.deployment.DeployResult;
44 import org.eclipse.aether.deployment.DeploymentException;
45 import org.eclipse.aether.graph.DependencyFilter;
46 import org.eclipse.aether.graph.DependencyNode;
47 import org.eclipse.aether.graph.DependencyVisitor;
48 import org.eclipse.aether.impl.ArtifactDescriptorReader;
49 import org.eclipse.aether.impl.ArtifactResolver;
50 import org.eclipse.aether.impl.DependencyCollector;
51 import org.eclipse.aether.impl.Deployer;
52 import org.eclipse.aether.impl.Installer;
53 import org.eclipse.aether.impl.LocalRepositoryProvider;
54 import org.eclipse.aether.impl.MetadataResolver;
55 import org.eclipse.aether.impl.RemoteRepositoryManager;
56 import org.eclipse.aether.impl.RepositorySystemLifecycle;
57 import org.eclipse.aether.impl.VersionRangeResolver;
58 import org.eclipse.aether.impl.VersionResolver;
59 import org.eclipse.aether.installation.InstallRequest;
60 import org.eclipse.aether.installation.InstallResult;
61 import org.eclipse.aether.installation.InstallationException;
62 import org.eclipse.aether.repository.Authentication;
63 import org.eclipse.aether.repository.LocalRepository;
64 import org.eclipse.aether.repository.LocalRepositoryManager;
65 import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
66 import org.eclipse.aether.repository.Proxy;
67 import org.eclipse.aether.repository.RemoteRepository;
68 import org.eclipse.aether.resolution.ArtifactDescriptorException;
69 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
70 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
71 import org.eclipse.aether.resolution.ArtifactRequest;
72 import org.eclipse.aether.resolution.ArtifactResolutionException;
73 import org.eclipse.aether.resolution.ArtifactResult;
74 import org.eclipse.aether.resolution.DependencyRequest;
75 import org.eclipse.aether.resolution.DependencyResolutionException;
76 import org.eclipse.aether.resolution.DependencyResult;
77 import org.eclipse.aether.resolution.MetadataRequest;
78 import org.eclipse.aether.resolution.MetadataResult;
79 import org.eclipse.aether.resolution.VersionRangeRequest;
80 import org.eclipse.aether.resolution.VersionRangeResolutionException;
81 import org.eclipse.aether.resolution.VersionRangeResult;
82 import org.eclipse.aether.resolution.VersionRequest;
83 import org.eclipse.aether.resolution.VersionResolutionException;
84 import org.eclipse.aether.resolution.VersionResult;
85 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
86 import org.eclipse.aether.util.ConfigUtils;
87 import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
88 import org.eclipse.aether.util.graph.visitor.LevelOrderDependencyNodeConsumerVisitor;
89 import org.eclipse.aether.util.graph.visitor.PostorderDependencyNodeConsumerVisitor;
90 import org.eclipse.aether.util.graph.visitor.PreorderDependencyNodeConsumerVisitor;
91
92 import static java.util.Objects.requireNonNull;
93
94
95
96
97 @Singleton
98 @Named
99 public class DefaultRepositorySystem implements RepositorySystem {
100 private final AtomicBoolean shutdown;
101
102 private final VersionResolver versionResolver;
103
104 private final VersionRangeResolver versionRangeResolver;
105
106 private final ArtifactResolver artifactResolver;
107
108 private final MetadataResolver metadataResolver;
109
110 private final ArtifactDescriptorReader artifactDescriptorReader;
111
112 private final DependencyCollector dependencyCollector;
113
114 private final Installer installer;
115
116 private final Deployer deployer;
117
118 private final LocalRepositoryProvider localRepositoryProvider;
119
120 private final SyncContextFactory syncContextFactory;
121
122 private final RemoteRepositoryManager remoteRepositoryManager;
123
124 private final RepositorySystemLifecycle repositorySystemLifecycle;
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 this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
143 this.versionRangeResolver = requireNonNull(versionRangeResolver, "version range resolver cannot be null");
144 this.artifactResolver = requireNonNull(artifactResolver, "artifact resolver cannot be null");
145 this.metadataResolver = requireNonNull(metadataResolver, "metadata resolver cannot be null");
146 this.artifactDescriptorReader =
147 requireNonNull(artifactDescriptorReader, "artifact descriptor reader cannot be null");
148 this.dependencyCollector = requireNonNull(dependencyCollector, "dependency collector cannot be null");
149 this.installer = requireNonNull(installer, "installer cannot be null");
150 this.deployer = requireNonNull(deployer, "deployer cannot be null");
151 this.localRepositoryProvider =
152 requireNonNull(localRepositoryProvider, "local repository provider cannot be null");
153 this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
154 this.remoteRepositoryManager =
155 requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
156 this.repositorySystemLifecycle =
157 requireNonNull(repositorySystemLifecycle, "repository system lifecycle cannot be null");
158 }
159
160 @Override
161 public VersionResult resolveVersion(RepositorySystemSession session, VersionRequest request)
162 throws VersionResolutionException {
163 validateSession(session);
164 requireNonNull(request, "request cannot be null");
165
166 return versionResolver.resolveVersion(session, request);
167 }
168
169 @Override
170 public VersionRangeResult resolveVersionRange(RepositorySystemSession session, VersionRangeRequest request)
171 throws VersionRangeResolutionException {
172 validateSession(session);
173 requireNonNull(request, "request cannot be null");
174
175 return versionRangeResolver.resolveVersionRange(session, request);
176 }
177
178 @Override
179 public ArtifactDescriptorResult readArtifactDescriptor(
180 RepositorySystemSession session, ArtifactDescriptorRequest request) throws ArtifactDescriptorException {
181 validateSession(session);
182 requireNonNull(request, "request cannot be null");
183
184 return artifactDescriptorReader.readArtifactDescriptor(session, request);
185 }
186
187 @Override
188 public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
189 throws ArtifactResolutionException {
190 validateSession(session);
191 requireNonNull(request, "request cannot be null");
192
193 return artifactResolver.resolveArtifact(session, request);
194 }
195
196 @Override
197 public List<ArtifactResult> resolveArtifacts(
198 RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
199 throws ArtifactResolutionException {
200 validateSession(session);
201 requireNonNull(requests, "requests cannot be null");
202
203 return artifactResolver.resolveArtifacts(session, requests);
204 }
205
206 @Override
207 public List<MetadataResult> resolveMetadata(
208 RepositorySystemSession session, Collection<? extends MetadataRequest> requests) {
209 validateSession(session);
210 requireNonNull(requests, "requests cannot be null");
211
212 return metadataResolver.resolveMetadata(session, requests);
213 }
214
215 @Override
216 public CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request)
217 throws DependencyCollectionException {
218 validateSession(session);
219 requireNonNull(request, "request cannot be null");
220
221 return dependencyCollector.collectDependencies(session, request);
222 }
223
224 @Override
225 public DependencyResult resolveDependencies(RepositorySystemSession session, DependencyRequest request)
226 throws DependencyResolutionException {
227 validateSession(session);
228 requireNonNull(request, "request cannot be null");
229
230 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
231
232 DependencyResult result = new DependencyResult(request);
233
234 DependencyCollectionException dce = null;
235 ArtifactResolutionException are = null;
236
237 if (request.getRoot() != null) {
238 result.setRoot(request.getRoot());
239 } else if (request.getCollectRequest() != null) {
240 CollectResult collectResult;
241 try {
242 request.getCollectRequest().setTrace(trace);
243 collectResult = dependencyCollector.collectDependencies(session, request.getCollectRequest());
244 } catch (DependencyCollectionException e) {
245 dce = e;
246 collectResult = e.getResult();
247 }
248 result.setRoot(collectResult.getRoot());
249 result.setCycles(collectResult.getCycles());
250 result.setCollectExceptions(collectResult.getExceptions());
251 } else {
252 throw new NullPointerException("dependency node and collect request cannot be null");
253 }
254
255 final ArrayList<DependencyNode> dependencyNodes = new ArrayList<>();
256 DependencyVisitor builder = getDependencyVisitor(session, dependencyNodes::add);
257 DependencyFilter filter = request.getFilter();
258 DependencyVisitor visitor = (filter != null) ? new FilteringDependencyVisitor(builder, filter) : builder;
259 if (result.getRoot() != null) {
260 result.getRoot().accept(visitor);
261 }
262
263 final List<ArtifactRequest> requests = dependencyNodes.stream()
264 .map(n -> {
265 if (n.getDependency() != null) {
266 ArtifactRequest artifactRequest = new ArtifactRequest(n);
267 artifactRequest.setTrace(trace);
268 return artifactRequest;
269 } else {
270 return null;
271 }
272 })
273 .filter(Objects::nonNull)
274 .collect(Collectors.toList());
275 List<ArtifactResult> results;
276 try {
277 results = artifactResolver.resolveArtifacts(session, requests);
278 } catch (ArtifactResolutionException e) {
279 are = e;
280 results = e.getResults();
281 }
282 result.setDependencyNodeResults(dependencyNodes);
283 result.setArtifactResults(results);
284
285 updateNodesWithResolvedArtifacts(results);
286
287 if (dce != null) {
288 throw new DependencyResolutionException(result, dce);
289 } else if (are != null) {
290 throw new DependencyResolutionException(result, are);
291 }
292
293 return result;
294 }
295
296 @Override
297 public List<DependencyNode> flattenDependencyNodes(RepositorySystemSession session, DependencyNode root) {
298 validateSession(session);
299 requireNonNull(root, "root cannot be null");
300
301 final ArrayList<DependencyNode> dependencyNodes = new ArrayList<>();
302 root.accept(getDependencyVisitor(session, dependencyNodes::add));
303 return dependencyNodes;
304 }
305
306 private DependencyVisitor getDependencyVisitor(
307 RepositorySystemSession session, Consumer<DependencyNode> nodeConsumer) {
308 String strategy = ConfigUtils.getString(
309 session,
310 ConfigurationProperties.DEFAULT_REPOSITORY_SYSTEM_RESOLVER_DEPENDENCIES_VISITOR,
311 ConfigurationProperties.REPOSITORY_SYSTEM_RESOLVER_DEPENDENCIES_VISITOR);
312 switch (strategy) {
313 case PreorderDependencyNodeConsumerVisitor.NAME:
314 return new PreorderDependencyNodeConsumerVisitor(nodeConsumer);
315 case PostorderDependencyNodeConsumerVisitor.NAME:
316 return new PostorderDependencyNodeConsumerVisitor(nodeConsumer);
317 case LevelOrderDependencyNodeConsumerVisitor.NAME:
318 return new LevelOrderDependencyNodeConsumerVisitor(nodeConsumer);
319 default:
320 throw new IllegalArgumentException("Invalid dependency visitor strategy: " + strategy);
321 }
322 }
323
324 private void updateNodesWithResolvedArtifacts(List<ArtifactResult> results) {
325 for (ArtifactResult result : results) {
326 Artifact artifact = result.getArtifact();
327 if (artifact != null) {
328 result.getRequest().getDependencyNode().setArtifact(artifact);
329 }
330 }
331 }
332
333 @Override
334 public InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException {
335 validateSession(session);
336 requireNonNull(request, "request cannot be null");
337
338 return installer.install(session, request);
339 }
340
341 @Override
342 public DeployResult deploy(RepositorySystemSession session, DeployRequest request) throws DeploymentException {
343 validateSession(session);
344 requireNonNull(request, "request cannot be null");
345
346 return deployer.deploy(session, request);
347 }
348
349 @Override
350 public LocalRepositoryManager newLocalRepositoryManager(
351 RepositorySystemSession session, LocalRepository localRepository) {
352 requireNonNull(session, "session cannot be null");
353 requireNonNull(localRepository, "localRepository cannot be null");
354
355 try {
356 return localRepositoryProvider.newLocalRepositoryManager(session, localRepository);
357 } catch (NoLocalRepositoryManagerException e) {
358 throw new IllegalArgumentException(e.getMessage(), e);
359 }
360 }
361
362 @Override
363 public SyncContext newSyncContext(RepositorySystemSession session, boolean shared) {
364 validateSession(session);
365 return syncContextFactory.newInstance(session, shared);
366 }
367
368 @Override
369 public List<RemoteRepository> newResolutionRepositories(
370 RepositorySystemSession session, List<RemoteRepository> repositories) {
371 validateSession(session);
372 validateRepositories(repositories);
373
374 repositories = remoteRepositoryManager.aggregateRepositories(session, new ArrayList<>(), repositories, true);
375 return repositories;
376 }
377
378 @Override
379 public RemoteRepository newDeploymentRepository(RepositorySystemSession session, RemoteRepository repository) {
380 validateSession(session);
381 requireNonNull(repository, "repository cannot be null");
382
383 RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
384 Authentication auth = session.getAuthenticationSelector().getAuthentication(repository);
385 builder.setAuthentication(auth);
386 Proxy proxy = session.getProxySelector().getProxy(repository);
387 builder.setProxy(proxy);
388 return builder.build();
389 }
390
391 @Override
392 public void addOnSystemEndedHandler(Runnable handler) {
393 repositorySystemLifecycle.addOnSystemEndedHandler(handler);
394 }
395
396 @Override
397 public void shutdown() {
398 if (shutdown.compareAndSet(false, true)) {
399 repositorySystemLifecycle.systemEnded();
400 }
401 }
402
403 private void validateSession(RepositorySystemSession session) {
404 requireNonNull(session, "repository system session cannot be null");
405 invalidSession(session.getLocalRepositoryManager(), "local repository manager");
406 invalidSession(session.getSystemProperties(), "system properties");
407 invalidSession(session.getUserProperties(), "user properties");
408 invalidSession(session.getConfigProperties(), "config properties");
409 invalidSession(session.getMirrorSelector(), "mirror selector");
410 invalidSession(session.getProxySelector(), "proxy selector");
411 invalidSession(session.getAuthenticationSelector(), "authentication selector");
412 invalidSession(session.getArtifactTypeRegistry(), "artifact type registry");
413 invalidSession(session.getData(), "data");
414 if (shutdown.get()) {
415 throw new IllegalStateException("repository system is already shut down");
416 }
417 }
418
419 private void validateRepositories(List<RemoteRepository> repositories) {
420 requireNonNull(repositories, "repositories cannot be null");
421 for (RemoteRepository repository : repositories) {
422 requireNonNull(repository, "repository cannot be null");
423 }
424 }
425
426 private void invalidSession(Object obj, String name) {
427 requireNonNull(obj, "repository system session's " + name + " cannot be null");
428 }
429 }