View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl.session;
20  
21  import java.io.File;
22  import java.util.Arrays;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.concurrent.atomic.AtomicBoolean;
27  import java.util.function.Supplier;
28  
29  import org.eclipse.aether.DefaultSessionData;
30  import org.eclipse.aether.RepositoryCache;
31  import org.eclipse.aether.RepositoryListener;
32  import org.eclipse.aether.RepositorySystem;
33  import org.eclipse.aether.RepositorySystemSession;
34  import org.eclipse.aether.RepositorySystemSession.CloseableSession;
35  import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
36  import org.eclipse.aether.SessionData;
37  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
38  import org.eclipse.aether.collection.DependencyGraphTransformer;
39  import org.eclipse.aether.collection.DependencyManager;
40  import org.eclipse.aether.collection.DependencySelector;
41  import org.eclipse.aether.collection.DependencyTraverser;
42  import org.eclipse.aether.collection.VersionFilter;
43  import org.eclipse.aether.impl.RepositorySystemLifecycle;
44  import org.eclipse.aether.repository.AuthenticationSelector;
45  import org.eclipse.aether.repository.LocalRepository;
46  import org.eclipse.aether.repository.LocalRepositoryManager;
47  import org.eclipse.aether.repository.MirrorSelector;
48  import org.eclipse.aether.repository.ProxySelector;
49  import org.eclipse.aether.repository.RemoteRepository;
50  import org.eclipse.aether.repository.WorkspaceReader;
51  import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
52  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
53  import org.eclipse.aether.transfer.TransferListener;
54  
55  import static java.util.Objects.requireNonNull;
56  import static java.util.stream.Collectors.toList;
57  
58  /**
59   * A default implementation of session builder. Is not immutable nor thread-safe.
60   */
61  public final class DefaultSessionBuilder implements SessionBuilder {
62      private static final MirrorSelector NULL_MIRROR_SELECTOR = r -> null;
63  
64      private static final ProxySelector NULL_PROXY_SELECTOR = RemoteRepository::getProxy;
65  
66      private static final AuthenticationSelector NULL_AUTHENTICATION_SELECTOR = RemoteRepository::getAuthentication;
67  
68      private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
69  
70      private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
71  
72      private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
73  
74      private final RepositorySystem repositorySystem;
75  
76      private final RepositorySystemLifecycle repositorySystemLifecycle;
77  
78      private final Supplier<String> sessionIdSupplier;
79  
80      private final AtomicBoolean closed;
81  
82      private boolean offline;
83  
84      private boolean ignoreArtifactDescriptorRepositories;
85  
86      private ResolutionErrorPolicy resolutionErrorPolicy;
87  
88      private ArtifactDescriptorPolicy artifactDescriptorPolicy;
89  
90      private String checksumPolicy;
91  
92      private String artifactUpdatePolicy;
93  
94      private String metadataUpdatePolicy;
95  
96      private LocalRepositoryManager localRepositoryManager;
97  
98      private List<LocalRepository> localRepositories;
99  
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 }