This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


The following commit(s) were added to refs/heads/master by this push:
     new 0766f6b3c Enhance RRF (#1709)
0766f6b3c is described below

commit 0766f6b3cc0eeee62569880c430a3a2fb5b2b2d8
Author: Tamas Cservenak <[email protected]>
AuthorDate: Thu Dec 11 16:20:36 2025 +0100

    Enhance RRF (#1709)
    
    Changes:
    * prefix: introduce "resolvePrefixFiles" config that controls 
auto-discovery (def: true; as before)
    * both: introduce "noInputOutcome" config that controls filtering outcome 
when enabled but no input provided (def: true; as before)
    * both: cleanup of configuration and use of helper classes
---
 .../GroupIdRemoteRepositoryFilterSource.java       | 79 +++++++++++++-------
 .../PrefixesRemoteRepositoryFilterSource.java      | 85 +++++++++++++++++-----
 .../RemoteRepositoryFilterSourceSupport.java       | 11 ++-
 .../internal/impl/filter/ruletree/GroupTree.java   |  2 -
 .../internal/impl/filter/ruletree/PrefixTree.java  |  2 -
 .../internal/impl/DefaultArtifactResolverTest.java |  6 +-
 .../internal/impl/DefaultMetadataResolverTest.java |  6 +-
 .../aether/internal/impl/filter/Filters.java       | 12 +--
 .../GroupIdRemoteRepositoryFilterSourceTest.java   |  7 ++
 .../PrefixesRemoteRepositoryFilterSourceTest.java  | 13 +++-
 .../RemoteRepositoryFilterSourceTestSupport.java   | 27 +++++++
 src/site/markdown/configuration.md                 |  3 +
 12 files changed, 191 insertions(+), 62 deletions(-)

diff --git 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSource.java
 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSource.java
index 32be14c79..dcf25d268 100644
--- 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSource.java
+++ 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSource.java
@@ -79,9 +79,6 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
         implements ArtifactResolverPostProcessor {
     public static final String NAME = "groupId";
 
-    private static final String CONFIG_PROPS_PREFIX =
-            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".";
-
     /**
      * Configuration to enable the GroupId filter (enabled by default). Can be 
fine-tuned per repository using
      * repository ID suffixes.
@@ -125,6 +122,24 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
 
     public static final boolean DEFAULT_SKIPPED = false;
 
+    /**
+     * Determines what happens when the filter is enabled, but has no groupId 
file available for given remote repository
+     * to work with. When set to {@code true} (default), the filter allows all 
requests to proceed for given remote
+     * repository when no groupId file is available. When set to {@code 
false}, the filter blocks all requests toward
+     * given remote repository when no groupId file is available. This setting 
allows repoId suffix, hence, can
+     * determine "global" or "repository targeted" behaviors.
+     *
+     * @since 2.0.14
+     * @configurationSource {@link 
RepositorySystemSession#getConfigProperties()}
+     * @configurationType {@link java.lang.Boolean}
+     * @configurationRepoIdSuffix Yes
+     * @configurationDefaultValue {@link #DEFAULT_NO_INPUT_OUTCOME}
+     */
+    public static final String CONFIG_PROP_NO_INPUT_OUTCOME =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".noInputOutcome";
+
+    public static final boolean DEFAULT_NO_INPUT_OUTCOME = true;
+
     /**
      * The basedir where to store filter files. If path is relative, it is 
resolved from local repository root.
      *
@@ -132,7 +147,8 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
      * @configurationType {@link java.lang.String}
      * @configurationDefaultValue {@link #LOCAL_REPO_PREFIX_DIR}
      */
-    public static final String CONFIG_PROP_BASEDIR = CONFIG_PROPS_PREFIX + 
"basedir";
+    public static final String CONFIG_PROP_BASEDIR =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".basedir";
 
     public static final String LOCAL_REPO_PREFIX_DIR = 
".remoteRepositoryFilters";
 
@@ -143,7 +159,8 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
      * @configurationType {@link java.lang.Boolean}
      * @configurationDefaultValue false
      */
-    public static final String CONFIG_PROP_RECORD = CONFIG_PROPS_PREFIX + 
"record";
+    public static final String CONFIG_PROP_RECORD =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".record";
 
     static final String GROUP_ID_FILE_PREFIX = "groupId-";
 
@@ -236,7 +253,7 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
                                 .add(line);
                         rules(session)
                                 .compute(normalized, (k, v) -> {
-                                    if (v == null || v == GroupTree.SENTINEL) {
+                                    if (v == null || v == DISABLED || v == 
ENABLED_NO_INPUT) {
                                         v = new GroupTree("");
                                     }
                                     return v;
@@ -260,6 +277,9 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
                         normalizeRemoteRepository(session, remoteRepository), 
r -> loadRepositoryRules(session, r));
     }
 
+    private static final GroupTree DISABLED = new GroupTree("disabled");
+    private static final GroupTree ENABLED_NO_INPUT = new 
GroupTree("enabled-no-input");
+
     private GroupTree loadRepositoryRules(RepositorySystemSession session, 
RemoteRepository remoteRepository) {
         if (isRepositoryFilteringEnabled(session, remoteRepository)) {
             Path filePath = ruleFile(session, remoteRepository);
@@ -277,10 +297,10 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
                 }
             }
             logger.debug("Group rules file for remote repository {} not 
available", remoteRepository);
-            return GroupTree.SENTINEL;
+            return ENABLED_NO_INPUT;
         }
         logger.debug("Group rules file for remote repository {} disabled", 
remoteRepository);
-        return GroupTree.SENTINEL;
+        return DISABLED;
     }
 
     private class GroupIdFilter implements RemoteRepositoryFilter {
@@ -291,35 +311,40 @@ public final class GroupIdRemoteRepositoryFilterSource 
extends RemoteRepositoryF
         }
 
         @Override
-        public Result acceptArtifact(RemoteRepository remoteRepository, 
Artifact artifact) {
-            return acceptGroupId(remoteRepository, artifact.getGroupId());
+        public Result acceptArtifact(RemoteRepository repository, Artifact 
artifact) {
+            return acceptGroupId(repository, artifact.getGroupId());
         }
 
         @Override
-        public Result acceptMetadata(RemoteRepository remoteRepository, 
Metadata metadata) {
-            return acceptGroupId(remoteRepository, metadata.getGroupId());
+        public Result acceptMetadata(RemoteRepository repository, Metadata 
metadata) {
+            return acceptGroupId(repository, metadata.getGroupId());
         }
 
-        private Result acceptGroupId(RemoteRepository remoteRepository, String 
groupId) {
-            GroupTree groupTree = cacheRules(session, remoteRepository);
-            if (GroupTree.SENTINEL == groupTree) {
-                return NOT_PRESENT_RESULT;
+        private Result acceptGroupId(RemoteRepository repository, String 
groupId) {
+            GroupTree groupTree = cacheRules(session, repository);
+            if (groupTree == DISABLED) {
+                return result(true, NAME, "Disabled");
+            } else if (groupTree == ENABLED_NO_INPUT) {
+                return result(
+                        ConfigUtils.getBoolean(
+                                session,
+                                DEFAULT_NO_INPUT_OUTCOME,
+                                CONFIG_PROP_NO_INPUT_OUTCOME + "." + 
repository.getId(),
+                                CONFIG_PROP_NO_INPUT_OUTCOME),
+                        NAME,
+                        "No input available");
             }
 
-            if (groupTree.acceptedGroupId(groupId)) {
-                return new SimpleResult(true, "G:" + groupId + " allowed from 
" + remoteRepository);
-            } else {
-                return new SimpleResult(false, "G:" + groupId + " NOT allowed 
from " + remoteRepository);
-            }
+            boolean accepted = groupTree.acceptedGroupId(groupId);
+            return result(
+                    accepted,
+                    NAME,
+                    accepted
+                            ? "G:" + groupId + " allowed from " + 
repository.getId()
+                            : "G:" + groupId + " NOT allowed from " + 
repository.getId());
         }
     }
 
-    /**
-     * Filter result when filter "stands aside" as it had no input.
-     */
-    private static final RemoteRepositoryFilter.Result NOT_PRESENT_RESULT =
-            new SimpleResult(true, "GroupId file not present");
-
     /**
      * Returns {@code true} if given session is recording.
      */
diff --git 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSource.java
 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSource.java
index c34c3f7fd..132973c4c 100644
--- 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSource.java
+++ 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSource.java
@@ -83,9 +83,6 @@ import static java.util.Objects.requireNonNull;
 public final class PrefixesRemoteRepositoryFilterSource extends 
RemoteRepositoryFilterSourceSupport {
     public static final String NAME = "prefixes";
 
-    private static final String CONFIG_PROPS_PREFIX =
-            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".";
-
     static final String PREFIX_FILE_TYPE = ".meta/prefixes.txt";
 
     /**
@@ -137,6 +134,39 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
 
     public static final boolean DEFAULT_SKIPPED = false;
 
+    /**
+     * Determines what happens when the filter is enabled, but has no prefixes 
available for given remote repository
+     * to work with. When set to {@code true} (default), the filter allows all 
requests to proceed for given remote
+     * repository when no prefixes are available. When set to {@code false}, 
the filter blocks all requests toward
+     * given remote repository when no prefixes are available. This setting 
allows repoId suffix, hence, can
+     * determine "global" or "repository targeted" behaviors.
+     *
+     * @since 2.0.14
+     * @configurationSource {@link 
RepositorySystemSession#getConfigProperties()}
+     * @configurationType {@link java.lang.Boolean}
+     * @configurationRepoIdSuffix Yes
+     * @configurationDefaultValue {@link #DEFAULT_NO_INPUT_OUTCOME}
+     */
+    public static final String CONFIG_PROP_NO_INPUT_OUTCOME =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".noInputOutcome";
+
+    public static final boolean DEFAULT_NO_INPUT_OUTCOME = true;
+
+    /**
+     * Configuration to allow Prefixes file resolution attempt from remote 
repository as "auto discovery". If this
+     * configuration set to {@code false} only user-provided prefixes will be 
used.
+     *
+     * @since 2.0.14
+     * @configurationSource {@link 
RepositorySystemSession#getConfigProperties()}
+     * @configurationType {@link java.lang.Boolean}
+     * @configurationRepoIdSuffix Yes
+     * @configurationDefaultValue {@link #DEFAULT_RESOLVE_PREFIX_FILES}
+     */
+    public static final String CONFIG_PROP_RESOLVE_PREFIX_FILES =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".resolvePrefixFiles";
+
+    public static final boolean DEFAULT_RESOLVE_PREFIX_FILES = true;
+
     /**
      * Configuration to allow Prefixes filter to auto-discover prefixes from 
mirrored repositories as well. For this to
      * work <em>Maven should be aware</em> that given remote repository is 
mirror and is usually backed by MRM. Given
@@ -179,7 +209,8 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
      * @configurationType {@link java.lang.String}
      * @configurationDefaultValue {@link #LOCAL_REPO_PREFIX_DIR}
      */
-    public static final String CONFIG_PROP_BASEDIR = CONFIG_PROPS_PREFIX + 
"basedir";
+    public static final String CONFIG_PROP_BASEDIR =
+            RemoteRepositoryFilterSourceSupport.CONFIG_PROPS_PREFIX + NAME + 
".basedir";
 
     public static final String LOCAL_REPO_PREFIX_DIR = 
".remoteRepositoryFilters";
 
@@ -272,6 +303,9 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
                         r -> loadPrefixTree(session, basedir, 
remoteRepository));
     }
 
+    private static final PrefixTree DISABLED = new PrefixTree("disabled");
+    private static final PrefixTree ENABLED_NO_INPUT = new 
PrefixTree("enabled-no-input");
+
     private PrefixTree loadPrefixTree(
             RepositorySystemSession session, Path baseDir, RemoteRepository 
remoteRepository) {
         if (isRepositoryFilteringEnabled(session, remoteRepository)) {
@@ -312,10 +346,10 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
                 }
             }
             logger.debug("Prefix file for remote repository {} not available", 
remoteRepository);
-            return PrefixTree.SENTINEL;
+            return ENABLED_NO_INPUT;
         }
         logger.debug("Prefix file for remote repository {} disabled", 
remoteRepository);
-        return PrefixTree.SENTINEL;
+        return DISABLED;
     }
 
     private Path resolvePrefixesFromLocalConfiguration(
@@ -331,6 +365,13 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
 
     private boolean supportedResolvePrefixesForRemoteRepository(
             RepositorySystemSession session, RemoteRepository 
remoteRepository) {
+        if (!ConfigUtils.getBoolean(
+                session,
+                DEFAULT_RESOLVE_PREFIX_FILES,
+                CONFIG_PROP_RESOLVE_PREFIX_FILES + "." + 
remoteRepository.getId(),
+                CONFIG_PROP_RESOLVE_PREFIX_FILES)) {
+            return false;
+        }
         if (remoteRepository.isRepositoryManager()) {
             return ConfigUtils.getBoolean(
                     session, DEFAULT_USE_REPOSITORY_MANAGERS, 
CONFIG_PROP_USE_REPOSITORY_MANAGERS);
@@ -383,7 +424,7 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
         public Result acceptArtifact(RemoteRepository remoteRepository, 
Artifact artifact) {
             RepositoryLayout repositoryLayout = cacheLayout(session, 
remoteRepository);
             if (repositoryLayout == NOT_SUPPORTED) {
-                return new SimpleResult(true, "Unsupported layout: " + 
remoteRepository);
+                return result(true, NAME, "Unsupported layout: " + 
remoteRepository);
             }
             return acceptPrefix(
                     remoteRepository,
@@ -394,7 +435,7 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
         public Result acceptMetadata(RemoteRepository remoteRepository, 
Metadata metadata) {
             RepositoryLayout repositoryLayout = cacheLayout(session, 
remoteRepository);
             if (repositoryLayout == NOT_SUPPORTED) {
-                return new SimpleResult(true, "Unsupported layout: " + 
remoteRepository);
+                return result(true, NAME, "Unsupported layout: " + 
remoteRepository);
             }
             return acceptPrefix(
                     remoteRepository,
@@ -403,20 +444,28 @@ public final class PrefixesRemoteRepositoryFilterSource 
extends RemoteRepository
 
         private Result acceptPrefix(RemoteRepository repository, String path) {
             PrefixTree prefixTree = cachePrefixTree(session, basedir, 
repository);
-            if (prefixTree == PrefixTree.SENTINEL) {
-                return NOT_PRESENT_RESULT;
-            }
-            if (prefixTree.acceptedPath(path)) {
-                return new SimpleResult(true, "Path " + path + " allowed from 
" + repository);
-            } else {
-                return new SimpleResult(false, "Path " + path + " NOT allowed 
from " + repository);
+            if (prefixTree == DISABLED) {
+                return result(true, NAME, "Disabled");
+            } else if (prefixTree == ENABLED_NO_INPUT) {
+                return result(
+                        ConfigUtils.getBoolean(
+                                session,
+                                DEFAULT_NO_INPUT_OUTCOME,
+                                CONFIG_PROP_NO_INPUT_OUTCOME + "." + 
repository.getId(),
+                                CONFIG_PROP_NO_INPUT_OUTCOME),
+                        NAME,
+                        "No input available");
             }
+            boolean accepted = prefixTree.acceptedPath(path);
+            return result(
+                    accepted,
+                    NAME,
+                    accepted
+                            ? "Path " + path + " allowed from " + 
repository.getId()
+                            : "Path " + path + " NOT allowed from " + 
repository.getId());
         }
     }
 
-    private static final RemoteRepositoryFilter.Result NOT_PRESENT_RESULT =
-            new SimpleResult(true, "Prefix file not present");
-
     private static final RepositoryLayout NOT_SUPPORTED = new 
RepositoryLayout() {
         @Override
         public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
diff --git 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceSupport.java
 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceSupport.java
index e97900d11..db576c107 100644
--- 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceSupport.java
+++ 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceSupport.java
@@ -129,12 +129,12 @@ public abstract class RemoteRepositoryFilterSourceSupport 
implements RemoteRepos
     /**
      * Simple {@link RemoteRepositoryFilter.Result} immutable implementation.
      */
-    protected static class SimpleResult implements 
RemoteRepositoryFilter.Result {
+    private static class SimpleResult implements RemoteRepositoryFilter.Result 
{
         private final boolean accepted;
 
         private final String reasoning;
 
-        public SimpleResult(boolean accepted, String reasoning) {
+        private SimpleResult(boolean accepted, String reasoning) {
             this.accepted = accepted;
             this.reasoning = requireNonNull(reasoning);
         }
@@ -149,4 +149,11 @@ public abstract class RemoteRepositoryFilterSourceSupport 
implements RemoteRepos
             return reasoning;
         }
     }
+
+    /**
+     * Visible for testing.
+     */
+    static RemoteRepositoryFilter.Result result(boolean accepted, String name, 
String message) {
+        return new SimpleResult(accepted, name + ": " + message);
+    }
 }
diff --git 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/GroupTree.java
 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/GroupTree.java
index 87d0023b1..7aaf74610 100644
--- 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/GroupTree.java
+++ 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/GroupTree.java
@@ -62,8 +62,6 @@ import static java.util.stream.Collectors.toList;
  * line is ignored.
  */
 public class GroupTree extends Node {
-    public static final GroupTree SENTINEL = new GroupTree("sentinel");
-
     private static final String ROOT = "*";
     private static final String MOD_EXCLUSION = "!";
     private static final String MOD_STOP = "=";
diff --git 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/PrefixTree.java
 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/PrefixTree.java
index c62b4360e..da11d65d4 100644
--- 
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/PrefixTree.java
+++ 
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/ruletree/PrefixTree.java
@@ -42,8 +42,6 @@ import static java.util.stream.Collectors.toList;
  * </ul>
  */
 public class PrefixTree extends Node {
-    public static final PrefixTree SENTINEL = new PrefixTree("sentinel");
-
     private static List<String> elementsOfPath(final String path) {
         return Arrays.stream(path.split("/")).filter(e -> 
!e.isEmpty()).collect(toList());
     }
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java
index 3dfce4f39..3fa7617d9 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java
@@ -293,7 +293,8 @@ public class DefaultArtifactResolverTest {
             assertFalse(result.getExceptions().isEmpty());
             assertInstanceOf(
                     ArtifactNotFoundException.class, 
result.getExceptions().get(0));
-            assertEquals("never-accept", 
result.getExceptions().get(0).getMessage());
+            assertEquals(
+                    "never-accept: never accept", 
result.getExceptions().get(0).getMessage());
 
             Artifact resolved = result.getArtifact();
             assertNull(resolved);
@@ -344,7 +345,8 @@ public class DefaultArtifactResolverTest {
             assertFalse(result.getExceptions().isEmpty());
             assertInstanceOf(
                     ArtifactNotFoundException.class, 
result.getExceptions().get(0));
-            assertEquals("never-accept-id", 
result.getExceptions().get(0).getMessage());
+            assertEquals(
+                    "never-accept-id: matched", 
result.getExceptions().get(0).getMessage());
 
             Artifact resolved = result.getArtifact();
             assertNull(resolved);
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultMetadataResolverTest.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultMetadataResolverTest.java
index ec52e82eb..6053a277e 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultMetadataResolverTest.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultMetadataResolverTest.java
@@ -340,7 +340,7 @@ public class DefaultMetadataResolverTest {
         assertSame(request, result.getRequest());
         assertNotNull(result.getException());
         assertInstanceOf(MetadataNotFoundException.class, 
result.getException());
-        assertEquals("never-accept", result.getException().getMessage());
+        assertEquals("never-accept: never accept", 
result.getException().getMessage());
         assertNull(result.getMetadata());
 
         connector.assertSeenExpected();
@@ -400,7 +400,9 @@ public class DefaultMetadataResolverTest {
         assertSame(request, result.getRequest());
         assertNotNull(result.getException());
         assertInstanceOf(MetadataNotFoundException.class, 
result.getException());
-        assertEquals("never-accept-" + repository.getId(), 
result.getException().getMessage());
+        assertEquals(
+                "never-accept-" + repository.getId() + ": matched",
+                result.getException().getMessage());
         assertNull(result.getMetadata());
 
         connector.assertSeenExpected();
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/Filters.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/Filters.java
index d9de53608..60292fa79 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/Filters.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/Filters.java
@@ -39,7 +39,7 @@ public final class Filters {
             }
 
             private final RemoteRepositoryFilter.Result RESULT =
-                    new RemoteRepositoryFilterSourceSupport.SimpleResult(true, 
getName());
+                    RemoteRepositoryFilterSourceSupport.result(true, 
getName(), "always accept");
 
             @Override
             public RemoteRepositoryFilter 
getRemoteRepositoryFilter(RepositorySystemSession session) {
@@ -68,10 +68,10 @@ public final class Filters {
             }
 
             private final RemoteRepositoryFilter.Result MATCHED =
-                    new RemoteRepositoryFilterSourceSupport.SimpleResult(true, 
getName());
+                    RemoteRepositoryFilterSourceSupport.result(true, 
getName(), "matched");
 
             private final RemoteRepositoryFilter.Result UNMATCHED =
-                    new 
RemoteRepositoryFilterSourceSupport.SimpleResult(false, getName());
+                    RemoteRepositoryFilterSourceSupport.result(false, 
getName(), "unmatched");
 
             @Override
             public RemoteRepositoryFilter 
getRemoteRepositoryFilter(RepositorySystemSession session) {
@@ -100,7 +100,7 @@ public final class Filters {
             }
 
             private final RemoteRepositoryFilter.Result RESULT =
-                    new 
RemoteRepositoryFilterSourceSupport.SimpleResult(false, getName());
+                    RemoteRepositoryFilterSourceSupport.result(false, 
getName(), "never accept");
 
             @Override
             public RemoteRepositoryFilter 
getRemoteRepositoryFilter(RepositorySystemSession session) {
@@ -129,10 +129,10 @@ public final class Filters {
             }
 
             private final RemoteRepositoryFilter.Result MATCHED =
-                    new 
RemoteRepositoryFilterSourceSupport.SimpleResult(false, getName());
+                    RemoteRepositoryFilterSourceSupport.result(false, 
getName(), "matched");
 
             private final RemoteRepositoryFilter.Result UNMATCHED =
-                    new RemoteRepositoryFilterSourceSupport.SimpleResult(true, 
getName());
+                    RemoteRepositoryFilterSourceSupport.result(true, 
getName(), "unmatched");
 
             @Override
             public RemoteRepositoryFilter 
getRemoteRepositoryFilter(RepositorySystemSession session) {
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSourceTest.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSourceTest.java
index 6bcbdaaf9..608773a31 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSourceTest.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSourceTest.java
@@ -55,6 +55,13 @@ public class GroupIdRemoteRepositoryFilterSourceTest extends 
RemoteRepositoryFil
                 Boolean.valueOf(enabled).toString());
     }
 
+    @Override
+    protected void setOutcome(DefaultRepositorySystemSession session, boolean 
outcome) {
+        session.setConfigProperty(
+                "aether.remoteRepositoryFilter." + 
GroupIdRemoteRepositoryFilterSource.NAME + ".noInputOutcome",
+                Boolean.valueOf(outcome).toString());
+    }
+
     protected void allowArtifact(
             DefaultRepositorySystemSession session, RemoteRepository 
remoteRepository, Artifact artifact) {
         DefaultRepositorySystemSession newSession = new 
DefaultRepositorySystemSession(session);
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSourceTest.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSourceTest.java
index 5db48616f..c469ba903 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSourceTest.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSourceTest.java
@@ -93,11 +93,22 @@ public class PrefixesRemoteRepositoryFilterSourceTest 
extends RemoteRepositoryFi
 
     @Override
     protected void enableSource(DefaultRepositorySystemSession session, 
boolean enabled) {
+        // disable resolving/auto discovery
+        session.setConfigProperty(
+                "aether.remoteRepositoryFilter." + 
PrefixesRemoteRepositoryFilterSource.NAME + ".resolvePrefixFiles",
+                Boolean.valueOf(false).toString());
         session.setConfigProperty(
                 "aether.remoteRepositoryFilter." + 
PrefixesRemoteRepositoryFilterSource.NAME,
                 Boolean.valueOf(enabled).toString());
     }
 
+    @Override
+    protected void setOutcome(DefaultRepositorySystemSession session, boolean 
outcome) {
+        session.setConfigProperty(
+                "aether.remoteRepositoryFilter." + 
PrefixesRemoteRepositoryFilterSource.NAME + ".noInputOutcome",
+                Boolean.valueOf(outcome).toString());
+    }
+
     @Override
     protected void allowArtifact(
             DefaultRepositorySystemSession session, RemoteRepository 
remoteRepository, Artifact artifact) {
@@ -131,6 +142,6 @@ public class PrefixesRemoteRepositoryFilterSourceTest 
extends RemoteRepositoryFi
         RemoteRepositoryFilter.Result result = filter.acceptArtifact(mirror, 
acceptedArtifact);
 
         assertTrue(result.isAccepted());
-        assertEquals("Prefix file not present", result.reasoning());
+        assertEquals("prefixes: No input available", result.reasoning());
     }
 }
diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceTestSupport.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceTestSupport.java
index c364aac3b..92caefcb0 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceTestSupport.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/filter/RemoteRepositoryFilterSourceTestSupport.java
@@ -56,6 +56,8 @@ public abstract class RemoteRepositoryFilterSourceTestSupport 
{
 
     protected abstract void enableSource(DefaultRepositorySystemSession 
session, boolean enabled);
 
+    protected abstract void setOutcome(DefaultRepositorySystemSession session, 
boolean enabled);
+
     protected abstract void allowArtifact(
             DefaultRepositorySystemSession session, RemoteRepository 
remoteRepository, Artifact artifact);
 
@@ -66,6 +68,31 @@ public abstract class 
RemoteRepositoryFilterSourceTestSupport {
         assertNull(filter);
     }
 
+    @Test
+    void enabledNoInput() {
+        enableSource(session, true);
+        RemoteRepositoryFilter filter = 
subject.getRemoteRepositoryFilter(session);
+        assertNotNull(filter);
+
+        RemoteRepositoryFilter.Result result = 
filter.acceptArtifact(remoteRepository, acceptedArtifact);
+
+        assertTrue(result.isAccepted());
+        assertTrue(result.reasoning().endsWith("No input available"));
+    }
+
+    @Test
+    void enabledNoInputAlteredOutcome() {
+        enableSource(session, true);
+        setOutcome(session, false);
+        RemoteRepositoryFilter filter = 
subject.getRemoteRepositoryFilter(session);
+        assertNotNull(filter);
+
+        RemoteRepositoryFilter.Result result = 
filter.acceptArtifact(remoteRepository, acceptedArtifact);
+
+        assertFalse(result.isAccepted());
+        assertTrue(result.reasoning().endsWith("No input available"));
+    }
+
     @Test
     void acceptedArtifact() {
         enableSource(session, true);
diff --git a/src/site/markdown/configuration.md 
b/src/site/markdown/configuration.md
index 295203c09..2e088bd0e 100644
--- a/src/site/markdown/configuration.md
+++ b/src/site/markdown/configuration.md
@@ -100,10 +100,13 @@ To modify this file, edit the template and regenerate.
 | `"aether.priority.implicit"` | `Boolean` | A flag indicating whether the 
priorities of pluggable extensions are implicitly given by their iteration 
order such that the first extension has the highest priority. If set, an 
extension's built-in priority as well as any corresponding 
<code>aether.priority.*</code> configuration properties are ignored when 
searching for a suitable implementation among the available extensions. This 
priority mode is meant for cases where the application will  [...]
 | `"aether.remoteRepositoryFilter.groupId"` | `Boolean` | Configuration to 
enable the GroupId filter (enabled by default). Can be fine-tuned per 
repository using repository ID suffixes. <strong>Important:</strong> For this 
filter to take effect, you must provide configuration files. Without 
configuration files, the enabled filter remains dormant and does not interfere 
with resolution. <strong>Configuration Files:</strong> <ul> <li>Location: 
Directory specified by <code>#CONFIG_PROP_BASED [...]
 | `"aether.remoteRepositoryFilter.groupId.basedir"` | `String` | The basedir 
where to store filter files. If path is relative, it is resolved from local 
repository root. |  `".remoteRepositoryFilters"`  | 1.9.0 |  No  | Session 
Configuration |
+| `"aether.remoteRepositoryFilter.groupId.noInputOutcome"` | `Boolean` | 
Determines what happens when the filter is enabled, but has no groupId file 
available for given remote repository to work with. When set to 
<code>true</code> (default), the filter allows all requests to proceed for 
given remote repository when no groupId file is available. When set to 
<code>false</code> , the filter blocks all requests toward given remote 
repository when no groupId file is available. This setting al [...]
 | `"aether.remoteRepositoryFilter.groupId.record"` | `Boolean` | Should filter 
go into "record" mode (and collect encountered artifacts)? |  `false`  | 1.9.0 
|  No  | Session Configuration |
 | `"aether.remoteRepositoryFilter.groupId.skipped"` | `Boolean` | 
Configuration to skip the GroupId filter for given request. This configuration 
is evaluated and if <code>true</code> the GroupId remote filter will not kick 
in. |  `false`  | 2.0.14 |  Yes  | Session Configuration |
 | `"aether.remoteRepositoryFilter.prefixes"` | `Boolean` | Configuration to 
enable the Prefixes filter (enabled by default). Can be fine-tuned per 
repository using repository ID suffixes. <strong>Important:</strong> For this 
filter to take effect, configuration files must be available. Without 
configuration files, the enabled filter remains dormant and does not interfere 
with resolution. <strong>Configuration File Resolution:</strong> <ol> 
<li><strong>User-provided files:</strong> Checke [...]
 | `"aether.remoteRepositoryFilter.prefixes.basedir"` | `String` | The basedir 
where to store filter files. If path is relative, it is resolved from local 
repository root. |  `".remoteRepositoryFilters"`  | 1.9.0 |  No  | Session 
Configuration |
+| `"aether.remoteRepositoryFilter.prefixes.noInputOutcome"` | `Boolean` | 
Determines what happens when the filter is enabled, but has no prefixes 
available for given remote repository to work with. When set to 
<code>true</code> (default), the filter allows all requests to proceed for 
given remote repository when no prefixes are available. When set to 
<code>false</code> , the filter blocks all requests toward given remote 
repository when no prefixes are available. This setting allows repo [...]
+| `"aether.remoteRepositoryFilter.prefixes.resolvePrefixFiles"` | `Boolean` | 
Configuration to allow Prefixes file resolution attempt from remote repository 
as "auto discovery". If this configuration set to <code>false</code> only 
user-provided prefixes will be used. |  `true`  | 2.0.14 |  Yes  | Session 
Configuration |
 | `"aether.remoteRepositoryFilter.prefixes.skipped"` | `Boolean` | 
Configuration to skip the Prefixes filter for given request. This configuration 
is evaluated and if <code>true</code> the prefixes remote filter will not kick 
in. Main use case is by filter itself, to prevent recursion during discovery of 
remote prefixes file, but this also allows other components to control prefix 
filter discovery, while leaving configuration like 
<code>#CONFIG_PROP_ENABLED</code> still show the "real st [...]
 | `"aether.remoteRepositoryFilter.prefixes.useMirroredRepositories"` | 
`Boolean` | Configuration to allow Prefixes filter to auto-discover prefixes 
from mirrored repositories as well. For this to work <em>Maven should be 
aware</em> that given remote repository is mirror and is usually backed by MRM. 
Given multiple MRM implementations messes up prefixes file, is better to just 
skip these. In other case, one may use <code>#CONFIG_PROP_ENABLED</code> with 
repository ID suffix. |  `false`  | [...]
 | `"aether.remoteRepositoryFilter.prefixes.useRepositoryManagers"` | `Boolean` 
| Configuration to allow Prefixes filter to auto-discover prefixes from 
repository managers as well. For this to work <em>Maven should be aware</em> 
that given remote repository is backed by repository manager. Given multiple 
MRM implementations messes up prefixes file, is better to just skip these. In 
other case, one may use <code>#CONFIG_PROP_ENABLED</code> with repository ID 
suffix. <em>Note: as of today, n [...]


Reply via email to