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