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 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 ScopeManager scopeManager; 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 setScopeManager(ScopeManager scopeManager) { 357 this.scopeManager = scopeManager; 358 return this; 359 } 360 361 @Override 362 public SessionBuilder addOnSessionEndedHandler(Runnable handler) { 363 requireNonNull(handler, "null handler"); 364 onSessionCloseHandlers.add(handler); 365 return this; 366 } 367 368 @Override 369 public DefaultSessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier) { 370 requireNonNull(cacheSupplier, "null cacheSupplier"); 371 this.repositoryCacheSupplier = cacheSupplier; 372 return this; 373 } 374 375 @Override 376 public SessionBuilder withLocalRepositoryBaseDirectories(Path... baseDirectories) { 377 return withLocalRepositoryBaseDirectories(Arrays.asList(baseDirectories)); 378 } 379 380 @Override 381 public SessionBuilder withLocalRepositoryBaseDirectories(Collection<Path> baseDirectories) { 382 requireNonNull(baseDirectories, "null baseDirectories"); 383 return withLocalRepositories( 384 baseDirectories.stream().map(LocalRepository::new).collect(toList())); 385 } 386 387 @Override 388 public SessionBuilder withLocalRepositories(LocalRepository... localRepositories) { 389 return withLocalRepositories(Arrays.asList(localRepositories)); 390 } 391 392 @Override 393 public SessionBuilder withLocalRepositories(Collection<LocalRepository> localRepositories) { 394 requireNonNull(localRepositories, "null localRepositories"); 395 this.localRepositories = localRepositories; 396 return this; 397 } 398 399 @Override 400 public SessionBuilder withRepositoryListener(RepositoryListener... repositoryListeners) { 401 return withRepositoryListener(Arrays.asList(repositoryListeners)); 402 } 403 404 @Override 405 public SessionBuilder withRepositoryListener(Collection<RepositoryListener> repositoryListeners) { 406 this.repositoryListener.addAll(repositoryListeners); 407 return this; 408 } 409 410 @Override 411 public SessionBuilder withTransferListener(TransferListener... transferListeners) { 412 return withTransferListener(Arrays.asList(transferListeners)); 413 } 414 415 @Override 416 public SessionBuilder withTransferListener(Collection<TransferListener> transferListeners) { 417 this.transferListener.addAll(transferListeners); 418 return this; 419 } 420 421 @Override 422 public SessionBuilder withRepositorySystemSession(RepositorySystemSession session) { 423 requireNonNull(session, "repository system session cannot be null"); 424 setOffline(session.isOffline()); 425 setIgnoreArtifactDescriptorRepositories(session.isIgnoreArtifactDescriptorRepositories()); 426 setResolutionErrorPolicy(session.getResolutionErrorPolicy()); 427 setArtifactDescriptorPolicy(session.getArtifactDescriptorPolicy()); 428 setChecksumPolicy(session.getChecksumPolicy()); 429 setUpdatePolicy(session.getUpdatePolicy()); 430 setMetadataUpdatePolicy(session.getMetadataUpdatePolicy()); 431 setLocalRepositoryManager(session.getLocalRepositoryManager()); 432 setWorkspaceReader(session.getWorkspaceReader()); 433 setRepositoryListener(session.getRepositoryListener()); 434 setTransferListener(session.getTransferListener()); 435 setSystemProperties(session.getSystemProperties()); 436 setUserProperties(session.getUserProperties()); 437 setConfigProperties(session.getConfigProperties()); 438 setMirrorSelector(session.getMirrorSelector()); 439 setProxySelector(session.getProxySelector()); 440 setAuthenticationSelector(session.getAuthenticationSelector()); 441 setArtifactTypeRegistry(session.getArtifactTypeRegistry()); 442 setDependencyTraverser(session.getDependencyTraverser()); 443 setDependencyManager(session.getDependencyManager()); 444 setDependencySelector(session.getDependencySelector()); 445 setVersionFilter(session.getVersionFilter()); 446 setDependencyGraphTransformer(session.getDependencyGraphTransformer()); 447 setData(session.getData()); 448 setCache(session.getCache()); 449 return this; 450 } 451 452 @Override 453 public CloseableSession build() { 454 return new DefaultCloseableSession( 455 sessionIdSupplier.get(), 456 offline, 457 ignoreArtifactDescriptorRepositories, 458 resolutionErrorPolicy, 459 artifactDescriptorPolicy, 460 checksumPolicy, 461 artifactUpdatePolicy, 462 metadataUpdatePolicy, 463 localRepositoryManager, 464 localRepositories, 465 workspaceReader, 466 repositoryListener, 467 transferListener, 468 copySafe(systemProperties, String.class), 469 copySafe(userProperties, String.class), 470 copySafe(configProperties, Object.class), 471 mirrorSelector, 472 proxySelector, 473 authenticationSelector, 474 artifactTypeRegistry, 475 dependencyTraverser, 476 dependencyManager, 477 dependencySelector, 478 versionFilter, 479 dependencyGraphTransformer, 480 sessionDataSupplier.get(), 481 repositoryCacheSupplier.get(), 482 scopeManager, 483 onSessionCloseHandlers, 484 repositorySystem, 485 repositorySystemLifecycle); 486 } 487 488 @SuppressWarnings("checkstyle:magicnumber") 489 private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) { 490 Map<String, T> map; 491 if (table == null || table.isEmpty()) { 492 map = new HashMap<>(); 493 } else { 494 map = new HashMap<>((int) (table.size() / 0.75f) + 1); 495 for (Map.Entry<?, ?> entry : table.entrySet()) { 496 Object key = entry.getKey(); 497 if (key instanceof String) { 498 Object value = entry.getValue(); 499 if (valueType.isInstance(value)) { 500 map.put(key.toString(), valueType.cast(value)); 501 } 502 } 503 } 504 } 505 return map; 506 } 507}