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.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Map;
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.scope.ScopeManager;
54  import org.eclipse.aether.transfer.TransferListener;
55  
56  import static java.util.Objects.requireNonNull;
57  import static java.util.stream.Collectors.toList;
58  
59  /**
60   * A default implementation of session builder. Is not immutable nor thread-safe.
61   */
62  public final class DefaultSessionBuilder implements SessionBuilder {
63      private static final MirrorSelector NULL_MIRROR_SELECTOR = r -> null;
64  
65      private static final ProxySelector PASS_THROUGH_PROXY_SELECTOR = RemoteRepository::getProxy;
66  
67      private static final AuthenticationSelector PASS_THROUGH_AUTHENTICATION_SELECTOR =
68              RemoteRepository::getAuthentication;
69  
70      private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
71  
72      private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
73  
74      private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
75  
76      private final RepositorySystem repositorySystem;
77  
78      private final RepositorySystemLifecycle repositorySystemLifecycle;
79  
80      private final Supplier<String> sessionIdSupplier;
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 Collection<LocalRepository> localRepositories;
99  
100     private WorkspaceReader workspaceReader;
101 
102     private final ArrayList<RepositoryListener> repositoryListener = new ArrayList<>();
103 
104     private final ArrayList<TransferListener> transferListener = new ArrayList<>();
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 = PASS_THROUGH_PROXY_SELECTOR;
115 
116     private AuthenticationSelector authenticationSelector = PASS_THROUGH_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     private ScopeManager scopeManager;
135 
136     private final ArrayList<Runnable> onSessionCloseHandlers = new ArrayList<>();
137 
138     /**
139      * Constructor for "top level" builders.
140      */
141     public DefaultSessionBuilder(
142             RepositorySystem repositorySystem,
143             RepositorySystemLifecycle repositorySystemLifecycle,
144             Supplier<String> sessionIdSupplier) {
145         this.repositorySystem = requireNonNull(repositorySystem);
146         this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
147         this.sessionIdSupplier = requireNonNull(sessionIdSupplier);
148     }
149 
150     @Override
151     public DefaultSessionBuilder setOffline(boolean offline) {
152         this.offline = offline;
153         return this;
154     }
155 
156     @Override
157     public DefaultSessionBuilder setIgnoreArtifactDescriptorRepositories(boolean ignoreArtifactDescriptorRepositories) {
158         this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
159         return this;
160     }
161 
162     @Override
163     public DefaultSessionBuilder setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) {
164         this.resolutionErrorPolicy = resolutionErrorPolicy;
165         return this;
166     }
167 
168     @Override
169     public DefaultSessionBuilder setArtifactDescriptorPolicy(ArtifactDescriptorPolicy artifactDescriptorPolicy) {
170         this.artifactDescriptorPolicy = artifactDescriptorPolicy;
171         return this;
172     }
173 
174     @Override
175     public DefaultSessionBuilder setChecksumPolicy(String checksumPolicy) {
176         this.checksumPolicy = checksumPolicy;
177         return this;
178     }
179 
180     @Override
181     public DefaultSessionBuilder setUpdatePolicy(String updatePolicy) {
182         setArtifactUpdatePolicy(updatePolicy);
183         setMetadataUpdatePolicy(updatePolicy);
184         return this;
185     }
186 
187     @Override
188     public DefaultSessionBuilder setArtifactUpdatePolicy(String artifactUpdatePolicy) {
189         this.artifactUpdatePolicy = artifactUpdatePolicy;
190         return this;
191     }
192 
193     @Override
194     public DefaultSessionBuilder setMetadataUpdatePolicy(String metadataUpdatePolicy) {
195         this.metadataUpdatePolicy = metadataUpdatePolicy;
196         return this;
197     }
198 
199     @Override
200     public DefaultSessionBuilder setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) {
201         this.localRepositoryManager = localRepositoryManager;
202         return this;
203     }
204 
205     @Override
206     public DefaultSessionBuilder setWorkspaceReader(WorkspaceReader workspaceReader) {
207         this.workspaceReader = workspaceReader;
208         return this;
209     }
210 
211     @Override
212     public DefaultSessionBuilder setRepositoryListener(RepositoryListener repositoryListener) {
213         this.repositoryListener.clear();
214         if (repositoryListener != null) {
215             this.repositoryListener.add(repositoryListener);
216         }
217         return this;
218     }
219 
220     @Override
221     public DefaultSessionBuilder setTransferListener(TransferListener transferListener) {
222         this.transferListener.clear();
223         if (transferListener != null) {
224             this.transferListener.add(transferListener);
225         }
226         return this;
227     }
228 
229     @Override
230     public DefaultSessionBuilder setSystemProperties(Map<?, ?> systemProperties) {
231         this.systemProperties = copySafe(systemProperties, String.class);
232         return this;
233     }
234 
235     @Override
236     public DefaultSessionBuilder setSystemProperty(String key, String value) {
237         if (value != null) {
238             systemProperties.put(key, value);
239         } else {
240             systemProperties.remove(key);
241         }
242         return this;
243     }
244 
245     @Override
246     public DefaultSessionBuilder setUserProperties(Map<?, ?> userProperties) {
247         this.userProperties = copySafe(userProperties, String.class);
248         return this;
249     }
250 
251     @Override
252     public DefaultSessionBuilder setUserProperty(String key, String value) {
253         if (value != null) {
254             userProperties.put(key, value);
255         } else {
256             userProperties.remove(key);
257         }
258         return this;
259     }
260 
261     @Override
262     public DefaultSessionBuilder setConfigProperties(Map<?, ?> configProperties) {
263         this.configProperties = copySafe(configProperties, Object.class);
264         return this;
265     }
266 
267     @Override
268     public DefaultSessionBuilder setConfigProperty(String key, Object value) {
269         if (value != null) {
270             configProperties.put(key, value);
271         } else {
272             configProperties.remove(key);
273         }
274         return this;
275     }
276 
277     @Override
278     public DefaultSessionBuilder setMirrorSelector(MirrorSelector mirrorSelector) {
279         this.mirrorSelector = mirrorSelector;
280         if (this.mirrorSelector == null) {
281             this.mirrorSelector = NULL_MIRROR_SELECTOR;
282         }
283         return this;
284     }
285 
286     @Override
287     public DefaultSessionBuilder setProxySelector(ProxySelector proxySelector) {
288         this.proxySelector = proxySelector;
289         if (this.proxySelector == null) {
290             this.proxySelector = PASS_THROUGH_PROXY_SELECTOR;
291         }
292         return this;
293     }
294 
295     @Override
296     public DefaultSessionBuilder setAuthenticationSelector(AuthenticationSelector authenticationSelector) {
297         this.authenticationSelector = authenticationSelector;
298         if (this.authenticationSelector == null) {
299             this.authenticationSelector = PASS_THROUGH_AUTHENTICATION_SELECTOR;
300         }
301         return this;
302     }
303 
304     @Override
305     public DefaultSessionBuilder setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) {
306         this.artifactTypeRegistry = artifactTypeRegistry;
307         if (this.artifactTypeRegistry == null) {
308             this.artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY;
309         }
310         return this;
311     }
312 
313     @Override
314     public DefaultSessionBuilder setDependencyTraverser(DependencyTraverser dependencyTraverser) {
315         this.dependencyTraverser = dependencyTraverser;
316         return this;
317     }
318 
319     @Override
320     public DefaultSessionBuilder setDependencyManager(DependencyManager dependencyManager) {
321         this.dependencyManager = dependencyManager;
322         return this;
323     }
324 
325     @Override
326     public DefaultSessionBuilder setDependencySelector(DependencySelector dependencySelector) {
327         this.dependencySelector = dependencySelector;
328         return this;
329     }
330 
331     @Override
332     public DefaultSessionBuilder setVersionFilter(VersionFilter versionFilter) {
333         this.versionFilter = versionFilter;
334         return this;
335     }
336 
337     @Override
338     public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransformer dependencyGraphTransformer) {
339         this.dependencyGraphTransformer = dependencyGraphTransformer;
340         return this;
341     }
342 
343     @Override
344     public DefaultSessionBuilder setData(SessionData data) {
345         return setSessionDataSupplier(() -> data);
346     }
347 
348     @Override
349     public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) {
350         requireNonNull(dataSupplier, "null dataSupplier");
351         this.sessionDataSupplier = dataSupplier;
352         return this;
353     }
354 
355     @Override
356     public DefaultSessionBuilder setCache(RepositoryCache cache) {
357         return setRepositoryCacheSupplier(() -> cache);
358     }
359 
360     @Override
361     public DefaultSessionBuilder setScopeManager(ScopeManager scopeManager) {
362         this.scopeManager = scopeManager;
363         return this;
364     }
365 
366     @Override
367     public SessionBuilder addOnSessionEndedHandler(Runnable handler) {
368         requireNonNull(handler, "null handler");
369         onSessionCloseHandlers.add(handler);
370         return this;
371     }
372 
373     @Override
374     public DefaultSessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier) {
375         requireNonNull(cacheSupplier, "null cacheSupplier");
376         this.repositoryCacheSupplier = cacheSupplier;
377         return this;
378     }
379 
380     @Override
381     public SessionBuilder withLocalRepositoryBaseDirectories(Path... baseDirectories) {
382         return withLocalRepositoryBaseDirectories(Arrays.asList(baseDirectories));
383     }
384 
385     @Override
386     public SessionBuilder withLocalRepositoryBaseDirectories(Collection<Path> baseDirectories) {
387         requireNonNull(baseDirectories, "null baseDirectories");
388         return withLocalRepositories(
389                 baseDirectories.stream().map(LocalRepository::new).collect(toList()));
390     }
391 
392     @Override
393     public SessionBuilder withLocalRepositories(LocalRepository... localRepositories) {
394         return withLocalRepositories(Arrays.asList(localRepositories));
395     }
396 
397     @Override
398     public SessionBuilder withLocalRepositories(Collection<LocalRepository> localRepositories) {
399         requireNonNull(localRepositories, "null localRepositories");
400         this.localRepositories = localRepositories;
401         return this;
402     }
403 
404     @Override
405     public SessionBuilder withRepositoryListener(RepositoryListener... repositoryListeners) {
406         return withRepositoryListener(Arrays.asList(repositoryListeners));
407     }
408 
409     @Override
410     public SessionBuilder withRepositoryListener(Collection<RepositoryListener> repositoryListeners) {
411         this.repositoryListener.addAll(repositoryListeners);
412         return this;
413     }
414 
415     @Override
416     public SessionBuilder withTransferListener(TransferListener... transferListeners) {
417         return withTransferListener(Arrays.asList(transferListeners));
418     }
419 
420     @Override
421     public SessionBuilder withTransferListener(Collection<TransferListener> transferListeners) {
422         this.transferListener.addAll(transferListeners);
423         return this;
424     }
425 
426     @Override
427     public SessionBuilder withRepositorySystemSession(RepositorySystemSession session) {
428         requireNonNull(session, "repository system session cannot be null");
429         setOffline(session.isOffline());
430         setIgnoreArtifactDescriptorRepositories(session.isIgnoreArtifactDescriptorRepositories());
431         setResolutionErrorPolicy(session.getResolutionErrorPolicy());
432         setArtifactDescriptorPolicy(session.getArtifactDescriptorPolicy());
433         setChecksumPolicy(session.getChecksumPolicy());
434         setUpdatePolicy(session.getUpdatePolicy());
435         setMetadataUpdatePolicy(session.getMetadataUpdatePolicy());
436         setLocalRepositoryManager(session.getLocalRepositoryManager());
437         setWorkspaceReader(session.getWorkspaceReader());
438         setRepositoryListener(session.getRepositoryListener());
439         setTransferListener(session.getTransferListener());
440         setSystemProperties(session.getSystemProperties());
441         setUserProperties(session.getUserProperties());
442         setConfigProperties(session.getConfigProperties());
443         setMirrorSelector(session.getMirrorSelector());
444         setProxySelector(session.getProxySelector());
445         setAuthenticationSelector(session.getAuthenticationSelector());
446         setArtifactTypeRegistry(session.getArtifactTypeRegistry());
447         setDependencyTraverser(session.getDependencyTraverser());
448         setDependencyManager(session.getDependencyManager());
449         setDependencySelector(session.getDependencySelector());
450         setVersionFilter(session.getVersionFilter());
451         setDependencyGraphTransformer(session.getDependencyGraphTransformer());
452         setData(session.getData());
453         setCache(session.getCache());
454         return this;
455     }
456 
457     @Override
458     public CloseableSession build() {
459         return new DefaultCloseableSession(
460                 sessionIdSupplier.get(),
461                 offline,
462                 ignoreArtifactDescriptorRepositories,
463                 resolutionErrorPolicy,
464                 artifactDescriptorPolicy,
465                 checksumPolicy,
466                 artifactUpdatePolicy,
467                 metadataUpdatePolicy,
468                 localRepositoryManager,
469                 localRepositories,
470                 workspaceReader,
471                 repositoryListener,
472                 transferListener,
473                 copySafe(systemProperties, String.class),
474                 copySafe(userProperties, String.class),
475                 copySafe(configProperties, Object.class),
476                 mirrorSelector,
477                 proxySelector,
478                 authenticationSelector,
479                 artifactTypeRegistry,
480                 dependencyTraverser,
481                 dependencyManager,
482                 dependencySelector,
483                 versionFilter,
484                 dependencyGraphTransformer,
485                 sessionDataSupplier.get(),
486                 repositoryCacheSupplier.get(),
487                 scopeManager,
488                 onSessionCloseHandlers,
489                 repositorySystem,
490                 repositorySystemLifecycle);
491     }
492 
493     @SuppressWarnings("checkstyle:magicnumber")
494     private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) {
495         Map<String, T> map;
496         if (table == null || table.isEmpty()) {
497             map = new HashMap<>();
498         } else {
499             map = new HashMap<>((int) (table.size() / 0.75f) + 1);
500             for (Map.Entry<?, ?> entry : table.entrySet()) {
501                 Object key = entry.getKey();
502                 if (key instanceof String) {
503                     Object value = entry.getValue();
504                     if (valueType.isInstance(value)) {
505                         map.put(key.toString(), valueType.cast(value));
506                     }
507                 }
508             }
509         }
510         return map;
511     }
512 }