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.supplier;
020
021import java.util.Arrays;
022import java.util.Locale;
023import java.util.function.Supplier;
024
025import org.apache.maven.utils.Os;
026import org.eclipse.aether.RepositorySystem;
027import org.eclipse.aether.RepositorySystemSession.CloseableSession;
028import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
029import org.eclipse.aether.artifact.ArtifactTypeRegistry;
030import org.eclipse.aether.artifact.DefaultArtifactType;
031import org.eclipse.aether.collection.DependencyGraphTransformer;
032import org.eclipse.aether.collection.DependencyManager;
033import org.eclipse.aether.collection.DependencySelector;
034import org.eclipse.aether.collection.DependencyTraverser;
035import org.eclipse.aether.impl.scope.InternalScopeManager;
036import org.eclipse.aether.internal.impl.scope.ManagedDependencyContextRefiner;
037import org.eclipse.aether.internal.impl.scope.ManagedScopeDeriver;
038import org.eclipse.aether.internal.impl.scope.ManagedScopeSelector;
039import org.eclipse.aether.internal.impl.scope.OptionalDependencySelector;
040import org.eclipse.aether.internal.impl.scope.ScopeDependencySelector;
041import org.eclipse.aether.internal.impl.scope.ScopeManagerImpl;
042import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
043import org.eclipse.aether.util.artifact.DefaultArtifactTypeRegistry;
044import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
045import org.eclipse.aether.util.graph.selector.AndDependencySelector;
046import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
047import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
048import org.eclipse.aether.util.graph.transformer.ConfigurableVersionSelector;
049import org.eclipse.aether.util.graph.transformer.ConflictResolver;
050import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
051import org.eclipse.aether.util.graph.traverser.FatArtifactTraverser;
052import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
053
054import static java.util.Objects.requireNonNull;
055
056/**
057 * A simple {@link Supplier} of {@link SessionBuilder} instances, that on each call supplies newly
058 * constructed instance. To create session out of builder, use {@link SessionBuilder#build()}. For proper closing
059 * of sessions, use {@link CloseableSession#close()} method on built instance(s).
060 * <p>
061 * Extend this class and override methods to customize, if needed.
062 * <p>
063 * Resolver created as this is NOT using {@link org.eclipse.aether.scope.ScopeManager}!
064 *
065 * @since 2.0.0
066 */
067public class SessionBuilderSupplier implements Supplier<SessionBuilder> {
068    protected final RepositorySystem repositorySystem;
069    protected final InternalScopeManager scopeManager;
070
071    public SessionBuilderSupplier(RepositorySystem repositorySystem) {
072        this.repositorySystem = requireNonNull(repositorySystem);
073        this.scopeManager = new ScopeManagerImpl(Maven3ScopeManagerConfiguration.INSTANCE);
074    }
075
076    protected void configureSessionBuilder(SessionBuilder session) {
077        session.setSystemProperties(System.getProperties());
078        boolean caseSensitive = !Os.IS_WINDOWS;
079        System.getenv().forEach((key, value) -> {
080            key = "env." + (caseSensitive ? key : key.toUpperCase(Locale.ENGLISH));
081            session.setSystemProperty(key, value);
082        });
083        session.setScopeManager(scopeManager);
084        session.setDependencyTraverser(getDependencyTraverser());
085        session.setDependencyManager(getDependencyManager());
086        session.setDependencySelector(getDependencySelector());
087        session.setDependencyGraphTransformer(getDependencyGraphTransformer());
088        session.setArtifactTypeRegistry(getArtifactTypeRegistry());
089        session.setArtifactDescriptorPolicy(getArtifactDescriptorPolicy());
090    }
091
092    protected InternalScopeManager getScopeManager() {
093        return this.scopeManager;
094    }
095
096    protected DependencyTraverser getDependencyTraverser() {
097        return new FatArtifactTraverser();
098    }
099
100    protected DependencyManager getDependencyManager() {
101        return new ClassicDependencyManager(getScopeManager());
102    }
103
104    protected DependencySelector getDependencySelector() {
105        return new AndDependencySelector(
106                ScopeDependencySelector.legacy(
107                        null,
108                        Arrays.asList(
109                                Maven3ScopeManagerConfiguration.DS_TEST, Maven3ScopeManagerConfiguration.DS_PROVIDED)),
110                OptionalDependencySelector.fromDirect(),
111                new ExclusionDependencySelector());
112    }
113
114    protected DependencyGraphTransformer getDependencyGraphTransformer() {
115        return new ChainedDependencyGraphTransformer(
116                new ConflictResolver(
117                        new ConfigurableVersionSelector(),
118                        new ManagedScopeSelector(getScopeManager()),
119                        new SimpleOptionalitySelector(),
120                        new ManagedScopeDeriver(getScopeManager())),
121                new ManagedDependencyContextRefiner(getScopeManager()));
122    }
123
124    protected ArtifactTypeRegistry getArtifactTypeRegistry() {
125        DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
126        stereotypes.add(new DefaultArtifactType("pom"));
127        stereotypes.add(new DefaultArtifactType("maven-plugin", "jar", "", "java"));
128        stereotypes.add(new DefaultArtifactType("jar", "jar", "", "java"));
129        stereotypes.add(new DefaultArtifactType("ejb", "jar", "", "java"));
130        stereotypes.add(new DefaultArtifactType("ejb-client", "jar", "client", "java"));
131        stereotypes.add(new DefaultArtifactType("test-jar", "jar", "tests", "java"));
132        stereotypes.add(new DefaultArtifactType("javadoc", "jar", "javadoc", "java"));
133        stereotypes.add(new DefaultArtifactType("java-source", "jar", "sources", "java", false, false));
134        stereotypes.add(new DefaultArtifactType("war", "war", "", "java", false, true));
135        stereotypes.add(new DefaultArtifactType("ear", "ear", "", "java", false, true));
136        stereotypes.add(new DefaultArtifactType("rar", "rar", "", "java", false, true));
137        stereotypes.add(new DefaultArtifactType("par", "par", "", "java", false, true));
138        return stereotypes;
139    }
140
141    protected ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
142        return new SimpleArtifactDescriptorPolicy(true, true);
143    }
144
145    /**
146     * Creates a new Maven-like repository system session by initializing the session with values typical for
147     * Maven-based resolution. In more detail, this method configures settings relevant for the processing of dependency
148     * graphs, most other settings remain at their generic default value. Use the various setters to further configure
149     * the session with authentication, mirror, proxy and other information required for your environment. At least,
150     * local repository manager needs to be configured to make session be able to create session instance.
151     *
152     * @return SessionBuilder configured with minimally required things for "Maven-based resolution". At least LRM must
153     * be set on builder to make it able to create session instances.
154     */
155    @Override
156    public SessionBuilder get() {
157        SessionBuilder builder = repositorySystem.createSessionBuilder();
158        configureSessionBuilder(builder);
159        return builder;
160    }
161}