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);
     }
 }

Reply via email to