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