From 27b69969a5a358142c8d5636837bc3d907d7e703 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Fri, 10 Mar 2023 12:47:20 +0100 Subject: [PATCH 1/2] Update project to utilize maven resolver If implemented this will upgrade the project off of the deprecated sonatype aether dependency to maven-resolver. * update to latest resolver and maven (move off org.sonatype) * keep all almost untouched (but mark deprecations) --- pom.xml | 141 +++---- resolver-integration/pom.xml | 4 +- .../airlift/resolver/TestArtifactResolve.java | 3 +- resolver/pom.xml | 48 +-- .../io/airlift/resolver/ArtifactResolver.java | 75 ++-- .../io/airlift/resolver/DefaultArtifact.java | 357 ------------------ .../main/java/io/airlift/resolver/Main.java | 3 +- .../internal/ConsoleRepositoryListener.java | 4 +- .../internal/ConsoleTransferListener.java | 6 +- .../resolver/internal/Slf4jLogger.java | 141 ------- .../resolver/internal/Slf4jLoggerManager.java | 142 ------- .../resolver/ArtifactResolverTest.java | 6 +- 12 files changed, 151 insertions(+), 779 deletions(-) delete mode 100644 resolver/src/main/java/io/airlift/resolver/DefaultArtifact.java delete mode 100644 resolver/src/main/java/io/airlift/resolver/internal/Slf4jLogger.java delete mode 100644 resolver/src/main/java/io/airlift/resolver/internal/Slf4jLoggerManager.java diff --git a/pom.xml b/pom.xml index 8c48569..5d07039 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.airlift airbase - 80 + 134 io.airlift.resolver @@ -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..59464c1 100644 --- a/resolver-integration/pom.xml +++ b/resolver-integration/pom.xml @@ -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..f321641 100644 --- a/resolver/pom.xml +++ b/resolver/pom.xml @@ -16,44 +16,38 @@ - org.sonatype.aether - aether-spi + org.apache.maven.resolver + maven-resolver-spi - org.sonatype.aether - aether-api + org.apache.maven.resolver + maven-resolver-api - org.sonatype.aether - aether-impl + org.apache.maven.resolver + maven-resolver-impl - org.sonatype.aether - aether-util + org.apache.maven.resolver + maven-resolver-util - org.sonatype.aether - aether-connector-file + org.apache.maven.resolver + maven-resolver-connector-basic - org.sonatype.aether - aether-connector-asynchttpclient + org.apache.maven.resolver + maven-resolver-transport-file - io.netty - netty - runtime - - - - org.apache.maven - maven-core + org.apache.maven.resolver + maven-resolver-transport-http @@ -68,18 +62,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 +81,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..4e1868c 100644 --- a/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java +++ b/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java @@ -17,40 +17,42 @@ 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 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.MavenRepositorySystemUtils; 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.DefaultServiceLocator; +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,7 +81,7 @@ public class ArtifactResolver .build(); private final RepositorySystem repositorySystem; - private final MavenRepositorySystemSession repositorySystemSession; + private final DefaultRepositorySystemSession repositorySystemSession; private final List repositories; public ArtifactResolver(String localRepositoryDir, String... remoteRepositoryUris) @@ -89,15 +91,16 @@ 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 + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.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()); @@ -105,7 +108,7 @@ public ArtifactResolver(String localRepositoryDir, List remoteRepository 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 +127,7 @@ public List resolveArtifacts(Iterable 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 +156,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); } @@ -187,6 +190,7 @@ public List resolvePom(File pomFile) private MavenProject getMavenProject(File pomFile) { + // TODO: move off deprecated org.apache.maven.repository.RepositorySystem (impl is in maven2 compat module) try { PlexusContainer container = container(); org.apache.maven.repository.RepositorySystem lrs = container.lookup(org.apache.maven.repository.RepositorySystem.class); @@ -285,12 +289,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 +305,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/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/test/java/io/airlift/resolver/ArtifactResolverTest.java b/resolver/src/test/java/io/airlift/resolver/ArtifactResolverTest.java index f59562b..79a1de4 100644 --- a/resolver/src/test/java/io/airlift/resolver/ArtifactResolverTest.java +++ b/resolver/src/test/java/io/airlift/resolver/ArtifactResolverTest.java @@ -14,9 +14,9 @@ package io.airlift.resolver; import com.google.common.collect.ImmutableList; -import org.sonatype.aether.artifact.Artifact; -import org.sonatype.aether.resolution.DependencyResolutionException; -import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.resolution.DependencyResolutionException; import org.testng.Assert; import org.testng.annotations.Test; From 8e148ee3c2b02cdd99f5c9f53f6e48040927e1d1 Mon Sep 17 00:00:00 2001 From: Hazmi Date: Mon, 28 Oct 2024 21:31:19 +0300 Subject: [PATCH 2/2] Match functionality If merged, this PR will match the functionality that was previously provided by the old sonatype version. Remove downloadable check Move project builder instantiation to speed up resolution --- .github/workflows/maven.yml | 30 + pom.xml | 26 +- resolver-integration/pom.xml | 5 +- resolver/pom.xml | 8 +- .../io/airlift/resolver/ArtifactResolver.java | 48 +- .../internal/DefaultArtifactResolver.java | 660 ++++++++++++++++++ .../internal/SafeTransferListener.java | 112 +++ .../io/airlift/resolver/internal/Utils.java | 28 + .../aether/impl/ResolverArtifactResolver.java | 232 ++++++ resolver/src/test/poms/maven-core-3.0.4.pom | 80 +-- 10 files changed, 1138 insertions(+), 91 deletions(-) create mode 100644 .github/workflows/maven.yml create mode 100644 resolver/src/main/java/io/airlift/resolver/internal/DefaultArtifactResolver.java create mode 100644 resolver/src/main/java/io/airlift/resolver/internal/SafeTransferListener.java create mode 100644 resolver/src/main/java/io/airlift/resolver/internal/Utils.java create mode 100644 resolver/src/main/java/org/eclipse/aether/impl/ResolverArtifactResolver.java diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..003da7d --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,30 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +name: Java CI with Maven + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + show-progress: false + # needed for the git-commit-id-plugin to work + fetch-depth: 0 + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + cache: maven + - name: Maven verify + run: mvn verify \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5d07039..d0abab4 100644 --- a/pom.xml +++ b/pom.xml @@ -2,12 +2,12 @@ 4.0.0 - io.airlift + com.facebook.airlift airbase - 134 + 102 - io.airlift.resolver + com.facebook.airlift.resolver resolver-root 1.7-SNAPSHOT pom @@ -37,7 +37,7 @@ - io.airlift.resolver + com.facebook.airlift.resolver resolver ${project.version} @@ -129,6 +129,24 @@ 3.5.1 + + org.slf4j + jcl-over-slf4j + 1.7.36 + + + + org.slf4j + slf4j-api + 1.7.36 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + javax.inject diff --git a/resolver-integration/pom.xml b/resolver-integration/pom.xml index 59464c1..ea5ffc3 100644 --- a/resolver-integration/pom.xml +++ b/resolver-integration/pom.xml @@ -2,12 +2,11 @@ 4.0.0 - io.airlift.resolver + com.facebook.airlift.resolver resolver-root 1.7-SNAPSHOT - io.airlift.resolver resolver-integration jar @@ -18,7 +17,7 @@ - io.airlift.resolver + com.facebook.airlift.resolver resolver test diff --git a/resolver/pom.xml b/resolver/pom.xml index f321641..8da9e1c 100644 --- a/resolver/pom.xml +++ b/resolver/pom.xml @@ -2,12 +2,11 @@ 4.0.0 - io.airlift.resolver + com.facebook.airlift.resolver resolver-root 1.7-SNAPSHOT - io.airlift.resolver resolver @@ -15,6 +14,11 @@ + + javax.inject + javax.inject + + org.apache.maven.resolver maven-resolver-spi diff --git a/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java b/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java index 4e1868c..3161374 100644 --- a/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java +++ b/resolver/src/main/java/io/airlift/resolver/ArtifactResolver.java @@ -17,13 +17,19 @@ import com.google.common.collect.ImmutableSet; import io.airlift.resolver.internal.ConsoleRepositoryListener; import io.airlift.resolver.internal.ConsoleTransferListener; +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.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; @@ -40,7 +46,11 @@ import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.impl.DefaultServiceLocator; +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; @@ -84,6 +94,10 @@ public class ArtifactResolver 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)); @@ -92,9 +106,15 @@ public ArtifactResolver(String localRepositoryDir, String... remoteRepositoryUri public ArtifactResolver(String localRepositoryDir, List remoteRepositoryUris) { // TODO: move off deprecated ServiceLocator, use Sisu instead - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + 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( TransporterFactory.class, FileTransporterFactory.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); @@ -105,6 +125,9 @@ public ArtifactResolver(String localRepositoryDir, List remoteRepository 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) { @@ -188,9 +211,8 @@ public List resolvePom(File pomFile) .collect(toImmutableList()); } - private MavenProject getMavenProject(File pomFile) + private void buildProjectBuilder() { - // TODO: move off deprecated org.apache.maven.repository.RepositorySystem (impl is in maven2 compat module) try { PlexusContainer container = container(); org.apache.maven.repository.RepositorySystem lrs = container.lookup(org.apache.maven.repository.RepositorySystem.class); @@ -201,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) { 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 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 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/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 impl) { + this.getEntry(type, true).setService(impl); + return this; + } + + public ResolverArtifactResolver addService(Class type, Class 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 providers; + private List instances; + + Entry(Class type) { + this.type = (Class)Objects.requireNonNull(type, "service type cannot be null"); + this.providers = new LinkedHashSet(8); + } + + public synchronized void setServices(T... services) { + this.providers.clear(); + if (services != null) { + Object[] var2 = services; + int var3 = services.length; + + for(int var4 = 0; var4 < var3; ++var4) { + T service = (T) var2[var4]; + this.providers.add(Objects.requireNonNull(service, "service instance cannot be null")); + } + } + + this.instances = null; + } + + public synchronized void setService(Class impl) { + this.providers.clear(); + this.addService(impl); + } + + public synchronized void addService(Class impl) { + this.providers.add(Objects.requireNonNull(impl, "implementation class cannot be null")); + this.instances = null; + } + + public T getInstance() { + List instances = this.getInstances(); + return instances.isEmpty() ? null : instances.get(0); + } + + public synchronized List getInstances() { + if (this.instances == null) { + this.instances = new ArrayList(this.providers.size()); + Iterator var1 = this.providers.iterator(); + + while(var1.hasNext()) { + Object provider = var1.next(); + Object instance; + if (provider instanceof Class) { + instance = this.newInstance((Class)provider); + } else { + instance = this.type.cast(provider); + } + + if (instance != null) { + this.instances.add((T) instance); + } + } + + this.instances = Collections.unmodifiableList(this.instances); + } + + return this.instances; + } + + private T newInstance(Class impl) { + try { + Constructor constr = impl.getDeclaredConstructor(); + if (!Modifier.isPublic(constr.getModifiers())) { + constr.setAccessible(true); + } + + Object obj = constr.newInstance(); + T instance = this.type.cast(obj); + if (instance instanceof Service) { + ((Service)instance).initService(ResolverArtifactResolver.this); + } + + return instance; + } catch (LinkageError | Exception var5) { + Throwable e = var5; + ResolverArtifactResolver.this.serviceCreationFailed(this.type, impl, e); + return null; + } + } + } + + public abstract static class ErrorHandler { + public ErrorHandler() { + } + + public void serviceCreationFailed(Class type, Class impl, Throwable exception) { + } + } +} diff --git a/resolver/src/test/poms/maven-core-3.0.4.pom b/resolver/src/test/poms/maven-core-3.0.4.pom index e117192..157f00d 100644 --- a/resolver/src/test/poms/maven-core-3.0.4.pom +++ b/resolver/src/test/poms/maven-core-3.0.4.pom @@ -24,84 +24,12 @@ Maven Core Maven Core classes. + - - - org.apache.maven - maven-model - - - org.apache.maven - maven-settings - - - org.apache.maven - maven-settings-builder - - - org.apache.maven - maven-repository-metadata - - - org.apache.maven - maven-artifact - - - org.apache.maven - maven-plugin-api - - - org.apache.maven - maven-model-builder - - - org.apache.maven - maven-aether-provider - - - org.sonatype.aether - aether-impl - ${aetherVersion} - - - org.sonatype.aether - aether-api - ${aetherVersion} - - - org.sonatype.aether - aether-util - ${aetherVersion} - - - - org.sonatype.sisu - sisu-inject-plexus - - - org.codehaus.plexus - plexus-interpolation - - - org.codehaus.plexus - plexus-utils - - - org.codehaus.plexus - plexus-classworlds - - - org.codehaus.plexus - plexus-component-annotations - - - org.sonatype.plexus - plexus-sec-dispatcher - - commons-jxpath - commons-jxpath - test + org.eclipse.jetty + jetty-io + 9.4.56.v20240826