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.nio.file.Path;
22  import java.util.*;
23  import java.util.function.Supplier;
24  
25  import org.eclipse.aether.DefaultSessionData;
26  import org.eclipse.aether.RepositoryCache;
27  import org.eclipse.aether.RepositoryListener;
28  import org.eclipse.aether.RepositorySystem;
29  import org.eclipse.aether.RepositorySystemSession;
30  import org.eclipse.aether.RepositorySystemSession.CloseableSession;
31  import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
32  import org.eclipse.aether.SessionData;
33  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
34  import org.eclipse.aether.collection.DependencyGraphTransformer;
35  import org.eclipse.aether.collection.DependencyManager;
36  import org.eclipse.aether.collection.DependencySelector;
37  import org.eclipse.aether.collection.DependencyTraverser;
38  import org.eclipse.aether.collection.VersionFilter;
39  import org.eclipse.aether.impl.RepositorySystemLifecycle;
40  import org.eclipse.aether.repository.AuthenticationSelector;
41  import org.eclipse.aether.repository.LocalRepository;
42  import org.eclipse.aether.repository.LocalRepositoryManager;
43  import org.eclipse.aether.repository.MirrorSelector;
44  import org.eclipse.aether.repository.ProxySelector;
45  import org.eclipse.aether.repository.RemoteRepository;
46  import org.eclipse.aether.repository.WorkspaceReader;
47  import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
48  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
49  import org.eclipse.aether.scope.ScopeManager;
50  import org.eclipse.aether.transfer.TransferListener;
51  
52  import static java.util.Objects.requireNonNull;
53  import static java.util.stream.Collectors.toList;
54  
55  /**
56   * A default implementation of session builder. Is not immutable nor thread-safe.
57   */
58  public final class DefaultSessionBuilder implements SessionBuilder {
59      private static final MirrorSelector NULL_MIRROR_SELECTOR = r -> null;
60  
61      private static final ProxySelector NULL_PROXY_SELECTOR = RemoteRepository::getProxy;
62  
63      private static final AuthenticationSelector NULL_AUTHENTICATION_SELECTOR = RemoteRepository::getAuthentication;
64  
65      private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
66  
67      private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
68  
69      private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
70  
71      private final RepositorySystem repositorySystem;
72  
73      private final RepositorySystemLifecycle repositorySystemLifecycle;
74  
75      private final Supplier<String> sessionIdSupplier;
76  
77      private boolean offline;
78  
79      private boolean ignoreArtifactDescriptorRepositories;
80  
81      private ResolutionErrorPolicy resolutionErrorPolicy;
82  
83      private ArtifactDescriptorPolicy artifactDescriptorPolicy;
84  
85      private String checksumPolicy;
86  
87      private String artifactUpdatePolicy;
88  
89      private String metadataUpdatePolicy;
90  
91      private LocalRepositoryManager localRepositoryManager;
92  
93      private Collection<LocalRepository> localRepositories;
94  
95      private WorkspaceReader workspaceReader;
96  
97      private final ArrayList<RepositoryListener> repositoryListener = new ArrayList<>();
98  
99      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 }