http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/LocalRepositoryManager.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/LocalRepositoryManager.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/LocalRepositoryManager.java new file mode 100644 index 0000000..649707c --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/LocalRepositoryManager.java @@ -0,0 +1,127 @@ +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 org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.metadata.Metadata; + +/** + * Manages access to a local repository. + * + * @see RepositorySystemSession#getLocalRepositoryManager() + * @see org.eclipse.aether.RepositorySystem#newLocalRepositoryManager(RepositorySystemSession, LocalRepository) + */ +public interface LocalRepositoryManager +{ + + /** + * Gets the description of the local repository being managed. + * + * @return The description of the local repository, never {@code null}. + */ + LocalRepository getRepository(); + + /** + * Gets the relative path for a locally installed artifact. Note that the artifact need not actually exist yet at + * the returned location, the path merely indicates where the artifact would eventually be stored. The path uses the + * forward slash as directory separator regardless of the underlying file system. + * + * @param artifact The artifact for which to determine the path, must not be {@code null}. + * @return The path, relative to the local repository's base directory. + */ + String getPathForLocalArtifact( Artifact artifact ); + + /** + * Gets the relative path for an artifact cached from a remote repository. Note that the artifact need not actually + * exist yet at the returned location, the path merely indicates where the artifact would eventually be stored. The + * path uses the forward slash as directory separator regardless of the underlying file system. + * + * @param artifact The artifact for which to determine the path, must not be {@code null}. + * @param repository The source repository of the artifact, must not be {@code null}. + * @param context The resolution context in which the artifact is being requested, may be {@code null}. + * @return The path, relative to the local repository's base directory. + */ + String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context ); + + /** + * Gets the relative path for locally installed metadata. Note that the metadata need not actually exist yet at the + * returned location, the path merely indicates where the metadata would eventually be stored. The path uses the + * forward slash as directory separator regardless of the underlying file system. + * + * @param metadata The metadata for which to determine the path, must not be {@code null}. + * @return The path, relative to the local repository's base directory. + */ + String getPathForLocalMetadata( Metadata metadata ); + + /** + * Gets the relative path for metadata cached from a remote repository. Note that the metadata need not actually + * exist yet at the returned location, the path merely indicates where the metadata would eventually be stored. The + * path uses the forward slash as directory separator regardless of the underlying file system. + * + * @param metadata The metadata for which to determine the path, must not be {@code null}. + * @param repository The source repository of the metadata, must not be {@code null}. + * @param context The resolution context in which the metadata is being requested, may be {@code null}. + * @return The path, relative to the local repository's base directory. + */ + String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context ); + + /** + * Queries for the existence of an artifact in the local repository. The request could be satisfied by a locally + * installed artifact or a previously downloaded artifact. + * + * @param session The repository system session during which the request is made, must not be {@code null}. + * @param request The artifact request, must not be {@code null}. + * @return The result of the request, never {@code null}. + */ + LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request ); + + /** + * Registers an installed or resolved artifact with the local repository. Note that artifact registration is merely + * concerned about updating the local repository's internal state, not about actually installing the artifact or its + * accompanying metadata. + * + * @param session The repository system session during which the registration is made, must not be {@code null}. + * @param request The registration request, must not be {@code null}. + */ + void add( RepositorySystemSession session, LocalArtifactRegistration request ); + + /** + * Queries for the existence of metadata in the local repository. The request could be satisfied by locally + * installed or previously downloaded metadata. + * + * @param session The repository system session during which the request is made, must not be {@code null}. + * @param request The metadata request, must not be {@code null}. + * @return The result of the request, never {@code null}. + */ + LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request ); + + /** + * Registers installed or resolved metadata with the local repository. Note that metadata registration is merely + * concerned about updating the local repository's internal state, not about actually installing the metadata. + * However, this method MUST be called after the actual install to give the repository manager the opportunity to + * inspect the added metadata. + * + * @param session The repository system session during which the registration is made, must not be {@code null}. + * @param request The registration request, must not be {@code null}. + */ + void add( RepositorySystemSession session, LocalMetadataRegistration request ); + +}
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/MirrorSelector.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/MirrorSelector.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/MirrorSelector.java new file mode 100644 index 0000000..d50262c --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/MirrorSelector.java @@ -0,0 +1,39 @@ +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. + */ + +/** + * Selects a mirror for a given remote repository. + * + * @see org.eclipse.aether.RepositorySystemSession#getMirrorSelector() + */ +public interface MirrorSelector +{ + + /** + * Selects a mirror for the specified repository. + * + * @param repository The repository to select a mirror for, must not be {@code null}. + * @return The selected mirror or {@code null} if none. + * @see RemoteRepository#getMirroredRepositories() + */ + RemoteRepository getMirror( RemoteRepository repository ); + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/NoLocalRepositoryManagerException.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/NoLocalRepositoryManagerException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/NoLocalRepositoryManagerException.java new file mode 100644 index 0000000..c804821 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/NoLocalRepositoryManagerException.java @@ -0,0 +1,102 @@ +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 org.eclipse.aether.RepositoryException; + +/** + * Thrown in case of an unsupported local repository type. + */ +public class NoLocalRepositoryManagerException + extends RepositoryException +{ + + private final transient LocalRepository repository; + + /** + * Creates a new exception with the specified repository. + * + * @param repository The local repository for which no support is available, may be {@code null}. + */ + public NoLocalRepositoryManagerException( LocalRepository repository ) + { + this( repository, toMessage( repository ) ); + } + + /** + * Creates a new exception with the specified repository and detail message. + * + * @param repository The local repository for which no support is available, may be {@code null}. + * @param message The detail message, may be {@code null}. + */ + public NoLocalRepositoryManagerException( LocalRepository repository, String message ) + { + super( message ); + this.repository = repository; + } + + /** + * Creates a new exception with the specified repository and cause. + * + * @param repository The local repository for which no support is available, may be {@code null}. + * @param cause The exception that caused this one, may be {@code null}. + */ + public NoLocalRepositoryManagerException( LocalRepository repository, Throwable cause ) + { + this( repository, toMessage( repository ), cause ); + } + + /** + * Creates a new exception with the specified repository, detail message and cause. + * + * @param repository The local repository for which no support is available, may be {@code null}. + * @param message The detail message, may be {@code null}. + * @param cause The exception that caused this one, may be {@code null}. + */ + public NoLocalRepositoryManagerException( LocalRepository repository, String message, Throwable cause ) + { + super( message, cause ); + this.repository = repository; + } + + private static String toMessage( LocalRepository repository ) + { + if ( repository != null ) + { + return "No manager available for local repository (" + repository.getBasedir().getAbsolutePath() + + ") of type " + repository.getContentType(); + } + else + { + return "No manager available for local repository"; + } + } + + /** + * Gets the local repository whose content type is not supported. + * + * @return The unsupported local repository or {@code null} if unknown. + */ + public LocalRepository getRepository() + { + return repository; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/Proxy.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/Proxy.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/Proxy.java new file mode 100644 index 0000000..8e8cba1 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/Proxy.java @@ -0,0 +1,158 @@ +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. + */ + +/** + * A proxy to use for connections to a repository. + */ +public final class Proxy +{ + + /** + * Type denoting a proxy for HTTP transfers. + */ + public static final String TYPE_HTTP = "http"; + + /** + * Type denoting a proxy for HTTPS transfers. + */ + public static final String TYPE_HTTPS = "https"; + + private final String type; + + private final String host; + + private final int port; + + private final Authentication auth; + + /** + * Creates a new proxy with the specified properties and no authentication. + * + * @param type The type of the proxy, e.g. "http", may be {@code null}. + * @param host The host of the proxy, may be {@code null}. + * @param port The port of the proxy. + */ + public Proxy( String type, String host, int port ) + { + this( type, host, port, null ); + } + + /** + * Creates a new proxy with the specified properties. + * + * @param type The type of the proxy, e.g. "http", may be {@code null}. + * @param host The host of the proxy, may be {@code null}. + * @param port The port of the proxy. + * @param auth The authentication to use for the proxy connection, may be {@code null}. + */ + public Proxy( String type, String host, int port, Authentication auth ) + { + this.type = ( type != null ) ? type : ""; + this.host = ( host != null ) ? host : ""; + this.port = port; + this.auth = auth; + } + + /** + * Gets the type of this proxy. + * + * @return The type of this proxy, never {@code null}. + */ + public String getType() + { + return type; + } + + /** + * Gets the host for this proxy. + * + * @return The host for this proxy, never {@code null}. + */ + public String getHost() + { + return host; + } + + /** + * Gets the port number for this proxy. + * + * @return The port number for this proxy. + */ + public int getPort() + { + return port; + } + + /** + * Gets the authentication to use for the proxy connection. + * + * @return The authentication to use or {@code null} if none. + */ + public Authentication getAuthentication() + { + return auth; + } + + @Override + public String toString() + { + return getHost() + ':' + getPort(); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + Proxy that = (Proxy) obj; + + return eq( type, that.type ) && eq( host, that.host ) && port == that.port && eq( auth, that.auth ); + } + + private static <T> boolean eq( T s1, T s2 ) + { + return s1 != null ? s1.equals( s2 ) : s2 == null; + } + + @Override + public int hashCode() + { + int hash = 17; + hash = hash * 31 + hash( host ); + hash = hash * 31 + hash( type ); + hash = hash * 31 + port; + hash = hash * 31 + hash( auth ); + return hash; + } + + private static int hash( Object obj ) + { + return obj != null ? obj.hashCode() : 0; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/ProxySelector.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/ProxySelector.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/ProxySelector.java new file mode 100644 index 0000000..29b9e4e --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/ProxySelector.java @@ -0,0 +1,38 @@ +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. + */ + +/** + * Selects a proxy for a given remote repository. + * + * @see org.eclipse.aether.RepositorySystemSession#getProxySelector() + */ +public interface ProxySelector +{ + + /** + * Selects a proxy for the specified remote repository. + * + * @param repository The repository for which to select a proxy, must not be {@code null}. + * @return The selected proxy or {@code null} if none. + */ + Proxy getProxy( RemoteRepository repository ); + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..31259ca --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RemoteRepository.java @@ -0,0 +1,582 @@ +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 java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 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. + * + * @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 {@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. + * + * @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. + * + * @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. + * + * @return The selected proxy or {@code null} if none. + */ + public Proxy getProxy() + { + return proxy; + } + + /** + * 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. + * + * @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. + * + * @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 eq( url, that.url ) && eq( type, that.type ) && eq( id, that.id ) + && eq( releasePolicy, that.releasePolicy ) && eq( snapshotPolicy, that.snapshotPolicy ) + && eq( proxy, that.proxy ) && eq( authentication, that.authentication ) + && eq( mirroredRepositories, that.mirroredRepositories ) && repositoryManager == that.repositoryManager; + } + + private static <T> boolean eq( T s1, T s2 ) + { + return s1 != null ? s1.equals( s2 ) : s2 == null; + } + + @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. + */ + 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. + * + * @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. + * + * @param prototype The remote repository to use as prototype, must not be {@code null}. + */ + public Builder( RemoteRepository prototype ) + { + if ( prototype == null ) + { + throw new IllegalArgumentException( "repository prototype missing" ); + } + this.prototype = prototype; + } + + /** + * 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 = ( builder != null ) ? builder.equals( prototype ) : prototype == null; + if ( equal ) + { + delta &= ~flag; + } + else + { + delta |= flag; + } + } + + /** + * 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". + * + * @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. + * + * @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. + * + * @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 = 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. + * + * @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. + * + * @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. + * + * @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. + * + * @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. + * + * @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<RemoteRepository>(); + } + 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 {@link #RemoteRepository.Builder(RemoteRepository) 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<RemoteRepository>(); + 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. + * + * @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; + } + + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RepositoryPolicy.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RepositoryPolicy.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RepositoryPolicy.java new file mode 100644 index 0000000..18fb850 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/RepositoryPolicy.java @@ -0,0 +1,161 @@ +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. + */ + +/** + * A policy controlling access to a repository. + */ +public final class RepositoryPolicy +{ + + /** + * Never update locally cached data. + */ + public static final String UPDATE_POLICY_NEVER = "never"; + + /** + * Always update locally cached data. + */ + public static final String UPDATE_POLICY_ALWAYS = "always"; + + /** + * Update locally cached data once a day. + */ + public static final String UPDATE_POLICY_DAILY = "daily"; + + /** + * Update locally cached data every X minutes as given by "interval:X". + */ + public static final String UPDATE_POLICY_INTERVAL = "interval"; + + /** + * Verify checksums and fail the resolution if they do not match. + */ + public static final String CHECKSUM_POLICY_FAIL = "fail"; + + /** + * Verify checksums and warn if they do not match. + */ + public static final String CHECKSUM_POLICY_WARN = "warn"; + + /** + * Do not verify checksums. + */ + public static final String CHECKSUM_POLICY_IGNORE = "ignore"; + + private final boolean enabled; + + private final String updatePolicy; + + private final String checksumPolicy; + + /** + * Creates a new policy with checksum warnings and daily update checks. + */ + public RepositoryPolicy() + { + this( true, UPDATE_POLICY_DAILY, CHECKSUM_POLICY_WARN ); + } + + /** + * Creates a new policy with the specified settings. + * + * @param enabled A flag whether the associated repository should be accessed or not. + * @param updatePolicy The update interval after which locally cached data from the repository is considered stale + * and should be refetched, may be {@code null}. + * @param checksumPolicy The way checksum verification should be handled, may be {@code null}. + */ + public RepositoryPolicy( boolean enabled, String updatePolicy, String checksumPolicy ) + { + this.enabled = enabled; + this.updatePolicy = ( updatePolicy != null ) ? updatePolicy : ""; + this.checksumPolicy = ( checksumPolicy != null ) ? checksumPolicy : ""; + } + + /** + * Indicates whether the associated repository should be contacted or not. + * + * @return {@code true} if the repository should be contacted, {@code false} otherwise. + */ + public boolean isEnabled() + { + return enabled; + } + + /** + * Gets the update policy for locally cached data from the repository. + * + * @return The update policy, never {@code null}. + */ + public String getUpdatePolicy() + { + return updatePolicy; + } + + /** + * Gets the policy for checksum validation. + * + * @return The checksum policy, never {@code null}. + */ + public String getChecksumPolicy() + { + return checksumPolicy; + } + + @Override + public String toString() + { + StringBuilder buffer = new StringBuilder( 256 ); + buffer.append( "enabled=" ).append( isEnabled() ); + buffer.append( ", checksums=" ).append( getChecksumPolicy() ); + buffer.append( ", updates=" ).append( getUpdatePolicy() ); + return buffer.toString(); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + + if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + RepositoryPolicy that = (RepositoryPolicy) obj; + + return enabled == that.enabled && updatePolicy.equals( that.updatePolicy ) + && checksumPolicy.equals( that.checksumPolicy ); + } + + @Override + public int hashCode() + { + int hash = 17; + hash = hash * 31 + ( enabled ? 1 : 0 ); + hash = hash * 31 + updatePolicy.hashCode(); + hash = hash * 31 + checksumPolicy.hashCode(); + return hash; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceReader.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceReader.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceReader.java new file mode 100644 index 0000000..d1140f3 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceReader.java @@ -0,0 +1,58 @@ +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.io.File; +import java.util.List; + +import org.eclipse.aether.artifact.Artifact; + +/** + * Manages a repository backed by the IDE workspace, a build session or a similar ad-hoc collection of artifacts. + * + * @see org.eclipse.aether.RepositorySystemSession#getWorkspaceReader() + */ +public interface WorkspaceReader +{ + + /** + * Gets a description of the workspace repository. + * + * @return The repository description, never {@code null}. + */ + WorkspaceRepository getRepository(); + + /** + * Locates the specified artifact. + * + * @param artifact The artifact to locate, must not be {@code null}. + * @return The path to the artifact or {@code null} if the artifact is not available. + */ + File findArtifact( Artifact artifact ); + + /** + * Determines all available versions of the specified artifact. + * + * @param artifact The artifact whose versions should be listed, must not be {@code null}. + * @return The available versions of the artifact, must not be {@code null}. + */ + List<String> findVersions( Artifact artifact ); + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceRepository.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceRepository.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceRepository.java new file mode 100644 index 0000000..38dc5c5 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/WorkspaceRepository.java @@ -0,0 +1,122 @@ +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.UUID; + +/** + * A repository backed by an IDE workspace, the output of a build session or similar ad-hoc collection of artifacts. As + * far as the repository system is concerned, a workspace repository is read-only, i.e. can only be used for artifact + * resolution but not installation/deployment. Note that this class merely describes such a repository, actual access to + * the contained artifacts is handled by a {@link WorkspaceReader}. + */ +public final class WorkspaceRepository + implements ArtifactRepository +{ + + private final String type; + + private final Object key; + + /** + * Creates a new workspace repository of type {@code "workspace"} and a random key. + */ + public WorkspaceRepository() + { + this( "workspace" ); + } + + /** + * Creates a new workspace repository with the specified type and a random key. + * + * @param type The type of the repository, may be {@code null}. + */ + public WorkspaceRepository( String type ) + { + this( type, null ); + } + + /** + * Creates a new workspace repository with the specified type and key. The key is used to distinguish one workspace + * from another and should be sensitive to the artifacts that are (potentially) available in the workspace. + * + * @param type The type of the repository, may be {@code null}. + * @param key The (comparison) key for the repository, may be {@code null} to generate a unique random key. + */ + public WorkspaceRepository( String type, Object key ) + { + this.type = ( type != null ) ? type : ""; + this.key = ( key != null ) ? key : UUID.randomUUID().toString().replace( "-", "" ); + } + + public String getContentType() + { + return type; + } + + public String getId() + { + return "workspace"; + } + + /** + * Gets the key of this workspace repository. The key is used to distinguish one workspace from another and should + * be sensitive to the artifacts that are (potentially) available in the workspace. + * + * @return The (comparison) key for this workspace repository, never {@code null}. + */ + public Object getKey() + { + return key; + } + + @Override + public String toString() + { + return "(" + getContentType() + ")"; + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + WorkspaceRepository that = (WorkspaceRepository) obj; + + return getContentType().equals( that.getContentType() ) && getKey().equals( that.getKey() ); + } + + @Override + public int hashCode() + { + int hash = 17; + hash = hash * 31 + getKey().hashCode(); + hash = hash * 31 + getContentType().hashCode(); + return hash; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/repository/package-info.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/repository/package-info.java b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/package-info.java new file mode 100644 index 0000000..538e7f1 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/repository/package-info.java @@ -0,0 +1,24 @@ +// CHECKSTYLE_OFF: RegexpHeader +/* + * 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. + */ +/** + * The definition of various kinds of repositories that host artifacts. + */ +package org.eclipse.aether.repository; + http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorException.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorException.java new file mode 100644 index 0000000..d645a82 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorException.java @@ -0,0 +1,91 @@ +package org.eclipse.aether.resolution; + +/* + * 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.RepositoryException; + +/** + * Thrown in case of an unreadable or unresolvable artifact descriptor. + */ +public class ArtifactDescriptorException + extends RepositoryException +{ + + private final transient ArtifactDescriptorResult result; + + /** + * Creates a new exception with the specified result. + * + * @param result The descriptor result at the point the exception occurred, may be {@code null}. + */ + public ArtifactDescriptorException( ArtifactDescriptorResult result ) + { + super( "Failed to read artifact descriptor" + + ( result != null ? " for " + result.getRequest().getArtifact() : "" ), getCause( result ) ); + this.result = result; + } + + /** + * Creates a new exception with the specified result and detail message. + * + * @param result The descriptor result at the point the exception occurred, may be {@code null}. + * @param message The detail message, may be {@code null}. + */ + public ArtifactDescriptorException( ArtifactDescriptorResult result, String message ) + { + super( message, getCause( result ) ); + this.result = result; + } + + /** + * Creates a new exception with the specified result, detail message and cause. + * + * @param result The descriptor result at the point the exception occurred, may be {@code null}. + * @param message The detail message, may be {@code null}. + * @param cause The exception that caused this one, may be {@code null}. + */ + public ArtifactDescriptorException( ArtifactDescriptorResult result, String message, Throwable cause ) + { + super( message, cause ); + this.result = result; + } + + /** + * Gets the descriptor result at the point the exception occurred. Despite being incomplete, callers might want to + * use this result to fail gracefully and continue their operation with whatever interim data has been gathered. + * + * @return The descriptor result or {@code null} if unknown. + */ + public ArtifactDescriptorResult getResult() + { + return result; + } + + private static Throwable getCause( ArtifactDescriptorResult result ) + { + Throwable cause = null; + if ( result != null && !result.getExceptions().isEmpty() ) + { + cause = result.getExceptions().get( 0 ); + } + return cause; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicy.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicy.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicy.java new file mode 100644 index 0000000..c4de9b2 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicy.java @@ -0,0 +1,61 @@ +package org.eclipse.aether.resolution; + +/* + * 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; + +/** + * Controls the handling of errors related to reading an artifact descriptor. + * + * @see RepositorySystemSession#getArtifactDescriptorPolicy() + */ +public interface ArtifactDescriptorPolicy +{ + + /** + * Bit mask indicating that errors while reading the artifact descriptor should not be tolerated. + */ + int STRICT = 0x00; + + /** + * Bit flag indicating that missing artifact descriptors should be silently ignored. + */ + int IGNORE_MISSING = 0x01; + + /** + * Bit flag indicating that existent but invalid artifact descriptors should be silently ignored. + */ + int IGNORE_INVALID = 0x02; + + /** + * Bit mask indicating that all errors should be silently ignored. + */ + int IGNORE_ERRORS = IGNORE_MISSING | IGNORE_INVALID; + + /** + * Gets the error policy for an artifact's descriptor. + * + * @param session The repository session during which the policy is determined, must not be {@code null}. + * @param request The policy request holding further details, must not be {@code null}. + * @return The bit mask describing the desired error policy. + */ + int getPolicy( RepositorySystemSession session, ArtifactDescriptorPolicyRequest request ); + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicyRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicyRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicyRequest.java new file mode 100644 index 0000000..ffaac16 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorPolicyRequest.java @@ -0,0 +1,106 @@ +package org.eclipse.aether.resolution; + +/* + * 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; + +/** + * A query for the error policy for a given artifact's descriptor. + * + * @see ArtifactDescriptorPolicy + */ +public final class ArtifactDescriptorPolicyRequest +{ + + private Artifact artifact; + + private String context = ""; + + /** + * Creates an uninitialized request. + */ + public ArtifactDescriptorPolicyRequest() + { + // enables default constructor + } + + /** + * Creates a request for the specified artifact. + * + * @param artifact The artifact for whose descriptor to determine the error policy, may be {@code null}. + * @param context The context in which this request is made, may be {@code null}. + */ + public ArtifactDescriptorPolicyRequest( Artifact artifact, String context ) + { + setArtifact( artifact ); + setRequestContext( context ); + } + + /** + * Gets the artifact for whose descriptor to determine the error policy. + * + * @return The artifact for whose descriptor to determine the error policy or {@code null} if not set. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact for whose descriptor to determine the error policy. + * + * @param artifact The artifact for whose descriptor to determine the error policy, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorPolicyRequest setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the context in which this request is made. + * + * @return The context, never {@code null}. + */ + public String getRequestContext() + { + return context; + } + + /** + * Sets the context in which this request is made. + * + * @param context The context, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorPolicyRequest setRequestContext( String context ) + { + this.context = ( context != null ) ? context : ""; + return this; + } + + @Override + public String toString() + { + return String.valueOf( getArtifact() ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorRequest.java new file mode 100644 index 0000000..387b1dc --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorRequest.java @@ -0,0 +1,190 @@ +package org.eclipse.aether.resolution; + +/* + * 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.Collections; +import java.util.List; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.repository.RemoteRepository; + +/** + * A request to read an artifact descriptor. + * + * @see RepositorySystem#readArtifactDescriptor(RepositorySystemSession, ArtifactDescriptorRequest) + */ +public final class ArtifactDescriptorRequest +{ + + private Artifact artifact; + + private List<RemoteRepository> repositories = Collections.emptyList(); + + private String context = ""; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. + */ + public ArtifactDescriptorRequest() + { + // enables default constructor + } + + /** + * Creates a request with the specified properties. + * + * @param artifact The artifact whose descriptor should be read, may be {@code null}. + * @param repositories The repositories to resolve the descriptor from, may be {@code null}. + * @param context The context in which this request is made, may be {@code null}. + */ + public ArtifactDescriptorRequest( Artifact artifact, List<RemoteRepository> repositories, String context ) + { + setArtifact( artifact ); + setRepositories( repositories ); + setRequestContext( context ); + } + + /** + * Gets the artifact whose descriptor shall be read. + * + * @return The artifact or {@code null} if not set. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact whose descriptor shall be read. Eventually, a valid request must have an artifact set. + * + * @param artifact The artifact, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorRequest setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the repositories to resolve the descriptor from. + * + * @return The repositories, never {@code null}. + */ + public List<RemoteRepository> getRepositories() + { + return repositories; + } + + /** + * Sets the repositories to resolve the descriptor from. + * + * @param repositories The repositories, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorRequest setRepositories( List<RemoteRepository> repositories ) + { + if ( repositories == null ) + { + this.repositories = Collections.emptyList(); + } + else + { + this.repositories = repositories; + } + return this; + } + + /** + * Adds the specified repository for the resolution of the artifact descriptor. + * + * @param repository The repository to add, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorRequest addRepository( RemoteRepository repository ) + { + if ( repository != null ) + { + if ( this.repositories.isEmpty() ) + { + this.repositories = new ArrayList<RemoteRepository>(); + } + this.repositories.add( repository ); + } + return this; + } + + /** + * Gets the context in which this request is made. + * + * @return The context, never {@code null}. + */ + public String getRequestContext() + { + return context; + } + + /** + * Sets the context in which this request is made. + * + * @param context The context, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorRequest setRequestContext( String context ) + { + this.context = ( context != null ) ? context : ""; + return this; + } + + /** + * Gets the trace information that describes the higher level request/operation in which this request is issued. + * + * @return The trace information about the higher level operation or {@code null} if none. + */ + public RequestTrace getTrace() + { + return trace; + } + + /** + * Sets the trace information that describes the higher level request/operation in which this request is issued. + * + * @param trace The trace information about the higher level operation, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactDescriptorRequest setTrace( RequestTrace trace ) + { + this.trace = trace; + return this; + } + + @Override + public String toString() + { + return getArtifact() + " < " + getRepositories(); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorResult.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorResult.java new file mode 100644 index 0000000..4c53b6e --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactDescriptorResult.java @@ -0,0 +1,466 @@ +package org.eclipse.aether.resolution; + +/* + * 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 java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.repository.RemoteRepository; + +/** + * The result from reading an artifact descriptor. + * + * @see RepositorySystem#readArtifactDescriptor(RepositorySystemSession, ArtifactDescriptorRequest) + */ +public final class ArtifactDescriptorResult +{ + + private final ArtifactDescriptorRequest request; + + private List<Exception> exceptions; + + private List<Artifact> relocations; + + private Collection<Artifact> aliases; + + private Artifact artifact; + + private ArtifactRepository repository; + + private List<Dependency> dependencies; + + private List<Dependency> managedDependencies; + + private List<RemoteRepository> repositories; + + private Map<String, Object> properties; + + /** + * Creates a new result for the specified request. + * + * @param request The descriptor request, must not be {@code null}. + */ + public ArtifactDescriptorResult( ArtifactDescriptorRequest request ) + { + if ( request == null ) + { + throw new IllegalArgumentException( "artifact descriptor request has not been specified" ); + } + this.request = request; + artifact = request.getArtifact(); + exceptions = Collections.emptyList(); + relocations = Collections.emptyList(); + aliases = Collections.emptyList(); + dependencies = managedDependencies = Collections.emptyList(); + repositories = Collections.emptyList(); + properties = Collections.emptyMap(); + } + + /** + * Gets the descriptor request that was made. + * + * @return The descriptor request, never {@code null}. + */ + public ArtifactDescriptorRequest getRequest() + { + return request; + } + + /** + * Gets the exceptions that occurred while reading the artifact descriptor. + * + * @return The exceptions that occurred, never {@code null}. + */ + public List<Exception> getExceptions() + { + return exceptions; + } + + /** + * Sets the exceptions that occurred while reading the artifact descriptor. + * + * @param exceptions The exceptions that occurred, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setExceptions( List<Exception> exceptions ) + { + if ( exceptions == null ) + { + this.exceptions = Collections.emptyList(); + } + else + { + this.exceptions = exceptions; + } + return this; + } + + /** + * Records the specified exception while reading the artifact descriptor. + * + * @param exception The exception to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addException( Exception exception ) + { + if ( exception != null ) + { + if ( exceptions.isEmpty() ) + { + exceptions = new ArrayList<Exception>(); + } + exceptions.add( exception ); + } + return this; + } + + /** + * Gets the relocations that were processed to read the artifact descriptor. The returned list denotes the hops that + * lead to the final artifact coordinates as given by {@link #getArtifact()}. + * + * @return The relocations that were processed, never {@code null}. + */ + public List<Artifact> getRelocations() + { + return relocations; + } + + /** + * Sets the relocations that were processed to read the artifact descriptor. + * + * @param relocations The relocations that were processed, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setRelocations( List<Artifact> relocations ) + { + if ( relocations == null ) + { + this.relocations = Collections.emptyList(); + } + else + { + this.relocations = relocations; + } + return this; + } + + /** + * Records the specified relocation hop while locating the artifact descriptor. + * + * @param artifact The artifact that got relocated, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addRelocation( Artifact artifact ) + { + if ( artifact != null ) + { + if ( relocations.isEmpty() ) + { + relocations = new ArrayList<Artifact>(); + } + relocations.add( artifact ); + } + return this; + } + + /** + * Gets the known aliases for this artifact. An alias denotes a different artifact with (almost) the same contents + * and can be used to mark a patched rebuild of some other artifact as such, thereby allowing conflict resolution to + * consider the patched and the original artifact as a conflict. + * + * @return The aliases of the artifact, never {@code null}. + */ + public Collection<Artifact> getAliases() + { + return aliases; + } + + /** + * Sets the aliases of the artifact. + * + * @param aliases The aliases of the artifact, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setAliases( Collection<Artifact> aliases ) + { + if ( aliases == null ) + { + this.aliases = Collections.emptyList(); + } + else + { + this.aliases = aliases; + } + return this; + } + + /** + * Records the specified alias. + * + * @param alias The alias for the artifact, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addAlias( Artifact alias ) + { + if ( alias != null ) + { + if ( aliases.isEmpty() ) + { + aliases = new ArrayList<Artifact>(); + } + aliases.add( alias ); + } + return this; + } + + /** + * Gets the artifact whose descriptor was read. This can be a different artifact than originally requested in case + * relocations were encountered. + * + * @return The artifact after following any relocations, never {@code null}. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact whose descriptor was read. + * + * @param artifact The artifact whose descriptor was read, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the repository from which the descriptor was eventually resolved. + * + * @return The repository from which the descriptor was resolved or {@code null} if unknown. + */ + public ArtifactRepository getRepository() + { + return repository; + } + + /** + * Sets the repository from which the descriptor was resolved. + * + * @param repository The repository from which the descriptor was resolved, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setRepository( ArtifactRepository repository ) + { + this.repository = repository; + return this; + } + + /** + * Gets the list of direct dependencies of the artifact. + * + * @return The list of direct dependencies, never {@code null} + */ + public List<Dependency> getDependencies() + { + return dependencies; + } + + /** + * Sets the list of direct dependencies of the artifact. + * + * @param dependencies The list of direct dependencies, may be {@code null} + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setDependencies( List<Dependency> dependencies ) + { + if ( dependencies == null ) + { + this.dependencies = Collections.emptyList(); + } + else + { + this.dependencies = dependencies; + } + return this; + } + + /** + * Adds the specified direct dependency. + * + * @param dependency The direct dependency to add, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addDependency( Dependency dependency ) + { + if ( dependency != null ) + { + if ( dependencies.isEmpty() ) + { + dependencies = new ArrayList<Dependency>(); + } + dependencies.add( dependency ); + } + return this; + } + + /** + * Gets the dependency management information. + * + * @return The dependency management information. + */ + public List<Dependency> getManagedDependencies() + { + return managedDependencies; + } + + /** + * Sets the dependency management information. + * + * @param dependencies The dependency management information, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setManagedDependencies( List<Dependency> dependencies ) + { + if ( dependencies == null ) + { + this.managedDependencies = Collections.emptyList(); + } + else + { + this.managedDependencies = dependencies; + } + return this; + } + + /** + * Adds the specified managed dependency. + * + * @param dependency The managed dependency to add, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addManagedDependency( Dependency dependency ) + { + if ( dependency != null ) + { + if ( managedDependencies.isEmpty() ) + { + managedDependencies = new ArrayList<Dependency>(); + } + managedDependencies.add( dependency ); + } + return this; + } + + /** + * Gets the remote repositories listed in the artifact descriptor. + * + * @return The remote repositories listed in the artifact descriptor, never {@code null}. + */ + public List<RemoteRepository> getRepositories() + { + return repositories; + } + + /** + * Sets the remote repositories listed in the artifact descriptor. + * + * @param repositories The remote repositories listed in the artifact descriptor, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setRepositories( List<RemoteRepository> repositories ) + { + if ( repositories == null ) + { + this.repositories = Collections.emptyList(); + } + else + { + this.repositories = repositories; + } + return this; + } + + /** + * Adds the specified remote repository. + * + * @param repository The remote repository to add, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult addRepository( RemoteRepository repository ) + { + if ( repository != null ) + { + if ( repositories.isEmpty() ) + { + repositories = new ArrayList<RemoteRepository>(); + } + repositories.add( repository ); + } + return this; + } + + /** + * Gets any additional information about the artifact in form of key-value pairs. <em>Note:</em> Regardless of their + * actual type, all property values must be treated as being read-only. + * + * @return The additional information about the artifact, never {@code null}. + */ + public Map<String, Object> getProperties() + { + return properties; + } + + /** + * Sets any additional information about the artifact in form of key-value pairs. + * + * @param properties The additional information about the artifact, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactDescriptorResult setProperties( Map<String, Object> properties ) + { + if ( properties == null ) + { + this.properties = Collections.emptyMap(); + } + else + { + this.properties = properties; + } + return this; + } + + @Override + public String toString() + { + return getArtifact() + " -> " + getDependencies(); + } + +}