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;
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     private <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) {
459         Map<String, T> map;
460         if (table == null || table.isEmpty()) {
461             map = new HashMap<>();
462         } else {
463             map = new HashMap<>((int) (table.size() / 0.75f) + 1);
464             for (Map.Entry<?, ?> entry : table.entrySet()) {
465                 Object key = entry.getKey();
466                 if (key instanceof String) {
467                     Object value = entry.getValue();
468                     if (valueType.isInstance(value)) {
469                         map.put(key.toString(), valueType.cast(value));
470                     }
471                 }
472             }
473         }
474         return map;
475     }
476 
477     @Override
478     public Map<String, String> getSystemProperties() {
479         return systemPropertiesView;
480     }
481 
482     /**
483      * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually
484      * collected from the runtime environment like {@link System#getProperties()} and environment variables.
485      * <p>
486      * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map
487      * that doesn't match this type will be silently ignored.
488      *
489      * @param systemProperties The system properties, may be {@code null} or empty if none.
490      * @return This session for chaining, never {@code null}.
491      */
492     public DefaultRepositorySystemSession setSystemProperties(Map<?, ?> systemProperties) {
493         verifyStateForMutation();
494         this.systemProperties = copySafe(systemProperties, String.class);
495         systemPropertiesView = Collections.unmodifiableMap(this.systemProperties);
496         return this;
497     }
498 
499     /**
500      * Sets the specified system property.
501      *
502      * @param key   The property key, must not be {@code null}.
503      * @param value The property value, may be {@code null} to remove/unset the property.
504      * @return This session for chaining, never {@code null}.
505      */
506     public DefaultRepositorySystemSession setSystemProperty(String key, String value) {
507         verifyStateForMutation();
508         if (value != null) {
509             systemProperties.put(key, value);
510         } else {
511             systemProperties.remove(key);
512         }
513         return this;
514     }
515 
516     @Override
517     public Map<String, String> getUserProperties() {
518         return userPropertiesView;
519     }
520 
521     /**
522      * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to
523      * system properties but are set on the discretion of the user and hence are considered of higher priority than
524      * system properties in case of conflicts.
525      * <p>
526      * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map
527      * that doesn't match this type will be silently ignored.
528      *
529      * @param userProperties The user properties, may be {@code null} or empty if none.
530      * @return This session for chaining, never {@code null}.
531      */
532     public DefaultRepositorySystemSession setUserProperties(Map<?, ?> userProperties) {
533         verifyStateForMutation();
534         this.userProperties = copySafe(userProperties, String.class);
535         userPropertiesView = Collections.unmodifiableMap(this.userProperties);
536         return this;
537     }
538 
539     /**
540      * Sets the specified user property.
541      *
542      * @param key   The property key, must not be {@code null}.
543      * @param value The property value, may be {@code null} to remove/unset the property.
544      * @return This session for chaining, never {@code null}.
545      */
546     public DefaultRepositorySystemSession setUserProperty(String key, String value) {
547         verifyStateForMutation();
548         if (value != null) {
549             userProperties.put(key, value);
550         } else {
551             userProperties.remove(key);
552         }
553         return this;
554     }
555 
556     @Override
557     public Map<String, Object> getConfigProperties() {
558         return configPropertiesView;
559     }
560 
561     /**
562      * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling,
563      * connector-specific behavior, etc.).
564      * <p>
565      * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the
566      * input map that doesn't match this type will be silently ignored.
567      *
568      * @param configProperties The configuration properties, may be {@code null} or empty if none.
569      * @return This session for chaining, never {@code null}.
570      */
571     public DefaultRepositorySystemSession setConfigProperties(Map<?, ?> configProperties) {
572         verifyStateForMutation();
573         this.configProperties = copySafe(configProperties, Object.class);
574         configPropertiesView = Collections.unmodifiableMap(this.configProperties);
575         return this;
576     }
577 
578     /**
579      * Sets the specified configuration property.
580      *
581      * @param key   The property key, must not be {@code null}.
582      * @param value The property value, may be {@code null} to remove/unset the property.
583      * @return This session for chaining, never {@code null}.
584      */
585     public DefaultRepositorySystemSession setConfigProperty(String key, Object value) {
586         verifyStateForMutation();
587         if (value != null) {
588             configProperties.put(key, value);
589         } else {
590             configProperties.remove(key);
591         }
592         return this;
593     }
594 
595     @Override
596     public MirrorSelector getMirrorSelector() {
597         return mirrorSelector;
598     }
599 
600     /**
601      * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is
602      * not used for remote repositories which are passed as request parameters to the repository system, those
603      * repositories are supposed to denote the effective repositories.
604      *
605      * @param mirrorSelector The mirror selector to use, may be {@code null}.
606      * @return This session for chaining, never {@code null}.
607      */
608     public DefaultRepositorySystemSession setMirrorSelector(MirrorSelector mirrorSelector) {
609         verifyStateForMutation();
610         this.mirrorSelector = mirrorSelector;
611         if (this.mirrorSelector == null) {
612             this.mirrorSelector = NullMirrorSelector.INSTANCE;
613         }
614         return this;
615     }
616 
617     @Override
618     public ProxySelector getProxySelector() {
619         return proxySelector;
620     }
621 
622     /**
623      * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is
624      * not used for remote repositories which are passed as request parameters to the repository system, those
625      * repositories are supposed to have their proxy (if any) already set.
626      *
627      * @param proxySelector The proxy selector to use, may be {@code null}.
628      * @return This session for chaining, never {@code null}.
629      * @see org.eclipse.aether.repository.RemoteRepository#getProxy()
630      */
631     public DefaultRepositorySystemSession setProxySelector(ProxySelector proxySelector) {
632         verifyStateForMutation();
633         this.proxySelector = proxySelector;
634         if (this.proxySelector == null) {
635             this.proxySelector = PassthroughProxySelector.INSTANCE;
636         }
637         return this;
638     }
639 
640     @Override
641     public AuthenticationSelector getAuthenticationSelector() {
642         return authenticationSelector;
643     }
644 
645     /**
646      * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this
647      * selector is not used for remote repositories which are passed as request parameters to the repository system,
648      * those repositories are supposed to have their authentication (if any) already set.
649      *
650      * @param authenticationSelector The authentication selector to use, may be {@code null}.
651      * @return This session for chaining, never {@code null}.
652      * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication()
653      */
654     public DefaultRepositorySystemSession setAuthenticationSelector(AuthenticationSelector authenticationSelector) {
655         verifyStateForMutation();
656         this.authenticationSelector = authenticationSelector;
657         if (this.authenticationSelector == null) {
658             this.authenticationSelector = PassthroughAuthenticationSelector.INSTANCE;
659         }
660         return this;
661     }
662 
663     @Override
664     public ArtifactTypeRegistry getArtifactTypeRegistry() {
665         return artifactTypeRegistry;
666     }
667 
668     /**
669      * Sets the registry of artifact types recognized by this session.
670      *
671      * @param artifactTypeRegistry The artifact type registry, may be {@code null}.
672      * @return This session for chaining, never {@code null}.
673      */
674     public DefaultRepositorySystemSession setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) {
675         verifyStateForMutation();
676         this.artifactTypeRegistry = artifactTypeRegistry;
677         if (this.artifactTypeRegistry == null) {
678             this.artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
679         }
680         return this;
681     }
682 
683     @Override
684     public DependencyTraverser getDependencyTraverser() {
685         return dependencyTraverser;
686     }
687 
688     /**
689      * Sets the dependency traverser to use for building dependency graphs.
690      *
691      * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}.
692      * @return This session for chaining, never {@code null}.
693      */
694     public DefaultRepositorySystemSession setDependencyTraverser(DependencyTraverser dependencyTraverser) {
695         verifyStateForMutation();
696         this.dependencyTraverser = dependencyTraverser;
697         return this;
698     }
699 
700     @Override
701     public DependencyManager getDependencyManager() {
702         return dependencyManager;
703     }
704 
705     /**
706      * Sets the dependency manager to use for building dependency graphs.
707      *
708      * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}.
709      * @return This session for chaining, never {@code null}.
710      */
711     public DefaultRepositorySystemSession setDependencyManager(DependencyManager dependencyManager) {
712         verifyStateForMutation();
713         this.dependencyManager = dependencyManager;
714         return this;
715     }
716 
717     @Override
718     public DependencySelector getDependencySelector() {
719         return dependencySelector;
720     }
721 
722     /**
723      * Sets the dependency selector to use for building dependency graphs.
724      *
725      * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}.
726      * @return This session for chaining, never {@code null}.
727      */
728     public DefaultRepositorySystemSession setDependencySelector(DependencySelector dependencySelector) {
729         verifyStateForMutation();
730         this.dependencySelector = dependencySelector;
731         return this;
732     }
733 
734     @Override
735     public VersionFilter getVersionFilter() {
736         return versionFilter;
737     }
738 
739     /**
740      * Sets the version filter to use for building dependency graphs.
741      *
742      * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter
743      *                      versions.
744      * @return This session for chaining, never {@code null}.
745      */
746     public DefaultRepositorySystemSession setVersionFilter(VersionFilter versionFilter) {
747         verifyStateForMutation();
748         this.versionFilter = versionFilter;
749         return this;
750     }
751 
752     @Override
753     public DependencyGraphTransformer getDependencyGraphTransformer() {
754         return dependencyGraphTransformer;
755     }
756 
757     /**
758      * Sets the dependency graph transformer to use for building dependency graphs.
759      *
760      * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be
761      *                                   {@code null}.
762      * @return This session for chaining, never {@code null}.
763      */
764     public DefaultRepositorySystemSession setDependencyGraphTransformer(
765             DependencyGraphTransformer dependencyGraphTransformer) {
766         verifyStateForMutation();
767         this.dependencyGraphTransformer = dependencyGraphTransformer;
768         return this;
769     }
770 
771     @Override
772     public SessionData getData() {
773         return data;
774     }
775 
776     /**
777      * Sets the custom data associated with this session.
778      *
779      * @param data The session data, may be {@code null}.
780      * @return This session for chaining, never {@code null}.
781      */
782     public DefaultRepositorySystemSession setData(SessionData data) {
783         verifyStateForMutation();
784         this.data = data;
785         if (this.data == null) {
786             this.data = new DefaultSessionData();
787         }
788         return this;
789     }
790 
791     @Override
792     public RepositoryCache getCache() {
793         return cache;
794     }
795 
796     /**
797      * Sets the cache the repository system may use to save data for future reuse during the session.
798      *
799      * @param cache The repository cache, may be {@code null} if none.
800      * @return This session for chaining, never {@code null}.
801      */
802     public DefaultRepositorySystemSession setCache(RepositoryCache cache) {
803         verifyStateForMutation();
804         this.cache = cache;
805         return this;
806     }
807 
808     @Override
809     public ScopeManager getScopeManager() {
810         return scopeManager;
811     }
812 
813     /**
814      * Sets the scope manager, may be {@code null}.
815      *
816      * @param scopeManager The scope manager, may be {@code null}.
817      * @return The session for chaining, never {@code null}.
818      * @since 2.0.0
819      */
820     public DefaultRepositorySystemSession setScopeManager(ScopeManager scopeManager) {
821         verifyStateForMutation();
822         this.scopeManager = scopeManager;
823         return this;
824     }
825 
826     @Override
827     public SystemDependencyScope getSystemDependencyScope() {
828         if (scopeManager != null) {
829             return scopeManager.getSystemDependencyScope().orElse(null);
830         } else {
831             return SystemDependencyScope.LEGACY;
832         }
833     }
834 
835     /**
836      * Registers onSessionEnded handler, if able to.
837      *
838      * @param handler The handler to register
839      * @return Return {@code true} if registration was possible, otherwise {@code false}.
840      */
841     @Override
842     public boolean addOnSessionEndedHandler(Runnable handler) {
843         return onSessionEndedRegistrar.apply(handler);
844     }
845 
846     /**
847      * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception.
848      * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable
849      * though.
850      */
851     public void setReadOnly() {
852         readOnly = true;
853     }
854 
855     /**
856      * Verifies this instance state for mutation operations: mutated instance must not be read-only or closed.
857      */
858     private void verifyStateForMutation() {
859         if (readOnly) {
860             throw new IllegalStateException("repository system session is read-only");
861         }
862     }
863 
864     /**
865      * Simple "pass through" implementation of {@link ProxySelector} that simply returns what passed in
866      * {@link RemoteRepository} have set already, may return {@code null}.
867      */
868     static class PassthroughProxySelector implements ProxySelector {
869 
870         public static final ProxySelector INSTANCE = new PassthroughProxySelector();
871 
872         @Override
873         public Proxy getProxy(RemoteRepository repository) {
874             requireNonNull(repository, "repository cannot be null");
875             return repository.getProxy();
876         }
877     }
878 
879     /**
880      * Simple "null" implementation of {@link MirrorSelector} that returns {@code null} for any passed
881      * in {@link RemoteRepository}.
882      */
883     static class NullMirrorSelector implements MirrorSelector {
884 
885         public static final MirrorSelector INSTANCE = new NullMirrorSelector();
886 
887         @Override
888         public RemoteRepository getMirror(RemoteRepository repository) {
889             requireNonNull(repository, "repository cannot be null");
890             return null;
891         }
892     }
893 
894     /**
895      * Simple "pass through" implementation of {@link AuthenticationSelector} that simply returns what passed in
896      * {@link RemoteRepository} have set already, may return {@code null}.
897      */
898     static class PassthroughAuthenticationSelector implements AuthenticationSelector {
899 
900         public static final AuthenticationSelector INSTANCE = new PassthroughAuthenticationSelector();
901 
902         @Override
903         public Authentication getAuthentication(RemoteRepository repository) {
904             requireNonNull(repository, "repository cannot be null");
905             return repository.getAuthentication();
906         }
907     }
908 
909     /**
910      * Simple "null" implementation of {@link ArtifactTypeRegistry} that returns {@code null} for any type ID.
911      */
912     static final class NullArtifactTypeRegistry implements ArtifactTypeRegistry {
913 
914         public static final ArtifactTypeRegistry INSTANCE = new NullArtifactTypeRegistry();
915 
916         @Override
917         public ArtifactType get(String typeId) {
918             return null;
919         }
920     }
921 }