You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2022/09/13 18:24:41 UTC
[maven-resolver] branch remote-repository-filter updated: First sketch
This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch remote-repository-filter
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/remote-repository-filter by this push:
new 7d1cf6d6 First sketch
7d1cf6d6 is described below
commit 7d1cf6d66322cecdc8e1345907f6158df3a38a27
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Tue Sep 13 20:24:24 2022 +0200
First sketch
---
.../eclipse/aether/impl/DefaultServiceLocator.java | 3 +
.../internal/impl/DefaultArtifactResolver.java | 48 +++++++--
.../internal/impl/DefaultMetadataResolver.java | 24 ++++-
.../DefaultRemoteRepositoryFilterSource.java | 78 ++++++++++++++
.../impl/filter/FilteringRepositoryConnector.java | 113 +++++++++++++++++++++
.../internal/impl/DefaultArtifactResolverTest.java | 2 +
.../internal/impl/DefaultMetadataResolverTest.java | 2 +
.../connector/filter/RemoteRepositoryFilter.java | 51 ++++++++++
.../filter/RemoteRepositoryFilterSource.java | 35 +++++++
9 files changed, 346 insertions(+), 10 deletions(-)
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
index 815c07cd..4a3e2b05 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
@@ -56,12 +56,14 @@ import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterSource;
import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactorySelector;
import org.eclipse.aether.internal.impl.synccontext.named.SimpleNamedLockFactorySelector;
import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
import org.eclipse.aether.spi.connector.transport.TransporterProvider;
@@ -230,6 +232,7 @@ public final class DefaultServiceLocator
addService( NamedLockFactorySelector.class, SimpleNamedLockFactorySelector.class );
addService( ChecksumAlgorithmFactorySelector.class, DefaultChecksumAlgorithmFactorySelector.class );
addService( LocalPathComposer.class, DefaultLocalPathComposer.class );
+ addService( RemoteRepositoryFilterSource.class, DefaultRemoteRepositoryFilterSource.class );
}
private <T> Entry<T> getEntry( Class<T> type, boolean create )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java
index 430ea381..52e948c3 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java
@@ -45,6 +45,8 @@ import org.eclipse.aether.impl.OfflineController;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.impl.RepositoryConnectorProvider;
import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
import org.eclipse.aether.spi.synccontext.SyncContextFactory;
import org.eclipse.aether.impl.UpdateCheck;
import org.eclipse.aether.impl.UpdateCheckManager;
@@ -106,6 +108,8 @@ public class DefaultArtifactResolver
private OfflineController offlineController;
+ private RemoteRepositoryFilterSource remoteRepositoryFilterSource;
+
public DefaultArtifactResolver()
{
// enables default constructor
@@ -117,7 +121,8 @@ public class DefaultArtifactResolver
VersionResolver versionResolver, UpdateCheckManager updateCheckManager,
RepositoryConnectorProvider repositoryConnectorProvider,
RemoteRepositoryManager remoteRepositoryManager, SyncContextFactory syncContextFactory,
- OfflineController offlineController )
+ OfflineController offlineController,
+ RemoteRepositoryFilterSource remoteRepositoryFilterSource )
{
setFileProcessor( fileProcessor );
setRepositoryEventDispatcher( repositoryEventDispatcher );
@@ -127,6 +132,7 @@ public class DefaultArtifactResolver
setRemoteRepositoryManager( remoteRepositoryManager );
setSyncContextFactory( syncContextFactory );
setOfflineController( offlineController );
+ setRemoteRepositoryFilterSource( remoteRepositoryFilterSource );
}
public void initService( ServiceLocator locator )
@@ -139,6 +145,7 @@ public class DefaultArtifactResolver
setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
setOfflineController( locator.getService( OfflineController.class ) );
+ setRemoteRepositoryFilterSource( locator.getService( RemoteRepositoryFilterSource.class ) );
}
/**
@@ -203,6 +210,14 @@ public class DefaultArtifactResolver
return this;
}
+ public DefaultArtifactResolver setRemoteRepositoryFilterSource(
+ RemoteRepositoryFilterSource remoteRepositoryFilterSource )
+ {
+ this.remoteRepositoryFilterSource = requireNonNull( remoteRepositoryFilterSource,
+ "remote repository filter source cannot be null" );
+ return this;
+ }
+
public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request )
throws ArtifactResolutionException
{
@@ -257,7 +272,21 @@ public class DefaultArtifactResolver
results.add( result );
Artifact artifact = request.getArtifact();
- List<RemoteRepository> repos = request.getRepositories();
+
+ RemoteRepositoryFilter filter = remoteRepositoryFilterSource.getRemoteRepositoryFilter( session );
+ List<RemoteRepository> filteredRepos = new ArrayList<>( request.getRepositories().size() );
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ if ( !filter.acceptArtifact( repository, artifact ) )
+ {
+ result.addException( new ArtifactNotFoundException( artifact, repository,
+ "Artifact " + artifact + " not allowed from " + repository ) );
+ }
+ else
+ {
+ filteredRepos.add( repository );
+ }
+ }
artifactResolving( session, trace, artifact );
@@ -283,7 +312,8 @@ public class DefaultArtifactResolver
VersionResult versionResult;
try
{
- VersionRequest versionRequest = new VersionRequest( artifact, repos, request.getRequestContext() );
+ VersionRequest versionRequest = new VersionRequest( artifact, filteredRepos,
+ request.getRequestContext() );
versionRequest.setTrace( trace );
versionResult = versionResolver.resolveVersion( session, versionRequest );
}
@@ -299,11 +329,11 @@ public class DefaultArtifactResolver
{
if ( versionResult.getRepository() instanceof RemoteRepository )
{
- repos = Collections.singletonList( (RemoteRepository) versionResult.getRepository() );
+ filteredRepos = Collections.singletonList( (RemoteRepository) versionResult.getRepository() );
}
else
{
- repos = Collections.emptyList();
+ filteredRepos = Collections.emptyList();
}
}
@@ -321,7 +351,7 @@ public class DefaultArtifactResolver
}
LocalArtifactResult local =
- lrm.find( session, new LocalArtifactRequest( artifact, repos, request.getRequestContext() ) );
+ lrm.find( session, new LocalArtifactRequest( artifact, filteredRepos, request.getRequestContext() ) );
if ( isLocallyInstalled( local, versionResult ) )
{
if ( local.getRepository() != null )
@@ -356,13 +386,13 @@ public class DefaultArtifactResolver
}
else if ( local.getFile() != null )
{
- LOGGER.debug( "Verifying availability of {} from {}", local.getFile(), repos );
+ LOGGER.debug( "Verifying availability of {} from {}", local.getFile(), filteredRepos );
}
- LOGGER.debug( "Resolving artifact {} from {}", artifact, repos );
+ LOGGER.debug( "Resolving artifact {} from {}", artifact, filteredRepos );
AtomicBoolean resolved = new AtomicBoolean( false );
Iterator<ResolutionGroup> groupIt = groups.iterator();
- for ( RemoteRepository repo : repos )
+ for ( RemoteRepository repo : filteredRepos )
{
if ( !repo.getPolicy( artifact.isSnapshot() ).isEnabled() )
{
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultMetadataResolver.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultMetadataResolver.java
index f65f0c2f..9fc81320 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultMetadataResolver.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultMetadataResolver.java
@@ -47,6 +47,7 @@ import org.eclipse.aether.impl.OfflineController;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.impl.RepositoryConnectorProvider;
import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
import org.eclipse.aether.spi.synccontext.SyncContextFactory;
import org.eclipse.aether.impl.UpdateCheck;
import org.eclipse.aether.impl.UpdateCheckManager;
@@ -95,6 +96,8 @@ public class DefaultMetadataResolver
private OfflineController offlineController;
+ private RemoteRepositoryFilterSource remoteRepositoryFilterSource;
+
public DefaultMetadataResolver()
{
// enables default constructor
@@ -105,7 +108,8 @@ public class DefaultMetadataResolver
UpdateCheckManager updateCheckManager,
RepositoryConnectorProvider repositoryConnectorProvider,
RemoteRepositoryManager remoteRepositoryManager, SyncContextFactory syncContextFactory,
- OfflineController offlineController )
+ OfflineController offlineController,
+ RemoteRepositoryFilterSource remoteRepositoryFilterSource )
{
setRepositoryEventDispatcher( repositoryEventDispatcher );
setUpdateCheckManager( updateCheckManager );
@@ -113,6 +117,7 @@ public class DefaultMetadataResolver
setRemoteRepositoryManager( remoteRepositoryManager );
setSyncContextFactory( syncContextFactory );
setOfflineController( offlineController );
+ setRemoteRepositoryFilterSource( remoteRepositoryFilterSource );
}
public void initService( ServiceLocator locator )
@@ -123,6 +128,7 @@ public class DefaultMetadataResolver
setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
setOfflineController( locator.getService( OfflineController.class ) );
+ setRemoteRepositoryFilterSource( locator.getService( RemoteRepositoryFilterSource.class ) );
}
public DefaultMetadataResolver setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher )
@@ -165,6 +171,14 @@ public class DefaultMetadataResolver
return this;
}
+ public DefaultMetadataResolver setRemoteRepositoryFilterSource(
+ RemoteRepositoryFilterSource remoteRepositoryFilterSource )
+ {
+ this.remoteRepositoryFilterSource = requireNonNull( remoteRepositoryFilterSource,
+ "remote repository filter cannot be null" );
+ return this;
+ }
+
public List<MetadataResult> resolveMetadata( RepositorySystemSession session,
Collection<? extends MetadataRequest> requests )
{
@@ -226,6 +240,14 @@ public class DefaultMetadataResolver
continue;
}
+ if ( !remoteRepositoryFilterSource.getRemoteRepositoryFilter( session )
+ .acceptMetadata( repository, metadata ) )
+ {
+ result.setException( new MetadataNotFoundException( metadata, repository,
+ "Metadata " + metadata + " not allowed from " + repository ) );
+ continue;
+ }
+
List<RemoteRepository> repositories = getEnabledSourceRepositories( repository, metadata.getNature() );
if ( repositories.isEmpty() )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/DefaultRemoteRepositoryFilterSource.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/DefaultRemoteRepositoryFilterSource.java
new file mode 100644
index 00000000..2b18673c
--- /dev/null
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/DefaultRemoteRepositoryFilterSource.java
@@ -0,0 +1,78 @@
+package org.eclipse.aether.internal.impl.filter;
+
+/*
+ * 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.
+ */
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource;
+import org.eclipse.aether.util.ConfigUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A filtering connector that filters transfers and delegates to another connector.
+ *
+ * @since TBD
+ */
+@Singleton
+@Named
+public final class DefaultRemoteRepositoryFilterSource
+ implements RemoteRepositoryFilterSource
+{
+ private static final String CONFIG_PROP_VALUE = "aether.artifactResolver.remoteRepositoryFilterSource.filter";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger( DefaultRemoteRepositoryFilterSource.class );
+
+ private static final class StaticRemoteRepositoryFilter implements RemoteRepositoryFilter
+ {
+ private final boolean value;
+
+ private StaticRemoteRepositoryFilter( boolean value )
+ {
+ this.value = value;
+ }
+
+ @Override
+ public boolean acceptArtifact( RemoteRepository remoteRepository, Artifact artifact )
+ {
+ return value;
+ }
+
+ @Override
+ public boolean acceptMetadata( RemoteRepository remoteRepository, Metadata metadata )
+ {
+ return value;
+ }
+ }
+
+ @Override
+ public RemoteRepositoryFilter getRemoteRepositoryFilter( RepositorySystemSession session )
+ {
+ boolean value = ConfigUtils.getBoolean( session, true, CONFIG_PROP_VALUE );
+ LOGGER.debug( "Creating static filter with value={}", value );
+ return new StaticRemoteRepositoryFilter( value );
+ }
+}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/FilteringRepositoryConnector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/FilteringRepositoryConnector.java
new file mode 100644
index 00000000..406e920a
--- /dev/null
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/FilteringRepositoryConnector.java
@@ -0,0 +1,113 @@
+package org.eclipse.aether.internal.impl.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.spi.connector.ArtifactDownload;
+import org.eclipse.aether.spi.connector.ArtifactUpload;
+import org.eclipse.aether.spi.connector.MetadataDownload;
+import org.eclipse.aether.spi.connector.MetadataUpload;
+import org.eclipse.aether.spi.connector.RepositoryConnector;
+import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A filtering connector that filters transfers and delegates to another connector.
+ *
+ * @since TBD
+ */
+public final class FilteringRepositoryConnector
+ implements RepositoryConnector
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger( FilteringRepositoryConnector.class );
+
+ private final RemoteRepository remoteRepository;
+
+ private final RepositoryConnector repositoryConnector;
+
+ private final RemoteRepositoryFilter remoteRepositoryFilter;
+
+ public FilteringRepositoryConnector( RemoteRepository remoteRepository,
+ RepositoryConnector repositoryConnector,
+ RemoteRepositoryFilter remoteRepositoryFilter )
+ {
+ this.remoteRepository = requireNonNull( remoteRepository );
+ this.repositoryConnector = requireNonNull( repositoryConnector );
+ this.remoteRepositoryFilter = requireNonNull( remoteRepositoryFilter );
+ }
+
+ @Override
+ public void close()
+ {
+ repositoryConnector.close();
+ }
+
+ @Override
+ public void get( Collection<? extends ArtifactDownload> artifactDownloads,
+ Collection<? extends MetadataDownload> metadataDownloads )
+ {
+ ArrayList<ArtifactDownload> filteredArtifactDownloads = new ArrayList<>( artifactDownloads.size() );
+ for ( ArtifactDownload artifactDownload : artifactDownloads )
+ {
+ if ( remoteRepositoryFilter.acceptArtifact( remoteRepository, artifactDownload.getArtifact() ) )
+ {
+ filteredArtifactDownloads.add( artifactDownload );
+ }
+ else
+ {
+ LOGGER.debug( "Artifact {} filtered out from remote repository {}",
+ artifactDownload.getArtifact(), remoteRepository );
+ }
+ }
+ ArrayList<MetadataDownload> filteredMetadataDownloads = new ArrayList<>( metadataDownloads.size() );
+ for ( MetadataDownload metadataDownload : metadataDownloads )
+ {
+ if ( remoteRepositoryFilter.acceptMetadata( remoteRepository, metadataDownload.getMetadata() ) )
+ {
+ filteredMetadataDownloads.add( metadataDownload );
+ }
+ else
+ {
+ LOGGER.debug( "Metadata {} filtered out from remote repository {}",
+ metadataDownload.getMetadata(), remoteRepository );
+ }
+ }
+ repositoryConnector.get( filteredArtifactDownloads, filteredMetadataDownloads );
+ }
+
+ @Override
+ public void put( Collection<? extends ArtifactUpload> artifactUploads,
+ Collection<? extends MetadataUpload> metadataUploads )
+ {
+ repositoryConnector.put( artifactUploads, metadataUploads );
+ }
+
+ @Override
+ public String toString()
+ {
+ return "filtered(" + repositoryConnector.toString() + ")";
+ }
+}
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 65ad4880..d5b3238b 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
@@ -38,6 +38,7 @@ import org.eclipse.aether.artifact.ArtifactProperties;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.impl.UpdateCheckManager;
import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterSource;
import org.eclipse.aether.internal.test.util.TestFileProcessor;
import org.eclipse.aether.internal.test.util.TestFileUtils;
import org.eclipse.aether.internal.test.util.TestLocalRepositoryManager;
@@ -103,6 +104,7 @@ public class DefaultArtifactResolverTest
resolver.setRemoteRepositoryManager( new StubRemoteRepositoryManager() );
resolver.setSyncContextFactory( new StubSyncContextFactory() );
resolver.setOfflineController( new DefaultOfflineController() );
+ resolver.setRemoteRepositoryFilterSource( new DefaultRemoteRepositoryFilterSource() );
artifact = new DefaultArtifact( "gid", "aid", "", "ext", "ver" );
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 27fec64c..e0c26aa9 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
@@ -31,6 +31,7 @@ import java.util.Set;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
+import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterSource;
import org.eclipse.aether.internal.test.util.TestFileUtils;
import org.eclipse.aether.internal.test.util.TestLocalRepositoryManager;
import org.eclipse.aether.internal.test.util.TestUtils;
@@ -80,6 +81,7 @@ public class DefaultMetadataResolverTest
resolver.setRemoteRepositoryManager( new StubRemoteRepositoryManager() );
resolver.setSyncContextFactory( new StubSyncContextFactory() );
resolver.setOfflineController( new DefaultOfflineController() );
+ resolver.setRemoteRepositoryFilterSource( new DefaultRemoteRepositoryFilterSource() );
repository =
new RemoteRepository.Builder( "test-DMRT", "default",
TestFileUtils.createTempDir().toURI().toURL().toString() ).build();
diff --git a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilter.java b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilter.java
new file mode 100644
index 00000000..e04bd13a
--- /dev/null
+++ b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilter.java
@@ -0,0 +1,51 @@
+package org.eclipse.aether.spi.connector.filter;
+
+/*
+ * 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.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Remote repository filter that decides should have given artifact or metadata be accepted (for further processing)
+ * from given remote repository.
+ *
+ * @since TBD
+ */
+public interface RemoteRepositoryFilter
+{
+ /**
+ * Decides should artifact be accepted from given remote repository.
+ *
+ * @param remoteRepository The remote repository, not {@code null}.
+ * @param artifact The artifact, not {@code null}.
+ * @return {@code true} if the artifact should be accepted.
+ */
+ boolean acceptArtifact( RemoteRepository remoteRepository, Artifact artifact );
+
+ /**
+ * Decides should metadata be accepted from given remote repository.
+ *
+ * @param remoteRepository The remote repository, not {@code null}.
+ * @param metadata The artifact, not {@code null}.
+ * @return {@code true} if the metadata should be accepted.
+ */
+ boolean acceptMetadata( RemoteRepository remoteRepository, Metadata metadata );
+}
diff --git a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilterSource.java b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilterSource.java
new file mode 100644
index 00000000..377a8000
--- /dev/null
+++ b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/filter/RemoteRepositoryFilterSource.java
@@ -0,0 +1,35 @@
+package org.eclipse.aether.spi.connector.filter;
+
+/*
+ * 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.
+ */
+
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * Remote repository filter source component.
+ *
+ * @since TBD
+ */
+public interface RemoteRepositoryFilterSource
+{
+ /**
+ * Provides the filter, never {@code null}.
+ */
+ RemoteRepositoryFilter getRemoteRepositoryFilter( RepositorySystemSession session );
+}