This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/transporter-properties in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
commit cd0936744734f8a5bf435d7e22ea60e907414173 Author: Konrad Windszus <[email protected]> AuthorDate: Wed Jan 28 11:33:10 2026 +0100 Expose transporter details per protocol Instead of purely relying on exception handling when a transporter cannot deal with a certain kind of repository an in advance check on the repository protocol is introduced This closes #1770 --- .../internal/impl/DefaultTransporterProvider.java | 7 +++++ .../connector/transport/TransporterFactory.java | 32 ++++++++++++++++++++++ .../transport/http/HttpTransporterFactory.java | 5 ++++ .../test/util/http/HttpTransporterTest.java | 3 +- .../transport/apache/ApacheTransporterFactory.java | 16 +---------- .../classpath/ClasspathTransporterFactory.java | 9 +++--- .../classpath/ClasspathTransporterTest.java | 9 +++--- .../transport/jdk/JdkTransporterFactory.java | 5 +--- .../transport/jetty/JettyTransporterFactory.java | 5 +--- 9 files changed, 59 insertions(+), 32 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTransporterProvider.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTransporterProvider.java index 615cfad7e..99cf8f87b 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTransporterProvider.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTransporterProvider.java @@ -66,6 +66,13 @@ public final class DefaultTransporterProvider implements TransporterProvider { List<NoTransporterException> errors = new ArrayList<>(); for (PrioritizedComponent<TransporterFactory> factory : factories.getEnabled()) { + if (!factory.getComponent().canHandle(repository.getProtocol())) { + LOGGER.debug( + "Transporter factory {} cannot deal with protocol {}", + factory.getComponent(), + repository.getProtocol()); + continue; + } try { Transporter transporter = factory.getComponent().newInstance(session, repository); diff --git a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/TransporterFactory.java b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/TransporterFactory.java index 49886e4b8..3f46dcfae 100644 --- a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/TransporterFactory.java +++ b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/TransporterFactory.java @@ -18,6 +18,8 @@ */ package org.eclipse.aether.spi.connector.transport; +import java.util.Map; + import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.transfer.NoTransporterException; @@ -31,9 +33,39 @@ import org.eclipse.aether.transfer.NoTransporterException; */ public interface TransporterFactory { + /** + * A key for transporter properties. + * @see #getProperties() + */ + public interface TransporterPropertyKey {} + + /** + * Indicates whether this factory can handle the specified repository protocol. + * Even if {@code true} is returned the factory may still refuse to create a transporter for the given protocol. + * + * @param repositoryProtocol The repository protocol to check, may be {@code null}. + * @return {@code true} if this factory can potentially handle the specified repository protocol, {@code false} otherwise. + * @see #newInstance(RepositorySystemSession, RemoteRepository) + */ + default boolean canHandle(String repositoryProtocol) { + return true; + } + + /** + * Gets the properties exposing information about this transporter factory. + * Some are mandatory and some are transporter-specific. + * + * @return A map of transporter property keys with values, never {@code null}. + * @throws UnsupportedOperationException if the transporter factory does not implement this method. + */ + default Map<TransporterPropertyKey, Object> getProperties() { + throw new UnsupportedOperationException("getProperties not implemented"); + } + /** * Tries to create a transporter for the specified remote repository. Typically, a factory will inspect * {@link RemoteRepository#getProtocol()} to determine whether it can handle a repository. + * This should be preceded by a call to {@link #canHandle(String)}. * * @param session The repository system session from which to configure the transporter, must not be {@code null}. * In particular, a transporter should obey the timeouts configured for the session. diff --git a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/http/HttpTransporterFactory.java b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/http/HttpTransporterFactory.java index a3c64bc5b..bf1547982 100644 --- a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/http/HttpTransporterFactory.java +++ b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/http/HttpTransporterFactory.java @@ -30,6 +30,11 @@ import org.eclipse.aether.transfer.NoTransporterException; */ public interface HttpTransporterFactory extends TransporterFactory { + @Override + default boolean canHandle(String repositoryProtocol) { + return "http".equalsIgnoreCase(repositoryProtocol) || "https".equalsIgnoreCase(repositoryProtocol); + } + /** * Tries to create HTTP transporter for the specified remote repository. * diff --git a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java index 316657d43..0bf9813b7 100644 --- a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java +++ b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java @@ -72,6 +72,7 @@ import org.junit.jupiter.params.provider.ValueSource; import static java.util.Objects.requireNonNull; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -1399,7 +1400,7 @@ public abstract class HttpTransporterTest { @Test void testInit_BadProtocol() { - assertThrows(NoTransporterException.class, () -> newTransporter("bad:/void")); + assertFalse(factory.canHandle("bad:/void")); } @Test diff --git a/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporterFactory.java b/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporterFactory.java index 3a3424a15..00909179c 100644 --- a/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporterFactory.java +++ b/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporterFactory.java @@ -56,27 +56,13 @@ public final class ApacheTransporterFactory implements HttpTransporterFactory { return priority; } - /** - * Sets the priority of this component. - * - * @param priority The priority. - * @return This component for chaining, never {@code null}. - */ - public ApacheTransporterFactory setPriority(float priority) { - this.priority = priority; - return this; - } - @Override public HttpTransporter newInstance(RepositorySystemSession session, RemoteRepository repository) throws NoTransporterException { requireNonNull(session, "session cannot be null"); requireNonNull(repository, "repository cannot be null"); - if (!"http".equalsIgnoreCase(repository.getProtocol()) && !"https".equalsIgnoreCase(repository.getProtocol())) { - throw new NoTransporterException(repository); - } - + // repository protocol already checked in canHandle return new ApacheTransporter(repository, session, checksumExtractor, pathProcessor); } } diff --git a/maven-resolver-transport-classpath/src/main/java/org/eclipse/aether/transport/classpath/ClasspathTransporterFactory.java b/maven-resolver-transport-classpath/src/main/java/org/eclipse/aether/transport/classpath/ClasspathTransporterFactory.java index 646dadbe2..b94d96610 100644 --- a/maven-resolver-transport-classpath/src/main/java/org/eclipse/aether/transport/classpath/ClasspathTransporterFactory.java +++ b/maven-resolver-transport-classpath/src/main/java/org/eclipse/aether/transport/classpath/ClasspathTransporterFactory.java @@ -69,16 +69,17 @@ public final class ClasspathTransporterFactory implements TransporterFactory { return this; } + @Override + public boolean canHandle(String repositoryProtocol) { + return "classpath".equalsIgnoreCase(repositoryProtocol); + } + @Override public Transporter newInstance(RepositorySystemSession session, RemoteRepository repository) throws NoTransporterException { requireNonNull(session, "session cannot be null"); requireNonNull(repository, "repository cannot be null"); - if (!"classpath".equalsIgnoreCase(repository.getProtocol())) { - throw new NoTransporterException(repository); - } - return new ClasspathTransporter(session, repository); } } diff --git a/maven-resolver-transport-classpath/src/test/java/org/eclipse/aether/transport/classpath/ClasspathTransporterTest.java b/maven-resolver-transport-classpath/src/test/java/org/eclipse/aether/transport/classpath/ClasspathTransporterTest.java index dc0d499f4..37f1f2f14 100644 --- a/maven-resolver-transport-classpath/src/test/java/org/eclipse/aether/transport/classpath/ClasspathTransporterTest.java +++ b/maven-resolver-transport-classpath/src/test/java/org/eclipse/aether/transport/classpath/ClasspathTransporterTest.java @@ -32,7 +32,6 @@ import org.eclipse.aether.spi.connector.transport.PeekTask; import org.eclipse.aether.spi.connector.transport.PutTask; import org.eclipse.aether.spi.connector.transport.Transporter; import org.eclipse.aether.spi.connector.transport.TransporterFactory; -import org.eclipse.aether.transfer.NoTransporterException; import org.eclipse.aether.transfer.TransferCancelledException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -59,7 +58,9 @@ public class ClasspathTransporterTest { transporter.close(); transporter = null; } - transporter = factory.newInstance(session, newRepo(url)); + RemoteRepository repo = newRepo(url); + assertTrue(factory.canHandle(repo.getProtocol())); + transporter = factory.newInstance(session, repo); } @BeforeEach @@ -259,8 +260,8 @@ public class ClasspathTransporterTest { } @Test - void testInit_BadProtocol() { - assertThrows(NoTransporterException.class, () -> newTransporter("bad:/void")); + void testCanHandle_BadProtocol() { + assertFalse(factory.canHandle("bad:/void")); } @Test diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java index bfc3c2098..044652a7a 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java +++ b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java @@ -68,10 +68,7 @@ public final class JdkTransporterFactory implements HttpTransporterFactory { requireNonNull(session, "session cannot be null"); requireNonNull(repository, "repository cannot be null"); - if (!"http".equalsIgnoreCase(repository.getProtocol()) && !"https".equalsIgnoreCase(repository.getProtocol())) { - throw new NoTransporterException(repository); - } - + // repository protocol already checked in canHandle return new JdkTransporter(session, repository, javaVersion(), checksumExtractor, pathProcessor); } diff --git a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporterFactory.java b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporterFactory.java index 83ecafce8..9dd9a898b 100644 --- a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporterFactory.java +++ b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporterFactory.java @@ -68,10 +68,7 @@ public final class JettyTransporterFactory implements HttpTransporterFactory { requireNonNull(session, "session cannot be null"); requireNonNull(repository, "repository cannot be null"); - if (!"http".equalsIgnoreCase(repository.getProtocol()) && !"https".equalsIgnoreCase(repository.getProtocol())) { - throw new NoTransporterException(repository); - } - + // repository protocol already checked in canHandle return new JettyTransporter(session, repository, checksumExtractor, pathProcessor); } }
