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