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