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