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