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