001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.internal.impl.session;
020
021import java.util.*;
022import java.util.concurrent.atomic.AtomicBoolean;
023
024import org.eclipse.aether.*;
025import org.eclipse.aether.RepositorySystemSession.CloseableSession;
026import org.eclipse.aether.artifact.ArtifactTypeRegistry;
027import org.eclipse.aether.collection.DependencyGraphTransformer;
028import org.eclipse.aether.collection.DependencyManager;
029import org.eclipse.aether.collection.DependencySelector;
030import org.eclipse.aether.collection.DependencyTraverser;
031import org.eclipse.aether.collection.VersionFilter;
032import org.eclipse.aether.impl.RepositorySystemLifecycle;
033import org.eclipse.aether.repository.AuthenticationSelector;
034import org.eclipse.aether.repository.LocalRepository;
035import org.eclipse.aether.repository.LocalRepositoryManager;
036import org.eclipse.aether.repository.MirrorSelector;
037import org.eclipse.aether.repository.ProxySelector;
038import org.eclipse.aether.repository.WorkspaceReader;
039import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
040import org.eclipse.aether.resolution.ResolutionErrorPolicy;
041import org.eclipse.aether.transfer.TransferListener;
042import org.eclipse.aether.util.listener.ChainedRepositoryListener;
043import org.eclipse.aether.util.listener.ChainedTransferListener;
044
045import static java.util.Objects.requireNonNull;
046
047/**
048 * A default implementation of repository system session that is immutable and thread-safe.
049 */
050public final class DefaultCloseableSession implements CloseableSession {
051    private final String sessionId;
052
053    private final AtomicBoolean closed;
054
055    private final boolean offline;
056
057    private final boolean ignoreArtifactDescriptorRepositories;
058
059    private final ResolutionErrorPolicy resolutionErrorPolicy;
060
061    private final ArtifactDescriptorPolicy artifactDescriptorPolicy;
062
063    private final String checksumPolicy;
064
065    private final String artifactUpdatePolicy;
066
067    private final String metadataUpdatePolicy;
068
069    private final LocalRepositoryManager localRepositoryManager;
070
071    private final WorkspaceReader workspaceReader;
072
073    private final RepositoryListener repositoryListener;
074
075    private final TransferListener transferListener;
076
077    private final Map<String, String> systemProperties;
078
079    private final Map<String, String> userProperties;
080
081    private final Map<String, Object> configProperties;
082
083    private final MirrorSelector mirrorSelector;
084
085    private final ProxySelector proxySelector;
086
087    private final AuthenticationSelector authenticationSelector;
088
089    private final ArtifactTypeRegistry artifactTypeRegistry;
090
091    private final DependencyTraverser dependencyTraverser;
092
093    private final DependencyManager dependencyManager;
094
095    private final DependencySelector dependencySelector;
096
097    private final VersionFilter versionFilter;
098
099    private final DependencyGraphTransformer dependencyGraphTransformer;
100
101    private final SessionData data;
102
103    private final RepositoryCache cache;
104
105    private final SystemScopeHandler systemScopeHandler;
106
107    private final RepositorySystem repositorySystem;
108
109    private final RepositorySystemLifecycle repositorySystemLifecycle;
110
111    @SuppressWarnings("checkstyle:parameternumber")
112    public DefaultCloseableSession(
113            String sessionId,
114            boolean offline,
115            boolean ignoreArtifactDescriptorRepositories,
116            ResolutionErrorPolicy resolutionErrorPolicy,
117            ArtifactDescriptorPolicy artifactDescriptorPolicy,
118            String checksumPolicy,
119            String artifactUpdatePolicy,
120            String metadataUpdatePolicy,
121            LocalRepositoryManager localRepositoryManager,
122            Collection<LocalRepository> localRepositories,
123            WorkspaceReader workspaceReader,
124            Collection<RepositoryListener> repositoryListener,
125            Collection<TransferListener> transferListener,
126            Map<String, String> systemProperties,
127            Map<String, String> userProperties,
128            Map<String, Object> configProperties,
129            MirrorSelector mirrorSelector,
130            ProxySelector proxySelector,
131            AuthenticationSelector authenticationSelector,
132            ArtifactTypeRegistry artifactTypeRegistry,
133            DependencyTraverser dependencyTraverser,
134            DependencyManager dependencyManager,
135            DependencySelector dependencySelector,
136            VersionFilter versionFilter,
137            DependencyGraphTransformer dependencyGraphTransformer,
138            SessionData data,
139            RepositoryCache cache,
140            SystemScopeHandler systemScopeHandler,
141            List<Runnable> onSessionEndedHandlers,
142            RepositorySystem repositorySystem,
143            RepositorySystemLifecycle repositorySystemLifecycle) {
144        this.sessionId = requireNonNull(sessionId);
145        this.closed = new AtomicBoolean(false);
146        this.offline = offline;
147        this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
148        this.resolutionErrorPolicy = resolutionErrorPolicy;
149        this.artifactDescriptorPolicy = artifactDescriptorPolicy;
150        this.checksumPolicy = checksumPolicy;
151        this.artifactUpdatePolicy = artifactUpdatePolicy;
152        this.metadataUpdatePolicy = metadataUpdatePolicy;
153        this.workspaceReader = workspaceReader;
154        this.repositoryListener = new ChainedRepositoryListener(repositoryListener);
155        this.transferListener = new ChainedTransferListener(transferListener);
156        this.systemProperties = Collections.unmodifiableMap(systemProperties);
157        this.userProperties = Collections.unmodifiableMap(userProperties);
158        this.configProperties = Collections.unmodifiableMap(configProperties);
159        this.mirrorSelector = requireNonNull(mirrorSelector);
160        this.proxySelector = requireNonNull(proxySelector);
161        this.authenticationSelector = requireNonNull(authenticationSelector);
162        this.artifactTypeRegistry = requireNonNull(artifactTypeRegistry);
163        this.dependencyTraverser = dependencyTraverser;
164        this.dependencyManager = dependencyManager;
165        this.dependencySelector = dependencySelector;
166        this.versionFilter = versionFilter;
167        this.dependencyGraphTransformer = dependencyGraphTransformer;
168        this.data = requireNonNull(data);
169        this.cache = cache;
170        this.systemScopeHandler = requireNonNull(systemScopeHandler);
171
172        this.repositorySystem = requireNonNull(repositorySystem);
173        this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
174
175        this.localRepositoryManager = getOrCreateLocalRepositoryManager(localRepositoryManager, localRepositories);
176
177        repositorySystemLifecycle.sessionStarted(this);
178        onSessionEndedHandlers.forEach(this::addOnSessionEndedHandler);
179    }
180
181    private LocalRepositoryManager getOrCreateLocalRepositoryManager(
182            LocalRepositoryManager localRepositoryManager, Collection<LocalRepository> localRepositories) {
183        if (localRepositoryManager != null) {
184            return localRepositoryManager;
185        } else if (localRepositories != null) {
186            return repositorySystem.newLocalRepositoryManager(this, new ArrayList<>(localRepositories));
187        } else {
188            throw new IllegalStateException("No local repository manager or local repositories set on session");
189        }
190    }
191
192    @Override
193    public String sessionId() {
194        return sessionId;
195    }
196
197    @Override
198    public boolean isOffline() {
199        return offline;
200    }
201
202    @Override
203    public boolean isIgnoreArtifactDescriptorRepositories() {
204        return ignoreArtifactDescriptorRepositories;
205    }
206
207    @Override
208    public ResolutionErrorPolicy getResolutionErrorPolicy() {
209        return resolutionErrorPolicy;
210    }
211
212    @Override
213    public ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
214        return artifactDescriptorPolicy;
215    }
216
217    @Override
218    public String getChecksumPolicy() {
219        return checksumPolicy;
220    }
221
222    @Override
223    public String getUpdatePolicy() {
224        return getArtifactUpdatePolicy();
225    }
226
227    @Override
228    public String getArtifactUpdatePolicy() {
229        return artifactUpdatePolicy;
230    }
231
232    @Override
233    public String getMetadataUpdatePolicy() {
234        return metadataUpdatePolicy;
235    }
236
237    @Override
238    public LocalRepository getLocalRepository() {
239        return getLocalRepositoryManager().getRepository();
240    }
241
242    @Override
243    public LocalRepositoryManager getLocalRepositoryManager() {
244        return localRepositoryManager;
245    }
246
247    @Override
248    public WorkspaceReader getWorkspaceReader() {
249        return workspaceReader;
250    }
251
252    @Override
253    public RepositoryListener getRepositoryListener() {
254        return repositoryListener;
255    }
256
257    @Override
258    public TransferListener getTransferListener() {
259        return transferListener;
260    }
261
262    @Override
263    public Map<String, String> getSystemProperties() {
264        return systemProperties;
265    }
266
267    @Override
268    public Map<String, String> getUserProperties() {
269        return userProperties;
270    }
271
272    @Override
273    public Map<String, Object> getConfigProperties() {
274        return configProperties;
275    }
276
277    @Override
278    public MirrorSelector getMirrorSelector() {
279        return mirrorSelector;
280    }
281
282    @Override
283    public ProxySelector getProxySelector() {
284        return proxySelector;
285    }
286
287    @Override
288    public AuthenticationSelector getAuthenticationSelector() {
289        return authenticationSelector;
290    }
291
292    @Override
293    public ArtifactTypeRegistry getArtifactTypeRegistry() {
294        return artifactTypeRegistry;
295    }
296
297    @Override
298    public DependencyTraverser getDependencyTraverser() {
299        return dependencyTraverser;
300    }
301
302    @Override
303    public DependencyManager getDependencyManager() {
304        return dependencyManager;
305    }
306
307    @Override
308    public DependencySelector getDependencySelector() {
309        return dependencySelector;
310    }
311
312    @Override
313    public VersionFilter getVersionFilter() {
314        return versionFilter;
315    }
316
317    @Override
318    public DependencyGraphTransformer getDependencyGraphTransformer() {
319        return dependencyGraphTransformer;
320    }
321
322    @Override
323    public SessionData getData() {
324        return data;
325    }
326
327    @Override
328    public RepositoryCache getCache() {
329        return cache;
330    }
331
332    @Override
333    public SystemScopeHandler getSystemScopeHandler() {
334        return systemScopeHandler;
335    }
336
337    @Override
338    public boolean addOnSessionEndedHandler(Runnable handler) {
339        throwIfClosed();
340        repositorySystemLifecycle.addOnSessionEndedHandle(this, handler);
341        return true;
342    }
343
344    @Override
345    public void close() {
346        if (closed.compareAndSet(false, true)) {
347            repositorySystemLifecycle.sessionEnded(this);
348        }
349    }
350
351    private void throwIfClosed() {
352        if (closed.get()) {
353            throw new IllegalStateException("Session " + sessionId + " already closed");
354        }
355    }
356}