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.function.Supplier;
27  
28  import org.eclipse.aether.DefaultSessionData;
29  import org.eclipse.aether.RepositoryCache;
30  import org.eclipse.aether.RepositoryListener;
31  import org.eclipse.aether.RepositorySystem;
32  import org.eclipse.aether.RepositorySystemSession;
33  import org.eclipse.aether.RepositorySystemSession.CloseableSession;
34  import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
35  import org.eclipse.aether.SessionData;
36  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
37  import org.eclipse.aether.collection.DependencyGraphTransformer;
38  import org.eclipse.aether.collection.DependencyManager;
39  import org.eclipse.aether.collection.DependencySelector;
40  import org.eclipse.aether.collection.DependencyTraverser;
41  import org.eclipse.aether.collection.VersionFilter;
42  import org.eclipse.aether.impl.RepositorySystemLifecycle;
43  import org.eclipse.aether.repository.AuthenticationSelector;
44  import org.eclipse.aether.repository.LocalRepository;
45  import org.eclipse.aether.repository.LocalRepositoryManager;
46  import org.eclipse.aether.repository.MirrorSelector;
47  import org.eclipse.aether.repository.ProxySelector;
48  import org.eclipse.aether.repository.RemoteRepository;
49  import org.eclipse.aether.repository.WorkspaceReader;
50  import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
51  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
52  import org.eclipse.aether.transfer.TransferListener;
53  
54  import static java.util.Objects.requireNonNull;
55  import static java.util.stream.Collectors.toList;
56  
57  /**
58   * A default implementation of session builder. Is not immutable nor thread-safe.
59   */
60  public final class DefaultSessionBuilder implements SessionBuilder {
61      private static final MirrorSelector NULL_MIRROR_SELECTOR = r -> null;
62  
63      private static final ProxySelector NULL_PROXY_SELECTOR = RemoteRepository::getProxy;
64  
65      private static final AuthenticationSelector NULL_AUTHENTICATION_SELECTOR = RemoteRepository::getAuthentication;
66  
67      private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
68  
69      private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
70  
71      private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
72  
73      private final RepositorySystem repositorySystem;
74  
75      private final RepositorySystemLifecycle repositorySystemLifecycle;
76  
77      private final Supplier<String> sessionIdSupplier;
78  
79      private boolean offline;
80  
81      private boolean ignoreArtifactDescriptorRepositories;
82  
83      private ResolutionErrorPolicy resolutionErrorPolicy;
84  
85      private ArtifactDescriptorPolicy artifactDescriptorPolicy;
86  
87      private String checksumPolicy;
88  
89      private String artifactUpdatePolicy;
90  
91      private String metadataUpdatePolicy;
92  
93      private LocalRepositoryManager localRepositoryManager;
94  
95      private List<LocalRepository> localRepositories;
96  
97      private WorkspaceReader workspaceReader;
98  
99      private RepositoryListener repositoryListener;
100 
101     private TransferListener transferListener;
102 
103     private Map<String, String> systemProperties = new HashMap<>();
104 
105     private Map<String, String> userProperties = new HashMap<>();
106 
107     private Map<String, Object> configProperties = new HashMap<>();
108 
109     private MirrorSelector mirrorSelector = NULL_MIRROR_SELECTOR;
110 
111     private ProxySelector proxySelector = NULL_PROXY_SELECTOR;
112 
113     private AuthenticationSelector authenticationSelector = NULL_AUTHENTICATION_SELECTOR;
114 
115     private ArtifactTypeRegistry artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY;
116 
117     private DependencyTraverser dependencyTraverser;
118 
119     private DependencyManager dependencyManager;
120 
121     private DependencySelector dependencySelector;
122 
123     private VersionFilter versionFilter;
124 
125     private DependencyGraphTransformer dependencyGraphTransformer;
126 
127     private Supplier<SessionData> sessionDataSupplier = DEFAULT_SESSION_DATA_SUPPLIER;
128 
129     private Supplier<RepositoryCache> repositoryCacheSupplier = DEFAULT_REPOSITORY_CACHE_SUPPLIER;
130 
131     /**
132      * Constructor for "top level" builders.
133      */
134     public DefaultSessionBuilder(
135             RepositorySystem repositorySystem,
136             RepositorySystemLifecycle repositorySystemLifecycle,
137             Supplier<String> sessionIdSupplier) {
138         this.repositorySystem = requireNonNull(repositorySystem);
139         this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
140         this.sessionIdSupplier = requireNonNull(sessionIdSupplier);
141     }
142 
143     @Override
144     public DefaultSessionBuilder setOffline(boolean offline) {
145         this.offline = offline;
146         return this;
147     }
148 
149     @Override
150     public DefaultSessionBuilder setIgnoreArtifactDescriptorRepositories(boolean ignoreArtifactDescriptorRepositories) {
151         this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
152         return this;
153     }
154 
155     @Override
156     public DefaultSessionBuilder setResolutionErrorPolicy(ResolutionErrorPolicy resolutionErrorPolicy) {
157         this.resolutionErrorPolicy = resolutionErrorPolicy;
158         return this;
159     }
160 
161     @Override
162     public DefaultSessionBuilder setArtifactDescriptorPolicy(ArtifactDescriptorPolicy artifactDescriptorPolicy) {
163         this.artifactDescriptorPolicy = artifactDescriptorPolicy;
164         return this;
165     }
166 
167     @Override
168     public DefaultSessionBuilder setChecksumPolicy(String checksumPolicy) {
169         this.checksumPolicy = checksumPolicy;
170         return this;
171     }
172 
173     @Override
174     public DefaultSessionBuilder setUpdatePolicy(String updatePolicy) {
175         setArtifactUpdatePolicy(updatePolicy);
176         setMetadataUpdatePolicy(updatePolicy);
177         return this;
178     }
179 
180     @Override
181     public DefaultSessionBuilder setArtifactUpdatePolicy(String artifactUpdatePolicy) {
182         this.artifactUpdatePolicy = artifactUpdatePolicy;
183         return this;
184     }
185 
186     @Override
187     public DefaultSessionBuilder setMetadataUpdatePolicy(String metadataUpdatePolicy) {
188         this.metadataUpdatePolicy = metadataUpdatePolicy;
189         return this;
190     }
191 
192     @Override
193     public DefaultSessionBuilder setLocalRepositoryManager(LocalRepositoryManager localRepositoryManager) {
194         this.localRepositoryManager = localRepositoryManager;
195         return this;
196     }
197 
198     @Override
199     public DefaultSessionBuilder setWorkspaceReader(WorkspaceReader workspaceReader) {
200         this.workspaceReader = workspaceReader;
201         return this;
202     }
203 
204     @Override
205     public DefaultSessionBuilder setRepositoryListener(RepositoryListener repositoryListener) {
206         this.repositoryListener = repositoryListener;
207         return this;
208     }
209 
210     @Override
211     public DefaultSessionBuilder setTransferListener(TransferListener transferListener) {
212         this.transferListener = transferListener;
213         return this;
214     }
215 
216     @Override
217     public DefaultSessionBuilder setSystemProperties(Map<?, ?> systemProperties) {
218         this.systemProperties = copySafe(systemProperties, String.class);
219         return this;
220     }
221 
222     @Override
223     public DefaultSessionBuilder setSystemProperty(String key, String value) {
224         if (value != null) {
225             systemProperties.put(key, value);
226         } else {
227             systemProperties.remove(key);
228         }
229         return this;
230     }
231 
232     @Override
233     public DefaultSessionBuilder setUserProperties(Map<?, ?> userProperties) {
234         this.userProperties = copySafe(userProperties, String.class);
235         return this;
236     }
237 
238     @Override
239     public DefaultSessionBuilder setUserProperty(String key, String value) {
240         if (value != null) {
241             userProperties.put(key, value);
242         } else {
243             userProperties.remove(key);
244         }
245         return this;
246     }
247 
248     @Override
249     public DefaultSessionBuilder setConfigProperties(Map<?, ?> configProperties) {
250         this.configProperties = copySafe(configProperties, Object.class);
251         return this;
252     }
253 
254     @Override
255     public DefaultSessionBuilder setConfigProperty(String key, Object value) {
256         if (value != null) {
257             configProperties.put(key, value);
258         } else {
259             configProperties.remove(key);
260         }
261         return this;
262     }
263 
264     @Override
265     public DefaultSessionBuilder setMirrorSelector(MirrorSelector mirrorSelector) {
266         this.mirrorSelector = mirrorSelector;
267         if (this.mirrorSelector == null) {
268             this.mirrorSelector = NULL_MIRROR_SELECTOR;
269         }
270         return this;
271     }
272 
273     @Override
274     public DefaultSessionBuilder setProxySelector(ProxySelector proxySelector) {
275         this.proxySelector = proxySelector;
276         if (this.proxySelector == null) {
277             this.proxySelector = NULL_PROXY_SELECTOR;
278         }
279         return this;
280     }
281 
282     @Override
283     public DefaultSessionBuilder setAuthenticationSelector(AuthenticationSelector authenticationSelector) {
284         this.authenticationSelector = authenticationSelector;
285         if (this.authenticationSelector == null) {
286             this.authenticationSelector = NULL_AUTHENTICATION_SELECTOR;
287         }
288         return this;
289     }
290 
291     @Override
292     public DefaultSessionBuilder setArtifactTypeRegistry(ArtifactTypeRegistry artifactTypeRegistry) {
293         this.artifactTypeRegistry = artifactTypeRegistry;
294         if (this.artifactTypeRegistry == null) {
295             this.artifactTypeRegistry = NULL_ARTIFACT_TYPE_REGISTRY;
296         }
297         return this;
298     }
299 
300     @Override
301     public DefaultSessionBuilder setDependencyTraverser(DependencyTraverser dependencyTraverser) {
302         this.dependencyTraverser = dependencyTraverser;
303         return this;
304     }
305 
306     @Override
307     public DefaultSessionBuilder setDependencyManager(DependencyManager dependencyManager) {
308         this.dependencyManager = dependencyManager;
309         return this;
310     }
311 
312     @Override
313     public DefaultSessionBuilder setDependencySelector(DependencySelector dependencySelector) {
314         this.dependencySelector = dependencySelector;
315         return this;
316     }
317 
318     @Override
319     public DefaultSessionBuilder setVersionFilter(VersionFilter versionFilter) {
320         this.versionFilter = versionFilter;
321         return this;
322     }
323 
324     @Override
325     public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransformer dependencyGraphTransformer) {
326         this.dependencyGraphTransformer = dependencyGraphTransformer;
327         return this;
328     }
329 
330     @Override
331     public DefaultSessionBuilder setData(SessionData data) {
332         return setSessionDataSupplier(() -> data);
333     }
334 
335     @Override
336     public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) {
337         requireNonNull(dataSupplier, "null dataSupplier");
338         this.sessionDataSupplier = dataSupplier;
339         return this;
340     }
341 
342     @Override
343     public DefaultSessionBuilder setCache(RepositoryCache cache) {
344         return setRepositoryCacheSupplier(() -> cache);
345     }
346 
347     @Override
348     public DefaultSessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier) {
349         requireNonNull(cacheSupplier, "null cacheSupplier");
350         this.repositoryCacheSupplier = cacheSupplier;
351         return this;
352     }
353 
354     @Override
355     public SessionBuilder withLocalRepositoryBaseDirectories(File... baseDirectories) {
356         return withLocalRepositoryBaseDirectories(Arrays.asList(baseDirectories));
357     }
358 
359     @Override
360     public SessionBuilder withLocalRepositoryBaseDirectories(List<File> baseDirectories) {
361         requireNonNull(baseDirectories, "null baseDirectories");
362         return withLocalRepositories(
363                 baseDirectories.stream().map(LocalRepository::new).collect(toList()));
364     }
365 
366     @Override
367     public SessionBuilder withLocalRepositories(LocalRepository... localRepositories) {
368         return withLocalRepositories(Arrays.asList(localRepositories));
369     }
370 
371     @Override
372     public SessionBuilder withLocalRepositories(List<LocalRepository> localRepositories) {
373         requireNonNull(localRepositories, "null localRepositories");
374         this.localRepositories = localRepositories;
375         return this;
376     }
377 
378     @Override
379     public SessionBuilder withRepositorySystemSession(RepositorySystemSession session) {
380         requireNonNull(session, "repository system session cannot be null");
381         setOffline(session.isOffline());
382         setIgnoreArtifactDescriptorRepositories(session.isIgnoreArtifactDescriptorRepositories());
383         setResolutionErrorPolicy(session.getResolutionErrorPolicy());
384         setArtifactDescriptorPolicy(session.getArtifactDescriptorPolicy());
385         setChecksumPolicy(session.getChecksumPolicy());
386         setUpdatePolicy(session.getUpdatePolicy());
387         setMetadataUpdatePolicy(session.getMetadataUpdatePolicy());
388         setLocalRepositoryManager(session.getLocalRepositoryManager());
389         setWorkspaceReader(session.getWorkspaceReader());
390         setRepositoryListener(session.getRepositoryListener());
391         setTransferListener(session.getTransferListener());
392         setSystemProperties(session.getSystemProperties());
393         setUserProperties(session.getUserProperties());
394         setConfigProperties(session.getConfigProperties());
395         setMirrorSelector(session.getMirrorSelector());
396         setProxySelector(session.getProxySelector());
397         setAuthenticationSelector(session.getAuthenticationSelector());
398         setArtifactTypeRegistry(session.getArtifactTypeRegistry());
399         setDependencyTraverser(session.getDependencyTraverser());
400         setDependencyManager(session.getDependencyManager());
401         setDependencySelector(session.getDependencySelector());
402         setVersionFilter(session.getVersionFilter());
403         setDependencyGraphTransformer(session.getDependencyGraphTransformer());
404         setData(session.getData());
405         setCache(session.getCache());
406         return this;
407     }
408 
409     @Override
410     public CloseableSession build() {
411         return new DefaultCloseableSession(
412                 sessionIdSupplier.get(),
413                 offline,
414                 ignoreArtifactDescriptorRepositories,
415                 resolutionErrorPolicy,
416                 artifactDescriptorPolicy,
417                 checksumPolicy,
418                 artifactUpdatePolicy,
419                 metadataUpdatePolicy,
420                 localRepositoryManager,
421                 localRepositories,
422                 workspaceReader,
423                 repositoryListener,
424                 transferListener,
425                 copySafe(systemProperties, String.class),
426                 copySafe(userProperties, String.class),
427                 copySafe(configProperties, Object.class),
428                 mirrorSelector,
429                 proxySelector,
430                 authenticationSelector,
431                 artifactTypeRegistry,
432                 dependencyTraverser,
433                 dependencyManager,
434                 dependencySelector,
435                 versionFilter,
436                 dependencyGraphTransformer,
437                 sessionDataSupplier.get(),
438                 repositoryCacheSupplier.get(),
439                 repositorySystem,
440                 repositorySystemLifecycle);
441     }
442 
443     @SuppressWarnings("checkstyle:magicnumber")
444     private static <T> Map<String, T> copySafe(Map<?, ?> table, Class<T> valueType) {
445         Map<String, T> map;
446         if (table == null || table.isEmpty()) {
447             map = new HashMap<>();
448         } else {
449             map = new HashMap<>((int) (table.size() / 0.75f) + 1);
450             for (Map.Entry<?, ?> entry : table.entrySet()) {
451                 Object key = entry.getKey();
452                 if (key instanceof String) {
453                     Object value = entry.getValue();
454                     if (valueType.isInstance(value)) {
455                         map.put(key.toString(), valueType.cast(value));
456                     }
457                 }
458             }
459         }
460         return map;
461     }
462 }