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 private <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) { 386 Map<String, T> map; 387 if (table == null || table.isEmpty()) { 388 map = new HashMap<>(); 389 } else { 390 map = new HashMap<>((int) (table.size() / 0.75f) + 1); 391 for (Map.Entry<?, ?> entry : table.entrySet()) { 392 Object key = entry.getKey(); 393 if (key instanceof String) { 394 Object value = entry.getValue(); 395 if (valueType.isInstance(value)) { 396 map.put(key.toString(), valueType.cast(value)); 397 } 398 } 399 } 400 } 401 return map; 402 } 403 404 @Override 405 public Map<String, String> getSystemProperties() { 406 return systemPropertiesView; 407 } 408 409 /** 410 * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually 411 * collected from the runtime environment like {@link System#getProperties()} and environment variables. 412 * <p> 413 * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map 414 * that doesn't match this type will be silently ignored. 415 * 416 * @param systemProperties The system properties, may be {@code null} or empty if none. 417 * @return This session for chaining, never {@code null}. 418 */ 419 public DefaultRepositorySystemSession setSystemProperties(Map<?, ?> systemProperties) { 420 verifyStateForMutation(); 421 this.systemProperties = copySafe(systemProperties, String.class); 422 systemPropertiesView = Collections.unmodifiableMap(this.systemProperties); 423 return this; 424 } 425 426 /** 427 * Sets the specified system property. 428 * 429 * @param key The property key, must not be {@code null}. 430 * @param value The property value, may be {@code null} to remove/unset the property. 431 * @return This session for chaining, never {@code null}. 432 */ 433 public DefaultRepositorySystemSession setSystemProperty(String key, String value) { 434 verifyStateForMutation(); 435 if (value != null) { 436 systemProperties.put(key, value); 437 } else { 438 systemProperties.remove(key); 439 } 440 return this; 441 } 442 443 @Override 444 public Map<String, String> getUserProperties() { 445 return userPropertiesView; 446 } 447 448 /** 449 * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to 450 * system properties but are set on the discretion of the user and hence are considered of higher priority than 451 * system properties in case of conflicts. 452 * <p> 453 * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map 454 * that doesn't match this type will be silently ignored. 455 * 456 * @param userProperties The user properties, may be {@code null} or empty if none. 457 * @return This session for chaining, never {@code null}. 458 */ 459 public DefaultRepositorySystemSession setUserProperties(Map<?, ?> userProperties) { 460 verifyStateForMutation(); 461 this.userProperties = copySafe(userProperties, String.class); 462 userPropertiesView = Collections.unmodifiableMap(this.userProperties); 463 return this; 464 } 465 466 /** 467 * Sets the specified user property. 468 * 469 * @param key The property key, must not be {@code null}. 470 * @param value The property value, may be {@code null} to remove/unset the property. 471 * @return This session for chaining, never {@code null}. 472 */ 473 public DefaultRepositorySystemSession setUserProperty(String key, String value) { 474 verifyStateForMutation(); 475 if (value != null) { 476 userProperties.put(key, value); 477 } else { 478 userProperties.remove(key); 479 } 480 return this; 481 } 482 483 @Override 484 public Map<String, Object> getConfigProperties() { 485 return configPropertiesView; 486 } 487 488 /** 489 * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling, 490 * connector-specific behavior, etc.). 491 * <p> 492 * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the 493 * input map that doesn't match this type will be silently ignored. 494 * 495 * @param configProperties The configuration properties, may be {@code null} or empty if none. 496 * @return This session for chaining, never {@code null}. 497 */ 498 public DefaultRepositorySystemSession setConfigProperties(Map<?, ?> configProperties) { 499 verifyStateForMutation(); 500 this.configProperties = copySafe(configProperties, Object.class); 501 configPropertiesView = Collections.unmodifiableMap(this.configProperties); 502 return this; 503 } 504 505 /** 506 * Sets the specified configuration property. 507 * 508 * @param key The property key, must not be {@code null}. 509 * @param value The property value, may be {@code null} to remove/unset the property. 510 * @return This session for chaining, never {@code null}. 511 */ 512 public DefaultRepositorySystemSession setConfigProperty(String key, Object value) { 513 verifyStateForMutation(); 514 if (value != null) { 515 configProperties.put(key, value); 516 } else { 517 configProperties.remove(key); 518 } 519 return this; 520 } 521 522 @Override 523 public MirrorSelector getMirrorSelector() { 524 return mirrorSelector; 525 } 526 527 /** 528 * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is 529 * not used for remote repositories which are passed as request parameters to the repository system, those 530 * repositories are supposed to denote the effective repositories. 531 * 532 * @param mirrorSelector The mirror selector to use, may be {@code null}. 533 * @return This session for chaining, never {@code null}. 534 */ 535 public DefaultRepositorySystemSession setMirrorSelector(MirrorSelector mirrorSelector) { 536 verifyStateForMutation(); 537 this.mirrorSelector = mirrorSelector; 538 if (this.mirrorSelector == null) { 539 this.mirrorSelector = NullMirrorSelector.INSTANCE; 540 } 541 return this; 542 } 543 544 @Override 545 public ProxySelector getProxySelector() { 546 return proxySelector; 547 } 548 549 /** 550 * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is 551 * not used for remote repositories which are passed as request parameters to the repository system, those 552 * repositories are supposed to have their proxy (if any) already set. 553 * 554 * @param proxySelector The proxy selector to use, may be {@code null}. 555 * @return This session for chaining, never {@code null}. 556 * @see org.eclipse.aether.repository.RemoteRepository#getProxy() 557 */ 558 public DefaultRepositorySystemSession setProxySelector(ProxySelector proxySelector) { 559 verifyStateForMutation(); 560 this.proxySelector = proxySelector; 561 if (this.proxySelector == null) { 562 this.proxySelector = NullProxySelector.INSTANCE; 563 } 564 return this; 565 } 566 567 @Override 568 public AuthenticationSelector getAuthenticationSelector() { 569 return authenticationSelector; 570 } 571 572 /** 573 * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this 574 * selector is not used for remote repositories which are passed as request parameters to the repository system, 575 * those repositories are supposed to have their authentication (if any) already set. 576 * 577 * @param authenticationSelector The authentication selector to use, may be {@code null}. 578 * @return This session for chaining, never {@code null}. 579 * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication() 580 */ 581 public DefaultRepositorySystemSession setAuthenticationSelector(AuthenticationSelector authenticationSelector) { 582 verifyStateForMutation(); 583 this.authenticationSelector = authenticationSelector; 584 if (this.authenticationSelector == null) { 585 this.authenticationSelector = NullAuthenticationSelector.INSTANCE; 586 } 587 return this; 588 } 589 590 @Override 591 public ArtifactTypeRegistry getArtifactTypeRegistry() { 592 return artifactTypeRegistry; 593 } 594 595 /** 596 * Sets the registry of artifact types recognized by this session. 597 * 598 * @param artifactTypeRegistry The artifact type registry, may be {@code null}. 599 * @return This session for chaining, never {@code null}. 600 */ 601 public DefaultRepositorySystemSession setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) { 602 verifyStateForMutation(); 603 this.artifactTypeRegistry = artifactTypeRegistry; 604 if (this.artifactTypeRegistry == null) { 605 this.artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE; 606 } 607 return this; 608 } 609 610 @Override 611 public DependencyTraverser getDependencyTraverser() { 612 return dependencyTraverser; 613 } 614 615 /** 616 * Sets the dependency traverser to use for building dependency graphs. 617 * 618 * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}. 619 * @return This session for chaining, never {@code null}. 620 */ 621 public DefaultRepositorySystemSession setDependencyTraverser(DependencyTraverser dependencyTraverser) { 622 verifyStateForMutation(); 623 this.dependencyTraverser = dependencyTraverser; 624 return this; 625 } 626 627 @Override 628 public DependencyManager getDependencyManager() { 629 return dependencyManager; 630 } 631 632 /** 633 * Sets the dependency manager to use for building dependency graphs. 634 * 635 * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}. 636 * @return This session for chaining, never {@code null}. 637 */ 638 public DefaultRepositorySystemSession setDependencyManager(DependencyManager dependencyManager) { 639 verifyStateForMutation(); 640 this.dependencyManager = dependencyManager; 641 return this; 642 } 643 644 @Override 645 public DependencySelector getDependencySelector() { 646 return dependencySelector; 647 } 648 649 /** 650 * Sets the dependency selector to use for building dependency graphs. 651 * 652 * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}. 653 * @return This session for chaining, never {@code null}. 654 */ 655 public DefaultRepositorySystemSession setDependencySelector(DependencySelector dependencySelector) { 656 verifyStateForMutation(); 657 this.dependencySelector = dependencySelector; 658 return this; 659 } 660 661 @Override 662 public VersionFilter getVersionFilter() { 663 return versionFilter; 664 } 665 666 /** 667 * Sets the version filter to use for building dependency graphs. 668 * 669 * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter 670 * versions. 671 * @return This session for chaining, never {@code null}. 672 */ 673 public DefaultRepositorySystemSession setVersionFilter(VersionFilter versionFilter) { 674 verifyStateForMutation(); 675 this.versionFilter = versionFilter; 676 return this; 677 } 678 679 @Override 680 public DependencyGraphTransformer getDependencyGraphTransformer() { 681 return dependencyGraphTransformer; 682 } 683 684 /** 685 * Sets the dependency graph transformer to use for building dependency graphs. 686 * 687 * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be 688 * {@code null}. 689 * @return This session for chaining, never {@code null}. 690 */ 691 public DefaultRepositorySystemSession setDependencyGraphTransformer( 692 DependencyGraphTransformer dependencyGraphTransformer) { 693 verifyStateForMutation(); 694 this.dependencyGraphTransformer = dependencyGraphTransformer; 695 return this; 696 } 697 698 @Override 699 public SessionData getData() { 700 return data; 701 } 702 703 /** 704 * Sets the custom data associated with this session. 705 * 706 * @param data The session data, may be {@code null}. 707 * @return This session for chaining, never {@code null}. 708 */ 709 public DefaultRepositorySystemSession setData(SessionData data) { 710 verifyStateForMutation(); 711 this.data = data; 712 if (this.data == null) { 713 this.data = new DefaultSessionData(); 714 } 715 return this; 716 } 717 718 @Override 719 public RepositoryCache getCache() { 720 return cache; 721 } 722 723 /** 724 * Sets the cache the repository system may use to save data for future reuse during the session. 725 * 726 * @param cache The repository cache, may be {@code null} if none. 727 * @return This session for chaining, never {@code null}. 728 */ 729 public DefaultRepositorySystemSession setCache(RepositoryCache cache) { 730 verifyStateForMutation(); 731 this.cache = cache; 732 return this; 733 } 734 735 /** 736 * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception. 737 * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable 738 * though. 739 */ 740 public void setReadOnly() { 741 readOnly = true; 742 } 743 744 /** 745 * Verifies this instance state for mutation operations: mutated instance must not be read-only or closed. 746 */ 747 private void verifyStateForMutation() { 748 if (readOnly) { 749 throw new IllegalStateException("repository system session is read-only"); 750 } 751 } 752 753 static class NullProxySelector implements ProxySelector { 754 755 public static final ProxySelector INSTANCE = new NullProxySelector(); 756 757 public Proxy getProxy(RemoteRepository repository) { 758 requireNonNull(repository, "repository cannot be null"); 759 return repository.getProxy(); 760 } 761 } 762 763 static class NullMirrorSelector implements MirrorSelector { 764 765 public static final MirrorSelector INSTANCE = new NullMirrorSelector(); 766 767 public RemoteRepository getMirror(RemoteRepository repository) { 768 requireNonNull(repository, "repository cannot be null"); 769 return null; 770 } 771 } 772 773 static class NullAuthenticationSelector implements AuthenticationSelector { 774 775 public static final AuthenticationSelector INSTANCE = new NullAuthenticationSelector(); 776 777 public Authentication getAuthentication(RemoteRepository repository) { 778 requireNonNull(repository, "repository cannot be null"); 779 return repository.getAuthentication(); 780 } 781 } 782 783 static final class NullArtifactTypeRegistry implements ArtifactTypeRegistry { 784 785 public static final ArtifactTypeRegistry INSTANCE = new NullArtifactTypeRegistry(); 786 787 public ArtifactType get(String typeId) { 788 return null; 789 } 790 } 791 792 static final class NullFileTransformerManager implements FileTransformerManager { 793 public static final FileTransformerManager INSTANCE = new NullFileTransformerManager(); 794 795 @Override 796 public Collection<FileTransformer> getTransformersForArtifact(Artifact artifact) { 797 return Collections.emptyList(); 798 } 799 } 800}