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.artifact.ArtifactTypeRegistry; 034import org.eclipse.aether.collection.DependencyGraphTransformer; 035import org.eclipse.aether.collection.DependencyManager; 036import org.eclipse.aether.collection.DependencySelector; 037import org.eclipse.aether.collection.DependencyTraverser; 038import org.eclipse.aether.collection.VersionFilter; 039import org.eclipse.aether.impl.RepositorySystemLifecycle; 040import org.eclipse.aether.repository.AuthenticationSelector; 041import org.eclipse.aether.repository.LocalRepository; 042import org.eclipse.aether.repository.LocalRepositoryManager; 043import org.eclipse.aether.repository.MirrorSelector; 044import org.eclipse.aether.repository.ProxySelector; 045import org.eclipse.aether.repository.RemoteRepository; 046import org.eclipse.aether.repository.WorkspaceReader; 047import org.eclipse.aether.resolution.ArtifactDescriptorPolicy; 048import org.eclipse.aether.resolution.ResolutionErrorPolicy; 049import org.eclipse.aether.scope.ScopeManager; 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 PASS_THROUGH_PROXY_SELECTOR = RemoteRepository::getProxy; 062 063 private static final AuthenticationSelector PASS_THROUGH_AUTHENTICATION_SELECTOR = 064 RemoteRepository::getAuthentication; 065 066 private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null; 067 068 private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new; 069 070 private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null; 071 072 private final RepositorySystem repositorySystem; 073 074 private final RepositorySystemLifecycle repositorySystemLifecycle; 075 076 private final Supplier<String> sessionIdSupplier; 077 078 private boolean offline; 079 080 private boolean ignoreArtifactDescriptorRepositories; 081 082 private ResolutionErrorPolicy resolutionErrorPolicy; 083 084 private ArtifactDescriptorPolicy artifactDescriptorPolicy; 085 086 private String checksumPolicy; 087 088 private String artifactUpdatePolicy; 089 090 private String metadataUpdatePolicy; 091 092 private LocalRepositoryManager localRepositoryManager; 093 094 private Collection<LocalRepository> localRepositories; 095 096 private WorkspaceReader workspaceReader; 097 098 private final ArrayList<RepositoryListener> repositoryListener = new ArrayList<>(); 099 100 private final ArrayList<TransferListener> transferListener = new ArrayList<>(); 101 102 private Map<String, String> systemProperties = new HashMap<>(); 103 104 private Map<String, String> userProperties = new HashMap<>(); 105 106 private Map<String, Object> configProperties = new HashMap<>(); 107 108 private MirrorSelector mirrorSelector = NULL_MIRROR_SELECTOR; 109 110 private ProxySelector proxySelector = PASS_THROUGH_PROXY_SELECTOR; 111 112 private AuthenticationSelector authenticationSelector = PASS_THROUGH_AUTHENTICATION_SELECTOR; 113 114 private ArtifactTypeRegistry artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY; 115 116 private DependencyTraverser dependencyTraverser; 117 118 private DependencyManager dependencyManager; 119 120 private DependencySelector dependencySelector; 121 122 private VersionFilter versionFilter; 123 124 private DependencyGraphTransformer dependencyGraphTransformer; 125 126 private Supplier<SessionData> sessionDataSupplier = DEFAULT_SESSION_DATA_SUPPLIER; 127 128 private Supplier<RepositoryCache> repositoryCacheSupplier = DEFAULT_REPOSITORY_CACHE_SUPPLIER; 129 130 private ScopeManager scopeManager; 131 132 private final ArrayList<Runnable> onSessionCloseHandlers = new ArrayList<>(); 133 134 /** 135 * Constructor for "top level" builders. 136 */ 137 public DefaultSessionBuilder( 138 RepositorySystem repositorySystem, 139 RepositorySystemLifecycle repositorySystemLifecycle, 140 Supplier<String> sessionIdSupplier) { 141 this.repositorySystem = requireNonNull(repositorySystem); 142 this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle); 143 this.sessionIdSupplier = requireNonNull(sessionIdSupplier); 144 } 145 146 @Override 147 public DefaultSessionBuilder setOffline(boolean offline) { 148 this.offline = offline; 149 return this; 150 } 151 152 @Override 153 public DefaultSessionBuilder setIgnoreArtifactDescriptorRepositories(boolean ignoreArtifactDescriptorRepositories) { 154 this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories; 155 return this; 156 } 157 158 @Override 159 public DefaultSessionBuilder setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) { 160 this.resolutionErrorPolicy = resolutionErrorPolicy; 161 return this; 162 } 163 164 @Override 165 public DefaultSessionBuilder setArtifactDescriptorPolicy(ArtifactDescriptorPolicy artifactDescriptorPolicy) { 166 this.artifactDescriptorPolicy = artifactDescriptorPolicy; 167 return this; 168 } 169 170 @Override 171 public DefaultSessionBuilder setChecksumPolicy(String checksumPolicy) { 172 this.checksumPolicy = checksumPolicy; 173 return this; 174 } 175 176 @Override 177 public DefaultSessionBuilder setUpdatePolicy(String updatePolicy) { 178 setArtifactUpdatePolicy(updatePolicy); 179 setMetadataUpdatePolicy(updatePolicy); 180 return this; 181 } 182 183 @Override 184 public DefaultSessionBuilder setArtifactUpdatePolicy(String artifactUpdatePolicy) { 185 this.artifactUpdatePolicy = artifactUpdatePolicy; 186 return this; 187 } 188 189 @Override 190 public DefaultSessionBuilder setMetadataUpdatePolicy(String metadataUpdatePolicy) { 191 this.metadataUpdatePolicy = metadataUpdatePolicy; 192 return this; 193 } 194 195 @Override 196 public DefaultSessionBuilder setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) { 197 this.localRepositoryManager = localRepositoryManager; 198 return this; 199 } 200 201 @Override 202 public DefaultSessionBuilder setWorkspaceReader(WorkspaceReader workspaceReader) { 203 this.workspaceReader = workspaceReader; 204 return this; 205 } 206 207 @Override 208 public DefaultSessionBuilder setRepositoryListener(RepositoryListener repositoryListener) { 209 this.repositoryListener.clear(); 210 if (repositoryListener != null) { 211 this.repositoryListener.add(repositoryListener); 212 } 213 return this; 214 } 215 216 @Override 217 public DefaultSessionBuilder setTransferListener(TransferListener transferListener) { 218 this.transferListener.clear(); 219 if (transferListener != null) { 220 this.transferListener.add(transferListener); 221 } 222 return this; 223 } 224 225 @Override 226 public DefaultSessionBuilder setSystemProperties(Map<?, ?> systemProperties) { 227 this.systemProperties = copySafe(systemProperties, String.class); 228 return this; 229 } 230 231 @Override 232 public DefaultSessionBuilder setSystemProperty(String key, String value) { 233 if (value != null) { 234 systemProperties.put(key, value); 235 } else { 236 systemProperties.remove(key); 237 } 238 return this; 239 } 240 241 @Override 242 public DefaultSessionBuilder setUserProperties(Map<?, ?> userProperties) { 243 this.userProperties = copySafe(userProperties, String.class); 244 return this; 245 } 246 247 @Override 248 public DefaultSessionBuilder setUserProperty(String key, String value) { 249 if (value != null) { 250 userProperties.put(key, value); 251 } else { 252 userProperties.remove(key); 253 } 254 return this; 255 } 256 257 @Override 258 public DefaultSessionBuilder setConfigProperties(Map<?, ?> configProperties) { 259 this.configProperties = copySafe(configProperties, Object.class); 260 return this; 261 } 262 263 @Override 264 public DefaultSessionBuilder setConfigProperty(String key, Object value) { 265 if (value != null) { 266 configProperties.put(key, value); 267 } else { 268 configProperties.remove(key); 269 } 270 return this; 271 } 272 273 @Override 274 public DefaultSessionBuilder setMirrorSelector(MirrorSelector mirrorSelector) { 275 this.mirrorSelector = mirrorSelector; 276 if (this.mirrorSelector == null) { 277 this.mirrorSelector = NULL_MIRROR_SELECTOR; 278 } 279 return this; 280 } 281 282 @Override 283 public DefaultSessionBuilder setProxySelector(ProxySelector proxySelector) { 284 this.proxySelector = proxySelector; 285 if (this.proxySelector == null) { 286 this.proxySelector = PASS_THROUGH_PROXY_SELECTOR; 287 } 288 return this; 289 } 290 291 @Override 292 public DefaultSessionBuilder setAuthenticationSelector(AuthenticationSelector authenticationSelector) { 293 this.authenticationSelector = authenticationSelector; 294 if (this.authenticationSelector == null) { 295 this.authenticationSelector = PASS_THROUGH_AUTHENTICATION_SELECTOR; 296 } 297 return this; 298 } 299 300 @Override 301 public DefaultSessionBuilder setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) { 302 this.artifactTypeRegistry = artifactTypeRegistry; 303 if (this.artifactTypeRegistry == null) { 304 this.artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY; 305 } 306 return this; 307 } 308 309 @Override 310 public DefaultSessionBuilder setDependencyTraverser(DependencyTraverser dependencyTraverser) { 311 this.dependencyTraverser = dependencyTraverser; 312 return this; 313 } 314 315 @Override 316 public DefaultSessionBuilder setDependencyManager(DependencyManager dependencyManager) { 317 this.dependencyManager = dependencyManager; 318 return this; 319 } 320 321 @Override 322 public DefaultSessionBuilder setDependencySelector(DependencySelector dependencySelector) { 323 this.dependencySelector = dependencySelector; 324 return this; 325 } 326 327 @Override 328 public DefaultSessionBuilder setVersionFilter(VersionFilter versionFilter) { 329 this.versionFilter = versionFilter; 330 return this; 331 } 332 333 @Override 334 public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransformer dependencyGraphTransformer) { 335 this.dependencyGraphTransformer = dependencyGraphTransformer; 336 return this; 337 } 338 339 @Override 340 public DefaultSessionBuilder setData(SessionData data) { 341 return setSessionDataSupplier(() -> data); 342 } 343 344 @Override 345 public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) { 346 requireNonNull(dataSupplier, "null dataSupplier"); 347 this.sessionDataSupplier = dataSupplier; 348 return this; 349 } 350 351 @Override 352 public DefaultSessionBuilder setCache(RepositoryCache cache) { 353 return setRepositoryCacheSupplier(() -> cache); 354 } 355 356 @Override 357 public DefaultSessionBuilder setScopeManager(ScopeManager scopeManager) { 358 this.scopeManager = scopeManager; 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 return this; 451 } 452 453 @Override 454 public CloseableSession build() { 455 return new DefaultCloseableSession( 456 sessionIdSupplier.get(), 457 offline, 458 ignoreArtifactDescriptorRepositories, 459 resolutionErrorPolicy, 460 artifactDescriptorPolicy, 461 checksumPolicy, 462 artifactUpdatePolicy, 463 metadataUpdatePolicy, 464 localRepositoryManager, 465 localRepositories, 466 workspaceReader, 467 repositoryListener, 468 transferListener, 469 copySafe(systemProperties, String.class), 470 copySafe(userProperties, String.class), 471 copySafe(configProperties, Object.class), 472 mirrorSelector, 473 proxySelector, 474 authenticationSelector, 475 artifactTypeRegistry, 476 dependencyTraverser, 477 dependencyManager, 478 dependencySelector, 479 versionFilter, 480 dependencyGraphTransformer, 481 sessionDataSupplier.get(), 482 repositoryCacheSupplier.get(), 483 scopeManager, 484 onSessionCloseHandlers, 485 repositorySystem, 486 repositorySystemLifecycle); 487 } 488 489 @SuppressWarnings("checkstyle:magicnumber") 490 private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) { 491 Map<String, T> map; 492 if (table == null || table.isEmpty()) { 493 map = new HashMap<>(); 494 } else { 495 map = new HashMap<>((int) (table.size() / 0.75f) + 1); 496 for (Map.Entry<?, ?> entry : table.entrySet()) { 497 Object key = entry.getKey(); 498 if (key instanceof String) { 499 Object value = entry.getValue(); 500 if (valueType.isInstance(value)) { 501 map.put(key.toString(), valueType.cast(value)); 502 } 503 } 504 } 505 } 506 return map; 507 } 508}