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