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