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