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