package org.eclipse.aether.repository;

/*
 * 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.Arrays;
import java.util.Collections;
import java.util.List;
import static java.util.Objects.requireNonNull;

import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

A repository on a remote server.
/** * A repository on a remote server. */
public final class RemoteRepository implements ArtifactRepository { private static final Pattern URL_PATTERN = Pattern.compile( "([^:/]+(:[^:/]{2,}+(?=://))?):(//([^@/]*@)?([^/:]+))?.*" ); private final String id; private final String type; private final String url; private final String host; private final String protocol; private final RepositoryPolicy releasePolicy; private final RepositoryPolicy snapshotPolicy; private final Proxy proxy; private final Authentication authentication; private final List<RemoteRepository> mirroredRepositories; private final boolean repositoryManager; RemoteRepository( Builder builder ) { if ( builder.prototype != null ) { id = ( builder.delta & Builder.ID ) != 0 ? builder.id : builder.prototype.id; type = ( builder.delta & Builder.TYPE ) != 0 ? builder.type : builder.prototype.type; url = ( builder.delta & Builder.URL ) != 0 ? builder.url : builder.prototype.url; releasePolicy = ( builder.delta & Builder.RELEASES ) != 0 ? builder.releasePolicy : builder.prototype.releasePolicy; snapshotPolicy = ( builder.delta & Builder.SNAPSHOTS ) != 0 ? builder.snapshotPolicy : builder.prototype.snapshotPolicy; proxy = ( builder.delta & Builder.PROXY ) != 0 ? builder.proxy : builder.prototype.proxy; authentication = ( builder.delta & Builder.AUTH ) != 0 ? builder.authentication : builder.prototype.authentication; repositoryManager = ( builder.delta & Builder.REPOMAN ) != 0 ? builder.repositoryManager : builder.prototype.repositoryManager; mirroredRepositories = ( builder.delta & Builder.MIRRORED ) != 0 ? copy( builder.mirroredRepositories ) : builder.prototype.mirroredRepositories; } else { id = builder.id; type = builder.type; url = builder.url; releasePolicy = builder.releasePolicy; snapshotPolicy = builder.snapshotPolicy; proxy = builder.proxy; authentication = builder.authentication; repositoryManager = builder.repositoryManager; mirroredRepositories = copy( builder.mirroredRepositories ); } Matcher m = URL_PATTERN.matcher( url ); if ( m.matches() ) { protocol = m.group( 1 ); String host = m.group( 5 ); this.host = ( host != null ) ? host : ""; } else { protocol = ""; host = ""; } } private static List<RemoteRepository> copy( List<RemoteRepository> repos ) { if ( repos == null || repos.isEmpty() ) { return Collections.emptyList(); } return Collections.unmodifiableList( Arrays.asList( repos.toArray( new RemoteRepository[repos.size()] ) ) ); } public String getId() { return id; } public String getContentType() { return type; }
Gets the (base) URL of this repository.
Returns:The (base) URL of this repository, never null.
/** * Gets the (base) URL of this repository. * * @return The (base) URL of this repository, never {@code null}. */
public String getUrl() { return url; }
Gets the protocol part from the repository's URL, for example file or http. As suggested by RFC 2396, section 3.1 "Scheme Component", the protocol name should be treated case-insensitively.
Returns:The protocol or an empty string if none, never null.
/** * Gets the protocol part from the repository's URL, for example {@code file} or {@code http}. As suggested by RFC * 2396, section 3.1 "Scheme Component", the protocol name should be treated case-insensitively. * * @return The protocol or an empty string if none, never {@code null}. */
public String getProtocol() { return protocol; }
Gets the host part from the repository's URL.
Returns:The host or an empty string if none, never null.
/** * Gets the host part from the repository's URL. * * @return The host or an empty string if none, never {@code null}. */
public String getHost() { return host; }
Gets the policy to apply for snapshot/release artifacts.
Params:
  • snapshot – true to retrieve the snapshot policy, false to retrieve the release policy.
Returns:The requested repository policy, never null.
/** * Gets the policy to apply for snapshot/release artifacts. * * @param snapshot {@code true} to retrieve the snapshot policy, {@code false} to retrieve the release policy. * @return The requested repository policy, never {@code null}. */
public RepositoryPolicy getPolicy( boolean snapshot ) { return snapshot ? snapshotPolicy : releasePolicy; }
Gets the proxy that has been selected for this repository.
Returns:The selected proxy or null if none.
/** * Gets the proxy that has been selected for this repository. * * @return The selected proxy or {@code null} if none. */
public Proxy getProxy() { return proxy; }
Gets the authentication that has been selected for this repository.
Returns:The selected authentication or null if none.
/** * Gets the authentication that has been selected for this repository. * * @return The selected authentication or {@code null} if none. */
public Authentication getAuthentication() { return authentication; }
Gets the repositories that this repository serves as a mirror for.
Returns:The (read-only) repositories being mirrored by this repository, never null.
/** * Gets the repositories that this repository serves as a mirror for. * * @return The (read-only) repositories being mirrored by this repository, never {@code null}. */
public List<RemoteRepository> getMirroredRepositories() { return mirroredRepositories; }
Indicates whether this repository refers to a repository manager or not.
Returns:true if this repository is a repository manager, false otherwise.
/** * Indicates whether this repository refers to a repository manager or not. * * @return {@code true} if this repository is a repository manager, {@code false} otherwise. */
public boolean isRepositoryManager() { return repositoryManager; } @Override public String toString() { StringBuilder buffer = new StringBuilder( 256 ); buffer.append( getId() ); buffer.append( " (" ).append( getUrl() ); buffer.append( ", " ).append( getContentType() ); boolean r = getPolicy( false ).isEnabled(), s = getPolicy( true ).isEnabled(); if ( r && s ) { buffer.append( ", releases+snapshots" ); } else if ( r ) { buffer.append( ", releases" ); } else if ( s ) { buffer.append( ", snapshots" ); } else { buffer.append( ", disabled" ); } if ( isRepositoryManager() ) { buffer.append( ", managed" ); } buffer.append( ")" ); return buffer.toString(); } @Override public boolean equals( Object obj ) { if ( this == obj ) { return true; } if ( obj == null || !getClass().equals( obj.getClass() ) ) { return false; } RemoteRepository that = (RemoteRepository) obj; return Objects.equals( url, that.url ) && Objects.equals( type, that.type ) && Objects.equals( id, that.id ) && Objects.equals( releasePolicy, that.releasePolicy ) && Objects.equals( snapshotPolicy, that.snapshotPolicy ) && Objects.equals( proxy, that.proxy ) && Objects.equals( authentication, that.authentication ) && Objects.equals( mirroredRepositories, that.mirroredRepositories ) && repositoryManager == that.repositoryManager; } @Override public int hashCode() { int hash = 17; hash = hash * 31 + hash( url ); hash = hash * 31 + hash( type ); hash = hash * 31 + hash( id ); hash = hash * 31 + hash( releasePolicy ); hash = hash * 31 + hash( snapshotPolicy ); hash = hash * 31 + hash( proxy ); hash = hash * 31 + hash( authentication ); hash = hash * 31 + hash( mirroredRepositories ); hash = hash * 31 + ( repositoryManager ? 1 : 0 ); return hash; } private static int hash( Object obj ) { return obj != null ? obj.hashCode() : 0; }
A builder to create remote repositories.
/** * A builder to create remote repositories. */
public static final class Builder { private static final RepositoryPolicy DEFAULT_POLICY = new RepositoryPolicy(); static final int ID = 0x0001, TYPE = 0x0002, URL = 0x0004, RELEASES = 0x0008, SNAPSHOTS = 0x0010, PROXY = 0x0020, AUTH = 0x0040, MIRRORED = 0x0080, REPOMAN = 0x0100; int delta; RemoteRepository prototype; String id; String type; String url; RepositoryPolicy releasePolicy = DEFAULT_POLICY; RepositoryPolicy snapshotPolicy = DEFAULT_POLICY; Proxy proxy; Authentication authentication; List<RemoteRepository> mirroredRepositories; boolean repositoryManager;
Creates a new repository builder.
Params:
  • id – The identifier of the repository, may be null.
  • type – The type of the repository, may be null.
  • url – The (base) URL of the repository, may be null.
/** * Creates a new repository builder. * * @param id The identifier of the repository, may be {@code null}. * @param type The type of the repository, may be {@code null}. * @param url The (base) URL of the repository, may be {@code null}. */
public Builder( String id, String type, String url ) { this.id = ( id != null ) ? id : ""; this.type = ( type != null ) ? type : ""; this.url = ( url != null ) ? url : ""; }
Creates a new repository builder which uses the specified remote repository as a prototype for the new one. All properties which have not been set on the builder will be copied from the prototype when building the repository.
Params:
  • prototype – The remote repository to use as prototype, must not be null.
/** * Creates a new repository builder which uses the specified remote repository as a prototype for the new one. * All properties which have not been set on the builder will be copied from the prototype when building the * repository. * * @param prototype The remote repository to use as prototype, must not be {@code null}. */
public Builder( RemoteRepository prototype ) { this.prototype = requireNonNull( prototype, "remote repository prototype cannot be null" ); }
Builds a new remote repository from the current values of this builder. The state of the builder itself remains unchanged.
Returns:The remote repository, never null.
/** * Builds a new remote repository from the current values of this builder. The state of the builder itself * remains unchanged. * * @return The remote repository, never {@code null}. */
public RemoteRepository build() { if ( prototype != null && delta == 0 ) { return prototype; } return new RemoteRepository( this ); } private <T> void delta( int flag, T builder, T prototype ) { boolean equal = Objects.equals( builder, prototype ); if ( equal ) { delta &= ~flag; } else { delta |= flag; } }
Sets the identifier of the repository.
Params:
  • id – The identifier of the repository, may be null.
Returns:This builder for chaining, never null.
/** * Sets the identifier of the repository. * * @param id The identifier of the repository, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setId( String id ) { this.id = ( id != null ) ? id : ""; if ( prototype != null ) { delta( ID, this.id, prototype.getId() ); } return this; }
Sets the type of the repository, e.g. "default".
Params:
  • type – The type of the repository, may be null.
Returns:This builder for chaining, never null.
/** * Sets the type of the repository, e.g. "default". * * @param type The type of the repository, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setContentType( String type ) { this.type = ( type != null ) ? type : ""; if ( prototype != null ) { delta( TYPE, this.type, prototype.getContentType() ); } return this; }
Sets the (base) URL of the repository.
Params:
  • url – The URL of the repository, may be null.
Returns:This builder for chaining, never null.
/** * Sets the (base) URL of the repository. * * @param url The URL of the repository, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setUrl( String url ) { this.url = ( url != null ) ? url : ""; if ( prototype != null ) { delta( URL, this.url, prototype.getUrl() ); } return this; }
Sets the policy to apply for snapshot and release artifacts.
Params:
  • policy – The repository policy to set, may be null to use a default policy.
Returns:This builder for chaining, never null.
/** * Sets the policy to apply for snapshot and release artifacts. * * @param policy The repository policy to set, may be {@code null} to use a default policy. * @return This builder for chaining, never {@code null}. */
public Builder setPolicy( RepositoryPolicy policy ) { this.releasePolicy = ( policy != null ) ? policy : DEFAULT_POLICY; this.snapshotPolicy = ( policy != null ) ? policy : DEFAULT_POLICY; if ( prototype != null ) { delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) ); delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) ); } return this; }
Sets the policy to apply for release artifacts.
Params:
  • releasePolicy – The repository policy to set, may be null to use a default policy.
