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