diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java index 99cec7d2e..8b359cea4 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java @@ -30,8 +30,32 @@ /** * A repository on a remote server. + *
+ * If use of instances of this class are meant to be used as keys, see {@link #toBareRemoteRepository()} method. */ public final class RemoteRepository implements ArtifactRepository { + /** + * The intent this repository is to be used for. Newly created repositories are usually "bare", and before + * their actual use (caller or repository system) adapts them, equip with auth/proxy info and even mirrors, if + * environment is configured for them. Note: "bare" does not always mean "without authentication", as client + * code may create with all required properties, but {@link org.eclipse.aether.RepositorySystem} will process + * them anyway, marking their "intent". + *
+ * Important consequence: the change of {@link Intent} on repository may affect the use cases when
+ * they are used as keys (they are suitable for that). To use {@link RemoteRepository} instances as key,
+ * you should use instances returned by method {@link #toBareRemoteRepository()}, that returns "normalized"
+ * repository instances usable as keys. Also, in "key usage case" two instances of remote repository are
+ * considered equal if following stands: {@code Objects.equals(r1.toBareRemoteRepository(), r2.toBareRemoteRepository())}.
+ *
+ * @see org.eclipse.aether.RepositorySystem#newResolutionRepositories(RepositorySystemSession, List)
+ * @see org.eclipse.aether.RepositorySystem#newDeploymentRepository(RepositorySystemSession, RemoteRepository)
+ * @since 2.0.14
+ */
+ public enum Intent {
+ BARE,
+ RESOLUTION,
+ DEPLOYMENT
+ }
private static final Pattern URL_PATTERN =
Pattern.compile("([^:/]+(:[^:/]{2,}+(?=://))?):(//([^@/]*@)?([^/:]+))?.*");
@@ -60,6 +84,10 @@ public final class RemoteRepository implements ArtifactRepository {
private final boolean blocked;
+ private final Intent intent;
+
+ private final int hashCode;
+
RemoteRepository(Builder builder) {
if (builder.prototype != null) {
id = (builder.delta & Builder.ID) != 0 ? builder.id : builder.prototype.id;
@@ -80,6 +108,7 @@ public final class RemoteRepository implements ArtifactRepository {
mirroredRepositories = (builder.delta & Builder.MIRRORED) != 0
? copy(builder.mirroredRepositories)
: builder.prototype.mirroredRepositories;
+ intent = (builder.delta & Builder.INTENT) != 0 ? builder.intent : builder.prototype.intent;
} else {
id = builder.id;
type = builder.type;
@@ -91,17 +120,31 @@ public final class RemoteRepository implements ArtifactRepository {
repositoryManager = builder.repositoryManager;
blocked = builder.blocked;
mirroredRepositories = copy(builder.mirroredRepositories);
+ intent = builder.intent;
}
Matcher m = URL_PATTERN.matcher(url);
if (m.matches()) {
- protocol = m.group(1);
- String host = m.group(5);
- this.host = (host != null) ? host : "";
+ String h = m.group(5);
+ this.host = (h != null) ? h : "";
+ this.protocol = m.group(1);
} else {
- protocol = "";
- host = "";
+ this.host = "";
+ this.protocol = "";
}
+
+ this.hashCode = Objects.hash(
+ id,
+ type,
+ url, // host, protocol derived from url
+ releasePolicy,
+ snapshotPolicy,
+ proxy,
+ authentication,
+ mirroredRepositories,
+ repositoryManager,
+ blocked,
+ intent);
}
private static List
+ *
+ * These properties are managed by repository system, based on configuration. See {@link org.eclipse.aether.RepositorySystem}
+ * and (internal component) {@code org.eclipse.aether.impl.RemoteRepositoryManager}.
+ *
+ * @since 2.0.14
+ */
+ public RemoteRepository toBareRemoteRepository() {
+ return new Builder(this)
+ .setIntent(Intent.BARE)
+ .setProxy(null)
+ .setAuthentication(null)
+ .setMirroredRepositories(null)
+ .setRepositoryManager(false)
+ .build();
}
/**
@@ -286,7 +355,8 @@ public static final class Builder {
AUTH = 0x0040,
MIRRORED = 0x0080,
REPOMAN = 0x0100,
- BLOCKED = 0x0200;
+ BLOCKED = 0x0200,
+ INTENT = 0x0400;
int delta;
@@ -312,6 +382,8 @@ public static final class Builder {
boolean blocked;
+ Intent intent = Intent.BARE;
+
/**
* Creates a new repository builder.
*
@@ -545,5 +617,20 @@ public Builder setBlocked(boolean blocked) {
}
return this;
}
+
+ /**
+ * Marks the intent for this repository.
+ *
+ * @param intent the intent with this remote repository.
+ * @return This builder for chaining, never {@code null}.
+ * @since 2.0.14
+ */
+ public Builder setIntent(Intent intent) {
+ this.intent = intent;
+ if (prototype != null) {
+ delta(INTENT, this.intent, prototype.intent);
+ }
+ return this;
+ }
}
}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRemoteRepositoryManager.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRemoteRepositoryManager.java
index 6995ded82..3ad72aade 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRemoteRepositoryManager.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRemoteRepositoryManager.java
@@ -26,6 +26,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
+import java.util.stream.Collectors;
import org.eclipse.aether.RepositoryCache;
import org.eclipse.aether.RepositorySystemSession;
@@ -160,7 +161,11 @@ public List
- *
+ * We use remote repositories as keys, so normalize them.
+ *
+ * @since 2.0.14
+ * @see RemoteRepository#toBareRemoteRepository()
*/
protected RemoteRepository normalizeRemoteRepository(
RepositorySystemSession session, RemoteRepository remoteRepository) {
- return new RemoteRepository.Builder(remoteRepository)
- .setProxy(null)
- .setAuthentication(null)
- .setMirroredRepositories(null)
- .setRepositoryManager(false)
- .build();
+ return remoteRepository.toBareRemoteRepository();
}
/**