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