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.internal.impl.session; 020 021import java.nio.file.Path; 022import java.util.*; 023import java.util.function.Supplier; 024 025import org.eclipse.aether.DefaultSessionData; 026import org.eclipse.aether.RepositoryCache; 027import org.eclipse.aether.RepositoryListener; 028import org.eclipse.aether.RepositorySystem; 029import org.eclipse.aether.RepositorySystemSession; 030import org.eclipse.aether.RepositorySystemSession.CloseableSession; 031import org.eclipse.aether.RepositorySystemSession.SessionBuilder; 032import org.eclipse.aether.SessionData; 033import org.eclipse.aether.SystemScopeHandler; 034import org.eclipse.aether.artifact.ArtifactTypeRegistry; 035import org.eclipse.aether.collection.DependencyGraphTransformer; 036import org.eclipse.aether.collection.DependencyManager; 037import org.eclipse.aether.collection.DependencySelector; 038import org.eclipse.aether.collection.DependencyTraverser; 039import org.eclipse.aether.collection.VersionFilter; 040import org.eclipse.aether.impl.RepositorySystemLifecycle; 041import org.eclipse.aether.repository.AuthenticationSelector; 042import org.eclipse.aether.repository.LocalRepository; 043import org.eclipse.aether.repository.LocalRepositoryManager; 044import org.eclipse.aether.repository.MirrorSelector; 045import org.eclipse.aether.repository.ProxySelector; 046import org.eclipse.aether.repository.RemoteRepository; 047import org.eclipse.aether.repository.WorkspaceReader; 048import org.eclipse.aether.resolution.ArtifactDescriptorPolicy; 049import org.eclipse.aether.resolution.ResolutionErrorPolicy; 050import org.eclipse.aether.transfer.TransferListener; 051 052import static java.util.Objects.requireNonNull; 053import static java.util.stream.Collectors.toList; 054 055/** 056 * A default implementation of session builder. Is not immutable nor thread-safe. 057 */ 058public final class DefaultSessionBuilder implements SessionBuilder { 059 private static final MirrorSelector NULL_MIRROR_SELECTOR = r -> null; 060 061 private static final ProxySelector NULL_PROXY_SELECTOR = RemoteRepository::getProxy; 062 063 private static final AuthenticationSelector NULL_AUTHENTICATION_SELECTOR = RemoteRepository::getAuthentication; 064 065 private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null; 066 067 private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new; 068 069 private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null; 070 071 private final RepositorySystem repositorySystem; 072 073 private final RepositorySystemLifecycle repositorySystemLifecycle; 074 075 private final Supplier<String> sessionIdSupplier; 076 077 private boolean offline; 078 079 private boolean ignoreArtifactDescriptorRepositories; 080 081 private ResolutionErrorPolicy resolutionErrorPolicy; 082 083 private ArtifactDescriptorPolicy artifactDescriptorPolicy; 084 085 private String checksumPolicy; 086 087 private String artifactUpdatePolicy; 088 089 private String metadataUpdatePolicy; 090 091 private LocalRepositoryManager localRepositoryManager; 092 093 private Collection<LocalRepository> localRepositories; 094 095 private WorkspaceReader workspaceReader; 096 097 private final ArrayList<RepositoryListener> repositoryListener = new ArrayList<>(); 098 099 private final ArrayList<TransferListener> transferListener = new ArrayList<>(); 100 101 private Map<String, String> systemProperties = new HashMap<>(); 102 103 private Map<String, String> userProperties = new HashMap<>(); 104 105 private Map<String, Object> configProperties = new HashMap<>(); 106 107 private MirrorSelector mirrorSelector = NULL_MIRROR_SELECTOR; 108 109 private ProxySelector proxySelector = NULL_PROXY_SELECTOR; 110 111 private AuthenticationSelector authenticationSelector = NULL_AUTHENTICATION_SELECTOR; 112 113 private ArtifactTypeRegistry artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY; 114 115 private DependencyTraverser dependencyTraverser; 116 117 private DependencyManager dependencyManager; 118 119 private DependencySelector dependencySelector; 120 121 private VersionFilter versionFilter; 122 123 private DependencyGraphTransformer dependencyGraphTransformer; 124 125 private Supplier<SessionData> sessionDataSupplier = DEFAULT_SESSION_DATA_SUPPLIER; 126 127 private Supplier<RepositoryCache> repositoryCacheSupplier = DEFAULT_REPOSITORY_CACHE_SUPPLIER; 128 129 private SystemScopeHandler systemScopeHandler = SystemScopeHandler.LEGACY; 130 131 private final ArrayList<Runnable> onSessionCloseHandlers = new ArrayList<>(); 132 133 /** 134 * Constructor for "top level" builders. 135 */ 136 public DefaultSessionBuilder( 137 RepositorySystem repositorySystem, 138 RepositorySystemLifecycle repositorySystemLifecycle, 139 Supplier<String> sessionIdSupplier) { 140 this.repositorySystem = requireNonNull(repositorySystem); 141 this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle); 142 this.sessionIdSupplier = requireNonNull(sessionIdSupplier); 143 } 144 145 @Override 146 public DefaultSessionBuilder setOffline(boolean offline) { 147 this.offline = offline; 148 return this; 149 } 150 151 @Override 152 public DefaultSessionBuilder setIgnoreArtifactDescriptorRepositories(boolean ignoreArtifactDescriptorRepositories) { 153 this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories; 154 return this; 155 } 156 157 @Override 158 public DefaultSessionBuilder setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) { 159 this.resolutionErrorPolicy = resolutionErrorPolicy; 160 return this; 161 } 162 163 @Override 164 public DefaultSessionBuilder setArtifactDescriptorPolicy(ArtifactDescriptorPolicy artifactDescriptorPolicy) { 165 this.artifactDescriptorPolicy = artifactDescriptorPolicy; 166 return this; 167 } 168 169 @Override 170 public DefaultSessionBuilder setChecksumPolicy(String checksumPolicy) { 171 this.checksumPolicy = checksumPolicy; 172 return this; 173 } 174 175 @Override 176 public DefaultSessionBuilder setUpdatePolicy(String updatePolicy) { 177 setArtifactUpdatePolicy(updatePolicy); 178 setMetadataUpdatePolicy(updatePolicy); 179 return this; 180 } 181 182 @Override 183 public DefaultSessionBuilder setArtifactUpdatePolicy(String artifactUpdatePolicy) { 184 this.artifactUpdatePolicy = artifactUpdatePolicy; 185 return this; 186 } 187 188 @Override 189 public DefaultSessionBuilder setMetadataUpdatePolicy(String metadataUpdatePolicy) { 190 this.metadataUpdatePolicy = metadataUpdatePolicy; 191 return this; 192 } 193 194 @Override 195 public DefaultSessionBuilder setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) { 196 this.localRepositoryManager = localRepositoryManager; 197 return this; 198 } 199 200 @Override 201 public DefaultSessionBuilder setWorkspaceReader(WorkspaceReader workspaceReader) { 202 this.workspaceReader = workspaceReader; 203 return this; 204 } 205 206 @Override 207 public DefaultSessionBuilder setRepositoryListener(RepositoryListener repositoryListener) { 208 this.repositoryListener.clear(); 209 if (repositoryListener != null) { 210 this.repositoryListener.add(repositoryListener); 211 } 212 return this; 213 } 214 215 @Override 216 public DefaultSessionBuilder setTransferListener(TransferListener transferListener) { 217 this.transferListener.clear(); 218 if (transferListener != null) { 219 this.transferListener.add(transferListener); 220 } 221 return this; 222 } 223 224 @Override 225 public DefaultSessionBuilder setSystemProperties(Map<?, ?> systemProperties) { 226 this.systemProperties = copySafe(systemProperties, String.class); 227 return this; 228 } 229 230 @Override 231 public DefaultSessionBuilder setSystemProperty(String key, String value) { 232 if (value != null) { 233 systemProperties.put(key, value); 234 } else { 235 systemProperties.remove(key); 236 } 237 return this; 238 } 239 240 @Override 241 public DefaultSessionBuilder setUserProperties(Map<?, ?> userProperties) { 242 this.userProperties = copySafe(userProperties, String.class); 243 return this; 244 } 245 246 @Override 247 public DefaultSessionBuilder setUserProperty(String key, String value) { 248 if (value != null) { 249 userProperties.put(key, value); 250 } else { 251 userProperties.remove(key); 252 } 253 return this; 254 } 255 256 @Override 257 public DefaultSessionBuilder setConfigProperties(Map<?, ?> configProperties) { 258 this.configProperties = copySafe(configProperties, Object.class); 259 return this; 260 } 261 262 @Override 263 public DefaultSessionBuilder setConfigProperty(String key, Object value) { 264 if (value != null) { 265 configProperties.put(key, value); 266 } else { 267 configProperties.remove(key); 268 } 269 return this; 270 } 271 272 @Override 273 public DefaultSessionBuilder setMirrorSelector(MirrorSelector mirrorSelector) { 274 this.mirrorSelector = mirrorSelector; 275 if (this.mirrorSelector == null) { 276 this.mirrorSelector = NULL_MIRROR_SELECTOR; 277 } 278 return this; 279 } 280 281 @Override 282 public DefaultSessionBuilder setProxySelector(ProxySelector proxySelector) { 283 this.proxySelector = proxySelector; 284 if (this.proxySelector == null) { 285 this.proxySelector = NULL_PROXY_SELECTOR; 286 } 287 return this; 288 } 289 290 @Override 291 public DefaultSessionBuilder setAuthenticationSelector(AuthenticationSelector authenticationSelector) { 292 this.authenticationSelector = authenticationSelector; 293 if (this.authenticationSelector == null) { 294 this.authenticationSelector = NULL_AUTHENTICATION_SELECTOR; 295 } 296 return this; 297 } 298 299 @Override 300 public DefaultSessionBuilder setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) { 301 this.artifactTypeRegistry = artifactTypeRegistry; 302 if (this.artifactTypeRegistry == null) { 303 this.artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY; 304 } 305 return this; 306 } 307 308 @Override 309 public DefaultSessionBuilder setDependencyTraverser(DependencyTraverser dependencyTraverser) { 310 this.dependencyTraverser = dependencyTraverser; 311 return this; 312 } 313 314 @Override 315 public DefaultSessionBuilder setDependencyManager(DependencyManager dependencyManager) { 316 this.dependencyManager = dependencyManager; 317 return this; 318 } 319 320 @Override 321 public DefaultSessionBuilder setDependencySelector(DependencySelector dependencySelector) { 322 this.dependencySelector = dependencySelector; 323 return this; 324 } 325 326 @Override 327 public DefaultSessionBuilder setVersionFilter(VersionFilter versionFilter) { 328 this.versionFilter = versionFilter; 329 return this; 330 } 331 332 @Override 333 public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransformer dependencyGraphTransformer) { 334 this.dependencyGraphTransformer = dependencyGraphTransformer; 335 return this; 336 } 337 338 @Override 339 public DefaultSessionBuilder setData(SessionData data) { 340 return setSessionDataSupplier(() -> data); 341 } 342 343 @Override 344 public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) { 345 requireNonNull(dataSupplier, "null dataSupplier"); 346 this.sessionDataSupplier = dataSupplier; 347 return this; 348 } 349 350 @Override 351 public DefaultSessionBuilder setCache(RepositoryCache cache) { 352 return setRepositoryCacheSupplier(() -> cache); 353 } 354 355 @Override 356 public DefaultSessionBuilder setSystemScopeHandler(SystemScopeHandler systemScopeHandler) { 357 requireNonNull(systemScopeHandler, "null systemScopeHandler"); 358 this.systemScopeHandler = systemScopeHandler; 359 return this; 360 } 361 362 @Override 363 public SessionBuilder addOnSessionEndedHandler(Runnable handler) { 364 requireNonNull(handler, "null handler"); 365 onSessionCloseHandlers.add(handler); 366 return this; 367 } 368 369 @Override 370 public DefaultSessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier) { 371 requireNonNull(cacheSupplier, "null cacheSupplier"); 372 this.repositoryCacheSupplier = cacheSupplier; 373 return this; 374 } 375 376 @Override 377 public SessionBuilder withLocalRepositoryBaseDirectories(Path... baseDirectories) { 378 return withLocalRepositoryBaseDirectories(Arrays.asList(baseDirectories)); 379 } 380 381 @Override 382 public SessionBuilder withLocalRepositoryBaseDirectories(Collection<Path> baseDirectories) { 383 requireNonNull(baseDirectories, "null baseDirectories"); 384 return withLocalRepositories( 385 baseDirectories.stream().map(LocalRepository::new).collect(toList())); 386 } 387 388 @Override 389 public SessionBuilder withLocalRepositories(LocalRepository... localRepositories) { 390 return withLocalRepositories(Arrays.asList(localRepositories)); 391 } 392 393 @Override 394 public SessionBuilder withLocalRepositories(Collection<LocalRepository> localRepositories) { 395 requireNonNull(localRepositories, "null localRepositories"); 396 this.localRepositories = localRepositories; 397 return this; 398 } 399 400 @Override 401 public SessionBuilder withRepositoryListener(RepositoryListener... repositoryListeners) { 402 return withRepositoryListener(Arrays.asList(repositoryListeners)); 403 } 404 405 @Override 406 public SessionBuilder withRepositoryListener(Collection<RepositoryListener> repositoryListeners) { 407 this.repositoryListener.addAll(repositoryListeners); 408 return this; 409 } 410 411 @Override 412 public SessionBuilder withTransferListener(TransferListener... transferListeners) { 413 return withTransferListener(Arrays.asList(transferListeners)); 414 } 415 416 @Override 417 public SessionBuilder withTransferListener(Collection<TransferListener> transferListeners) { 418 this.transferListener.addAll(transferListeners); 419 return this; 420 } 421 422 @Override 423 public SessionBuilder withRepositorySystemSession(RepositorySystemSession session) { 424 requireNonNull(session, "repository system session cannot be null"); 425 setOffline(session.isOffline()); 426 setIgnoreArtifactDescriptorRepositories(session.isIgnoreArtifactDescriptorRepositories()); 427 setResolutionErrorPolicy(session.getResolutionErrorPolicy()); 428 setArtifactDescriptorPolicy(session.getArtifactDescriptorPolicy()); 429 setChecksumPolicy(session.getChecksumPolicy()); 430 setUpdatePolicy(session.getUpdatePolicy()); 431 setMetadataUpdatePolicy(session.getMetadataUpdatePolicy()); 432 setLocalRepositoryManager(session.getLocalRepositoryManager()); 433 setWorkspaceReader(session.getWorkspaceReader()); 434 setRepositoryListener(session.getRepositoryListener()); 435 setTransferListener(session.getTransferListener()); 436 setSystemProperties(session.getSystemProperties()); 437 setUserProperties(session.getUserProperties()); 438 setConfigProperties(session.getConfigProperties()); 439 setMirrorSelector(session.getMirrorSelector()); 440 setProxySelector(session.getProxySelector()); 441 setAuthenticationSelector(session.getAuthenticationSelector()); 442 setArtifactTypeRegistry(session.getArtifactTypeRegistry()); 443 setDependencyTraverser(session.getDependencyTraverser()); 444 setDependencyManager(session.getDependencyManager()); 445 setDependencySelector(session.getDependencySelector()); 446 setVersionFilter(session.getVersionFilter()); 447 setDependencyGraphTransformer(session.getDependencyGraphTransformer()); 448 setData(session.getData()); 449 setCache(session.getCache()); 450 setSystemScopeHandler(session.getSystemScopeHandler()); 451 return this; 452 } 453 454 @Override 455 public CloseableSession build() { 456 return new DefaultCloseableSession( 457 sessionIdSupplier.get(), 458 offline, 459 ignoreArtifactDescriptorRepositories, 460 resolutionErrorPolicy, 461 artifactDescriptorPolicy, 462 checksumPolicy, 463 artifactUpdatePolicy, 464 metadataUpdatePolicy, 465 localRepositoryManager, 466 localRepositories, 467 workspaceReader, 468 repositoryListener, 469 transferListener, 470 copySafe(systemProperties, String.class), 471 copySafe(userProperties, String.class), 472 copySafe(configProperties, Object.class), 473 mirrorSelector, 474 proxySelector, 475 authenticationSelector, 476 artifactTypeRegistry, 477 dependencyTraverser, 478 dependencyManager, 479 dependencySelector, 480 versionFilter, 481 dependencyGraphTransformer, 482 sessionDataSupplier.get(), 483 repositoryCacheSupplier.get(), 484 systemScopeHandler, 485 onSessionCloseHandlers, 486 repositorySystem, 487 repositorySystemLifecycle); 488 } 489 490 @SuppressWarnings("checkstyle:magicnumber") 491 private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) { 492 Map<String, T> map; 493 if (table == null || table.isEmpty()) { 494 map = new HashMap<>(); 495 } else { 496 map = new HashMap<>((int) (table.size() / 0.75f) + 1); 497 for (Map.Entry<?, ?> entry : table.entrySet()) { 498 Object key = entry.getKey(); 499 if (key instanceof String) { 500 Object value = entry.getValue(); 501 if (valueType.isInstance(value)) { 502 map.put(key.toString(), valueType.cast(value)); 503 } 504 } 505 } 506 } 507 return map; 508 } 509}