X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.repo%2Fsrc%2Forg%2Feclipse%2Faether%2Fgraph%2FDependency.java;fp=org.argeo.slc.repo%2Fsrc%2Forg%2Feclipse%2Faether%2Fgraph%2FDependency.java;h=72ea0f6d805130515cf14914ca083093d4b49947;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.repo/src/org/eclipse/aether/graph/Dependency.java b/org.argeo.slc.repo/src/org/eclipse/aether/graph/Dependency.java new file mode 100644 index 0000000..72ea0f6 --- /dev/null +++ b/org.argeo.slc.repo/src/org/eclipse/aether/graph/Dependency.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.graph; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.NoSuchElementException; +import java.util.Set; + +import org.eclipse.aether.artifact.Artifact; + +/** + * A dependency to some artifact. Note: Instances of this class are immutable and the exposed mutators return + * new objects rather than changing the current instance. + */ +public final class Dependency +{ + + private final Artifact artifact; + + private final String scope; + + private final Boolean optional; + + private final Set exclusions; + + /** + * Creates a mandatory dependency on the specified artifact with the given scope. + * + * @param artifact The artifact being depended on, must not be {@code null}. + * @param scope The scope of the dependency, may be {@code null}. + */ + public Dependency( Artifact artifact, String scope ) + { + this( artifact, scope, false ); + } + + /** + * Creates a dependency on the specified artifact with the given scope. + * + * @param artifact The artifact being depended on, must not be {@code null}. + * @param scope The scope of the dependency, may be {@code null}. + * @param optional A flag whether the dependency is optional or mandatory, may be {@code null}. + */ + public Dependency( Artifact artifact, String scope, Boolean optional ) + { + this( artifact, scope, optional, null ); + } + + /** + * Creates a dependency on the specified artifact with the given scope and exclusions. + * + * @param artifact The artifact being depended on, must not be {@code null}. + * @param scope The scope of the dependency, may be {@code null}. + * @param optional A flag whether the dependency is optional or mandatory, may be {@code null}. + * @param exclusions The exclusions that apply to transitive dependencies, may be {@code null} if none. + */ + public Dependency( Artifact artifact, String scope, Boolean optional, Collection exclusions ) + { + this( artifact, scope, Exclusions.copy( exclusions ), optional ); + } + + private Dependency( Artifact artifact, String scope, Set exclusions, Boolean optional ) + { + // NOTE: This constructor assumes immutability of the provided exclusion collection, for internal use only + if ( artifact == null ) + { + throw new IllegalArgumentException( "no artifact specified for dependency" ); + } + this.artifact = artifact; + this.scope = ( scope != null ) ? scope : ""; + this.optional = optional; + this.exclusions = exclusions; + } + + /** + * Gets the artifact being depended on. + * + * @return The artifact, never {@code null}. + */ + public Artifact getArtifact() + { + return artifact; + } + + /** + * Sets the artifact being depended on. + * + * @param artifact The artifact, must not be {@code null}. + * @return The new dependency, never {@code null}. + */ + public Dependency setArtifact( Artifact artifact ) + { + if ( this.artifact.equals( artifact ) ) + { + return this; + } + return new Dependency( artifact, scope, exclusions, optional ); + } + + /** + * Gets the scope of the dependency. The scope defines in which context this dependency is relevant. + * + * @return The scope or an empty string if not set, never {@code null}. + */ + public String getScope() + { + return scope; + } + + /** + * Sets the scope of the dependency, e.g. "compile". + * + * @param scope The scope of the dependency, may be {@code null}. + * @return The new dependency, never {@code null}. + */ + public Dependency setScope( String scope ) + { + if ( this.scope.equals( scope ) || ( scope == null && this.scope.length() <= 0 ) ) + { + return this; + } + return new Dependency( artifact, scope, exclusions, optional ); + } + + /** + * Indicates whether this dependency is optional or not. Optional dependencies can be ignored in some contexts. + * + * @return {@code true} if the dependency is (definitively) optional, {@code false} otherwise. + */ + public boolean isOptional() + { + return Boolean.TRUE.equals( optional ); + } + + /** + * Gets the optional flag for the dependency. Note: Most clients will usually call {@link #isOptional()} to + * determine the optional flag, this method is for advanced use cases where three-valued logic is required. + * + * @return The optional flag or {@code null} if unspecified. + */ + public Boolean getOptional() + { + return optional; + } + + /** + * Sets the optional flag for the dependency. + * + * @param optional {@code true} if the dependency is optional, {@code false} if the dependency is mandatory, may be + * {@code null} if unspecified. + * @return The new dependency, never {@code null}. + */ + public Dependency setOptional( Boolean optional ) + { + if ( eq( this.optional, optional ) ) + { + return this; + } + return new Dependency( artifact, scope, exclusions, optional ); + } + + /** + * Gets the exclusions for this dependency. Exclusions can be used to remove transitive dependencies during + * resolution. + * + * @return The (read-only) exclusions, never {@code null}. + */ + public Collection getExclusions() + { + return exclusions; + } + + /** + * Sets the exclusions for the dependency. + * + * @param exclusions The exclusions, may be {@code null}. + * @return The new dependency, never {@code null}. + */ + public Dependency setExclusions( Collection exclusions ) + { + if ( hasEquivalentExclusions( exclusions ) ) + { + return this; + } + return new Dependency( artifact, scope, optional, exclusions ); + } + + private boolean hasEquivalentExclusions( Collection exclusions ) + { + if ( exclusions == null || exclusions.isEmpty() ) + { + return this.exclusions.isEmpty(); + } + if ( exclusions instanceof Set ) + { + return this.exclusions.equals( exclusions ); + } + return exclusions.size() >= this.exclusions.size() && this.exclusions.containsAll( exclusions ) + && exclusions.containsAll( this.exclusions ); + } + + @Override + public String toString() + { + return String.valueOf( getArtifact() ) + " (" + getScope() + ( isOptional() ? "?" : "" ) + ")"; + } + + @Override + public boolean equals( Object obj ) + { + if ( obj == this ) + { + return true; + } + else if ( obj == null || !getClass().equals( obj.getClass() ) ) + { + return false; + } + + Dependency that = (Dependency) obj; + + return artifact.equals( that.artifact ) && scope.equals( that.scope ) && eq( optional, that.optional ) + && exclusions.equals( that.exclusions ); + } + + private static boolean eq( T o1, T o2 ) + { + return ( o1 != null ) ? o1.equals( o2 ) : o2 == null; + } + + @Override + public int hashCode() + { + int hash = 17; + hash = hash * 31 + artifact.hashCode(); + hash = hash * 31 + scope.hashCode(); + hash = hash * 31 + ( optional != null ? optional.hashCode() : 0 ); + hash = hash * 31 + exclusions.size(); + return hash; + } + + private static class Exclusions + extends AbstractSet + { + + private final Exclusion[] exclusions; + + public static Set copy( Collection exclusions ) + { + if ( exclusions == null || exclusions.isEmpty() ) + { + return Collections.emptySet(); + } + return new Exclusions( exclusions ); + } + + private Exclusions( Collection exclusions ) + { + if ( exclusions.size() > 1 && !( exclusions instanceof Set ) ) + { + exclusions = new LinkedHashSet( exclusions ); + } + this.exclusions = exclusions.toArray( new Exclusion[exclusions.size()] ); + } + + @Override + public Iterator iterator() + { + return new Iterator() + { + + private int cursor = 0; + + public boolean hasNext() + { + return cursor < exclusions.length; + } + + public Exclusion next() + { + try + { + Exclusion exclusion = exclusions[cursor]; + cursor++; + return exclusion; + } + catch ( IndexOutOfBoundsException e ) + { + throw new NoSuchElementException(); + } + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + + }; + } + + @Override + public int size() + { + return exclusions.length; + } + + } + +}