Returns:This builder for chaining, never null.
/** * Sets the policy to apply for release artifacts. * * @param releasePolicy The repository policy to set, may be {@code null} to use a default policy. * @return This builder for chaining, never {@code null}. */
public Builder setReleasePolicy( RepositoryPolicy releasePolicy ) { this.releasePolicy = ( releasePolicy != null ) ? releasePolicy : DEFAULT_POLICY; if ( prototype != null ) { delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) ); } return this; }
Sets the policy to apply for snapshot artifacts.
Params:
  • snapshotPolicy – The repository policy to set, may be null to use a default policy.
Returns:This builder for chaining, never null.
/** * Sets the policy to apply for snapshot artifacts. * * @param snapshotPolicy The repository policy to set, may be {@code null} to use a default policy. * @return This builder for chaining, never {@code null}. */
public Builder setSnapshotPolicy( RepositoryPolicy snapshotPolicy ) { this.snapshotPolicy = ( snapshotPolicy != null ) ? snapshotPolicy : DEFAULT_POLICY; if ( prototype != null ) { delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) ); } return this; }
Sets the proxy to use in order to access the repository.
Params:
  • proxy – The proxy to use, may be null.
Returns:This builder for chaining, never null.
/** * Sets the proxy to use in order to access the repository. * * @param proxy The proxy to use, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setProxy( Proxy proxy ) { this.proxy = proxy; if ( prototype != null ) { delta( PROXY, this.proxy, prototype.getProxy() ); } return this; }
Sets the authentication to use in order to access the repository.
Params:
  • authentication – The authentication to use, may be null.
Returns:This builder for chaining, never null.
/** * Sets the authentication to use in order to access the repository. * * @param authentication The authentication to use, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setAuthentication( Authentication authentication ) { this.authentication = authentication; if ( prototype != null ) { delta( AUTH, this.authentication, prototype.getAuthentication() ); } return this; }
Sets the repositories being mirrored by the repository.
Params:
  • mirroredRepositories – The repositories being mirrored by the repository, may be null.
Returns:This builder for chaining, never null.
/** * Sets the repositories being mirrored by the repository. * * @param mirroredRepositories The repositories being mirrored by the repository, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder setMirroredRepositories( List<RemoteRepository> mirroredRepositories ) { if ( this.mirroredRepositories == null ) { this.mirroredRepositories = new ArrayList<>(); } else { this.mirroredRepositories.clear(); } if ( mirroredRepositories != null ) { this.mirroredRepositories.addAll( mirroredRepositories ); } if ( prototype != null ) { delta( MIRRORED, this.mirroredRepositories, prototype.getMirroredRepositories() ); } return this; }
Adds the specified repository to the list of repositories being mirrored by the repository. If this builder was constructed from a prototype, the given repository will be added to the list of mirrored repositories from the prototype.
Params:
  • mirroredRepository – The repository being mirrored by the repository, may be null.
Returns:This builder for chaining, never null.
/** * Adds the specified repository to the list of repositories being mirrored by the repository. If this builder * was {@link Builder constructed from a prototype}, the given repository * will be added to the list of mirrored repositories from the prototype. * * @param mirroredRepository The repository being mirrored by the repository, may be {@code null}. * @return This builder for chaining, never {@code null}. */
public Builder addMirroredRepository( RemoteRepository mirroredRepository ) { if ( mirroredRepository != null ) { if ( this.mirroredRepositories == null ) { this.mirroredRepositories = new ArrayList<>(); if ( prototype != null ) { mirroredRepositories.addAll( prototype.getMirroredRepositories() ); } } mirroredRepositories.add( mirroredRepository ); if ( prototype != null ) { delta |= MIRRORED; } } return this; }
Marks the repository as a repository manager or not.
Params:
  • repositoryManager – true if the repository points at a repository manager, false if the repository is just serving static contents.
Returns:This builder for chaining, never null.
/** * Marks the repository as a repository manager or not. * * @param repositoryManager {@code true} if the repository points at a repository manager, {@code false} if the * repository is just serving static contents. * @return This builder for chaining, never {@code null}. */
public Builder setRepositoryManager( boolean repositoryManager ) { this.repositoryManager = repositoryManager; if ( prototype != null ) { delta( REPOMAN, this.repositoryManager, prototype.isRepositoryManager() ); } return this; } } }