http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java new file mode 100644 index 0000000..a220207 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactRequest.java @@ -0,0 +1,232 @@ +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.graph.DependencyNode; +import org.eclipse.aether.repository.RemoteRepository; + +/** + * A request to resolve an artifact. + * + * @see RepositorySystem#resolveArtifacts(RepositorySystemSession, java.util.Collection) + * @see Artifact#getFile() + */ +public final class ArtifactRequest +{ + + private Artifact artifact; + + private DependencyNode node; + + private List<RemoteRepository> repositories = Collections.emptyList(); + + private String context = ""; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. + */ + public ArtifactRequest() + { + // enables default constructor + } + + /** + * Creates a request with the specified properties. + * + * @param artifact The artifact to resolve, may be {@code null}. + * @param repositories The repositories to resolve the artifact from, may be {@code null}. + * @param context The context in which this request is made, may be {@code null}. + */ + public ArtifactRequest( Artifact artifact, List<RemoteRepository> repositories, String context ) + { + setArtifact( artifact ); + setRepositories( repositories ); + setRequestContext( context ); + } + + /** + * Creates a request from the specified dependency node. + * + * @param node The dependency node to resolve, may be {@code null}. + */ + public ArtifactRequest( DependencyNode node ) + { + setDependencyNode( node ); + setRepositories( node.getRepositories() ); + setRequestContext( node.getRequestContext() ); + } + + /** + * Gets the artifact to resolve. + * + * @return The artifact to resolve or {@code null}. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact to resolve. + * + * @param artifact The artifact to resolve, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactRequest setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the dependency node (if any) for which to resolve the artifact. + * + * @return The dependency node to resolve or {@code null} if unknown. + */ + public DependencyNode getDependencyNode() + { + return node; + } + + /** + * Sets the dependency node to resolve. + * + * @param node The dependency node to resolve, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactRequest setDependencyNode( DependencyNode node ) + { + this.node = node; + if ( node != null ) + { + setArtifact( node.getDependency().getArtifact() ); + } + return this; + } + + /** + * Gets the repositories to resolve the artifact from. + * + * @return The repositories, never {@code null}. + */ + public List<RemoteRepository> getRepositories() + { + return repositories; + } + + /** + * Sets the repositories to resolve the artifact from. + * + * @param repositories The repositories, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactRequest setRepositories( List<RemoteRepository> repositories ) + { + if ( repositories == null ) + { + this.repositories = Collections.emptyList(); + } + else + { + this.repositories = repositories; + } + return this; + } + + /** + * Adds the specified repository for the resolution. + * + * @param repository The repository to add, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ArtifactRequest 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 ArtifactRequest 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 ArtifactRequest 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/ArtifactResolutionException.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java new file mode 100644 index 0000000..bfae4a0 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java @@ -0,0 +1,173 @@ +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.Collections; +import java.util.List; + +import org.eclipse.aether.RepositoryException; +import org.eclipse.aether.transfer.ArtifactNotFoundException; +import org.eclipse.aether.transfer.RepositoryOfflineException; + +/** + * Thrown in case of a unresolvable artifacts. + */ +public class ArtifactResolutionException + extends RepositoryException +{ + + private final transient List<ArtifactResult> results; + + /** + * Creates a new exception with the specified results. + * + * @param results The resolution results at the point the exception occurred, may be {@code null}. + */ + public ArtifactResolutionException( List<ArtifactResult> results ) + { + super( getMessage( results ), getCause( results ) ); + this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList(); + } + + /** + * Creates a new exception with the specified results and detail message. + * + * @param results The resolution results at the point the exception occurred, may be {@code null}. + * @param message The detail message, may be {@code null}. + */ + public ArtifactResolutionException( List<ArtifactResult> results, String message ) + { + super( message, getCause( results ) ); + this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList(); + } + + /** + * Creates a new exception with the specified results, detail message and cause. + * + * @param results The resolution results 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 ArtifactResolutionException( List<ArtifactResult> results, String message, Throwable cause ) + { + super( message, cause ); + this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList(); + } + + /** + * Gets the resolution results at the point the exception occurred. Despite being incomplete, callers might want to + * use these results to fail gracefully and continue their operation with whatever interim data has been gathered. + * + * @return The resolution results or {@code null} if unknown. + */ + public List<ArtifactResult> getResults() + { + return results; + } + + /** + * Gets the first result from {@link #getResults()}. This is a convenience method for cases where callers know only + * a single result/request is involved. + * + * @return The (first) resolution result or {@code null} if none. + */ + public ArtifactResult getResult() + { + return ( results != null && !results.isEmpty() ) ? results.get( 0 ) : null; + } + + private static String getMessage( List<? extends ArtifactResult> results ) + { + StringBuilder buffer = new StringBuilder( 256 ); + + buffer.append( "The following artifacts could not be resolved: " ); + + int unresolved = 0; + + String sep = ""; + for ( ArtifactResult result : results ) + { + if ( !result.isResolved() ) + { + unresolved++; + + buffer.append( sep ); + buffer.append( result.getRequest().getArtifact() ); + sep = ", "; + } + } + + Throwable cause = getCause( results ); + if ( cause != null ) + { + if ( unresolved == 1 ) + { + buffer.setLength( 0 ); + buffer.append( cause.getMessage() ); + } + else + { + buffer.append( ": " ).append( cause.getMessage() ); + } + } + + return buffer.toString(); + } + + private static Throwable getCause( List<? extends ArtifactResult> results ) + { + for ( ArtifactResult result : results ) + { + if ( !result.isResolved() ) + { + Throwable notFound = null, offline = null; + for ( Throwable t : result.getExceptions() ) + { + if ( t instanceof ArtifactNotFoundException ) + { + if ( notFound == null ) + { + notFound = t; + } + if ( offline == null && t.getCause() instanceof RepositoryOfflineException ) + { + offline = t; + } + } + else + { + return t; + } + + } + if ( offline != null ) + { + return offline; + } + if ( notFound != null ) + { + return notFound; + } + } + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java new file mode 100644 index 0000000..5ae820b --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java @@ -0,0 +1,188 @@ +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.artifact.Artifact; +import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.transfer.ArtifactNotFoundException; + +/** + * The result of an artifact resolution request. + * + * @see RepositorySystem#resolveArtifacts(RepositorySystemSession, java.util.Collection) + * @see Artifact#getFile() + */ +public final class ArtifactResult +{ + + private final ArtifactRequest request; + + private List<Exception> exceptions; + + private Artifact artifact; + + private ArtifactRepository repository; + + /** + * Creates a new result for the specified request. + * + * @param request The resolution request, must not be {@code null}. + */ + public ArtifactResult( ArtifactRequest request ) + { + if ( request == null ) + { + throw new IllegalArgumentException( "resolution request has not been specified" ); + } + this.request = request; + exceptions = Collections.emptyList(); + } + + /** + * Gets the resolution request that was made. + * + * @return The resolution request, never {@code null}. + */ + public ArtifactRequest getRequest() + { + return request; + } + + /** + * Gets the resolved artifact (if any). Use {@link #getExceptions()} to query the errors that occurred while trying + * to resolve the artifact. + * + * @return The resolved artifact or {@code null} if the resolution failed. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the resolved artifact. + * + * @param artifact The resolved artifact, may be {@code null} if the resolution failed. + * @return This result for chaining, never {@code null}. + */ + public ArtifactResult setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the exceptions that occurred while resolving the artifact. Note that this list can be non-empty even if the + * artifact was successfully resolved, e.g. when one of the contacted remote repositories didn't contain the + * artifact but a later repository eventually contained it. + * + * @return The exceptions that occurred, never {@code null}. + * @see #isResolved() + */ + public List<Exception> getExceptions() + { + return exceptions; + } + + /** + * Records the specified exception while resolving the artifact. + * + * @param exception The exception to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactResult addException( Exception exception ) + { + if ( exception != null ) + { + if ( exceptions.isEmpty() ) + { + exceptions = new ArrayList<Exception>(); + } + exceptions.add( exception ); + } + return this; + } + + /** + * Gets the repository from which the artifact was eventually resolved. Note that successive resolutions of the same + * artifact might yield different results if the employed local repository does not track the origin of an artifact. + * + * @return The repository from which the artifact was resolved or {@code null} if unknown. + */ + public ArtifactRepository getRepository() + { + return repository; + } + + /** + * Sets the repository from which the artifact was resolved. + * + * @param repository The repository from which the artifact was resolved, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public ArtifactResult setRepository( ArtifactRepository repository ) + { + this.repository = repository; + return this; + } + + /** + * Indicates whether the requested artifact was resolved. Note that the artifact might have been successfully + * resolved despite {@link #getExceptions()} indicating transfer errors while trying to fetch the artifact from some + * of the specified remote repositories. + * + * @return {@code true} if the artifact was resolved, {@code false} otherwise. + * @see Artifact#getFile() + */ + public boolean isResolved() + { + return getArtifact() != null && getArtifact().getFile() != null; + } + + /** + * Indicates whether the requested artifact is not present in any of the specified repositories. + * + * @return {@code true} if the artifact is not present in any repository, {@code false} otherwise. + */ + public boolean isMissing() + { + for ( Exception e : getExceptions() ) + { + if ( !( e instanceof ArtifactNotFoundException ) ) + { + return false; + } + } + return !isResolved(); + } + + @Override + public String toString() + { + return getArtifact() + " < " + getRepository(); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java new file mode 100644 index 0000000..138304a --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyRequest.java @@ -0,0 +1,187 @@ +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.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.graph.DependencyNode; + +/** + * A request to resolve transitive dependencies. This request can either be supplied with a {@link CollectRequest} to + * calculate the transitive dependencies or with an already resolved dependency graph. + * + * @see RepositorySystem#resolveDependencies(RepositorySystemSession, DependencyRequest) + * @see Artifact#getFile() + */ +public final class DependencyRequest +{ + + private DependencyNode root; + + private CollectRequest collectRequest; + + private DependencyFilter filter; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. Note that either {@link #setRoot(DependencyNode)} or + * {@link #setCollectRequest(CollectRequest)} must eventually be called to create a valid request. + */ + public DependencyRequest() + { + // enables default constructor + } + + /** + * Creates a request for the specified dependency graph and with the given resolution filter. + * + * @param node The root node of the dependency graph whose artifacts should be resolved, may be {@code null}. + * @param filter The resolution filter to use, may be {@code null}. + */ + public DependencyRequest( DependencyNode node, DependencyFilter filter ) + { + setRoot( node ); + setFilter( filter ); + } + + /** + * Creates a request for the specified collect request and with the given resolution filter. + * + * @param request The collect request used to calculate the dependency graph whose artifacts should be resolved, may + * be {@code null}. + * @param filter The resolution filter to use, may be {@code null}. + */ + public DependencyRequest( CollectRequest request, DependencyFilter filter ) + { + setCollectRequest( request ); + setFilter( filter ); + } + + /** + * Gets the root node of the dependency graph whose artifacts should be resolved. + * + * @return The root node of the dependency graph or {@code null} if none. + */ + public DependencyNode getRoot() + { + return root; + } + + /** + * Sets the root node of the dependency graph whose artifacts should be resolved. When this request is processed, + * the nodes of the given dependency graph will be updated to refer to the resolved artifacts. Eventually, either + * {@link #setRoot(DependencyNode)} or {@link #setCollectRequest(CollectRequest)} must be called to create a valid + * request. + * + * @param root The root node of the dependency graph, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public DependencyRequest setRoot( DependencyNode root ) + { + this.root = root; + return this; + } + + /** + * Gets the collect request used to calculate the dependency graph whose artifacts should be resolved. + * + * @return The collect request or {@code null} if none. + */ + public CollectRequest getCollectRequest() + { + return collectRequest; + } + + /** + * Sets the collect request used to calculate the dependency graph whose artifacts should be resolved. Eventually, + * either {@link #setRoot(DependencyNode)} or {@link #setCollectRequest(CollectRequest)} must be called to create a + * valid request. If this request is supplied with a dependency node via {@link #setRoot(DependencyNode)}, the + * collect request is ignored. + * + * @param collectRequest The collect request, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public DependencyRequest setCollectRequest( CollectRequest collectRequest ) + { + this.collectRequest = collectRequest; + return this; + } + + /** + * Gets the resolution filter used to select which artifacts of the dependency graph should be resolved. + * + * @return The resolution filter or {@code null} to resolve all artifacts of the dependency graph. + */ + public DependencyFilter getFilter() + { + return filter; + } + + /** + * Sets the resolution filter used to select which artifacts of the dependency graph should be resolved. For + * example, use this filter to restrict resolution to dependencies of a certain scope. + * + * @param filter The resolution filter, may be {@code null} to resolve all artifacts of the dependency graph. + * @return This request for chaining, never {@code null}. + */ + public DependencyRequest setFilter( DependencyFilter filter ) + { + this.filter = filter; + 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 DependencyRequest setTrace( RequestTrace trace ) + { + this.trace = trace; + return this; + } + + @Override + public String toString() + { + if ( root != null ) + { + return String.valueOf( root ); + } + return String.valueOf( collectRequest ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java new file mode 100644 index 0000000..2c12b57 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResolutionException.java @@ -0,0 +1,83 @@ +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 a unresolvable dependencies. + */ +public class DependencyResolutionException + extends RepositoryException +{ + + private final transient DependencyResult result; + + /** + * Creates a new exception with the specified result and cause. + * + * @param result The dependency result at the point the exception occurred, may be {@code null}. + * @param cause The exception that caused this one, may be {@code null}. + */ + public DependencyResolutionException( DependencyResult result, Throwable cause ) + { + super( getMessage( cause ), cause ); + this.result = result; + } + + /** + * Creates a new exception with the specified result, detail message and cause. + * + * @param result The dependency 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 DependencyResolutionException( DependencyResult result, String message, Throwable cause ) + { + super( message, cause ); + this.result = result; + } + + private static String getMessage( Throwable cause ) + { + String msg = null; + if ( cause != null ) + { + msg = cause.getMessage(); + } + if ( msg == null || msg.length() <= 0 ) + { + msg = "Could not resolve transitive dependencies"; + } + return msg; + } + + /** + * Gets the dependency 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 dependency result or {@code null} if unknown. + */ + public DependencyResult getResult() + { + return result; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java new file mode 100644 index 0000000..030e923 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/DependencyResult.java @@ -0,0 +1,195 @@ +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.Collections; +import java.util.List; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.graph.DependencyCycle; +import org.eclipse.aether.graph.DependencyNode; + +/** + * The result of a dependency resolution request. + * + * @see RepositorySystem#resolveDependencies(RepositorySystemSession, DependencyRequest) + */ +public final class DependencyResult +{ + + private final DependencyRequest request; + + private DependencyNode root; + + private List<DependencyCycle> cycles; + + private List<Exception> collectExceptions; + + private List<ArtifactResult> artifactResults; + + /** + * Creates a new result for the specified request. + * + * @param request The resolution request, must not be {@code null}. + */ + public DependencyResult( DependencyRequest request ) + { + if ( request == null ) + { + throw new IllegalArgumentException( "dependency request has not been specified" ); + } + this.request = request; + root = request.getRoot(); + cycles = Collections.emptyList(); + collectExceptions = Collections.emptyList(); + artifactResults = Collections.emptyList(); + } + + /** + * Gets the resolution request that was made. + * + * @return The resolution request, never {@code null}. + */ + public DependencyRequest getRequest() + { + return request; + } + + /** + * Gets the root node of the resolved dependency graph. Note that this dependency graph might be + * incomplete/unfinished in case of {@link #getCollectExceptions()} indicating errors during its calculation. + * + * @return The root node of the resolved dependency graph or {@code null} if none. + */ + public DependencyNode getRoot() + { + return root; + } + + /** + * Sets the root node of the resolved dependency graph. + * + * @param root The root node of the resolved dependency graph, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public DependencyResult setRoot( DependencyNode root ) + { + this.root = root; + return this; + } + + /** + * Gets the dependency cycles that were encountered while building the dependency graph. Note that dependency cycles + * will only be reported here if the underlying request was created from a + * {@link org.eclipse.aether.collection.CollectRequest CollectRequest}. If the underlying {@link DependencyRequest} + * was created from an existing dependency graph, information about cycles will not be available in this result. + * + * @return The dependency cycles in the (raw) graph, never {@code null}. + */ + public List<DependencyCycle> getCycles() + { + return cycles; + } + + /** + * Records the specified dependency cycles while building the dependency graph. + * + * @param cycles The dependency cycles to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public DependencyResult setCycles( List<DependencyCycle> cycles ) + { + if ( cycles == null ) + { + this.cycles = Collections.emptyList(); + } + else + { + this.cycles = cycles; + } + return this; + } + + /** + * Gets the exceptions that occurred while building the dependency graph. + * + * @return The exceptions that occurred, never {@code null}. + */ + public List<Exception> getCollectExceptions() + { + return collectExceptions; + } + + /** + * Records the specified exceptions while building the dependency graph. + * + * @param exceptions The exceptions to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public DependencyResult setCollectExceptions( List<Exception> exceptions ) + { + if ( exceptions == null ) + { + this.collectExceptions = Collections.emptyList(); + } + else + { + this.collectExceptions = exceptions; + } + return this; + } + + /** + * Gets the resolution results for the dependency artifacts that matched {@link DependencyRequest#getFilter()}. + * + * @return The resolution results for the dependency artifacts, never {@code null}. + */ + public List<ArtifactResult> getArtifactResults() + { + return artifactResults; + } + + /** + * Sets the resolution results for the artifacts that matched {@link DependencyRequest#getFilter()}. + * + * @param results The resolution results for the artifacts, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public DependencyResult setArtifactResults( List<ArtifactResult> results ) + { + if ( results == null ) + { + this.artifactResults = Collections.emptyList(); + } + else + { + this.artifactResults = results; + } + return this; + } + + @Override + public String toString() + { + return String.valueOf( artifactResults ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java new file mode 100644 index 0000000..86063ff --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataRequest.java @@ -0,0 +1,232 @@ +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.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.repository.RemoteRepository; + +/** + * A request to resolve metadata from either a remote repository or the local repository. + * + * @see RepositorySystem#resolveMetadata(RepositorySystemSession, java.util.Collection) + * @see Metadata#getFile() + */ +public final class MetadataRequest +{ + + private Metadata metadata; + + private RemoteRepository repository; + + private String context = ""; + + private boolean deleteLocalCopyIfMissing; + + private boolean favorLocalRepository; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. + */ + public MetadataRequest() + { + // enables default constructor + } + + /** + * Creates a request to resolve the specified metadata from the local repository. + * + * @param metadata The metadata to resolve, may be {@code null}. + */ + public MetadataRequest( Metadata metadata ) + { + setMetadata( metadata ); + } + + /** + * Creates a request with the specified properties. + * + * @param metadata The metadata to resolve, may be {@code null}. + * @param repository The repository to resolve the metadata from, may be {@code null} to resolve from the local + * repository. + * @param context The context in which this request is made, may be {@code null}. + */ + public MetadataRequest( Metadata metadata, RemoteRepository repository, String context ) + { + setMetadata( metadata ); + setRepository( repository ); + setRequestContext( context ); + } + + /** + * Gets the metadata to resolve. + * + * @return The metadata or {@code null} if not set. + */ + public Metadata getMetadata() + { + return metadata; + } + + /** + * Sets the metadata to resolve. + * + * @param metadata The metadata, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public MetadataRequest setMetadata( Metadata metadata ) + { + this.metadata = metadata; + return this; + } + + /** + * Gets the repository from which the metadata should be resolved. + * + * @return The repository or {@code null} to resolve from the local repository. + */ + public RemoteRepository getRepository() + { + return repository; + } + + /** + * Sets the repository from which the metadata should be resolved. + * + * @param repository The repository, may be {@code null} to resolve from the local repository. + * @return This request for chaining, never {@code null}. + */ + public MetadataRequest setRepository( RemoteRepository repository ) + { + this.repository = 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 MetadataRequest setRequestContext( String context ) + { + this.context = ( context != null ) ? context : ""; + return this; + } + + /** + * Indicates whether the locally cached copy of the metadata should be removed if the corresponding file does not + * exist (any more) in the remote repository. + * + * @return {@code true} if locally cached metadata should be deleted if no corresponding remote file exists, + * {@code false} to keep the local copy. + */ + public boolean isDeleteLocalCopyIfMissing() + { + return deleteLocalCopyIfMissing; + } + + /** + * Controls whether the locally cached copy of the metadata should be removed if the corresponding file does not + * exist (any more) in the remote repository. + * + * @param deleteLocalCopyIfMissing {@code true} if locally cached metadata should be deleted if no corresponding + * remote file exists, {@code false} to keep the local copy. + * @return This request for chaining, never {@code null}. + */ + public MetadataRequest setDeleteLocalCopyIfMissing( boolean deleteLocalCopyIfMissing ) + { + this.deleteLocalCopyIfMissing = deleteLocalCopyIfMissing; + return this; + } + + /** + * Indicates whether the metadata resolution should be suppressed if the corresponding metadata of the local + * repository is up-to-date according to the update policy of the remote repository. In this case, the metadata + * resolution will even be suppressed if no local copy of the remote metadata exists yet. + * + * @return {@code true} to suppress resolution of remote metadata if the corresponding metadata of the local + * repository is up-to-date, {@code false} to resolve the remote metadata normally according to the update + * policy. + */ + public boolean isFavorLocalRepository() + { + return favorLocalRepository; + } + + /** + * Controls resolution of remote metadata when already corresponding metadata of the local repository exists. In + * cases where the local repository's metadata is sufficient and going to be preferred, resolution of the remote + * metadata can be suppressed to avoid unnecessary network access. + * + * @param favorLocalRepository {@code true} to suppress resolution of remote metadata if the corresponding metadata + * of the local repository is up-to-date, {@code false} to resolve the remote metadata normally according + * to the update policy. + * @return This request for chaining, never {@code null}. + */ + public MetadataRequest setFavorLocalRepository( boolean favorLocalRepository ) + { + this.favorLocalRepository = favorLocalRepository; + 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 MetadataRequest setTrace( RequestTrace trace ) + { + this.trace = trace; + return this; + } + + @Override + public String toString() + { + return getMetadata() + " < " + getRepository(); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java new file mode 100644 index 0000000..2bba499 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/MetadataResult.java @@ -0,0 +1,166 @@ +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.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.transfer.MetadataNotFoundException; + +/** + * The result of a metadata resolution request. + * + * @see RepositorySystem#resolveMetadata(RepositorySystemSession, java.util.Collection) + */ +public final class MetadataResult +{ + + private final MetadataRequest request; + + private Exception exception; + + private boolean updated; + + private Metadata metadata; + + /** + * Creates a new result for the specified request. + * + * @param request The resolution request, must not be {@code null}. + */ + public MetadataResult( MetadataRequest request ) + { + if ( request == null ) + { + throw new IllegalArgumentException( "metadata request has not been specified" ); + } + this.request = request; + } + + /** + * Gets the resolution request that was made. + * + * @return The resolution request, never {@code null}. + */ + public MetadataRequest getRequest() + { + return request; + } + + /** + * Gets the resolved metadata (if any). + * + * @return The resolved metadata or {@code null} if the resolution failed. + */ + public Metadata getMetadata() + { + return metadata; + } + + /** + * Sets the resolved metadata. + * + * @param metadata The resolved metadata, may be {@code null} if the resolution failed. + * @return This result for chaining, never {@code null}. + */ + public MetadataResult setMetadata( Metadata metadata ) + { + this.metadata = metadata; + return this; + } + + /** + * Records the specified exception while resolving the metadata. + * + * @param exception The exception to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public MetadataResult setException( Exception exception ) + { + this.exception = exception; + return this; + } + + /** + * Gets the exception that occurred while resolving the metadata. + * + * @return The exception that occurred or {@code null} if none. + */ + public Exception getException() + { + return exception; + } + + /** + * Sets the updated flag for the metadata. + * + * @param updated {@code true} if the metadata was actually fetched from the remote repository during the + * resolution, {@code false} if the metadata was resolved from a locally cached copy. + * @return This result for chaining, never {@code null}. + */ + public MetadataResult setUpdated( boolean updated ) + { + this.updated = updated; + return this; + } + + /** + * Indicates whether the metadata was actually fetched from the remote repository or resolved from the local cache. + * If metadata has been locally cached during a previous resolution request and this local copy is still up-to-date + * according to the remote repository's update policy, no remote access is made. + * + * @return {@code true} if the metadata was actually fetched from the remote repository during the resolution, + * {@code false} if the metadata was resolved from a locally cached copy. + */ + public boolean isUpdated() + { + return updated; + } + + /** + * Indicates whether the requested metadata was resolved. Note that the metadata might have been successfully + * resolved (from the local cache) despite {@link #getException()} indicating a transfer error while trying to + * refetch the metadata from the remote repository. + * + * @return {@code true} if the metadata was resolved, {@code false} otherwise. + * @see Metadata#getFile() + */ + public boolean isResolved() + { + return getMetadata() != null && getMetadata().getFile() != null; + } + + /** + * Indicates whether the requested metadata is not present in the remote repository. + * + * @return {@code true} if the metadata is not present in the remote repository, {@code false} otherwise. + */ + public boolean isMissing() + { + return getException() instanceof MetadataNotFoundException; + } + + @Override + public String toString() + { + return getMetadata() + ( isUpdated() ? " (updated)" : " (cached)" ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java new file mode 100644 index 0000000..5158fa0 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicy.java @@ -0,0 +1,82 @@ +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; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.metadata.Metadata; + +/** + * Controls the caching of resolution errors for artifacts/metadata from remote repositories. If caching is enabled for + * a given resource, a marker will be set (usually somewhere in the local repository) to suppress repeated resolution + * attempts for the broken resource, thereby avoiding expensive but useless network IO. The error marker is considered + * stale once the repository's update policy has expired at which point a future resolution attempt will be allowed. + * Error caching considers the current network settings such that fixes to the configuration like authentication or + * proxy automatically trigger revalidation with the remote side regardless of the time elapsed since the previous + * resolution error. + * + * @see RepositorySystemSession#getResolutionErrorPolicy() + */ +public interface ResolutionErrorPolicy +{ + + /** + * Bit mask indicating that resolution errors should not be cached in the local repository. This forces the system + * to always query the remote repository for locally missing artifacts/metadata. + */ + int CACHE_DISABLED = 0x00; + + /** + * Bit flag indicating whether missing artifacts/metadata should be cached in the local repository. If caching is + * enabled, resolution will not be reattempted until the update policy for the affected resource has expired. + */ + int CACHE_NOT_FOUND = 0x01; + + /** + * Bit flag indicating whether connectivity/transfer errors (e.g. unreachable host, bad authentication) should be + * cached in the local repository. If caching is enabled, resolution will not be reattempted until the update policy + * for the affected resource has expired. + */ + int CACHE_TRANSFER_ERROR = 0x02; + + /** + * Bit mask indicating that all resolution errors should be cached in the local repository. + */ + int CACHE_ALL = CACHE_NOT_FOUND | CACHE_TRANSFER_ERROR; + + /** + * Gets the error policy for an artifact. + * + * @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 getArtifactPolicy( RepositorySystemSession session, ResolutionErrorPolicyRequest<Artifact> request ); + + /** + * Gets the error policy for some metadata. + * + * @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 getMetadataPolicy( RepositorySystemSession session, ResolutionErrorPolicyRequest<Metadata> request ); + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java new file mode 100644 index 0000000..9126914 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ResolutionErrorPolicyRequest.java @@ -0,0 +1,107 @@ +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.repository.RemoteRepository; + +/** + * A query for the resolution error policy for a given artifact/metadata. + * + * @param <T> The type of the affected repository item (artifact or metadata). + * @see ResolutionErrorPolicy + */ +public final class ResolutionErrorPolicyRequest<T> +{ + + private T item; + + private RemoteRepository repository; + + /** + * Creates an uninitialized request. + */ + public ResolutionErrorPolicyRequest() + { + // enables default constructor + } + + /** + * Creates a request for the specified artifact/metadata and remote repository. + * + * @param item The artifact/metadata for which to determine the error policy, may be {@code null}. + * @param repository The repository from which the resolution is attempted, may be {@code null}. + */ + public ResolutionErrorPolicyRequest( T item, RemoteRepository repository ) + { + setItem( item ); + setRepository( repository ); + } + + /** + * Gets the artifact/metadata for which to determine the error policy. + * + * @return The artifact/metadata for which to determine the error policy or {@code null} if not set. + */ + public T getItem() + { + return item; + } + + /** + * Sets the artifact/metadata for which to determine the error policy. + * + * @param item The artifact/metadata for which to determine the error policy, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ResolutionErrorPolicyRequest<T> setItem( T item ) + { + this.item = item; + return this; + } + + /** + * Gets the remote repository from which the resolution of the artifact/metadata is attempted. + * + * @return The involved remote repository or {@code null} if not set. + */ + public RemoteRepository getRepository() + { + return repository; + } + + /** + * Sets the remote repository from which the resolution of the artifact/metadata is attempted. + * + * @param repository The repository from which the resolution is attempted, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public ResolutionErrorPolicyRequest<T> setRepository( RemoteRepository repository ) + { + this.repository = repository; + return this; + } + + @Override + public String toString() + { + return getItem() + " < " + getRepository(); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.java new file mode 100644 index 0000000..d6aa16b --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeRequest.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 resolve a version range. + * + * @see RepositorySystem#resolveVersionRange(RepositorySystemSession, VersionRangeRequest) + */ +public final class VersionRangeRequest +{ + + private Artifact artifact; + + private List<RemoteRepository> repositories = Collections.emptyList(); + + private String context = ""; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. + */ + public VersionRangeRequest() + { + // enables default constructor + } + + /** + * Creates a request with the specified properties. + * + * @param artifact The artifact whose version range should be resolved, may be {@code null}. + * @param repositories The repositories to resolve the version from, may be {@code null}. + * @param context The context in which this request is made, may be {@code null}. + */ + public VersionRangeRequest( Artifact artifact, List<RemoteRepository> repositories, String context ) + { + setArtifact( artifact ); + setRepositories( repositories ); + setRequestContext( context ); + } + + /** + * Gets the artifact whose version range shall be resolved. + * + * @return The artifact or {@code null} if not set. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact whose version range shall be resolved. + * + * @param artifact The artifact, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRangeRequest setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the repositories to resolve the version range from. + * + * @return The repositories, never {@code null}. + */ + public List<RemoteRepository> getRepositories() + { + return repositories; + } + + /** + * Sets the repositories to resolve the version range from. + * + * @param repositories The repositories, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRangeRequest setRepositories( List<RemoteRepository> repositories ) + { + if ( repositories == null ) + { + this.repositories = Collections.emptyList(); + } + else + { + this.repositories = repositories; + } + return this; + } + + /** + * Adds the specified repository for the resolution. + * + * @param repository The repository to add, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRangeRequest 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 VersionRangeRequest 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 VersionRangeRequest 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/VersionRangeResolutionException.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java new file mode 100644 index 0000000..deb0e52 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResolutionException.java @@ -0,0 +1,105 @@ +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 unparseable or unresolvable version range. + */ +public class VersionRangeResolutionException + extends RepositoryException +{ + + private final transient VersionRangeResult result; + + /** + * Creates a new exception with the specified result. + * + * @param result The version range result at the point the exception occurred, may be {@code null}. + */ + public VersionRangeResolutionException( VersionRangeResult result ) + { + super( getMessage( result ), getCause( result ) ); + this.result = result; + } + + private static String getMessage( VersionRangeResult result ) + { + StringBuilder buffer = new StringBuilder( 256 ); + buffer.append( "Failed to resolve version range" ); + if ( result != null ) + { + buffer.append( " for " ).append( result.getRequest().getArtifact() ); + if ( !result.getExceptions().isEmpty() ) + { + buffer.append( ": " ).append( result.getExceptions().iterator().next().getMessage() ); + } + } + return buffer.toString(); + } + + private static Throwable getCause( VersionRangeResult result ) + { + Throwable cause = null; + if ( result != null && !result.getExceptions().isEmpty() ) + { + cause = result.getExceptions().get( 0 ); + } + return cause; + } + + /** + * Creates a new exception with the specified result and detail message. + * + * @param result The version range result at the point the exception occurred, may be {@code null}. + * @param message The detail message, may be {@code null}. + */ + public VersionRangeResolutionException( VersionRangeResult result, String message ) + { + super( message ); + this.result = result; + } + + /** + * Creates a new exception with the specified result, detail message and cause. + * + * @param result The version range 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 VersionRangeResolutionException( VersionRangeResult result, String message, Throwable cause ) + { + super( message, cause ); + this.result = result; + } + + /** + * Gets the version range 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 version range result or {@code null} if unknown. + */ + public VersionRangeResult getResult() + { + return result; + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java new file mode 100644 index 0000000..4749f7c --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRangeResult.java @@ -0,0 +1,240 @@ +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.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.version.Version; +import org.eclipse.aether.version.VersionConstraint; + +/** + * The result of a version range resolution request. + * + * @see RepositorySystem#resolveVersionRange(RepositorySystemSession, VersionRangeRequest) + */ +public final class VersionRangeResult +{ + + private final VersionRangeRequest request; + + private List<Exception> exceptions; + + private List<Version> versions; + + private Map<Version, ArtifactRepository> repositories; + + private VersionConstraint versionConstraint; + + /** + * Creates a new result for the specified request. + * + * @param request The resolution request, must not be {@code null}. + */ + public VersionRangeResult( VersionRangeRequest request ) + { + if ( request == null ) + { + throw new IllegalArgumentException( "version range request has not been specified" ); + } + this.request = request; + exceptions = Collections.emptyList(); + versions = Collections.emptyList(); + repositories = Collections.emptyMap(); + } + + /** + * Gets the resolution request that was made. + * + * @return The resolution request, never {@code null}. + */ + public VersionRangeRequest getRequest() + { + return request; + } + + /** + * Gets the exceptions that occurred while resolving the version range. + * + * @return The exceptions that occurred, never {@code null}. + */ + public List<Exception> getExceptions() + { + return exceptions; + } + + /** + * Records the specified exception while resolving the version range. + * + * @param exception The exception to record, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public VersionRangeResult addException( Exception exception ) + { + if ( exception != null ) + { + if ( exceptions.isEmpty() ) + { + exceptions = new ArrayList<Exception>(); + } + exceptions.add( exception ); + } + return this; + } + + /** + * Gets the versions (in ascending order) that matched the requested range. + * + * @return The matching versions (if any), never {@code null}. + */ + public List<Version> getVersions() + { + return versions; + } + + /** + * Adds the specified version to the result. Note that versions must be added in ascending order. + * + * @param version The version to add, must not be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public VersionRangeResult addVersion( Version version ) + { + if ( versions.isEmpty() ) + { + versions = new ArrayList<Version>(); + } + versions.add( version ); + return this; + } + + /** + * Sets the versions (in ascending order) matching the requested range. + * + * @param versions The matching versions, may be empty or {@code null} if none. + * @return This result for chaining, never {@code null}. + */ + public VersionRangeResult setVersions( List<Version> versions ) + { + if ( versions == null ) + { + this.versions = Collections.emptyList(); + } + else + { + this.versions = versions; + } + return this; + } + + /** + * Gets the lowest version matching the requested range. + * + * @return The lowest matching version or {@code null} if no versions matched the requested range. + */ + public Version getLowestVersion() + { + if ( versions.isEmpty() ) + { + return null; + } + return versions.get( 0 ); + } + + /** + * Gets the highest version matching the requested range. + * + * @return The highest matching version or {@code null} if no versions matched the requested range. + */ + public Version getHighestVersion() + { + if ( versions.isEmpty() ) + { + return null; + } + return versions.get( versions.size() - 1 ); + } + + /** + * Gets the repository from which the specified version was resolved. + * + * @param version The version whose source repository should be retrieved, must not be {@code null}. + * @return The repository from which the version was resolved or {@code null} if unknown. + */ + public ArtifactRepository getRepository( Version version ) + { + return repositories.get( version ); + } + + /** + * Records the repository from which the specified version was resolved + * + * @param version The version whose source repository is to be recorded, must not be {@code null}. + * @param repository The repository from which the version was resolved, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public VersionRangeResult setRepository( Version version, ArtifactRepository repository ) + { + if ( repository != null ) + { + if ( repositories.isEmpty() ) + { + repositories = new HashMap<Version, ArtifactRepository>(); + } + repositories.put( version, repository ); + } + return this; + } + + /** + * Gets the version constraint that was parsed from the artifact's version string. + * + * @return The parsed version constraint or {@code null}. + */ + public VersionConstraint getVersionConstraint() + { + return versionConstraint; + } + + /** + * Sets the version constraint that was parsed from the artifact's version string. + * + * @param versionConstraint The parsed version constraint, may be {@code null}. + * @return This result for chaining, never {@code null}. + */ + public VersionRangeResult setVersionConstraint( VersionConstraint versionConstraint ) + { + this.versionConstraint = versionConstraint; + return this; + } + + @Override + public String toString() + { + return String.valueOf( repositories ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/3a1b8ae0/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.java new file mode 100644 index 0000000..3dde7dd --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/VersionRequest.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 resolve a metaversion. + * + * @see RepositorySystem#resolveVersion(RepositorySystemSession, VersionRequest) + */ +public final class VersionRequest +{ + + private Artifact artifact; + + private List<RemoteRepository> repositories = Collections.emptyList(); + + private String context = ""; + + private RequestTrace trace; + + /** + * Creates an uninitialized request. + */ + public VersionRequest() + { + // enables default constructor + } + + /** + * Creates a request with the specified properties. + * + * @param artifact The artifact whose (meta-)version should be resolved, may be {@code null}. + * @param repositories The repositories to resolve the version from, may be {@code null}. + * @param context The context in which this request is made, may be {@code null}. + */ + public VersionRequest( Artifact artifact, List<RemoteRepository> repositories, String context ) + { + setArtifact( artifact ); + setRepositories( repositories ); + setRequestContext( context ); + } + + /** + * Gets the artifact whose (meta-)version shall be resolved. + * + * @return The artifact or {@code null} if not set. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact whose (meta-)version shall be resolved. + * + * @param artifact The artifact, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRequest setArtifact( Artifact artifact ) + { + this.artifact = artifact; + return this; + } + + /** + * Gets the repositories to resolve the version from. + * + * @return The repositories, never {@code null}. + */ + public List<RemoteRepository> getRepositories() + { + return repositories; + } + + /** + * Sets the repositories to resolve the version from. + * + * @param repositories The repositories, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRequest setRepositories( List<RemoteRepository> repositories ) + { + if ( repositories == null ) + { + this.repositories = Collections.emptyList(); + } + else + { + this.repositories = repositories; + } + return this; + } + + /** + * Adds the specified repository for the resolution. + * + * @param repository The repository to add, may be {@code null}. + * @return This request for chaining, never {@code null}. + */ + public VersionRequest 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 VersionRequest 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 VersionRequest setTrace( RequestTrace trace ) + { + this.trace = trace; + return this; + } + + @Override + public String toString() + { + return getArtifact() + " < " + getRepositories(); + } + +}