diff --git a/pom.xml b/pom.xml
index 8c48569..a590078 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,12 +4,12 @@
io.airlift
airbase
- 80
+ 134
io.airlift.resolver
resolver-root
- 1.7-SNAPSHOT
+ 1.7.4-wxd
pom
Resolve the dependencies of Maven coordinates or POM file
@@ -23,8 +23,8 @@
- 1.13.1
- 3.0.4
+ 1.9.6
+ 3.8.7
true
@@ -43,63 +43,52 @@
- org.sonatype.aether
- aether-spi
+ org.apache.maven.resolver
+ maven-resolver-spi
${dep.aether.version}
- org.sonatype.aether
- aether-api
+ org.apache.maven.resolver
+ maven-resolver-api
${dep.aether.version}
- org.sonatype.aether
- aether-impl
+ org.apache.maven.resolver
+ maven-resolver-impl
${dep.aether.version}
- org.sonatype.aether
- aether-util
+ org.apache.maven.resolver
+ maven-resolver-util
${dep.aether.version}
- org.sonatype.aether
- aether-connector-file
+ org.apache.maven.resolver
+ maven-resolver-connector-basic
${dep.aether.version}
- org.sonatype.aether
- aether-connector-asynchttpclient
+ org.apache.maven.resolver
+ maven-resolver-transport-file
${dep.aether.version}
-
-
- org.jboss.netty
- netty
-
-
- io.netty
- netty
- 3.6.2.Final
+ org.apache.maven.resolver
+ maven-resolver-transport-http
+ ${dep.aether.version}
+
- org.apache.maven
- maven-core
- ${dep.maven.version}
-
-
- org.sonatype.sisu
- sisu-inject-plexus
-
-
+ commons-codec
+ commons-codec
+ 1.15
@@ -116,54 +105,76 @@
org.apache.maven
- maven-aether-provider
+ maven-resolver-provider
${dep.maven.version}
org.apache.maven
- maven-embedder
+ maven-core
${dep.maven.version}
-
-
- org.sonatype.sisu
- sisu-inject-plexus
-
-
- commons-cli
- commons-cli
-
-
+
+
+
+
+ org.apache.maven
+ maven-compat
+ ${dep.maven.version}
+ runtime
org.codehaus.plexus
- plexus-container-default
- 1.5.5
+ plexus-utils
+ 3.5.1
+
+
+
+
+ javax.inject
+ javax.inject
+ 1
+
+
+ org.eclipse.sisu
+ org.eclipse.sisu.inject
+ 0.3.5
+ runtime
+
+
+
+ org.codehaus.plexus
+ plexus-classworlds
+ 2.6.0
+
+
+
+ org.eclipse.sisu
+ org.eclipse.sisu.plexus
+ 0.3.5
+
+
+ com.google.inject
+ guice
+ 4.2.3
+ runtime
+
+
+ com.google.guava
+ guava
+ 31.1-jre
- commons-logging
- commons-logging-api
-
-
- com.google.collections
- google-collections
-
-
- junit
- junit
-
-
- log4j
- log4j
+ com.google.guava
+ listenablefuture
-
- org.codehaus.plexus
- plexus-classworlds
- 2.4
+ com.google.guava
+ failureaccess
+ 1.0.1
+ runtime
diff --git a/resolver-integration/pom.xml b/resolver-integration/pom.xml
index a4b4782..3d35ccf 100644
--- a/resolver-integration/pom.xml
+++ b/resolver-integration/pom.xml
@@ -4,7 +4,7 @@
io.airlift.resolver
resolver-root
- 1.7-SNAPSHOT
+ 1.7.4-wxd
io.airlift.resolver
@@ -30,8 +30,8 @@
- org.sonatype.aether
- aether-api
+ org.apache.maven.resolver
+ maven-resolver-api
test
diff --git a/resolver-integration/src/test/java/io/airlift/resolver/TestArtifactResolve.java b/resolver-integration/src/test/java/io/airlift/resolver/TestArtifactResolve.java
index 42cea0a..84721d5 100644
--- a/resolver-integration/src/test/java/io/airlift/resolver/TestArtifactResolve.java
+++ b/resolver-integration/src/test/java/io/airlift/resolver/TestArtifactResolve.java
@@ -13,7 +13,8 @@
*/
package io.airlift.resolver;
-import org.sonatype.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/resolver/pom.xml b/resolver/pom.xml
index 248c347..9cc5773 100644
--- a/resolver/pom.xml
+++ b/resolver/pom.xml
@@ -4,7 +4,7 @@
io.airlift.resolver
resolver-root
- 1.7-SNAPSHOT
+ 1.7.4-wxd
io.airlift.resolver
@@ -16,44 +16,43 @@
- org.sonatype.aether
- aether-spi
+ javax.inject
+ javax.inject
- org.sonatype.aether
- aether-api
+ org.apache.maven.resolver
+ maven-resolver-spi
- org.sonatype.aether
- aether-impl
+ org.apache.maven.resolver
+ maven-resolver-api
- org.sonatype.aether
- aether-util
+ org.apache.maven.resolver
+ maven-resolver-impl
- org.sonatype.aether
- aether-connector-file
+ org.apache.maven.resolver
+ maven-resolver-util
- org.sonatype.aether
- aether-connector-asynchttpclient
+ org.apache.maven.resolver
+ maven-resolver-connector-basic
- io.netty
- netty
- runtime
+ org.apache.maven.resolver
+ maven-resolver-transport-file
- org.apache.maven
- maven-core
+ org.apache.maven.resolver
+ maven-resolver-transport-http
@@ -68,18 +67,17 @@
org.apache.maven
- maven-aether-provider
+ maven-resolver-provider
org.apache.maven
- maven-embedder
- runtime
+ maven-core
- org.codehaus.plexus
- plexus-container-default
+ org.apache.maven
+ maven-compat
@@ -88,9 +86,8 @@
- com.google.inject
- guice
- runtime
+ org.eclipse.sisu
+ org.eclipse.sisu.plexus
diff --git a/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java b/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java
index b21e431..3161374 100644
--- a/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java
+++ b/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java
@@ -17,40 +17,52 @@
import com.google.common.collect.ImmutableSet;
import io.airlift.resolver.internal.ConsoleRepositoryListener;
import io.airlift.resolver.internal.ConsoleTransferListener;
-import io.airlift.resolver.internal.Slf4jLoggerManager;
+import io.airlift.resolver.internal.DefaultArtifactResolver;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
-import org.apache.maven.repository.internal.MavenRepositorySystemSession;
-import org.apache.maven.repository.internal.MavenServiceLocator;
+import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader;
+import org.apache.maven.repository.internal.DefaultVersionRangeResolver;
+import org.apache.maven.repository.internal.DefaultVersionResolver;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.apache.maven.repository.internal.SnapshotMetadataGeneratorFactory;
+import org.apache.maven.repository.internal.VersionsMetadataGeneratorFactory;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.logging.Logger;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.collection.CollectRequest;
-import org.sonatype.aether.connector.async.AsyncRepositoryConnectorFactory;
-import org.sonatype.aether.connector.file.FileRepositoryConnectorFactory;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.graph.Exclusion;
-import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager;
-import org.sonatype.aether.repository.LocalRepositoryManager;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.resolution.ArtifactResult;
-import org.sonatype.aether.resolution.DependencyRequest;
-import org.sonatype.aether.resolution.DependencyResolutionException;
-import org.sonatype.aether.resolution.DependencyResult;
-import org.sonatype.aether.spi.connector.RepositoryConnectorFactory;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-import org.sonatype.aether.util.artifact.JavaScopes;
-import org.sonatype.aether.util.filter.DependencyFilterUtils;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.Exclusion;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.impl.ResolverArtifactResolver;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.resolution.DependencyRequest;
+import org.eclipse.aether.resolution.DependencyResolutionException;
+import org.eclipse.aether.resolution.DependencyResult;
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
+import org.eclipse.aether.spi.connector.transport.TransporterFactory;
+import org.eclipse.aether.transport.file.FileTransporterFactory;
+import org.eclipse.aether.transport.http.HttpTransporterFactory;
+import org.eclipse.aether.util.artifact.JavaScopes;
+import org.eclipse.aether.util.filter.DependencyFilterUtils;
import java.io.File;
import java.util.ArrayList;
@@ -79,9 +91,13 @@ public class ArtifactResolver
.build();
private final RepositorySystem repositorySystem;
- private final MavenRepositorySystemSession repositorySystemSession;
+ private final DefaultRepositorySystemSession repositorySystemSession;
private final List repositories;
+ private ProjectBuilder projectBuilder;
+
+ private ProjectBuildingRequest builderRequest;
+
public ArtifactResolver(String localRepositoryDir, String... remoteRepositoryUris)
{
this(localRepositoryDir, Arrays.asList(remoteRepositoryUris));
@@ -89,23 +105,33 @@ public ArtifactResolver(String localRepositoryDir, String... remoteRepositoryUri
public ArtifactResolver(String localRepositoryDir, List remoteRepositoryUris)
{
- MavenServiceLocator locator = new MavenServiceLocator();
- locator.addService(RepositoryConnectorFactory.class, FileRepositoryConnectorFactory.class);
- locator.addService(RepositoryConnectorFactory.class, AsyncRepositoryConnectorFactory.class);
+ // TODO: move off deprecated ServiceLocator, use Sisu instead
+ ResolverArtifactResolver locator = new ResolverArtifactResolver();
+ locator.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class);
+ locator.addService(VersionResolver.class, DefaultVersionResolver.class);
+ locator.addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class);
+ locator.addService(MetadataGeneratorFactory.class, SnapshotMetadataGeneratorFactory.class);
+ locator.addService(MetadataGeneratorFactory.class, VersionsMetadataGeneratorFactory.class);
+ locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
+ locator.addService(org.eclipse.aether.impl.ArtifactResolver.class, DefaultArtifactResolver.class);
+ locator.addService(TransporterFactory.class, FileTransporterFactory.class);
+ locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
repositorySystem = locator.getService(RepositorySystem.class);
- repositorySystemSession = new MavenRepositorySystemSession();
-
- LocalRepositoryManager localRepositoryManager = new SimpleLocalRepositoryManager(localRepositoryDir);
- repositorySystemSession.setLocalRepositoryManager(localRepositoryManager);
+ repositorySystemSession = MavenRepositorySystemUtils.newSession();
+ LocalRepository localRepo = new LocalRepository(localRepositoryDir);
+ repositorySystemSession.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(repositorySystemSession, localRepo));
repositorySystemSession.setTransferListener(new ConsoleTransferListener());
repositorySystemSession.setRepositoryListener(new ConsoleRepositoryListener());
+ // Recreating ProjectBuilder & ProjectBuilderRequest caused major slowdowns
+ buildProjectBuilder();
+
List repositories = new ArrayList<>(remoteRepositoryUris.size());
int index = 0;
for (String repositoryUri : remoteRepositoryUris) {
- repositories.add(new RemoteRepository("repo-" + index++, "default", repositoryUri));
+ repositories.add(new RemoteRepository.Builder("repo-" + index++, "default", repositoryUri ).build() );
}
this.repositories = Collections.unmodifiableList(repositories);
}
@@ -124,7 +150,7 @@ public List resolveArtifacts(Iterable extends Artifact> sourceArtifa
for (RemoteRepository repository : repositories) {
// Hack: avoid using deprecated Maven Central URLs
if (DEPRECATED_MAVEN_CENTRAL_URIS.contains(repository.getUrl())) {
- repository = new RemoteRepository(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI);
+ repository = new RemoteRepository.Builder(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI).build();
}
collectRequest.addRepository(repository);
}
@@ -153,13 +179,13 @@ public List resolvePom(File pomFile)
ImmutableList.Builder allRepositories = ImmutableList.builder();
for (RemoteRepository repository : pom.getRemoteProjectRepositories()) {
if (DEPRECATED_MAVEN_CENTRAL_URIS.contains(repository.getUrl())) {
- repository = new RemoteRepository(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI);
+ repository = new RemoteRepository.Builder(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI).build();
}
allRepositories.add(repository);
}
for (RemoteRepository repository : repositories) {
if (DEPRECATED_MAVEN_CENTRAL_URIS.contains(repository.getUrl())) {
- repository = new RemoteRepository(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI);
+ repository = new RemoteRepository.Builder(repository.getId(), repository.getContentType(), MAVEN_CENTRAL_URI).build();
}
allRepositories.add(repository);
}
@@ -185,7 +211,7 @@ public List resolvePom(File pomFile)
.collect(toImmutableList());
}
- private MavenProject getMavenProject(File pomFile)
+ private void buildProjectBuilder()
{
try {
PlexusContainer container = container();
@@ -197,7 +223,21 @@ private MavenProject getMavenProject(File pomFile)
request.setProcessPlugins(false);
request.setLocalRepository(lrs.createDefaultLocalRepository());
request.setRemoteRepositories(Arrays.asList(new ArtifactRepository[] {lrs.createDefaultRemoteRepository()}.clone()));
- ProjectBuildingResult result = projectBuilder.build(pomFile, request);
+ this.projectBuilder = projectBuilder;
+ this.builderRequest = request;
+ }catch (Exception e) {
+ throw new RuntimeException("Error initializing project builder: ", e);
+ }
+ }
+ private MavenProject getMavenProject(File pomFile)
+ {
+ // TODO: move off deprecated org.apache.maven.repository.RepositorySystem (impl is in maven2 compat module)
+ try {
+ if (projectBuilder == null || builderRequest == null)
+ {
+ buildProjectBuilder();
+ }
+ ProjectBuildingResult result = projectBuilder.build(pomFile, builderRequest);
return result.getProject();
}
catch (Exception e) {
@@ -285,12 +325,15 @@ private List resolveArtifacts(DependencyRequest dependencyRequest)
private static PlexusContainer container()
{
+ // TODO: move off Plexus DI, use Sisu instead
try {
ClassWorld classWorld = new ClassWorld("plexus.core", Thread.currentThread().getContextClassLoader());
ContainerConfiguration cc = new DefaultContainerConfiguration()
.setClassWorld(classWorld)
.setRealm(null)
+ .setAutoWiring(true)
+ .setClassPathScanning(PlexusConstants.SCANNING_CACHE)
.setName("maven");
DefaultPlexusContainer container = new DefaultPlexusContainer(cc);
@@ -298,7 +341,7 @@ private static PlexusContainer container()
// NOTE: To avoid inconsistencies, we'll use the Thread context class loader exclusively for lookups
container.setLookupRealm(null);
- container.setLoggerManager(new Slf4jLoggerManager());
+ //container.setLoggerManager(new Slf4jLoggerManager());
container.getLoggerManager().setThresholds(Logger.LEVEL_INFO);
return container;
diff --git a/resolver/src/main/java/io/airlift/resolver/DefaultArtifact.java b/resolver/src/main/java/io/airlift/resolver/DefaultArtifact.java
deleted file mode 100644
index 7a11091..0000000
--- a/resolver/src/main/java/io/airlift/resolver/DefaultArtifact.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.airlift.resolver;
-
-/*******************************************************************************
- * Copyright (c) 2010-2011 Sonatype, Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.artifact.ArtifactType;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A simple artifact. Note: Instances of this class are immutable and the exposed mutators return new objects
- * rather than changing the current instance.
- *
- * @author Benjamin Bentmann
- */
-public final class DefaultArtifact
- implements Artifact
-{
- private static final String SNAPSHOT = "SNAPSHOT";
- private static final Pattern SNAPSHOT_TIMESTAMP = Pattern.compile("^(.*-)?([0-9]{8}.[0-9]{6}-[0-9]+)$");
-
- private final String groupId;
- private final String artifactId;
- private final String version;
- private final String classifier;
- private final String extension;
- private final File file;
- private final Map properties;
- private String baseVersion;
-
- /**
- * Creates a new artifact with the specified coordinates. If not specified in the artifact coordinates, the
- * artifact's extension defaults to {@code jar} and classifier to an empty string.
- *
- * @param coords The artifact coordinates in the format
- * {@code :[:[:]]:}, must not be {@code null}.
- */
- public DefaultArtifact(String coords)
- {
- this(coords, Collections.emptyMap());
- }
-
- /**
- * Creates a new artifact with the specified coordinates and properties. If not specified in the artifact
- * coordinates, the artifact's extension defaults to {@code jar} and classifier to an empty string.
- *
- * @param coords The artifact coordinates in the format
- * {@code :[:[:]]:}, must not be {@code null}.
- * @param properties The artifact properties, may be {@code null}.
- */
- public DefaultArtifact(String coords, Map properties)
- {
- Pattern p = Pattern.compile("([^: ]+):([^: ]+)(:([^: ]*)(:([^: ]+))?)?:([^: ]+)");
- Matcher m = p.matcher(coords);
- if (!m.matches()) {
- throw new IllegalArgumentException("Bad artifact coordinates " + coords
- + ", expected format is :[:[:]]:");
- }
- this.groupId = m.group(1);
- this.artifactId = m.group(2);
- this.extension = get(m.group(4), "jar");
- this.classifier = get(m.group(6), "");
- this.version = m.group(7);
- this.file = null;
- this.properties = Collections.unmodifiableMap(new LinkedHashMap<>(properties));
- }
-
- private static String get(String value, String defaultValue)
- {
- return (value == null || value.length() <= 0) ? defaultValue : value;
- }
-
- /**
- * Creates a new artifact with the specified coordinates and no classifier. Passing {@code null} for any of the
- * coordinates is equivalent to specifying an empty string.
- *
- * @param groupId The group identifier of the artifact, may be {@code null}.
- * @param artifactId The artifact identifier of the artifact, may be {@code null}.
- * @param extension The file extension of the artifact, may be {@code null}.
- * @param version The version of the artifact, may be {@code null}.
- */
- public DefaultArtifact(String groupId, String artifactId, String extension, String version)
- {
- this(groupId, artifactId, "", extension, version);
- }
-
- /**
- * Creates a new artifact with the specified coordinates. Passing {@code null} for any of the coordinates is
- * equivalent to specifying an empty string.
- *
- * @param groupId The group identifier of the artifact, may be {@code null}.
- * @param artifactId The artifact identifier of the artifact, may be {@code null}.
- * @param classifier The classifier of the artifact, may be {@code null}.
- * @param extension The file extension of the artifact, may be {@code null}.
- * @param version The version of the artifact, may be {@code null}.
- */
- public DefaultArtifact(String groupId, String artifactId, String classifier, String extension, String version)
- {
- this(groupId, artifactId, classifier, extension, version, null, (File) null);
- }
-
- /**
- * Creates a new artifact with the specified coordinates. Passing {@code null} for any of the coordinates is
- * equivalent to specifying an empty string. The optional artifact type provided to this constructor will be used to
- * determine the artifact's classifier and file extension if the corresponding arguments for this constructor are
- * {@code null}.
- *
- * @param groupId The group identifier of the artifact, may be {@code null}.
- * @param artifactId The artifact identifier of the artifact, may be {@code null}.
- * @param classifier The classifier of the artifact, may be {@code null}.
- * @param extension The file extension of the artifact, may be {@code null}.
- * @param version The version of the artifact, may be {@code null}.
- * @param type The artifact type from which to query classifier, file extension and properties, may be {@code null}.
- */
- public DefaultArtifact(String groupId, String artifactId, String classifier, String extension, String version,
- ArtifactType type)
- {
- this(groupId, artifactId, classifier, extension, version, null, type);
- }
-
- /**
- * Creates a new artifact with the specified coordinates and properties. Passing {@code null} for any of the
- * coordinates is equivalent to specifying an empty string. The optional artifact type provided to this constructor
- * will be used to determine the artifact's classifier and file extension if the corresponding arguments for this
- * constructor are {@code null}. If the artifact type specifies properties, those will get merged with the
- * properties passed directly into the constructor, with the latter properties taking precedence.
- *
- * @param groupId The group identifier of the artifact, may be {@code null}.
- * @param artifactId The artifact identifier of the artifact, may be {@code null}.
- * @param classifier The classifier of the artifact, may be {@code null}.
- * @param extension The file extension of the artifact, may be {@code null}.
- * @param version The version of the artifact, may be {@code null}.
- * @param properties The properties of the artifact, may be {@code null} if none.
- * @param type The artifact type from which to query classifier, file extension and properties, may be {@code null}.
- */
- public DefaultArtifact(String groupId, String artifactId, String classifier, String extension, String version,
- Map properties, ArtifactType type)
- {
- this.groupId = emptify(groupId);
- this.artifactId = emptify(artifactId);
- if (classifier != null || type == null) {
- this.classifier = emptify(classifier);
- }
- else {
- this.classifier = emptify(type.getClassifier());
- }
- if (extension != null || type == null) {
- this.extension = emptify(extension);
- }
- else {
- this.extension = emptify(type.getExtension());
- }
- this.version = emptify(version);
- this.file = null;
- this.properties = merge(properties, (type != null) ? type.getProperties() : null);
- }
-
- private static Map merge(Map dominant, Map recessive)
- {
- Map properties;
-
- if ((dominant == null || dominant.isEmpty()) && (recessive == null || recessive.isEmpty())) {
- properties = Collections.emptyMap();
- }
- else {
- properties = new HashMap<>();
- if (recessive != null) {
- properties.putAll(recessive);
- }
- if (dominant != null) {
- properties.putAll(dominant);
- }
- }
-
- return properties;
- }
-
- /**
- * Creates a new artifact with the specified coordinates, properties and file. Passing {@code null} for any of the
- * coordinates is equivalent to specifying an empty string.
- *
- * @param groupId The group identifier of the artifact, may be {@code null}.
- * @param artifactId The artifact identifier of the artifact, may be {@code null}.
- * @param classifier The classifier of the artifact, may be {@code null}.
- * @param extension The file extension of the artifact, may be {@code null}.
- * @param version The version of the artifact, may be {@code null}.
- * @param properties The properties of the artifact, may be {@code null} if none.
- * @param file The resolved file of the artifact, may be {@code null}.
- */
- public DefaultArtifact(String groupId, String artifactId, String classifier, String extension, String version,
- Map properties, File file)
- {
- this.groupId = emptify(groupId);
- this.artifactId = emptify(artifactId);
- this.classifier = emptify(classifier);
- this.extension = emptify(extension);
- this.version = emptify(version);
- this.file = file;
- this.properties = Collections.unmodifiableMap(new LinkedHashMap<>(properties));
- }
-
- DefaultArtifact(String groupId, String artifactId, String classifier, String extension, String version, File file,
- Map properties)
- {
- // NOTE: This constructor assumes immutability of the provided properties, for internal use only
- this.groupId = emptify(groupId);
- this.artifactId = emptify(artifactId);
- this.classifier = emptify(classifier);
- this.extension = emptify(extension);
- this.version = emptify(version);
- this.file = file;
- this.properties = properties;
- }
-
- private static String emptify(String str)
- {
- return (str == null) ? "" : str;
- }
-
- @Override
- public String getGroupId()
- {
- return groupId;
- }
-
- @Override
- public String getArtifactId()
- {
- return artifactId;
- }
-
- @Override
- public String getBaseVersion()
- {
- if (baseVersion == null) {
- baseVersion = toBaseVersion(getVersion());
- }
- return baseVersion;
- }
-
- @Override
- public String getVersion()
- {
- return version;
- }
-
- @Override
- public Artifact setVersion(String version)
- {
- if (this.version.equals(version) || (version == null && this.version.length() <= 0)) {
- return this;
- }
- return new DefaultArtifact(groupId, artifactId, classifier, extension, version, file, properties);
- }
-
- @Override
- public boolean isSnapshot()
- {
- return version.endsWith(SNAPSHOT) || SNAPSHOT_TIMESTAMP.matcher(version).matches();
- }
-
- @Override
- public String getClassifier()
- {
- return classifier;
- }
-
- @Override
- public String getExtension()
- {
- return extension;
- }
-
- @Override
- public File getFile()
- {
- return file;
- }
-
- @Override
- public Artifact setFile(File file)
- {
- if ((this.file == null) ? file == null : this.file.equals(file)) {
- return this;
- }
- return new DefaultArtifact(groupId, artifactId, classifier, extension, version, file, properties);
- }
-
- @Override
- public String getProperty(String key, String defaultValue)
- {
- String value = properties.get(key);
- return (value != null) ? value : defaultValue;
- }
-
- @Override
- public Map getProperties()
- {
- return Collections.unmodifiableMap(properties);
- }
-
- @Override
- public Artifact setProperties(Map properties)
- {
- if (this.properties.equals(properties) || (properties == null && this.properties.isEmpty())) {
- return this;
- }
- return new DefaultArtifact(groupId, artifactId, classifier, extension, version, file, Collections.unmodifiableMap(new LinkedHashMap<>(properties)));
- }
-
- protected static String toBaseVersion(String version)
- {
- if (version == null) {
- return version;
- }
-
- if (version.startsWith("[") || version.startsWith("(")) {
- return version;
- }
-
- Matcher m = SNAPSHOT_TIMESTAMP.matcher(version);
- if (!m.matches()) {
- return version;
- }
-
- if (m.group(1) == null) {
- return SNAPSHOT;
- }
-
- return m.group(1) + SNAPSHOT;
- }
-}
diff --git a/resolver/src/main/java/io/airlift/resolver/Main.java b/resolver/src/main/java/io/airlift/resolver/Main.java
index fe53281..ad9e01b 100644
--- a/resolver/src/main/java/io/airlift/resolver/Main.java
+++ b/resolver/src/main/java/io/airlift/resolver/Main.java
@@ -13,7 +13,8 @@
*/
package io.airlift.resolver;
-import org.sonatype.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
import java.io.File;
import java.util.ArrayList;
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/ConsoleRepositoryListener.java b/resolver/src/main/java/io/airlift/resolver/internal/ConsoleRepositoryListener.java
index 13e39cc..0123554 100644
--- a/resolver/src/main/java/io/airlift/resolver/internal/ConsoleRepositoryListener.java
+++ b/resolver/src/main/java/io/airlift/resolver/internal/ConsoleRepositoryListener.java
@@ -15,8 +15,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonatype.aether.AbstractRepositoryListener;
-import org.sonatype.aether.RepositoryEvent;
+import org.eclipse.aether.AbstractRepositoryListener;
+import org.eclipse.aether.RepositoryEvent;
/**
* A simplistic repository listener that logs events to the console.
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/ConsoleTransferListener.java b/resolver/src/main/java/io/airlift/resolver/internal/ConsoleTransferListener.java
index c6fa1ad..1ec3d3c 100644
--- a/resolver/src/main/java/io/airlift/resolver/internal/ConsoleTransferListener.java
+++ b/resolver/src/main/java/io/airlift/resolver/internal/ConsoleTransferListener.java
@@ -15,9 +15,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonatype.aether.transfer.AbstractTransferListener;
-import org.sonatype.aether.transfer.TransferEvent;
-import org.sonatype.aether.transfer.TransferResource;
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferResource;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/DefaultArtifactResolver.java b/resolver/src/main/java/io/airlift/resolver/internal/DefaultArtifactResolver.java
new file mode 100644
index 0000000..ccd467b
--- /dev/null
+++ b/resolver/src/main/java/io/airlift/resolver/internal/DefaultArtifactResolver.java
@@ -0,0 +1,660 @@
+package io.airlift.resolver.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.SyncContext;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.ArtifactResolver;
+import org.eclipse.aether.impl.OfflineController;
+import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
+import org.eclipse.aether.impl.RemoteRepositoryManager;
+import org.eclipse.aether.impl.RepositoryConnectorProvider;
+import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.impl.UpdateCheck;
+import org.eclipse.aether.impl.UpdateCheckManager;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.repository.LocalArtifactRegistration;
+import org.eclipse.aether.repository.LocalArtifactRequest;
+import org.eclipse.aether.repository.LocalArtifactResult;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.resolution.VersionRequest;
+import org.eclipse.aether.resolution.VersionResolutionException;
+import org.eclipse.aether.resolution.VersionResult;
+import org.eclipse.aether.spi.connector.ArtifactDownload;
+import org.eclipse.aether.spi.connector.RepositoryConnector;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
+import org.eclipse.aether.spi.io.FileProcessor;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
+import org.eclipse.aether.spi.synccontext.SyncContextFactory;
+import org.eclipse.aether.transfer.ArtifactFilteredOutException;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+import org.eclipse.aether.transfer.ArtifactTransferException;
+import org.eclipse.aether.transfer.NoRepositoryConnectorException;
+import org.eclipse.aether.transfer.RepositoryOfflineException;
+import org.eclipse.aether.util.ConfigUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+@Named
+public class DefaultArtifactResolver implements ArtifactResolver, Service {
+ private static final String CONFIG_PROP_SNAPSHOT_NORMALIZATION = "aether.artifactResolver.snapshotNormalization";
+ private static final String CONFIG_PROP_SIMPLE_LRM_INTEROP = "aether.artifactResolver.simpleLrmInterop";
+ private static final Logger LOGGER = LoggerFactory.getLogger(io.airlift.resolver.internal.DefaultArtifactResolver.class);
+ private FileProcessor fileProcessor;
+ private RepositoryEventDispatcher repositoryEventDispatcher;
+ private VersionResolver versionResolver;
+ private UpdateCheckManager updateCheckManager;
+ private RepositoryConnectorProvider repositoryConnectorProvider;
+ private RemoteRepositoryManager remoteRepositoryManager;
+ private SyncContextFactory syncContextFactory;
+ private OfflineController offlineController;
+ private Map artifactResolverPostProcessors;
+ private RemoteRepositoryFilterManager remoteRepositoryFilterManager;
+
+ public DefaultArtifactResolver() {
+ }
+
+ @Inject
+ DefaultArtifactResolver(FileProcessor fileProcessor, RepositoryEventDispatcher repositoryEventDispatcher, VersionResolver versionResolver, UpdateCheckManager updateCheckManager, RepositoryConnectorProvider repositoryConnectorProvider, RemoteRepositoryManager remoteRepositoryManager, SyncContextFactory syncContextFactory, OfflineController offlineController, Map artifactResolverPostProcessors, RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
+ this.setFileProcessor(fileProcessor);
+ this.setRepositoryEventDispatcher(repositoryEventDispatcher);
+ this.setVersionResolver(versionResolver);
+ this.setUpdateCheckManager(updateCheckManager);
+ this.setRepositoryConnectorProvider(repositoryConnectorProvider);
+ this.setRemoteRepositoryManager(remoteRepositoryManager);
+ this.setSyncContextFactory(syncContextFactory);
+ this.setOfflineController(offlineController);
+ this.setArtifactResolverPostProcessors(artifactResolverPostProcessors);
+ this.setRemoteRepositoryFilterManager(remoteRepositoryFilterManager);
+ }
+
+ public void initService(ServiceLocator locator) {
+ this.setFileProcessor((FileProcessor)locator.getService(FileProcessor.class));
+ this.setRepositoryEventDispatcher((RepositoryEventDispatcher)locator.getService(RepositoryEventDispatcher.class));
+ this.setVersionResolver((VersionResolver)locator.getService(VersionResolver.class));
+ this.setUpdateCheckManager((UpdateCheckManager)locator.getService(UpdateCheckManager.class));
+ this.setRepositoryConnectorProvider((RepositoryConnectorProvider)locator.getService(RepositoryConnectorProvider.class));
+ this.setRemoteRepositoryManager((RemoteRepositoryManager)locator.getService(RemoteRepositoryManager.class));
+ this.setSyncContextFactory((SyncContextFactory)locator.getService(SyncContextFactory.class));
+ this.setOfflineController((OfflineController)locator.getService(OfflineController.class));
+ this.setArtifactResolverPostProcessors(Collections.emptyMap());
+ this.setRemoteRepositoryFilterManager((RemoteRepositoryFilterManager)locator.getService(RemoteRepositoryFilterManager.class));
+ }
+
+ /** @deprecated */
+ @Deprecated
+ public io.airlift.resolver.internal.DefaultArtifactResolver setLoggerFactory(org.eclipse.aether.spi.log.LoggerFactory loggerFactory) {
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setFileProcessor(FileProcessor fileProcessor) {
+ this.fileProcessor = (FileProcessor)Objects.requireNonNull(fileProcessor, "file processor cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setRepositoryEventDispatcher(RepositoryEventDispatcher repositoryEventDispatcher) {
+ this.repositoryEventDispatcher = (RepositoryEventDispatcher)Objects.requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setVersionResolver(VersionResolver versionResolver) {
+ this.versionResolver = (VersionResolver)Objects.requireNonNull(versionResolver, "version resolver cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setUpdateCheckManager(UpdateCheckManager updateCheckManager) {
+ this.updateCheckManager = (UpdateCheckManager)Objects.requireNonNull(updateCheckManager, "update check manager cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setRepositoryConnectorProvider(RepositoryConnectorProvider repositoryConnectorProvider) {
+ this.repositoryConnectorProvider = (RepositoryConnectorProvider)Objects.requireNonNull(repositoryConnectorProvider, "repository connector provider cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setRemoteRepositoryManager(RemoteRepositoryManager remoteRepositoryManager) {
+ this.remoteRepositoryManager = (RemoteRepositoryManager)Objects.requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setSyncContextFactory(SyncContextFactory syncContextFactory) {
+ this.syncContextFactory = (SyncContextFactory)Objects.requireNonNull(syncContextFactory, "sync context factory cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setOfflineController(OfflineController offlineController) {
+ this.offlineController = (OfflineController)Objects.requireNonNull(offlineController, "offline controller cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setArtifactResolverPostProcessors(Map artifactResolverPostProcessors) {
+ this.artifactResolverPostProcessors = (Map)Objects.requireNonNull(artifactResolverPostProcessors, "artifact resolver post-processors cannot be null");
+ return this;
+ }
+
+ public io.airlift.resolver.internal.DefaultArtifactResolver setRemoteRepositoryFilterManager(RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
+ this.remoteRepositoryFilterManager = (RemoteRepositoryFilterManager)Objects.requireNonNull(remoteRepositoryFilterManager, "remote repository filter manager cannot be null");
+ return this;
+ }
+
+ public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request) throws ArtifactResolutionException {
+ Objects.requireNonNull(session, "session cannot be null");
+ Objects.requireNonNull(session, "session cannot be null");
+ return (ArtifactResult)this.resolveArtifacts(session, Collections.singleton(request)).get(0);
+ }
+
+ public List resolveArtifacts(RepositorySystemSession session, Collection extends ArtifactRequest> requests) throws ArtifactResolutionException {
+ Objects.requireNonNull(session, "session cannot be null");
+ Objects.requireNonNull(session, "session cannot be null");
+ SyncContext syncContext = this.syncContextFactory.newInstance(session, false);
+
+ List var9;
+ try {
+ Collection artifacts = new ArrayList(requests.size());
+ Iterator var5 = requests.iterator();
+
+ while(var5.hasNext()) {
+ ArtifactRequest request = (ArtifactRequest)var5.next();
+ if (request.getArtifact().getProperty("localPath", (String)null) == null) {
+ artifacts.add(request.getArtifact());
+ }
+ }
+
+ syncContext.acquire(artifacts, (Collection)null);
+ var9 = this.resolve(session, requests);
+ } catch (Throwable var8) {
+ if (syncContext != null) {
+ try {
+ syncContext.close();
+ } catch (Throwable var7) {
+ var8.addSuppressed(var7);
+ }
+ }
+
+ throw var8;
+ }
+
+ if (syncContext != null) {
+ syncContext.close();
+ }
+
+ return var9;
+ }
+
+ private List resolve(RepositorySystemSession session, Collection extends ArtifactRequest> requests) throws ArtifactResolutionException {
+ List results = new ArrayList(requests.size());
+ boolean failures = false;
+ boolean simpleLrmInterop = ConfigUtils.getBoolean(session, false, new String[]{"aether.artifactResolver.simpleLrmInterop"});
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ WorkspaceReader workspace = session.getWorkspaceReader();
+ List groups = new ArrayList();
+ RemoteRepositoryFilter filter = this.remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
+ Iterator var10 = requests.iterator();
+
+ while(true) {
+ label169:
+ while(var10.hasNext()) {
+ ArtifactRequest request = (ArtifactRequest)var10.next();
+ RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
+ ArtifactResult result = new ArtifactResult(request);
+ results.add(result);
+ Artifact artifact = request.getArtifact();
+ this.artifactResolving(session, trace, artifact);
+ String localPath = artifact.getProperty("localPath", (String)null);
+ if (localPath != null) {
+ File file = new File(localPath);
+ if (!file.isFile()) {
+ failures = true;
+ result.addException(new ArtifactNotFoundException(artifact, (RemoteRepository)null));
+ } else {
+ artifact = artifact.setFile(file);
+ result.setArtifact(artifact);
+ this.artifactResolved(session, trace, artifact, (ArtifactRepository)null, result.getExceptions());
+ }
+ } else {
+ List remoteRepositories = request.getRepositories();
+ List filteredRemoteRepositories = new ArrayList(remoteRepositories);
+ if (filter != null) {
+ Iterator var18 = remoteRepositories.iterator();
+
+ while(var18.hasNext()) {
+ RemoteRepository repository = (RemoteRepository)var18.next();
+ RemoteRepositoryFilter.Result filterResult = filter.acceptArtifact(repository, artifact);
+ if (!filterResult.isAccepted()) {
+ result.addException(new ArtifactFilteredOutException(artifact, repository, filterResult.reasoning()));
+ ((List)filteredRemoteRepositories).remove(repository);
+ }
+ }
+ }
+
+ VersionResult versionResult;
+ try {
+ VersionRequest versionRequest = new VersionRequest(artifact, (List)filteredRemoteRepositories, request.getRequestContext());
+ versionRequest.setTrace(trace);
+ versionResult = this.versionResolver.resolveVersion(session, versionRequest);
+ } catch (VersionResolutionException var28) {
+ VersionResolutionException e = var28;
+ result.addException(e);
+ continue;
+ }
+
+ artifact = artifact.setVersion(versionResult.getVersion());
+ if (versionResult.getRepository() != null) {
+ if (versionResult.getRepository() instanceof RemoteRepository) {
+ filteredRemoteRepositories = Collections.singletonList((RemoteRepository)versionResult.getRepository());
+ } else {
+ filteredRemoteRepositories = Collections.emptyList();
+ }
+ }
+
+ if (workspace != null) {
+ File file = workspace.findArtifact(artifact);
+ if (file != null) {
+ artifact = artifact.setFile(file);
+ result.setArtifact(artifact);
+ result.setRepository(workspace.getRepository());
+ this.artifactResolved(session, trace, artifact, result.getRepository(), (List)null);
+ continue;
+ }
+ }
+
+ LocalArtifactResult local = lrm.find(session, new LocalArtifactRequest(artifact, (List)filteredRemoteRepositories, request.getRequestContext()));
+ result.setLocalArtifactResult(local);
+ boolean found = filter != null && local.isAvailable() || this.isLocallyInstalled(local, versionResult);
+ if (found || local.getFile() != null) {
+ if (local.getRepository() != null) {
+ result.setRepository(local.getRepository());
+ } else {
+ result.setRepository(lrm.getRepository());
+ }
+
+ try {
+ artifact = artifact.setFile(this.getFile(session, artifact, local.getFile()));
+ result.setArtifact(artifact);
+ this.artifactResolved(session, trace, artifact, result.getRepository(), (List)null);
+ } catch (ArtifactTransferException var27) {
+ ArtifactTransferException e = var27;
+ result.addException(e);
+ }
+
+ if (filter == null && simpleLrmInterop && !local.isAvailable()) {
+ lrm.add(session, new LocalArtifactRegistration(artifact));
+ }
+ } else {
+
+ LOGGER.debug("Resolving artifact {} from {}", artifact, remoteRepositories);
+ AtomicBoolean resolved = new AtomicBoolean(false);
+ Iterator groupIt = groups.iterator();
+ Iterator var23 = ((List)filteredRemoteRepositories).iterator();
+
+ while(true) {
+ RemoteRepository repo;
+ while(true) {
+ do {
+ if (!var23.hasNext()) {
+ continue label169;
+ }
+
+ repo = (RemoteRepository)var23.next();
+ } while(!repo.getPolicy(artifact.isSnapshot()).isEnabled());
+
+ try {
+ Utils.checkOffline(session, this.offlineController, repo);
+ break;
+ } catch (RepositoryOfflineException var29) {
+ RepositoryOfflineException e = var29;
+ Exception exception = new ArtifactNotFoundException(artifact, repo, "Cannot access " + repo.getId() + " (" + repo.getUrl() + ") in offline mode and the artifact " + artifact + " has not been downloaded from it before.", e);
+ result.addException(exception);
+ }
+ }
+
+ io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup group = null;
+
+ while(groupIt.hasNext()) {
+ io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup t = (io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup)groupIt.next();
+ if (t.matches(repo)) {
+ group = t;
+ break;
+ }
+ }
+
+ if (group == null) {
+ group = new io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup(repo);
+ groups.add(group);
+ groupIt = Collections.emptyIterator();
+ }
+
+ group.items.add(new io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionItem(trace, artifact, resolved, result, local, repo));
+ }
+ }
+ }
+ }
+
+ var10 = groups.iterator();
+
+ while(var10.hasNext()) {
+ io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup group = (io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup)var10.next();
+ this.performDownloads(session, group);
+ }
+
+ var10 = this.artifactResolverPostProcessors.values().iterator();
+
+ while(var10.hasNext()) {
+ ArtifactResolverPostProcessor artifactResolverPostProcessor = (ArtifactResolverPostProcessor)var10.next();
+ artifactResolverPostProcessor.postProcess(session, results);
+ }
+
+ var10 = results.iterator();
+
+ while(true) {
+ ArtifactResult result;
+ ArtifactRequest request;
+ Artifact artifact;
+ do {
+ if (!var10.hasNext()) {
+ if (failures) {
+ throw new ArtifactResolutionException(results);
+ }
+
+ return results;
+ }
+
+ result = (ArtifactResult)var10.next();
+ request = result.getRequest();
+ artifact = result.getArtifact();
+ } while(artifact != null && artifact.getFile() != null);
+
+ failures = true;
+ if (result.getExceptions().isEmpty()) {
+ Exception exception = new ArtifactNotFoundException(request.getArtifact(), (RemoteRepository)null);
+ result.addException(exception);
+ }
+
+ RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
+ this.artifactResolved(session, trace, request.getArtifact(), (ArtifactRepository)null, result.getExceptions());
+ }
+ }
+ }
+
+ private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) {
+ if (lar.isAvailable()) {
+ return true;
+ } else {
+ if (lar.getFile() != null) {
+ if (vr.getRepository() instanceof LocalRepository) {
+ return true;
+ }
+
+ if (vr.getRepository() == null && lar.getRequest().getRepositories().isEmpty()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private File getFile(RepositorySystemSession session, Artifact artifact, File file) throws ArtifactTransferException {
+ if (artifact.isSnapshot() && !artifact.getVersion().equals(artifact.getBaseVersion()) && ConfigUtils.getBoolean(session, true, new String[]{"aether.artifactResolver.snapshotNormalization"})) {
+ String name = file.getName().replace(artifact.getVersion(), artifact.getBaseVersion());
+ File dst = new File(file.getParent(), name);
+ boolean copy = dst.length() != file.length() || dst.lastModified() != file.lastModified();
+ if (copy) {
+ try {
+ this.fileProcessor.copy(file, dst);
+ dst.setLastModified(file.lastModified());
+ } catch (IOException var8) {
+ IOException e = var8;
+ throw new ArtifactTransferException(artifact, (RemoteRepository)null, e);
+ }
+ }
+
+ file = dst;
+ }
+
+ return file;
+ }
+
+ private void performDownloads(RepositorySystemSession session, io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup group) {
+ List downloads = this.gatherDownloads(session, group);
+ if (!downloads.isEmpty()) {
+ Iterator var4 = downloads.iterator();
+
+ while(var4.hasNext()) {
+ ArtifactDownload download = (ArtifactDownload)var4.next();
+ this.artifactDownloading(session, download.getTrace(), download.getArtifact(), group.repository);
+ }
+
+ try {
+ RepositoryConnector connector = this.repositoryConnectorProvider.newRepositoryConnector(session, group.repository);
+
+ try {
+ connector.get(downloads, (Collection)null);
+ } catch (Throwable var8) {
+ if (connector != null) {
+ try {
+ connector.close();
+ } catch (Throwable var7) {
+ var8.addSuppressed(var7);
+ }
+ }
+
+ throw var8;
+ }
+
+ if (connector != null) {
+ connector.close();
+ }
+ } catch (NoRepositoryConnectorException var9) {
+ NoRepositoryConnectorException e = var9;
+ Iterator var12 = downloads.iterator();
+
+ while(var12.hasNext()) {
+ ArtifactDownload download = (ArtifactDownload)var12.next();
+ download.setException(new ArtifactTransferException(download.getArtifact(), group.repository, e));
+ }
+ }
+
+ this.evaluateDownloads(session, group);
+ }
+ }
+
+ private List gatherDownloads(RepositorySystemSession session, io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup group) {
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ List downloads = new ArrayList();
+ Iterator var5 = group.items.iterator();
+
+ while(true) {
+ while(true) {
+ io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionItem item;
+ Artifact artifact;
+ do {
+ if (!var5.hasNext()) {
+ return downloads;
+ }
+
+ item = (io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionItem)var5.next();
+ artifact = item.artifact;
+ } while(item.resolved.get());
+
+ ArtifactDownload download = new ArtifactDownload();
+ download.setArtifact(artifact);
+ download.setRequestContext(item.request.getRequestContext());
+ download.setListener(SafeTransferListener.wrap(session));
+ download.setTrace(item.trace);
+ if (item.local.getFile() != null) {
+ download.setFile(item.local.getFile());
+ download.setExistenceCheck(true);
+ } else {
+ String path = lrm.getPathForRemoteArtifact(artifact, group.repository, item.request.getRequestContext());
+ download.setFile(new File(lrm.getRepository().getBasedir(), path));
+ }
+
+ boolean snapshot = artifact.isSnapshot();
+ RepositoryPolicy policy = this.remoteRepositoryManager.getPolicy(session, group.repository, !snapshot, snapshot);
+ int errorPolicy = Utils.getPolicy(session, artifact, group.repository);
+ if ((errorPolicy & 3) != 0) {
+ UpdateCheck check = new UpdateCheck();
+ check.setItem(artifact);
+ check.setFile(download.getFile());
+ check.setFileValid(false);
+ check.setRepository(group.repository);
+ check.setPolicy(policy.getUpdatePolicy());
+ item.updateCheck = check;
+ this.updateCheckManager.checkArtifact(session, check);
+ if (!check.isRequired()) {
+ item.result.addException(check.getException());
+ continue;
+ }
+ }
+
+ download.setChecksumPolicy(policy.getChecksumPolicy());
+ download.setRepositories(item.repository.getMirroredRepositories());
+ downloads.add(download);
+ item.download = download;
+ }
+ }
+ }
+
+ private void evaluateDownloads(RepositorySystemSession session, io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionGroup group) {
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ Iterator var4 = group.items.iterator();
+
+ while(var4.hasNext()) {
+ io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionItem item = (io.airlift.resolver.internal.DefaultArtifactResolver.ResolutionItem)var4.next();
+ ArtifactDownload download = item.download;
+ if (download != null) {
+ Artifact artifact = download.getArtifact();
+ if (download.getException() == null) {
+ item.resolved.set(true);
+ item.result.setRepository(group.repository);
+
+ try {
+ artifact = artifact.setFile(this.getFile(session, artifact, download.getFile()));
+ item.result.setArtifact(artifact);
+ lrm.add(session, new LocalArtifactRegistration(artifact, group.repository, download.getSupportedContexts()));
+ } catch (ArtifactTransferException var9) {
+ ArtifactTransferException e = var9;
+ download.setException(e);
+ item.result.addException(e);
+ }
+ } else {
+ item.result.addException(download.getException());
+ }
+
+ if (item.updateCheck != null) {
+ item.updateCheck.setException(download.getException());
+ this.updateCheckManager.touchArtifact(session, item.updateCheck);
+ }
+
+ this.artifactDownloaded(session, download.getTrace(), artifact, group.repository, download.getException());
+ if (download.getException() == null) {
+ this.artifactResolved(session, download.getTrace(), artifact, group.repository, (List)null);
+ }
+ }
+ }
+
+ }
+
+ private void artifactResolving(RepositorySystemSession session, RequestTrace trace, Artifact artifact) {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVING);
+ event.setTrace(trace);
+ event.setArtifact(artifact);
+ this.repositoryEventDispatcher.dispatch(event.build());
+ }
+
+ private void artifactResolved(RepositorySystemSession session, RequestTrace trace, Artifact artifact, ArtifactRepository repository, List exceptions) {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVED);
+ event.setTrace(trace);
+ event.setArtifact(artifact);
+ event.setRepository(repository);
+ event.setExceptions(exceptions);
+ if (artifact != null) {
+ event.setFile(artifact.getFile());
+ }
+
+ this.repositoryEventDispatcher.dispatch(event.build());
+ }
+
+ private void artifactDownloading(RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository) {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADING);
+ event.setTrace(trace);
+ event.setArtifact(artifact);
+ event.setRepository(repository);
+ this.repositoryEventDispatcher.dispatch(event.build());
+ }
+
+ private void artifactDownloaded(RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository, Exception exception) {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADED);
+ event.setTrace(trace);
+ event.setArtifact(artifact);
+ event.setRepository(repository);
+ event.setException(exception);
+ if (artifact != null) {
+ event.setFile(artifact.getFile());
+ }
+
+ this.repositoryEventDispatcher.dispatch(event.build());
+ }
+
+ static class ResolutionGroup {
+ final RemoteRepository repository;
+ final List items = new ArrayList();
+
+ ResolutionGroup(RemoteRepository repository) {
+ this.repository = repository;
+ }
+
+ boolean matches(RemoteRepository repo) {
+ return this.repository.getUrl().equals(repo.getUrl()) && this.repository.getContentType().equals(repo.getContentType()) && this.repository.isRepositoryManager() == repo.isRepositoryManager();
+ }
+ }
+
+ static class ResolutionItem {
+ final RequestTrace trace;
+ final ArtifactRequest request;
+ final ArtifactResult result;
+ final LocalArtifactResult local;
+ final RemoteRepository repository;
+ final Artifact artifact;
+ final AtomicBoolean resolved;
+ ArtifactDownload download;
+ UpdateCheck updateCheck;
+
+ ResolutionItem(RequestTrace trace, Artifact artifact, AtomicBoolean resolved, ArtifactResult result, LocalArtifactResult local, RemoteRepository repository) {
+ this.trace = trace;
+ this.artifact = artifact;
+ this.resolved = resolved;
+ this.result = result;
+ this.request = result.getRequest();
+ this.local = local;
+ this.repository = repository;
+ }
+ }
+}
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/SafeTransferListener.java b/resolver/src/main/java/io/airlift/resolver/internal/SafeTransferListener.java
new file mode 100644
index 0000000..37111a0
--- /dev/null
+++ b/resolver/src/main/java/io/airlift/resolver/internal/SafeTransferListener.java
@@ -0,0 +1,112 @@
+package io.airlift.resolver.internal;
+
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transfer.TransferCancelledException;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+
+class SafeTransferListener extends AbstractTransferListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(io.airlift.resolver.internal.SafeTransferListener.class);
+ private final TransferListener listener;
+
+ public static TransferListener wrap(RepositorySystemSession session) {
+ TransferListener listener = session.getTransferListener();
+ return listener == null ? null : new io.airlift.resolver.internal.SafeTransferListener(listener);
+ }
+
+ protected SafeTransferListener(RepositorySystemSession session) {
+ this(session.getTransferListener());
+ }
+
+ private SafeTransferListener(TransferListener listener) {
+ this.listener = listener;
+ }
+
+ private void logError(TransferEvent event, Throwable e) {
+ LOGGER.debug("Failed to dispatch transfer event '{}' to {}", new Object[]{event, this.listener.getClass().getCanonicalName(), e});
+ }
+
+ public void transferInitiated(TransferEvent event) throws TransferCancelledException {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferInitiated(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+
+ public void transferStarted(TransferEvent event) throws TransferCancelledException {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferStarted(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+
+ public void transferProgressed(TransferEvent event) throws TransferCancelledException {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferProgressed(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+
+ public void transferCorrupted(TransferEvent event) throws TransferCancelledException {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferCorrupted(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+
+ public void transferSucceeded(TransferEvent event) {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferSucceeded(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+
+ public void transferFailed(TransferEvent event) {
+ Objects.requireNonNull(event, "event cannot be null");
+ if (this.listener != null) {
+ try {
+ this.listener.transferFailed(event);
+ } catch (LinkageError | RuntimeException var3) {
+ Throwable e = var3;
+ this.logError(event, e);
+ }
+ }
+
+ }
+}
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLogger.java b/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLogger.java
deleted file mode 100644
index 1c3df09..0000000
--- a/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLogger.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package io.airlift.resolver.internal;
-
-import org.codehaus.plexus.logging.Logger;
-
-/**
- * Adapt an SLF4J logger to a Plexus logger, ignoring Plexus logger API parts that are not classical and
- * probably not really used.
- *
- * @author Jason van Zyl
- */
-public class Slf4jLogger
- implements Logger
-{
- private final org.slf4j.Logger logger;
-
- public Slf4jLogger(org.slf4j.Logger logger)
- {
- this.logger = logger;
- }
-
- public void debug(String message)
- {
- logger.debug(message);
- }
-
- public void debug(String message, Throwable throwable)
- {
- logger.debug(message, throwable);
- }
-
- public boolean isDebugEnabled()
- {
- return logger.isDebugEnabled();
- }
-
- public void info(String message)
- {
- logger.info(message);
- }
-
- public void info(String message, Throwable throwable)
- {
- logger.info(message, throwable);
- }
-
- public boolean isInfoEnabled()
- {
- return logger.isInfoEnabled();
- }
-
- public void warn(String message)
- {
- logger.warn(message);
- }
-
- public void warn(String message, Throwable throwable)
- {
- logger.warn(message, throwable);
- }
-
- public boolean isWarnEnabled()
- {
- return logger.isWarnEnabled();
- }
-
- public void error(String message)
- {
- logger.error(message);
- }
-
- public void error(String message, Throwable throwable)
- {
- logger.error(message, throwable);
- }
-
- public boolean isErrorEnabled()
- {
- return logger.isErrorEnabled();
- }
-
- public void fatalError(String message)
- {
- logger.error(message);
- }
-
- public void fatalError(String message, Throwable throwable)
- {
- logger.error(message, throwable);
- }
-
- public boolean isFatalErrorEnabled()
- {
- return logger.isErrorEnabled();
- }
-
- /**
- * Warning: ignored (always return 0 == Logger.LEVEL_DEBUG
).
- */
- public int getThreshold()
- {
- return 0;
- }
-
- /**
- * Warning: ignored.
- */
- public void setThreshold(int threshold)
- {
- }
-
- /**
- * Warning: ignored (always return null
).
- */
- public Logger getChildLogger(String name)
- {
- return null;
- }
-
- public String getName()
- {
- return logger.getName();
- }
-}
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLoggerManager.java b/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLoggerManager.java
deleted file mode 100644
index 7422b9e..0000000
--- a/resolver/src/main/java/io/airlift/resolver/internal/Slf4jLoggerManager.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package io.airlift.resolver.internal;
-
-import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.logging.LoggerManager;
-import org.slf4j.ILoggerFactory;
-import org.slf4j.LoggerFactory;
-
-/**
- * Use an SLF4J {@link org.slf4j.ILoggerFactory} as a backing for a Plexus {@link org.codehaus.plexus.logging.LoggerManager},
- * ignoring Plexus logger API parts that are not classical and probably not really used.
- *
- * @author Jason van Zyl
- * @since 3.1
- */
-public class Slf4jLoggerManager
- implements LoggerManager
-{
- private final ILoggerFactory loggerFactory;
-
- public Slf4jLoggerManager()
- {
- loggerFactory = LoggerFactory.getILoggerFactory();
- }
-
- public Logger getLoggerForComponent(String role)
- {
- return new Slf4jLogger(loggerFactory.getLogger(role));
- }
-
- /**
- * The logger name for a component with a non-null hint is role.hint
.
- * Warning: this does not conform to logger name as class name convention.
- * (and what about null
and default
hint equivalence?)
- */
- public Logger getLoggerForComponent(String role, String hint)
- {
- return (null == hint
- ? getLoggerForComponent(role)
- : new Slf4jLogger(loggerFactory.getLogger(role + '.' + hint)));
- }
-
- //
- // Trying to give loggers back is a bad idea. Ceki said so :-)
- // notice to self: what was this method supposed to do?
- //
-
- /**
- * Warning: ignored.
- */
- @Override
- public void setThreshold(String role, int threshold)
- {
- }
-
- /**
- * Warning: ignored.
- */
- @Override
- public void setThreshold(String role, String roleHint, int threshold)
- {
- }
-
- /**
- * Warning: ignored.
- */
- @Override
- public int getThreshold(String role)
- {
- return 0;
- }
-
- /**
- * Warning: ignored.
- */
- @Override
- public int getThreshold(String role, String roleHint)
- {
- return 0;
- }
-
- /**
- * Warning: ignored.
- */
- public void returnComponentLogger(String role)
- {
- }
-
- /**
- * Warning: ignored.
- */
- public void returnComponentLogger(String role, String hint)
- {
- }
-
- /**
- * Warning: ignored (always return 0
).
- */
- public int getThreshold()
- {
- return 0;
- }
-
- /**
- * Warning: ignored.
- */
- public void setThreshold(int threshold)
- {
- }
-
- /**
- * Warning: ignored.
- */
- public void setThresholds(int threshold)
- {
- }
-
- /**
- * Warning: ignored (always return 0
).
- */
- public int getActiveLoggerCount()
- {
- return 0;
- }
-}
diff --git a/resolver/src/main/java/io/airlift/resolver/internal/Utils.java b/resolver/src/main/java/io/airlift/resolver/internal/Utils.java
new file mode 100644
index 0000000..8287686
--- /dev/null
+++ b/resolver/src/main/java/io/airlift/resolver/internal/Utils.java
@@ -0,0 +1,28 @@
+package io.airlift.resolver.internal;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.OfflineController;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ResolutionErrorPolicy;
+import org.eclipse.aether.resolution.ResolutionErrorPolicyRequest;
+import org.eclipse.aether.transfer.RepositoryOfflineException;
+
+public class Utils {
+ public static void checkOffline(RepositorySystemSession session, OfflineController offlineController, RemoteRepository repository) throws RepositoryOfflineException {
+ if (session.isOffline()) {
+ offlineController.checkOffline(session, repository);
+ }
+
+ }
+ public static int getPolicy(RepositorySystemSession session, Artifact artifact, RemoteRepository repository) {
+ ResolutionErrorPolicy rep = session.getResolutionErrorPolicy();
+ return rep == null ? 0 : rep.getArtifactPolicy(session, new ResolutionErrorPolicyRequest(artifact, repository));
+ }
+
+ public static int getPolicy(RepositorySystemSession session, Metadata metadata, RemoteRepository repository) {
+ ResolutionErrorPolicy rep = session.getResolutionErrorPolicy();
+ return rep == null ? 0 : rep.getMetadataPolicy(session, new ResolutionErrorPolicyRequest(metadata, repository));
+ }
+}
diff --git a/resolver/src/main/java/org/eclipse/aether/impl/ResolverArtifactResolver.java b/resolver/src/main/java/org/eclipse/aether/impl/ResolverArtifactResolver.java
new file mode 100644
index 0000000..822afad
--- /dev/null
+++ b/resolver/src/main/java/org/eclipse/aether/impl/ResolverArtifactResolver.java
@@ -0,0 +1,232 @@
+package org.eclipse.aether.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
+import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
+import org.eclipse.aether.internal.impl.DefaultDeployer;
+import org.eclipse.aether.internal.impl.DefaultFileProcessor;
+import org.eclipse.aether.internal.impl.DefaultInstaller;
+import org.eclipse.aether.internal.impl.DefaultLocalPathComposer;
+import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider;
+import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
+import org.eclipse.aether.internal.impl.DefaultOfflineController;
+import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
+import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider;
+import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher;
+import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
+import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
+import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle;
+import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
+import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
+import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager;
+import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
+import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
+import org.eclipse.aether.internal.impl.LocalPathComposer;
+import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.internal.impl.TrackingFileManager;
+import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector;
+import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
+import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
+import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
+import org.eclipse.aether.internal.impl.synccontext.legacy.DefaultSyncContextFactory;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
+import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
+import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
+import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
+import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
+import org.eclipse.aether.spi.connector.transport.TransporterProvider;
+import org.eclipse.aether.spi.io.FileProcessor;
+import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.log.LoggerFactory;
+
+public final class ResolverArtifactResolver implements ServiceLocator {
+ private final Map, Entry>> entries = new HashMap();
+ private ErrorHandler errorHandler;
+
+ public ResolverArtifactResolver() {
+ this.addService(RepositorySystem.class, DefaultRepositorySystem.class);
+ this.addService(DependencyCollector.class, DefaultDependencyCollector.class);
+ this.addService(Deployer.class, DefaultDeployer.class);
+ this.addService(Installer.class, DefaultInstaller.class);
+ this.addService(MetadataResolver.class, DefaultMetadataResolver.class);
+ this.addService(RepositoryLayoutProvider.class, DefaultRepositoryLayoutProvider.class);
+ this.addService(RepositoryLayoutFactory.class, Maven2RepositoryLayoutFactory.class);
+ this.addService(TransporterProvider.class, DefaultTransporterProvider.class);
+ this.addService(ChecksumPolicyProvider.class, DefaultChecksumPolicyProvider.class);
+ this.addService(RepositoryConnectorProvider.class, DefaultRepositoryConnectorProvider.class);
+ this.addService(RemoteRepositoryManager.class, DefaultRemoteRepositoryManager.class);
+ this.addService(UpdateCheckManager.class, DefaultUpdateCheckManager.class);
+ this.addService(UpdatePolicyAnalyzer.class, DefaultUpdatePolicyAnalyzer.class);
+ this.addService(FileProcessor.class, DefaultFileProcessor.class);
+ this.addService(SyncContextFactory.class, DefaultSyncContextFactory.class);
+ this.addService(org.eclipse.aether.spi.synccontext.SyncContextFactory.class, org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory.class);
+ this.addService(RepositoryEventDispatcher.class, DefaultRepositoryEventDispatcher.class);
+ this.addService(OfflineController.class, DefaultOfflineController.class);
+ this.addService(LocalRepositoryProvider.class, DefaultLocalRepositoryProvider.class);
+ this.addService(LocalRepositoryManagerFactory.class, SimpleLocalRepositoryManagerFactory.class);
+ this.addService(LocalRepositoryManagerFactory.class, EnhancedLocalRepositoryManagerFactory.class);
+ this.addService(LoggerFactory.class, Slf4jLoggerFactory.class);
+ this.addService(TrackingFileManager.class, DefaultTrackingFileManager.class);
+ this.addService(ChecksumAlgorithmFactorySelector.class, DefaultChecksumAlgorithmFactorySelector.class);
+ this.addService(LocalPathComposer.class, DefaultLocalPathComposer.class);
+ this.addService(RemoteRepositoryFilterManager.class, DefaultRemoteRepositoryFilterManager.class);
+ this.addService(RepositorySystemLifecycle.class, DefaultRepositorySystemLifecycle.class);
+ this.addService(NamedLockFactoryAdapterFactory.class, NamedLockFactoryAdapterFactoryImpl.class);
+ }
+
+ private Entry getEntry(Class type, boolean create) {
+ Entry entry = (Entry)this.entries.get(Objects.requireNonNull(type, "service type cannot be null"));
+ if (entry == null && create) {
+ entry = new Entry(type);
+ this.entries.put(type, entry);
+ }
+
+ return entry;
+ }
+
+ public ResolverArtifactResolver setService(Class type, Class extends T> impl) {
+ this.getEntry(type, true).setService(impl);
+ return this;
+ }
+
+ public ResolverArtifactResolver addService(Class type, Class extends T> impl) {
+ this.getEntry(type, true).addService(impl);
+ return this;
+ }
+
+ public ResolverArtifactResolver setServices(Class type, T... services) {
+ this.getEntry(type, true).setServices(services);
+ return this;
+ }
+
+ public T getService(Class type) {
+ Entry entry = this.getEntry(type, false);
+ return entry != null ? entry.getInstance() : null;
+ }
+
+ public List getServices(Class type) {
+ Entry entry = this.getEntry(type, false);
+ return entry != null ? entry.getInstances() : null;
+ }
+
+ private void serviceCreationFailed(Class> type, Class> impl, Throwable exception) {
+ if (this.errorHandler != null) {
+ this.errorHandler.serviceCreationFailed(type, impl, exception);
+ }
+
+ }
+
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
+
+ private class Entry {
+ private final Class type;
+ private final Collection