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 PASS_THROUGH_PROXY_SELECTOR = RemoteRepository::getProxy;
62  
63      private static final AuthenticationSelector PASS_THROUGH_AUTHENTICATION_SELECTOR =
64              RemoteRepository::getAuthentication;
65  
66      private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
67  
68      private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
69  
70      private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
71  
72      private final RepositorySystem repositorySystem;
73  
74      private final RepositorySystemLifecycle repositorySystemLifecycle;
75  
76      private final Supplier<String> sessionIdSupplier;
77  
78      private boolean offline;
79  
80      private boolean ignoreArtifactDescriptorRepositories;
81  
82      private ResolutionErrorPolicy resolutionErrorPolicy;
83  
84      private ArtifactDescriptorPolicy artifactDescriptorPolicy;
85  
86      private String checksumPolicy;
87  
88      private String artifactUpdatePolicy;
89  
90      private String metadataUpdatePolicy;
91  
92      private LocalRepositoryManager localRepositoryManager;
93  
94      private Collection<LocalRepository> localRepositories;
95  
96      private WorkspaceReader workspaceReader;
97  
98      private final ArrayList<RepositoryListener> repositoryListener = new ArrayList<>();
99  
100     private final ArrayList<TransferListener> transferListener = new ArrayList<>();
101 
102     private Map<String, String> systemProperties = new HashMap<>();
103 
104     private Map<String, String> userProperties = new HashMap<>();
105 
106     private Map<String, Object> configProperties = new HashMap<>();
107 
108     private MirrorSelector mirrorSelector = NULL_MIRROR_SELECTOR;
109 
110     private ProxySelector proxySelector = PASS_THROUGH_PROXY_SELECTOR;
111 
112     private AuthenticationSelector authenticationSelector = PASS_THROUGH_AUTHENTICATION_SELECTOR;
113 
114     private ArtifactTypeRegistry artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY;
115 
116     private DependencyTraverser dependencyTraverser;
117 
118     private DependencyManager dependencyManager;
119 
120     private DependencySelector dependencySelector;
121 
122     private VersionFilter versionFilter;
123 
124     private DependencyGraphTransformer dependencyGraphTransformer;
125 
126     private Supplier<SessionData> sessionDataSupplier = DEFAULT_SESSION_DATA_SUPPLIER;
127 
128     private Supplier<RepositoryCache> repositoryCacheSupplier = DEFAULT_REPOSITORY_CACHE_SUPPLIER;
129 
130     private ScopeManager scopeManager;
131 
132     private final ArrayList<Runnable> onSessionCloseHandlers = new ArrayList<>();
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     }
145 
146     @Override
147     public DefaultSessionBuilder setOffline(boolean offline) {
148         this.offline = offline;
149         return this;
150     }
151 
152     @Override
153     public DefaultSessionBuilder setIgnoreArtifactDescriptorRepositories(boolean ignoreArtifactDescriptorRepositories) {
154         this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
155         return this;
156     }
157 
158     @Override
159     public DefaultSessionBuilder setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) {
160         this.resolutionErrorPolicy = resolutionErrorPolicy;
161         return this;
162     }
163 
164     @Override
165     public DefaultSessionBuilder setArtifactDescriptorPolicy(ArtifactDescriptorPolicy artifactDescriptorPolicy) {
166         this.artifactDescriptorPolicy = artifactDescriptorPolicy;
167         return this;
168     }
169 
170     @Override
171     public DefaultSessionBuilder setChecksumPolicy(String checksumPolicy) {
172         this.checksumPolicy = checksumPolicy;
173         return this;
174     }
175 
176     @Override
177     public DefaultSessionBuilder setUpdatePolicy(String updatePolicy) {
178         setArtifactUpdatePolicy(updatePolicy);
179         setMetadataUpdatePolicy(updatePolicy);
180         return this;
181     }
182 
183     @Override
184     public DefaultSessionBuilder setArtifactUpdatePolicy(String artifactUpdatePolicy) {
185         this.artifactUpdatePolicy = artifactUpdatePolicy;
186         return this;
187     }
188 
189     @Override
190     public DefaultSessionBuilder setMetadataUpdatePolicy(String metadataUpdatePolicy) {
191         this.metadataUpdatePolicy = metadataUpdatePolicy;
192         return this;
193     }
194 
195     @Override
196     public DefaultSessionBuilder setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) {
197         this.localRepositoryManager = localRepositoryManager;
198         return this;
199     }
200 
201     @Override
202     public DefaultSessionBuilder setWorkspaceReader(WorkspaceReader workspaceReader) {
203         this.workspaceReader = workspaceReader;
204         return this;
205     }
206 
207     @Override
208     public DefaultSessionBuilder setRepositoryListener(RepositoryListener repositoryListener) {
209         this.repositoryListener.clear();
210         if (repositoryListener != null) {
211             this.repositoryListener.add(repositoryListener);
212         }
213         return this;
214     }
215 
216     @Override
217     public DefaultSessionBuilder setTransferListener(TransferListener transferListener) {
218         this.transferListener.clear();
219         if (transferListener != null) {
220             this.transferListener.add(transferListener);
221         }
222         return this;
223     }
224 
225     @Override
226     public DefaultSessionBuilder setSystemProperties(Map<?, ?> systemProperties) {
227         this.systemProperties = copySafe(systemProperties, String.class);
228         return this;
229     }
230 
231     @Override
232     public DefaultSessionBuilder setSystemProperty(String key, String value) {
233         if (value != null) {
234             systemProperties.put(key, value);
235         } else {
236             systemProperties.remove(key);
237         }
238         return this;
239     }
240 
241     @Override
242     public DefaultSessionBuilder setUserProperties(Map<?, ?> userProperties) {
243         this.userProperties = copySafe(userProperties, String.class);
244         return this;
245     }
246 
247     @Override
248     public DefaultSessionBuilder setUserProperty(String key, String value) {
249         if (value != null) {
250             userProperties.put(key, value);
251         } else {
252             userProperties.remove(key);
253         }
254         return this;
255     }
256 
257     @Override
258     public DefaultSessionBuilder setConfigProperties(Map<?, ?> configProperties) {
259         this.configProperties = copySafe(configProperties, Object.class);
260         return this;
261     }
262 
263     @Override
264     public DefaultSessionBuilder setConfigProperty(String key, Object value) {
265         if (value != null) {
266             configProperties.put(key, value);
267         } else {
268             configProperties.remove(key);
269         }
270         return this;
271     }
272 
273     @Override
274     public DefaultSessionBuilder setMirrorSelector(MirrorSelector mirrorSelector) {
275         this.mirrorSelector = mirrorSelector;
276         if (this.mirrorSelector == null) {
277             this.mirrorSelector = NULL_MIRROR_SELECTOR;
278         }
279         return this;
280     }
281 
282     @Override
283     public DefaultSessionBuilder setProxySelector(ProxySelector proxySelector) {
284         this.proxySelector = proxySelector;
285         if (this.proxySelector == null) {
286             this.proxySelector = PASS_THROUGH_PROXY_SELECTOR;
287         }
288         return this;
289     }
290 
291     @Override
292     public DefaultSessionBuilder setAuthenticationSelector(AuthenticationSelector authenticationSelector) {
293         this.authenticationSelector = authenticationSelector;
294         if (this.authenticationSelector == null) {
295             this.authenticationSelector = PASS_THROUGH_AUTHENTICATION_SELECTOR;
296         }
297         return this;
298     }
299 
300     @Override
301     public DefaultSessionBuilder setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) {
302         this.artifactTypeRegistry = artifactTypeRegistry;
303         if (this.artifactTypeRegistry == null) {
304             this.artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY;
305         }
306         return this;
307     }
308 
309     @Override
310     public DefaultSessionBuilder setDependencyTraverser(DependencyTraverser dependencyTraverser) {
311         this.dependencyTraverser = dependencyTraverser;
312         return this;
313     }
314 
315     @Override
316     public DefaultSessionBuilder setDependencyManager(DependencyManager dependencyManager) {
317         this.dependencyManager = dependencyManager;
318         return this;
319     }
320 
321     @Override
322     public DefaultSessionBuilder setDependencySelector(DependencySelector dependencySelector) {
323         this.dependencySelector = dependencySelector;
324         return this;
325     }
326 
327     @Override
328     public DefaultSessionBuilder setVersionFilter(VersionFilter versionFilter) {
329         this.versionFilter = versionFilter;
330         return this;
331     }
332 
333     @Override
334     public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransformer dependencyGraphTransformer) {
335         this.dependencyGraphTransformer = dependencyGraphTransformer;
336         return this;
337     }
338 
339     @Override
340     public DefaultSessionBuilder setData(SessionData data) {
341         return setSessionDataSupplier(() -> data);
342     }
343 
344     @Override
345     public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) {
346         requireNonNull(dataSupplier, "null dataSupplier");
347         this.sessionDataSupplier = dataSupplier;
348         return this;
349     }
350 
351     @Override
352     public DefaultSessionBuilder setCache(RepositoryCache cache) {
353         return setRepositoryCacheSupplier(() -> cache);
354     }
355 
356     @Override
357     public DefaultSessionBuilder setScopeManager(ScopeManager scopeManager) {
358         this.scopeManager = scopeManager;
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         return this;
451     }
452 
453     @Override
454     public CloseableSession build() {
455         return new DefaultCloseableSession(
456                 sessionIdSupplier.get(),
457                 offline,
458                 ignoreArtifactDescriptorRepositories,
459                 resolutionErrorPolicy,
460                 artifactDescriptorPolicy,
461                 checksumPolicy,
462                 artifactUpdatePolicy,
463                 metadataUpdatePolicy,
464                 localRepositoryManager,
465                 localRepositories,
466                 workspaceReader,
467                 repositoryListener,
468                 transferListener,
469                 copySafe(systemProperties, String.class),
470                 copySafe(userProperties, String.class),
471                 copySafe(configProperties, Object.class),
472                 mirrorSelector,
473                 proxySelector,
474                 authenticationSelector,
475                 artifactTypeRegistry,
476                 dependencyTraverser,
477                 dependencyManager,
478                 dependencySelector,
479                 versionFilter,
480                 dependencyGraphTransformer,
481                 sessionDataSupplier.get(),
482                 repositoryCacheSupplier.get(),
483                 scopeManager,
484                 onSessionCloseHandlers,
485                 repositorySystem,
486                 repositorySystemLifecycle);
487     }
488 
489     @SuppressWarnings("checkstyle:magicnumber")
490     private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) {
491         Map<String, T> map;
492         if (table == null || table.isEmpty()) {
493             map = new HashMap<>();
494         } else {
495             map = new HashMap<>((int) (table.size() / 0.75f) + 1);
496             for (Map.Entry<?, ?> entry : table.entrySet()) {
497                 Object key = entry.getKey();
498                 if (key instanceof String) {
499                     Object value = entry.getValue();
500                     if (valueType.isInstance(value)) {
501                         map.put(key.toString(), valueType.cast(value));
502                     }
503                 }
504             }
505         }
506         return map;
507     }
508 }