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