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;
20
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.function.Function;
25
26 import org.eclipse.aether.artifact.ArtifactType;
27 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
28 import org.eclipse.aether.collection.DependencyGraphTransformer;
29 import org.eclipse.aether.collection.DependencyManager;
30 import org.eclipse.aether.collection.DependencySelector;
31 import org.eclipse.aether.collection.DependencyTraverser;
32 import org.eclipse.aether.collection.VersionFilter;
33 import org.eclipse.aether.repository.Authentication;
34 import org.eclipse.aether.repository.AuthenticationSelector;
35 import org.eclipse.aether.repository.LocalRepository;
36 import org.eclipse.aether.repository.LocalRepositoryManager;
37 import org.eclipse.aether.repository.MirrorSelector;
38 import org.eclipse.aether.repository.Proxy;
39 import org.eclipse.aether.repository.ProxySelector;
40 import org.eclipse.aether.repository.RemoteRepository;
41 import org.eclipse.aether.repository.RepositoryPolicy;
42 import org.eclipse.aether.repository.WorkspaceReader;
43 import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
44 import org.eclipse.aether.resolution.ResolutionErrorPolicy;
45 import org.eclipse.aether.scope.ScopeManager;
46 import org.eclipse.aether.scope.SystemDependencyScope;
47 import org.eclipse.aether.transfer.TransferListener;
48
49 import static java.util.Objects.requireNonNull;
50
51 /**
52 * A legacy repository system session. It is usable to "derive" sessions from existing session instances (using
53 * copy-constructor), but the recommended way to derive sessions is using
54 * {@link org.eclipse.aether.RepositorySystemSession.SessionBuilder#withRepositorySystemSession(RepositorySystemSession)}
55 * instead.
56 * <p>
57 * <em>Important: while the default constructor on this class is deprecated only, it is left only to guarantee
58 * backward compatibility with legacy code, but the default constructor should not be used anymore. Using that
59 * constructor will lead to resource leaks.</em>
60 * <p>
61 * <strong>Note:</strong> This class is not thread-safe. It is assumed that the mutators get only called during an
62 * initialization phase and that the session itself is not changed once initialized and being used by the repository
63 * system. It is recommended to call {@link #setReadOnly()} once the session has been fully initialized to prevent
64 * accidental manipulation of it afterward.
65 *
66 * @see RepositorySystem#createSessionBuilder()
67 * @see RepositorySystemSession.SessionBuilder
68 * @see RepositorySystemSession.CloseableSession
69 */
70 public final class DefaultRepositorySystemSession implements RepositorySystemSession {
71 private boolean readOnly;
72
73 private boolean offline;
74
75 private boolean ignoreArtifactDescriptorRepositories;
76
77 private ResolutionErrorPolicy resolutionErrorPolicy;
78
79 private ArtifactDescriptorPolicy artifactDescriptorPolicy;
80
81 private String checksumPolicy;
82
83 private String artifactUpdatePolicy;
84
85 private String metadataUpdatePolicy;
86
87 private LocalRepositoryManager localRepositoryManager;
88
89 private WorkspaceReader workspaceReader;
90
91 private RepositoryListener repositoryListener;
92
93 private TransferListener transferListener;
94
95 private Map<String, String> systemProperties;
96
97 private Map<String, String> systemPropertiesView;
98
99 private Map<String, String> userProperties;
100
101 private Map<String, String> userPropertiesView;
102
103 private Map<String, Object> configProperties;
104
105 private Map<String, Object> configPropertiesView;
106
107 private MirrorSelector mirrorSelector;
108
109 private ProxySelector proxySelector;
110
111 private AuthenticationSelector authenticationSelector;
112
113 private ArtifactTypeRegistry artifactTypeRegistry;
114
115 private DependencyTraverser dependencyTraverser;
116
117 private DependencyManager dependencyManager;
118
119 private DependencySelector dependencySelector;
120
121 private VersionFilter versionFilter;
122
123 private DependencyGraphTransformer dependencyGraphTransformer;
124
125 private SessionData data;
126
127 private RepositoryCache cache;
128
129 private ScopeManager scopeManager;
130
131 private final Function<Runnable, Boolean> onSessionEndedRegistrar;
132
133 /**
134 * Creates an uninitialized session. <em>Note:</em> The new session is not ready to use, as a bare minimum,
135 * {@link #setLocalRepositoryManager(LocalRepositoryManager)} needs to be called but usually other settings also
136 * need to be customized to achieve meaningful behavior.
137 *
138 * @deprecated This way of creating session should be avoided, is in place just to offer backward binary
139 * compatibility with Resolver 1.x using code, but offers reduced functionality.
140 * Use {@link RepositorySystem#createSessionBuilder()} instead.
141 */
142 @Deprecated
143 public DefaultRepositorySystemSession() {
144 this(h -> false);
145 }
146
147 /**
148 * Creates an uninitialized session. <em>Note:</em> The new session is not ready to use, as a bare minimum,
149 * {@link #setLocalRepositoryManager(LocalRepositoryManager)} needs to be called but usually other settings also
150 * need to be customized to achieve meaningful behavior.
151 * <p>
152 * Note: preferred way to create sessions is {@link RepositorySystem#createSessionBuilder()}, as then client code
153 * does not have to fiddle with session close callbacks. This constructor is meant more for testing purposes.
154 *
155 * @since 2.0.0
156 */
157 public DefaultRepositorySystemSession(Function<Runnable, Boolean> onSessionEndedRegistrar) {
158 systemProperties = new HashMap<>();
159 systemPropertiesView = Collections.unmodifiableMap(systemProperties);
160 userProperties = new HashMap<>();
161 userPropertiesView = Collections.unmodifiableMap(userProperties);
162 configProperties = new HashMap<>();
163 configPropertiesView = Collections.unmodifiableMap(configProperties);
164 mirrorSelector = NullMirrorSelector.INSTANCE;
165 proxySelector = PassthroughProxySelector.INSTANCE;
166 authenticationSelector = PassthroughAuthenticationSelector.INSTANCE;
167 artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
168 data = new DefaultSessionData();
169 this.onSessionEndedRegistrar = requireNonNull(onSessionEndedRegistrar, "onSessionEndedRegistrar");
170 }
171
172 /**
173 * Creates a shallow copy of the specified session. Actually, the copy is not completely shallow, all maps holding
174 * system/user/config properties are copied as well. In other words, invoking any mutator on the new session itself
175 * has no effect on the original session. Other mutable objects like the session data and cache (if any) are not
176 * copied and will be shared with the original session unless reconfigured.
177 *
178 * @param session The session to copy, must not be {@code null}.
179 */
180 public DefaultRepositorySystemSession(RepositorySystemSession session) {
181 requireNonNull(session, "repository system session cannot be null");
182
183 setOffline(session.isOffline());
184 setIgnoreArtifactDescriptorRepositories(session.isIgnoreArtifactDescriptorRepositories());
185 setResolutionErrorPolicy(session.getResolutionErrorPolicy());
186 setArtifactDescriptorPolicy(session.getArtifactDescriptorPolicy());
187 setChecksumPolicy(session.getChecksumPolicy());
188 setUpdatePolicy(session.getUpdatePolicy());
189 setMetadataUpdatePolicy(session.getMetadataUpdatePolicy());
190 setLocalRepositoryManager(session.getLocalRepositoryManager());
191 setWorkspaceReader(session.getWorkspaceReader());
192 setRepositoryListener(session.getRepositoryListener());
193 setTransferListener(session.getTransferListener());
194 setSystemProperties(session.getSystemProperties());
195 setUserProperties(session.getUserProperties());
196 setConfigProperties(session.getConfigProperties());
197 setMirrorSelector(session.getMirrorSelector());
198 setProxySelector(session.getProxySelector());
199 setAuthenticationSelector(session.getAuthenticationSelector());
200 setArtifactTypeRegistry(session.getArtifactTypeRegistry());
201 setDependencyTraverser(session.getDependencyTraverser());
202 setDependencyManager(session.getDependencyManager());
203 setDependencySelector(session.getDependencySelector());
204 setVersionFilter(session.getVersionFilter());
205 setDependencyGraphTransformer(session.getDependencyGraphTransformer());
206 setData(session.getData());
207 setCache(session.getCache());
208 setScopeManager(session.getScopeManager());
209 this.onSessionEndedRegistrar = session::addOnSessionEndedHandler;
210 }
211
212 @Override
213 public boolean isOffline() {
214 return offline;
215 }
216
217 /**
218 * Controls whether the repository system operates in offline mode and avoids/refuses any access to remote
219 * repositories.
220 *
221 * @param offline {@code true} if the repository system is in offline mode, {@code false} otherwise.
222 * @return This session for chaining, never {@code null}.
223 */
224 public DefaultRepositorySystemSession setOffline(boolean offline) {
225 verifyStateForMutation();
226 this.offline = offline;
227 return this;
228 }
229
230 @Override
231 public boolean isIgnoreArtifactDescriptorRepositories() {
232 return ignoreArtifactDescriptorRepositories;
233 }
234
235 /**
236 * Controls whether repositories declared in artifact descriptors should be ignored during transitive dependency
237 * collection. If enabled, only the repositories originally provided with the collect request will be considered.
238 *
239 * @param ignoreArtifactDescriptorRepositories {@code true} to ignore additional repositories from artifact
240 * descriptors, {@code false} to merge those with the originally
241 * specified repositories.
242 * @return This session for chaining, never {@code null}.
243 */
244 public DefaultRepositorySystemSession setIgnoreArtifactDescriptorRepositories(
245 boolean ignoreArtifactDescriptorRepositories) {
246 verifyStateForMutation();
247 this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
248 return this;
249 }
250
251 @Override
252 public ResolutionErrorPolicy getResolutionErrorPolicy() {
253 return resolutionErrorPolicy;
254 }
255
256 /**
257 * Sets the policy which controls whether resolutions errors from remote repositories should be cached.
258 *
259 * @param resolutionErrorPolicy The resolution error policy for this session, may be {@code null} if resolution
260 * errors should generally not be cached.
261 * @return This session for chaining, never {@code null}.
262 */
263 public DefaultRepositorySystemSession setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) {
264 verifyStateForMutation();
265 this.resolutionErrorPolicy = resolutionErrorPolicy;
266 return this;
267 }
268
269 @Override
270 public ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
271 return artifactDescriptorPolicy;
272 }
273
274 /**
275 * Sets the policy which controls how errors related to reading artifact descriptors should be handled.
276 *
277 * @param artifactDescriptorPolicy The descriptor error policy for this session, may be {@code null} if descriptor
278 * errors should generally not be tolerated.
279 * @return This session for chaining, never {@code null}.
280 */
281 public DefaultRepositorySystemSession setArtifactDescriptorPolicy(
282 ArtifactDescriptorPolicy artifactDescriptorPolicy) {
283 verifyStateForMutation();
284 this.artifactDescriptorPolicy = artifactDescriptorPolicy;
285 return this;
286 }
287
288 @Override
289 public String getChecksumPolicy() {
290 return checksumPolicy;
291 }
292
293 /**
294 * Sets the global checksum policy. If set, the global checksum policy overrides the checksum policies of the remote
295 * repositories being used for resolution.
296 *
297 * @param checksumPolicy The global checksum policy, may be {@code null}/empty to apply the per-repository policies.
298 * @return This session for chaining, never {@code null}.
299 * @see RepositoryPolicy#CHECKSUM_POLICY_FAIL
300 * @see RepositoryPolicy#CHECKSUM_POLICY_IGNORE
301 * @see RepositoryPolicy#CHECKSUM_POLICY_WARN
302 */
303 public DefaultRepositorySystemSession setChecksumPolicy(String checksumPolicy) {
304 verifyStateForMutation();
305 this.checksumPolicy = checksumPolicy;
306 return this;
307 }
308
309 @Override
310 public String getUpdatePolicy() {
311 return getArtifactUpdatePolicy();
312 }
313
314 /**
315 * Sets the global update policy. If set, the global update policy overrides the update policies of the remote
316 * repositories being used for resolution.
317 * <p>
318 * This method is meant for code that does not want to distinguish between artifact and metadata policies.
319 * Note: applications should either use get/set updatePolicy (this method and
320 * {@link RepositorySystemSession#getUpdatePolicy()}) or also distinguish between artifact and
321 * metadata update policies (and use other methods), but <em>should not mix the two!</em>
322 *
323 * @param updatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
324 * @return This session for chaining, never {@code null}.
325 * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
326 * @see RepositoryPolicy#UPDATE_POLICY_DAILY
327 * @see RepositoryPolicy#UPDATE_POLICY_NEVER
328 * @see #setArtifactUpdatePolicy(String)
329 * @see #setMetadataUpdatePolicy(String)
330 */
331 public DefaultRepositorySystemSession setUpdatePolicy(String updatePolicy) {
332 verifyStateForMutation();
333 setArtifactUpdatePolicy(updatePolicy);
334 setMetadataUpdatePolicy(updatePolicy);
335 return this;
336 }
337
338 @Override
339 public String getArtifactUpdatePolicy() {
340 return artifactUpdatePolicy;
341 }
342
343 /**
344 * Sets the global artifact update policy. If set, the global update policy overrides the artifact update policies
345 * of the remote repositories being used for resolution.
346 *
347 * @param artifactUpdatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
348 * @return This session for chaining, never {@code null}.
349 * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
350 * @see RepositoryPolicy#UPDATE_POLICY_DAILY
351 * @see RepositoryPolicy#UPDATE_POLICY_NEVER
352 * @since 2.0.0
353 */
354 public DefaultRepositorySystemSession setArtifactUpdatePolicy(String artifactUpdatePolicy) {
355 verifyStateForMutation();
356 this.artifactUpdatePolicy = artifactUpdatePolicy;
357 return this;
358 }
359
360 @Override
361 public String getMetadataUpdatePolicy() {
362 return metadataUpdatePolicy;
363 }
364
365 /**
366 * Sets the global metadata update policy. If set, the global update policy overrides the metadata update policies
367 * of the remote repositories being used for resolution.
368 *
369 * @param metadataUpdatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
370 * @return This session for chaining, never {@code null}.
371 * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
372 * @see RepositoryPolicy#UPDATE_POLICY_DAILY
373 * @see RepositoryPolicy#UPDATE_POLICY_NEVER
374 * @since 2.0.0
375 */
376 public DefaultRepositorySystemSession setMetadataUpdatePolicy(String metadataUpdatePolicy) {
377 verifyStateForMutation();
378 this.metadataUpdatePolicy = metadataUpdatePolicy;
379 return this;
380 }
381
382 @Override
383 public LocalRepository getLocalRepository() {
384 LocalRepositoryManager lrm = getLocalRepositoryManager();
385 return (lrm != null) ? lrm.getRepository() : null;
386 }
387
388 @Override
389 public LocalRepositoryManager getLocalRepositoryManager() {
390 return localRepositoryManager;
391 }
392
393 /**
394 * Sets the local repository manager used during this session. <em>Note:</em> Eventually, a valid session must have
395 * a local repository manager set.
396 *
397 * @param localRepositoryManager The local repository manager used during this session, may be {@code null}.
398 * @return This session for chaining, never {@code null}.
399 */
400 public DefaultRepositorySystemSession setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) {
401 verifyStateForMutation();
402 this.localRepositoryManager = localRepositoryManager;
403 return this;
404 }
405
406 @Override
407 public WorkspaceReader getWorkspaceReader() {
408 return workspaceReader;
409 }
410
411 /**
412 * Sets the workspace reader used during this session. If set, the workspace reader will usually be consulted first
413 * to resolve artifacts.
414 *
415 * @param workspaceReader The workspace reader for this session, may be {@code null} if none.
416 * @return This session for chaining, never {@code null}.
417 */
418 public DefaultRepositorySystemSession setWorkspaceReader(WorkspaceReader workspaceReader) {
419 verifyStateForMutation();
420 this.workspaceReader = workspaceReader;
421 return this;
422 }
423
424 @Override
425 public RepositoryListener getRepositoryListener() {
426 return repositoryListener;
427 }
428
429 /**
430 * Sets the listener being notified of actions in the repository system.
431 *
432 * @param repositoryListener The repository listener, may be {@code null} if none.
433 * @return This session for chaining, never {@code null}.
434 */
435 public DefaultRepositorySystemSession setRepositoryListener(RepositoryListener repositoryListener) {
436 verifyStateForMutation();
437 this.repositoryListener = repositoryListener;
438 return this;
439 }
440
441 @Override
442 public TransferListener getTransferListener() {
443 return transferListener;
444 }
445
446 /**
447 * Sets the listener being notified of uploads/downloads by the repository system.
448 *
449 * @param transferListener The transfer listener, may be {@code null} if none.
450 * @return This session for chaining, never {@code null}.
451 */
452 public DefaultRepositorySystemSession setTransferListener(TransferListener transferListener) {
453 verifyStateForMutation();
454 this.transferListener = transferListener;
455 return this;
456 }
457
458 @SuppressWarnings("checkstyle:magicnumber")
459 private <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) {
460 Map<String, T> map;
461 if (table == null || table.isEmpty()) {
462 map = new HashMap<>();
463 } else {
464 map = new HashMap<>((int) (table.size() / 0.75f) + 1);
465 for (Map.Entry<?, ?> entry : table.entrySet()) {
466 Object key = entry.getKey();
467 if (key instanceof String) {
468 Object value = entry.getValue();
469 if (valueType.isInstance(value)) {
470 map.put(key.toString(), valueType.cast(value));
471 }
472 }
473 }
474 }
475 return map;
476 }
477
478 @Override
479 public Map<String, String> getSystemProperties() {
480 return systemPropertiesView;
481 }
482
483 /**
484 * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually
485 * collected from the runtime environment like {@link System#getProperties()} and environment variables.
486 * <p>
487 * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map
488 * that doesn't match this type will be silently ignored.
489 *
490 * @param systemProperties The system properties, may be {@code null} or empty if none.
491 * @return This session for chaining, never {@code null}.
492 */
493 public DefaultRepositorySystemSession setSystemProperties(Map<?, ?> systemProperties) {
494 verifyStateForMutation();
495 this.systemProperties = copySafe(systemProperties, String.class);
496 systemPropertiesView = Collections.unmodifiableMap(this.systemProperties);
497 return this;
498 }
499
500 /**
501 * Sets the specified system property.
502 *
503 * @param key The property key, must not be {@code null}.
504 * @param value The property value, may be {@code null} to remove/unset the property.
505 * @return This session for chaining, never {@code null}.
506 */
507 public DefaultRepositorySystemSession setSystemProperty(String key, String value) {
508 verifyStateForMutation();
509 if (value != null) {
510 systemProperties.put(key, value);
511 } else {
512 systemProperties.remove(key);
513 }
514 return this;
515 }
516
517 @Override
518 public Map<String, String> getUserProperties() {
519 return userPropertiesView;
520 }
521
522 /**
523 * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to
524 * system properties but are set on the discretion of the user and hence are considered of higher priority than
525 * system properties in case of conflicts.
526 * <p>
527 * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map
528 * that doesn't match this type will be silently ignored.
529 *
530 * @param userProperties The user properties, may be {@code null} or empty if none.
531 * @return This session for chaining, never {@code null}.
532 */
533 public DefaultRepositorySystemSession setUserProperties(Map<?, ?> userProperties) {
534 verifyStateForMutation();
535 this.userProperties = copySafe(userProperties, String.class);
536 userPropertiesView = Collections.unmodifiableMap(this.userProperties);
537 return this;
538 }
539
540 /**
541 * Sets the specified user property.
542 *
543 * @param key The property key, must not be {@code null}.
544 * @param value The property value, may be {@code null} to remove/unset the property.
545 * @return This session for chaining, never {@code null}.
546 */
547 public DefaultRepositorySystemSession setUserProperty(String key, String value) {
548 verifyStateForMutation();
549 if (value != null) {
550 userProperties.put(key, value);
551 } else {
552 userProperties.remove(key);
553 }
554 return this;
555 }
556
557 @Override
558 public Map<String, Object> getConfigProperties() {
559 return configPropertiesView;
560 }
561
562 /**
563 * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling,
564 * connector-specific behavior, etc.).
565 * <p>
566 * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the
567 * input map that doesn't match this type will be silently ignored.
568 *
569 * @param configProperties The configuration properties, may be {@code null} or empty if none.
570 * @return This session for chaining, never {@code null}.
571 */
572 public DefaultRepositorySystemSession setConfigProperties(Map<?, ?> configProperties) {
573 verifyStateForMutation();
574 this.configProperties = copySafe(configProperties, Object.class);
575 configPropertiesView = Collections.unmodifiableMap(this.configProperties);
576 return this;
577 }
578
579 /**
580 * Sets the specified configuration property.
581 *
582 * @param key The property key, must not be {@code null}.
583 * @param value The property value, may be {@code null} to remove/unset the property.
584 * @return This session for chaining, never {@code null}.
585 */
586 public DefaultRepositorySystemSession setConfigProperty(String key, Object value) {
587 verifyStateForMutation();
588 if (value != null) {
589 configProperties.put(key, value);
590 } else {
591 configProperties.remove(key);
592 }
593 return this;
594 }
595
596 @Override
597 public MirrorSelector getMirrorSelector() {
598 return mirrorSelector;
599 }
600
601 /**
602 * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is
603 * not used for remote repositories which are passed as request parameters to the repository system, those
604 * repositories are supposed to denote the effective repositories.
605 *
606 * @param mirrorSelector The mirror selector to use, may be {@code null}.
607 * @return This session for chaining, never {@code null}.
608 */
609 public DefaultRepositorySystemSession setMirrorSelector(MirrorSelector mirrorSelector) {
610 verifyStateForMutation();
611 this.mirrorSelector = mirrorSelector;
612 if (this.mirrorSelector == null) {
613 this.mirrorSelector = NullMirrorSelector.INSTANCE;
614 }
615 return this;
616 }
617
618 @Override
619 public ProxySelector getProxySelector() {
620 return proxySelector;
621 }
622
623 /**
624 * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is
625 * not used for remote repositories which are passed as request parameters to the repository system, those
626 * repositories are supposed to have their proxy (if any) already set.
627 *
628 * @param proxySelector The proxy selector to use, may be {@code null}.
629 * @return This session for chaining, never {@code null}.
630 * @see org.eclipse.aether.repository.RemoteRepository#getProxy()
631 */
632 public DefaultRepositorySystemSession setProxySelector(ProxySelector proxySelector) {
633 verifyStateForMutation();
634 this.proxySelector = proxySelector;
635 if (this.proxySelector == null) {
636 this.proxySelector = PassthroughProxySelector.INSTANCE;
637 }
638 return this;
639 }
640
641 @Override
642 public AuthenticationSelector getAuthenticationSelector() {
643 return authenticationSelector;
644 }
645
646 /**
647 * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this
648 * selector is not used for remote repositories which are passed as request parameters to the repository system,
649 * those repositories are supposed to have their authentication (if any) already set.
650 *
651 * @param authenticationSelector The authentication selector to use, may be {@code null}.
652 * @return This session for chaining, never {@code null}.
653 * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication()
654 */
655 public DefaultRepositorySystemSession setAuthenticationSelector(AuthenticationSelector authenticationSelector) {
656 verifyStateForMutation();
657 this.authenticationSelector = authenticationSelector;
658 if (this.authenticationSelector == null) {
659 this.authenticationSelector = PassthroughAuthenticationSelector.INSTANCE;
660 }
661 return this;
662 }
663
664 @Override
665 public ArtifactTypeRegistry getArtifactTypeRegistry() {
666 return artifactTypeRegistry;
667 }
668
669 /**
670 * Sets the registry of artifact types recognized by this session.
671 *
672 * @param artifactTypeRegistry The artifact type registry, may be {@code null}.
673 * @return This session for chaining, never {@code null}.
674 */
675 public DefaultRepositorySystemSession setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) {
676 verifyStateForMutation();
677 this.artifactTypeRegistry = artifactTypeRegistry;
678 if (this.artifactTypeRegistry == null) {
679 this.artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
680 }
681 return this;
682 }
683
684 @Override
685 public DependencyTraverser getDependencyTraverser() {
686 return dependencyTraverser;
687 }
688
689 /**
690 * Sets the dependency traverser to use for building dependency graphs.
691 *
692 * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}.
693 * @return This session for chaining, never {@code null}.
694 */
695 public DefaultRepositorySystemSession setDependencyTraverser(DependencyTraverser dependencyTraverser) {
696 verifyStateForMutation();
697 this.dependencyTraverser = dependencyTraverser;
698 return this;
699 }
700
701 @Override
702 public DependencyManager getDependencyManager() {
703 return dependencyManager;
704 }
705
706 /**
707 * Sets the dependency manager to use for building dependency graphs.
708 *
709 * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}.
710 * @return This session for chaining, never {@code null}.
711 */
712 public DefaultRepositorySystemSession setDependencyManager(DependencyManager dependencyManager) {
713 verifyStateForMutation();
714 this.dependencyManager = dependencyManager;
715 return this;
716 }
717
718 @Override
719 public DependencySelector getDependencySelector() {
720 return dependencySelector;
721 }
722
723 /**
724 * Sets the dependency selector to use for building dependency graphs.
725 *
726 * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}.
727 * @return This session for chaining, never {@code null}.
728 */
729 public DefaultRepositorySystemSession setDependencySelector(DependencySelector dependencySelector) {
730 verifyStateForMutation();
731 this.dependencySelector = dependencySelector;
732 return this;
733 }
734
735 @Override
736 public VersionFilter getVersionFilter() {
737 return versionFilter;
738 }
739
740 /**
741 * Sets the version filter to use for building dependency graphs.
742 *
743 * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter
744 * versions.
745 * @return This session for chaining, never {@code null}.
746 */
747 public DefaultRepositorySystemSession setVersionFilter(VersionFilter versionFilter) {
748 verifyStateForMutation();
749 this.versionFilter = versionFilter;
750 return this;
751 }
752
753 @Override
754 public DependencyGraphTransformer getDependencyGraphTransformer() {
755 return dependencyGraphTransformer;
756 }
757
758 /**
759 * Sets the dependency graph transformer to use for building dependency graphs.
760 *
761 * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be
762 * {@code null}.
763 * @return This session for chaining, never {@code null}.
764 */
765 public DefaultRepositorySystemSession setDependencyGraphTransformer(
766 DependencyGraphTransformer dependencyGraphTransformer) {
767 verifyStateForMutation();
768 this.dependencyGraphTransformer = dependencyGraphTransformer;
769 return this;
770 }
771
772 @Override
773 public SessionData getData() {
774 return data;
775 }
776
777 /**
778 * Sets the custom data associated with this session.
779 *
780 * @param data The session data, may be {@code null}.
781 * @return This session for chaining, never {@code null}.
782 */
783 public DefaultRepositorySystemSession setData(SessionData data) {
784 verifyStateForMutation();
785 this.data = data;
786 if (this.data == null) {
787 this.data = new DefaultSessionData();
788 }
789 return this;
790 }
791
792 @Override
793 public RepositoryCache getCache() {
794 return cache;
795 }
796
797 /**
798 * Sets the cache the repository system may use to save data for future reuse during the session.
799 *
800 * @param cache The repository cache, may be {@code null} if none.
801 * @return This session for chaining, never {@code null}.
802 */
803 public DefaultRepositorySystemSession setCache(RepositoryCache cache) {
804 verifyStateForMutation();
805 this.cache = cache;
806 return this;
807 }
808
809 @Override
810 public ScopeManager getScopeManager() {
811 return scopeManager;
812 }
813
814 /**
815 * Sets the scope manager, may be {@code null}.
816 *
817 * @param scopeManager The scope manager, may be {@code null}.
818 * @return The session for chaining, never {@code null}.
819 * @since 2.0.0
820 */
821 public DefaultRepositorySystemSession setScopeManager(ScopeManager scopeManager) {
822 verifyStateForMutation();
823 this.scopeManager = scopeManager;
824 return this;
825 }
826
827 @Override
828 public SystemDependencyScope getSystemDependencyScope() {
829 if (scopeManager != null) {
830 return scopeManager.getSystemDependencyScope().orElse(null);
831 } else {
832 return SystemDependencyScope.LEGACY;
833 }
834 }
835
836 /**
837 * Registers onSessionEnded handler, if able to.
838 *
839 * @param handler The handler to register
840 * @return Return {@code true} if registration was possible, otherwise {@code false}.
841 */
842 @Override
843 public boolean addOnSessionEndedHandler(Runnable handler) {
844 return onSessionEndedRegistrar.apply(handler);
845 }
846
847 /**
848 * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception.
849 * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable
850 * though.
851 */
852 public void setReadOnly() {
853 readOnly = true;
854 }
855
856 /**
857 * Verifies this instance state for mutation operations: mutated instance must not be read-only or closed.
858 */
859 private void verifyStateForMutation() {
860 if (readOnly) {
861 throw new IllegalStateException("repository system session is read-only");
862 }
863 }
864
865 /**
866 * Simple "pass through" implementation of {@link ProxySelector} that simply returns what passed in
867 * {@link RemoteRepository} have set already, may return {@code null}.
868 */
869 static class PassthroughProxySelector implements ProxySelector {
870
871 public static final ProxySelector INSTANCE = new PassthroughProxySelector();
872
873 @Override
874 public Proxy getProxy(RemoteRepository repository) {
875 requireNonNull(repository, "repository cannot be null");
876 return repository.getProxy();
877 }
878 }
879
880 /**
881 * Simple "null" implementation of {@link MirrorSelector} that returns {@code null} for any passed
882 * in {@link RemoteRepository}.
883 */
884 static class NullMirrorSelector implements MirrorSelector {
885
886 public static final MirrorSelector INSTANCE = new NullMirrorSelector();
887
888 @Override
889 public RemoteRepository getMirror(RemoteRepository repository) {
890 requireNonNull(repository, "repository cannot be null");
891 return null;
892 }
893 }
894
895 /**
896 * Simple "pass through" implementation of {@link AuthenticationSelector} that simply returns what passed in
897 * {@link RemoteRepository} have set already, may return {@code null}.
898 */
899 static class PassthroughAuthenticationSelector implements AuthenticationSelector {
900
901 public static final AuthenticationSelector INSTANCE = new PassthroughAuthenticationSelector();
902
903 @Override
904 public Authentication getAuthentication(RemoteRepository repository) {
905 requireNonNull(repository, "repository cannot be null");
906 return repository.getAuthentication();
907 }
908 }
909
910 /**
911 * Simple "null" implementation of {@link ArtifactTypeRegistry} that returns {@code null} for any type ID.
912 */
913 static final class NullArtifactTypeRegistry implements ArtifactTypeRegistry {
914
915 public static final ArtifactTypeRegistry INSTANCE = new NullArtifactTypeRegistry();
916
917 @Override
918 public ArtifactType get(String typeId) {
919 return null;
920 }
921 }
922 }