MNG-3876: Add in the maven-artifact code so we can start creating facades and back it with mercury

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@721307 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jason van Zyl 2008-11-27 22:32:16 +00:00
parent a648f36be2
commit aba2b12837
186 changed files with 24756 additions and 44 deletions

View File

@ -83,7 +83,7 @@ TODO:
<!-- Pull the dependencies for Modello -->
<artifact:dependencies pathId="modello.pathid" filesetId="modello.fileset" verbose="${verbose}">
<localRepository path="${maven.repo.local}"/>
<dependency groupId="org.codehaus.modello" artifactId="modello-maven-plugin" version="1.0-alpha-20"/>
<dependency groupId="org.codehaus.modello" artifactId="modello-maven-plugin" version="1.0-alpha-21"/>
</artifact:dependencies>
<!-- Pull the dependencies for the MetadataGenerator CLI -->
@ -153,6 +153,7 @@ TODO:
<modello file="maven-project/src/main/mdo/profiles.mdo"/>
<modello file="maven-core/src/main/mdo/settings.mdo"/>
<modello file="maven-toolchain/src/main/mdo/toolchains.xml"/>
<modello file="maven-compat/src/main/mdo/metadata.mdo"/>
</target>
<target name="compile-boot" depends="generate-sources" description="compiles the bootstrap sources">

View File

@ -24,16 +24,39 @@
<artifactId>maven-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<version>1.2_Java1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<configuration>
<version>1.0.0</version>
<model>src/main/mdo/metadata.mdo</model>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>

View File

@ -0,0 +1,176 @@
package org.apache.maven.artifact;
/*
* 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.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import org.apache.maven.artifact.versioning.VersionRange;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;
/**
* Description of an artifact.
*
* @todo do we really need an interface here?
* @todo get rid of the multiple states we can have (project, parent, etc artifacts, file == null, snapshot, etc) - construct subclasses and use accordingly?
*/
public interface Artifact
extends Comparable
{
String LATEST_VERSION = "LATEST";
String SNAPSHOT_VERSION = "SNAPSHOT";
Pattern VERSION_FILE_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}.[0-9]{6})-([0-9]+)$" );
// TODO: into artifactScope handler
String SCOPE_COMPILE = ArtifactScopeEnum.compile.toString();
String SCOPE_TEST = ArtifactScopeEnum.test.toString();
String SCOPE_RUNTIME = ArtifactScopeEnum.runtime.toString();
String SCOPE_PROVIDED = ArtifactScopeEnum.provided.toString();
String SCOPE_SYSTEM = ArtifactScopeEnum.system.toString();
String SCOPE_IMPORT = "import"; // Used to import dependencyManagement dependencies
String RELEASE_VERSION = "RELEASE";
String getGroupId();
String getArtifactId();
String getVersion();
void setVersion( String version );
/**
* Get the artifactScope of the artifact. If the artifact is a standalone rather than a dependency, it's artifactScope will be
* <code>null</code>. The artifactScope may not be the same as it was declared on the original dependency, as this is the
* result of combining it with the main project artifactScope.
*
* @return the artifactScope
*/
String getScope();
String getType();
String getClassifier();
// only providing this since classifier is *very* optional...
boolean hasClassifier();
File getFile();
void setFile( File destination );
String getBaseVersion();
/** @todo would like to get rid of this - or at least only have one. Base version should be immutable. */
void setBaseVersion( String baseVersion );
// ----------------------------------------------------------------------
String getId();
String getDependencyConflictId();
void addMetadata( ArtifactMetadata metadata );
Collection<ArtifactMetadata> getMetadataList();
void setRepository( ArtifactRepository remoteRepository );
ArtifactRepository getRepository();
void updateVersion( String version,
ArtifactRepository localRepository );
String getDownloadUrl();
void setDownloadUrl( String downloadUrl );
ArtifactFilter getDependencyFilter();
void setDependencyFilter( ArtifactFilter artifactFilter );
ArtifactHandler getArtifactHandler();
/**
* @return {@link List} &lt; {@link String} > with artifact ids
*/
List<String> getDependencyTrail();
/**
* @param dependencyTrail {@link List} &lt; {@link String} > with artifact ids
*/
void setDependencyTrail( List<String> dependencyTrail );
void setScope( String scope );
VersionRange getVersionRange();
void setVersionRange( VersionRange newRange );
void selectVersion( String version );
void setGroupId( String groupId );
void setArtifactId( String artifactId );
boolean isSnapshot();
void setResolved( boolean resolved );
boolean isResolved();
void setResolvedVersion( String version );
/** @todo remove, a quick hack for the lifecycle executor */
void setArtifactHandler( ArtifactHandler handler );
boolean isRelease();
void setRelease( boolean release );
List<ArtifactVersion> getAvailableVersions();
void setAvailableVersions( List<ArtifactVersion> versions );
boolean isOptional();
void setOptional( boolean optional );
ArtifactVersion getSelectedVersion()
throws OverConstrainedVersionException;
boolean isSelectedVersionKnown()
throws OverConstrainedVersionException;
}

View File

@ -0,0 +1,106 @@
package org.apache.maven.artifact;
/**
* Type safe reincarnation of Artifact scope. Also supplies the <code>DEFAULT_SCOPE<code> as well
* as convenience method to deal with scope relationships.
*
* @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
*
*/
public enum ArtifactScopeEnum
{
compile( 1 ), test( 2 ), runtime( 3 ), provided( 4 ), system( 5 );
public static final ArtifactScopeEnum DEFAULT_SCOPE = compile;
private int id;
// Constructor
ArtifactScopeEnum( int id )
{
this.id = id;
}
int getId()
{
return id;
}
/**
* Helper method to simplify null processing
*
* @return
*/
public static final ArtifactScopeEnum checkScope( ArtifactScopeEnum scope )
{
return scope == null ? DEFAULT_SCOPE : scope;
}
/**
*
* @return unsafe String representation of this scope.
*/
public String getScope()
{
if ( id == 1 )
{
return Artifact.SCOPE_COMPILE;
}
else if ( id == 2 )
{
return Artifact.SCOPE_TEST;
}
else if ( id == 3 )
{
return Artifact.SCOPE_RUNTIME;
}
else if ( id == 4 )
{
return Artifact.SCOPE_PROVIDED;
}
else
{
return Artifact.SCOPE_SYSTEM;
}
}
private static final ArtifactScopeEnum [][][] _compliancySets = {
{ { compile }, { compile, provided, system } }
, { { test }, { compile, test, provided, system } }
, { { runtime }, { compile, runtime, system } }
, { { provided }, { compile, test, provided } }
};
/**
* scope relationship function. Used by the graph conflict resolution policies
*
* @param scope
* @return true is supplied scope is an inclusive sub-scope of current one.
*/
public boolean encloses( ArtifactScopeEnum scope )
{
final ArtifactScopeEnum s = checkScope(scope);
// system scope is historic only - and simple
if( id == system.id )
return scope.id == system.id;
for( ArtifactScopeEnum[][] set : _compliancySets )
{
if( id == set[0][0].id )
{
for( ArtifactScopeEnum ase : set[1] )
{
if( s.id == ase.id )
return true;
}
break;
}
}
return false;
}
}

View File

@ -0,0 +1,115 @@
package org.apache.maven.artifact;
/*
* 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.HashMap;
import java.util.Map;
/**
* Type safe enumeration for the artifact status field.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public final class ArtifactStatus
implements Comparable
{
/** No trust - no information about status. */
public static final ArtifactStatus NONE = new ArtifactStatus( "none", 0 );
/** No trust - information was generated with defaults. */
public static final ArtifactStatus GENERATED = new ArtifactStatus( "generated", 1 );
/** Low trust - was converted from the Maven 1.x repository. */
public static final ArtifactStatus CONVERTED = new ArtifactStatus( "converted", 2 );
/** Moderate trust - it was deployed directly from a partner. */
public static final ArtifactStatus PARTNER = new ArtifactStatus( "partner", 3 );
/** Moderate trust - it was deployed directly by a user. */
public static final ArtifactStatus DEPLOYED = new ArtifactStatus( "deployed", 4 );
/** Trusted, as it has had its data verified by hand. */
public static final ArtifactStatus VERIFIED = new ArtifactStatus( "verified", 5 );
private final int rank;
private final String key;
private static Map<String,ArtifactStatus> map;
private ArtifactStatus( String key,
int rank )
{
this.rank = rank;
this.key = key;
if ( map == null )
{
map = new HashMap<String,ArtifactStatus>();
}
map.put( key, this );
}
public static ArtifactStatus valueOf( String status )
{
ArtifactStatus retVal = null;
if ( status != null )
{
retVal = map.get( status );
}
return retVal != null ? retVal : NONE;
}
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
final ArtifactStatus that = (ArtifactStatus) o;
return rank == that.rank;
}
public int hashCode()
{
return rank;
}
public String toString()
{
return key;
}
public int compareTo( Object o )
{
ArtifactStatus s = (ArtifactStatus) o;
return rank - s.rank;
}
}

View File

@ -0,0 +1,181 @@
package org.apache.maven.artifact;
/*
* 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.apache.maven.artifact.versioning.VersionRange;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
public final class ArtifactUtils
{
private ArtifactUtils()
{
}
public static boolean isSnapshot( String version )
{
return ( version != null ) &&
( version.toUpperCase().endsWith( Artifact.SNAPSHOT_VERSION ) || Artifact.VERSION_FILE_PATTERN.matcher( version )
.matches() );
}
public static String toSnapshotVersion( String version )
{
Matcher m = Artifact.VERSION_FILE_PATTERN.matcher( version );
if ( m.matches() )
{
return m.group( 1 ) + "-" + Artifact.SNAPSHOT_VERSION;
}
else
{
return version;
}
}
public static String versionlessKey( Artifact artifact )
{
return versionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
}
public static String versionlessKey( String groupId,
String artifactId )
{
if ( groupId == null )
{
throw new NullPointerException( "groupId was null" );
}
if ( artifactId == null )
{
throw new NullPointerException( "artifactId was null" );
}
return groupId + ":" + artifactId;
}
public static String artifactId( String groupId,
String artifactId,
String type,
String version )
{
return artifactId( groupId, artifactId, type, null, version );
}
public static String artifactId( String groupId,
String artifactId,
String type,
String classifier,
String baseVersion )
{
return groupId + ":" + artifactId + ":" + type + ( classifier != null ? ":" + classifier : "" ) + ":" +
baseVersion;
}
public static Map<String,Artifact> artifactMapByVersionlessId( Collection<Artifact> artifacts )
{
Map<String,Artifact> artifactMap = new LinkedHashMap<String,Artifact>();
if ( artifacts != null )
{
for (Artifact artifact : artifacts) {
artifactMap.put(versionlessKey(artifact), artifact);
}
}
return artifactMap;
}
public static Map<String,Artifact> artifactMapByArtifactId( Collection<Artifact> artifacts )
{
Map<String,Artifact> artifactMap = new LinkedHashMap<String,Artifact>();
if ( artifacts != null )
{
for (Artifact artifact : artifacts) {
artifactMap.put(artifact.getId(), artifact);
}
}
return artifactMap;
}
public static Artifact copyArtifact( Artifact artifact )
{
VersionRange range = artifact.getVersionRange();
// For some reason with the introduction of MNG-1577 we have the case in Yoko where a depMan section has
// something like the following:
//
// <dependencyManagement>
// <dependencies>
// <!-- Yoko modules -->
// <dependency>
// <groupId>org.apache.yoko</groupId>
// <artifactId>yoko-core</artifactId>
// <version>${version}</version>
// </dependency>
// ...
//
// And the range is not set so we'll check here and set it. jvz.
if ( range == null )
{
range = VersionRange.createFromVersion( artifact.getVersion() );
}
DefaultArtifact clone = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), range.cloneOf(),
artifact.getScope(), artifact.getType(), artifact.getClassifier(),
artifact.getArtifactHandler(), artifact.isOptional() );
clone.setRelease( artifact.isRelease() );
clone.setResolvedVersion( artifact.getVersion() );
clone.setResolved( artifact.isResolved() );
clone.setFile( artifact.getFile() );
clone.setAvailableVersions( copyList( artifact.getAvailableVersions() ) );
clone.setBaseVersion( artifact.getBaseVersion() );
clone.setDependencyFilter( artifact.getDependencyFilter() );
clone.setDependencyTrail( copyList( artifact.getDependencyTrail() ) );
clone.setDownloadUrl( artifact.getDownloadUrl() );
clone.setRepository( artifact.getRepository() );
return clone;
}
private static <T> List<T> copyList( List<T> original )
{
List<T> copy = null;
if ( original != null )
{
copy = new ArrayList<T>();
if ( !original.isEmpty() )
{
copy.addAll( original );
}
}
return copy;
}
}

View File

@ -0,0 +1,611 @@
package org.apache.maven.artifact;
/*
* 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.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
* @version $Id$
* @todo this should possibly be replaced by type handler
*/
public class DefaultArtifact
implements Artifact
{
private String groupId;
private String artifactId;
/**
* The resolved version for the artifact after conflict resolution, that has not been transformed.
*
* @todo should be final
*/
private String baseVersion;
private final String type;
private final String classifier;
private String scope;
private File file;
private ArtifactRepository repository;
private String downloadUrl;
private ArtifactFilter dependencyFilter;
private ArtifactHandler artifactHandler;
private List<String> dependencyTrail;
private String version;
private VersionRange versionRange;
private boolean resolved;
private boolean release;
private List<ArtifactVersion> availableVersions;
private Map<Object,ArtifactMetadata> metadataMap;
private boolean optional;
public DefaultArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String scope,
String type,
String classifier,
ArtifactHandler artifactHandler )
{
this( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler, false );
}
public DefaultArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String scope,
String type,
String classifier,
ArtifactHandler artifactHandler,
boolean optional )
{
this.groupId = groupId;
this.artifactId = artifactId;
this.versionRange = versionRange;
selectVersionFromNewRangeIfAvailable();
this.artifactHandler = artifactHandler;
this.scope = scope;
this.type = type;
if ( classifier == null )
{
classifier = artifactHandler.getClassifier();
}
this.classifier = classifier;
this.optional = optional;
validateIdentity();
}
private void validateIdentity()
{
if ( empty( groupId ) )
{
throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
"The groupId cannot be empty." );
}
if ( artifactId == null )
{
throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
"The artifactId cannot be empty." );
}
if ( type == null )
{
throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
"The type cannot be empty." );
}
if ( ( version == null ) && ( versionRange == null ) )
{
throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
"The version cannot be empty." );
}
}
private boolean empty( String value )
{
return ( value == null ) || ( value.trim().length() < 1 );
}
public String getClassifier()
{
return classifier;
}
public boolean hasClassifier()
{
return StringUtils.isNotEmpty( classifier );
}
public String getScope()
{
return scope;
}
public String getGroupId()
{
return groupId;
}
public String getArtifactId()
{
return artifactId;
}
public String getVersion()
{
return version;
}
public void setVersion( String version )
{
this.version = version;
setBaseVersionInternal( version );
versionRange = null;
}
public String getType()
{
return type;
}
public void setFile( File file )
{
this.file = file;
}
public File getFile()
{
return file;
}
public ArtifactRepository getRepository()
{
return repository;
}
public void setRepository( ArtifactRepository repository )
{
this.repository = repository;
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
public String getId()
{
return getDependencyConflictId() + ":" + getBaseVersion();
}
public String getDependencyConflictId()
{
StringBuffer sb = new StringBuffer();
sb.append( getGroupId() );
sb.append( ":" );
appendArtifactTypeClassifierString( sb );
return sb.toString();
}
private void appendArtifactTypeClassifierString( StringBuffer sb )
{
sb.append( getArtifactId() );
sb.append( ":" );
sb.append( getType() );
if ( hasClassifier() )
{
sb.append( ":" );
sb.append( getClassifier() );
}
}
public void addMetadata( ArtifactMetadata metadata )
{
if ( metadataMap == null )
{
metadataMap = new HashMap<Object,ArtifactMetadata>();
}
ArtifactMetadata m = metadataMap.get( metadata.getKey() );
if ( m != null )
{
m.merge( metadata );
}
else
{
metadataMap.put( metadata.getKey(), metadata );
}
}
public Collection<ArtifactMetadata> getMetadataList()
{
if (metadataMap == null) {
return Collections.emptyList();
}
return metadataMap.values();
}
// ----------------------------------------------------------------------
// Object overrides
// ----------------------------------------------------------------------
public String toString()
{
StringBuffer sb = new StringBuffer();
if ( getGroupId() != null )
{
sb.append( getGroupId() );
sb.append( ":" );
}
appendArtifactTypeClassifierString( sb );
sb.append( ":" );
if ( getBaseVersionInternal() != null )
{
sb.append( getBaseVersionInternal() );
}
else
{
sb.append( versionRange.toString() );
}
if ( scope != null )
{
sb.append( ":" );
sb.append( scope );
}
return sb.toString();
}
public int hashCode()
{
int result = 17;
result = 37 * result + groupId.hashCode();
result = 37 * result + artifactId.hashCode();
result = 37 * result + type.hashCode();
if ( version != null )
{
result = 37 * result + version.hashCode();
}
result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 );
return result;
}
public boolean equals( Object o )
{
if ( o == this )
{
return true;
}
if ( !( o instanceof Artifact ) )
{
return false;
}
Artifact a = (Artifact) o;
if ( !a.getGroupId().equals( groupId ) )
{
return false;
}
else if ( !a.getArtifactId().equals( artifactId ) )
{
return false;
}
else if ( !a.getVersion().equals( version ) )
{
return false;
}
else if ( !a.getType().equals( type ) )
{
return false;
}
else if ( a.getClassifier() == null ? classifier != null : !a.getClassifier().equals( classifier ) )
{
return false;
}
// We don't consider the version range in the comparison, just the resolved version
return true;
}
public String getBaseVersion()
{
if ( baseVersion == null )
{
if ( version == null )
{
throw new NullPointerException( "version was null for " + groupId + ":" + artifactId );
}
setBaseVersionInternal( version );
}
return baseVersion;
}
protected String getBaseVersionInternal()
{
if ( ( baseVersion == null ) && ( version != null ) )
{
setBaseVersionInternal( version );
}
return baseVersion;
}
public void setBaseVersion( String baseVersion )
{
setBaseVersionInternal( baseVersion );
}
protected void setBaseVersionInternal( String baseVersion )
{
Matcher m = VERSION_FILE_PATTERN.matcher( baseVersion );
if ( m.matches() )
{
this.baseVersion = m.group( 1 ) + "-" + SNAPSHOT_VERSION;
}
else
{
this.baseVersion = baseVersion;
}
}
public int compareTo( Object o )
{
Artifact a = (Artifact) o;
int result = groupId.compareTo( a.getGroupId() );
if ( result == 0 )
{
result = artifactId.compareTo( a.getArtifactId() );
if ( result == 0 )
{
result = type.compareTo( a.getType() );
if ( result == 0 )
{
if ( classifier == null )
{
if ( a.getClassifier() != null )
{
result = 1;
}
}
else
{
if ( a.getClassifier() != null )
{
result = classifier.compareTo( a.getClassifier() );
}
else
{
result = -1;
}
}
if ( result == 0 )
{
// We don't consider the version range in the comparison, just the resolved version
result = new DefaultArtifactVersion( version ).compareTo(
new DefaultArtifactVersion( a.getVersion() ) );
}
}
}
}
return result;
}
public void updateVersion( String version,
ArtifactRepository localRepository )
{
setResolvedVersion( version );
setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
}
public String getDownloadUrl()
{
return downloadUrl;
}
public void setDownloadUrl( String downloadUrl )
{
this.downloadUrl = downloadUrl;
}
public ArtifactFilter getDependencyFilter()
{
return dependencyFilter;
}
public void setDependencyFilter( ArtifactFilter artifactFilter )
{
dependencyFilter = artifactFilter;
}
public ArtifactHandler getArtifactHandler()
{
return artifactHandler;
}
public List<String> getDependencyTrail()
{
return dependencyTrail;
}
public void setDependencyTrail( List<String> dependencyTrail )
{
this.dependencyTrail = dependencyTrail;
}
public void setScope( String scope )
{
this.scope = scope;
}
public VersionRange getVersionRange()
{
return versionRange;
}
public void setVersionRange( VersionRange versionRange )
{
this.versionRange = versionRange;
selectVersionFromNewRangeIfAvailable();
}
private void selectVersionFromNewRangeIfAvailable()
{
if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
{
selectVersion( versionRange.getRecommendedVersion().toString() );
}
else
{
version = null;
baseVersion = null;
}
}
public void selectVersion( String version )
{
this.version = version;
setBaseVersionInternal( version );
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public boolean isSnapshot()
{
return getBaseVersion() != null && (getBaseVersion().endsWith(SNAPSHOT_VERSION) || getBaseVersion().equals(LATEST_VERSION));
}
public void setResolved( boolean resolved )
{
this.resolved = resolved;
}
public boolean isResolved()
{
return resolved;
}
public void setResolvedVersion( String version )
{
this.version = version;
// retain baseVersion
}
public void setArtifactHandler( ArtifactHandler artifactHandler )
{
this.artifactHandler = artifactHandler;
}
public void setRelease( boolean release )
{
this.release = release;
}
public boolean isRelease()
{
return release;
}
public List<ArtifactVersion> getAvailableVersions()
{
return availableVersions;
}
public void setAvailableVersions( List<ArtifactVersion> availableVersions )
{
this.availableVersions = availableVersions;
}
public boolean isOptional()
{
return optional;
}
public ArtifactVersion getSelectedVersion()
throws OverConstrainedVersionException
{
return versionRange.getSelectedVersion( this );
}
public boolean isSelectedVersionKnown()
throws OverConstrainedVersionException
{
return versionRange.isSelectedVersionKnown( this );
}
public void setOptional( boolean optional )
{
this.optional = optional;
}
}

View File

@ -0,0 +1,36 @@
package org.apache.maven.artifact;
/*
* 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.
*/
/**
* Exception that occurs when an artifact file is used, but has not been resolved.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
* @todo it may be better for artifact.getFile() to throw it - perhaps it is a runtime exception?
*/
public class DependencyResolutionRequiredException
extends Exception
{
public DependencyResolutionRequiredException( Artifact artifact )
{
super( "Attempted to access the artifact " + artifact + "; which has not yet been resolved" );
}
}

View File

@ -0,0 +1,100 @@
package org.apache.maven.artifact;
/*
* 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.
*/
/**
* Exception thrown when the identity of an artifact can not be established,
* eg. one of groupId, artifactId, version or type is null.
*/
public class InvalidArtifactRTException
extends RuntimeException
{
private final String groupId;
private final String artifactId;
private final String version;
private final String type;
private final String baseMessage;
public InvalidArtifactRTException( String groupId,
String artifactId,
String version,
String type,
String message )
{
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
this.type = type;
this.baseMessage = message;
}
public InvalidArtifactRTException( String groupId,
String artifactId,
String version,
String type,
String message,
Throwable cause )
{
super( cause );
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
this.type = type;
this.baseMessage = message;
}
public String getMessage()
{
return "For artifact {" + getArtifactKey() + "}: " + getBaseMessage();
}
public String getBaseMessage()
{
return baseMessage;
}
public String getArtifactId()
{
return artifactId;
}
public String getGroupId()
{
return groupId;
}
public String getType()
{
return type;
}
public String getVersion()
{
return version;
}
public String getArtifactKey()
{
return groupId + ":" + artifactId + ":" + version + ":" + type;
}
}

View File

@ -0,0 +1,71 @@
package org.apache.maven.artifact;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import java.net.MalformedURLException;
/*
* 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.
*/
/**
* Error constructing an artifact repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class InvalidRepositoryException
extends Exception
{
private final String repositoryId;
public InvalidRepositoryException( String message,
String repositoryId,
MalformedURLException cause )
{
super( message, cause );
this.repositoryId = repositoryId;
}
protected InvalidRepositoryException( String message,
String repositoryId,
ComponentLookupException cause )
{
super( message, cause );
this.repositoryId = repositoryId;
}
@Deprecated
public InvalidRepositoryException( String message, Throwable t )
{
super( message );
this.repositoryId = null;
}
protected InvalidRepositoryException( String message,
String repositoryId )
{
super( message );
this.repositoryId = repositoryId;
}
public String getRepositoryId()
{
return repositoryId;
}
}

View File

@ -0,0 +1,39 @@
package org.apache.maven.artifact;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
/**
* Exception which is meant to occur when a layout specified for a particular
* repository doesn't have a corresponding {@link ArtifactRepositoryLayout}
* component in the current container.
*
* @author jdcasey
*/
public class UnknownRepositoryLayoutException
extends InvalidRepositoryException
{
private final String layoutId;
public UnknownRepositoryLayoutException( String repositoryId,
String layoutId )
{
super( "Cannot find ArtifactRepositoryLayout instance for: " + layoutId, repositoryId );
this.layoutId = layoutId;
}
public UnknownRepositoryLayoutException( String repositoryId,
String layoutId,
ComponentLookupException e )
{
super( "Cannot find ArtifactRepositoryLayout instance for: " + layoutId, repositoryId, e );
this.layoutId = layoutId;
}
public String getLayoutId()
{
return layoutId;
}
}

View File

@ -0,0 +1,65 @@
package org.apache.maven.artifact.deployer;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.io.File;
public interface ArtifactDeployer
{
String ROLE = ArtifactDeployer.class.getName();
/**
* Deploy an artifact from a particular directory. The artifact handler is used to determine the filename
* of the source file.
*
* @param basedir the directory where the artifact is stored
* @param finalName the name of the artifact sans extension
* @param artifact the artifact definition
* @param deploymentRepository the repository to deploy to
* @param localRepository the local repository to install into
* @throws ArtifactDeploymentException if an error occurred deploying the artifact
* @deprecated to be removed before 2.0 after the instlal/deploy plugins use the alternate method
*/
@Deprecated
void deploy( String basedir,
String finalName,
Artifact artifact,
ArtifactRepository deploymentRepository,
ArtifactRepository localRepository )
throws ArtifactDeploymentException;
/**
* Deploy an artifact from a particular file.
*
* @param source the file to deploy
* @param artifact the artifact definition
* @param deploymentRepository the repository to deploy to
* @param localRepository the local repository to install into
* @throws ArtifactDeploymentException if an error occurred deploying the artifact
*/
void deploy( File source,
Artifact artifact,
ArtifactRepository deploymentRepository,
ArtifactRepository localRepository )
throws ArtifactDeploymentException;
}

View File

@ -0,0 +1,44 @@
package org.apache.maven.artifact.deployer;
/*
* 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.
*/
/**
* @author Jason van Zyl
* @version $Id$
*/
public class ArtifactDeploymentException
extends Exception
{
public ArtifactDeploymentException( String message )
{
super( message );
}
public ArtifactDeploymentException( Throwable cause )
{
super( cause );
}
public ArtifactDeploymentException( String message,
Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,108 @@
package org.apache.maven.artifact.deployer;
/*
* 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.io.IOException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataDeploymentException;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.artifact.transform.ArtifactTransformationManager;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
/** @plexus.component */
public class DefaultArtifactDeployer
extends AbstractLogEnabled
implements ArtifactDeployer
{
/** @plexus.requirement */
private WagonManager wagonManager;
/** @plexus.requirement */
private ArtifactTransformationManager transformationManager;
/** @plexus.requirement */
private RepositoryMetadataManager repositoryMetadataManager;
/** @plexus.requirement */
private ArtifactMetadataSource metadataSource;
/** @plexus.requirement role-hint="default" */
private ArtifactRepositoryLayout defaultLayout;
/**
* @deprecated we want to use the artifact method only, and ensure artifact.file is set
* correctly.
*/
@Deprecated
public void deploy( String basedir, String finalName, Artifact artifact, ArtifactRepository deploymentRepository, ArtifactRepository localRepository )
throws ArtifactDeploymentException
{
String extension = artifact.getArtifactHandler().getExtension();
File source = new File( basedir, finalName + "." + extension );
deploy( source, artifact, deploymentRepository, localRepository );
}
public void deploy( File source, Artifact artifact, ArtifactRepository deploymentRepository, ArtifactRepository localRepository )
throws ArtifactDeploymentException
{
if ( !wagonManager.isOnline() )
{
// deployment shouldn't silently fail when offline
throw new ArtifactDeploymentException( "System is offline. Cannot deploy artifact: " + artifact + "." );
}
try
{
transformationManager.transformForDeployment( artifact, deploymentRepository, localRepository );
// Copy the original file to the new one if it was transformed
File artifactFile = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
if ( !artifactFile.equals( source ) )
{
FileUtils.copyFile( source, artifactFile );
}
wagonManager.putArtifact( source, artifact, deploymentRepository );
// must be after the artifact is installed
for ( ArtifactMetadata metadata : artifact.getMetadataList() )
{
repositoryMetadataManager.deploy( metadata, localRepository, deploymentRepository );
}
}
catch ( TransferFailedException e )
{
throw new ArtifactDeploymentException( "Error deploying artifact: " + e.getMessage(), e );
}
catch ( IOException e )
{
throw new ArtifactDeploymentException( "Error deploying artifact: " + e.getMessage(), e );
}
catch ( RepositoryMetadataDeploymentException e )
{
throw new ArtifactDeploymentException( "Error installing artifact's metadata: " + e.getMessage(), e );
}
}
}

View File

@ -0,0 +1,99 @@
package org.apache.maven.artifact.factory;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.VersionRange;
public interface ArtifactFactory
{
String ROLE = ArtifactFactory.class.getName();
// TODO: deprecate and chase down (probably used for copying only)
Artifact createArtifact( String groupId,
String artifactId,
String version,
String scope,
String type );
Artifact createArtifactWithClassifier( String groupId,
String artifactId,
String version,
String type,
String classifier );
Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope );
Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
boolean optional );
Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope );
Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope,
boolean optional );
Artifact createBuildArtifact( String groupId,
String artifactId,
String version,
String packaging );
Artifact createProjectArtifact( String groupId,
String artifactId,
String version );
Artifact createParentArtifact( String groupId,
String artifactId,
String version );
Artifact createPluginArtifact( String groupId,
String artifactId,
VersionRange versionRange );
Artifact createProjectArtifact( String groupId,
String artifactId,
String version,
String scope );
Artifact createExtensionArtifact( String groupId,
String artifactId,
VersionRange versionRange );
}

View File

@ -0,0 +1,219 @@
package org.apache.maven.artifact.factory;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.versioning.VersionRange;
/** @plexus.component */
public class DefaultArtifactFactory
implements ArtifactFactory
{
/** @plexus.requirement */
private ArtifactHandlerManager artifactHandlerManager;
public DefaultArtifactFactory()
{
}
public Artifact createArtifact( String groupId,
String artifactId,
String version,
String scope,
String type )
{
return createArtifact( groupId, artifactId, version, scope, type, null, null );
}
public Artifact createArtifactWithClassifier( String groupId,
String artifactId,
String version,
String type,
String classifier )
{
return createArtifact( groupId, artifactId, version, null, type, classifier, null );
}
public Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, null );
}
public Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
boolean optional )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, null, optional );
}
public Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
}
public Artifact createDependencyArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope,
boolean optional )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, optional );
}
public Artifact createBuildArtifact( String groupId,
String artifactId,
String version,
String packaging )
{
return createArtifact( groupId, artifactId, version, null, packaging, null, null );
}
public Artifact createProjectArtifact( String groupId,
String artifactId,
String version )
{
return createProjectArtifact( groupId, artifactId, version, null );
}
public Artifact createParentArtifact( String groupId,
String artifactId,
String version )
{
return createProjectArtifact( groupId, artifactId, version );
}
public Artifact createPluginArtifact( String groupId,
String artifactId,
VersionRange versionRange )
{
return createArtifact( groupId, artifactId, versionRange, "maven-plugin", null, Artifact.SCOPE_RUNTIME, null );
}
public Artifact createProjectArtifact( String groupId,
String artifactId,
String version,
String scope )
{
return createArtifact( groupId, artifactId, version, scope, "pom" );
}
public Artifact createExtensionArtifact( String groupId,
String artifactId,
VersionRange versionRange )
{
return createArtifact( groupId, artifactId, versionRange, "jar", null, Artifact.SCOPE_RUNTIME, null );
}
private Artifact createArtifact( String groupId,
String artifactId,
String version,
String scope,
String type,
String classifier,
String inheritedScope )
{
VersionRange versionRange = null;
if ( version != null )
{
versionRange = VersionRange.createFromVersion( version );
}
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
}
private Artifact createArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope )
{
return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, false );
}
private Artifact createArtifact( String groupId,
String artifactId,
VersionRange versionRange,
String type,
String classifier,
String scope,
String inheritedScope,
boolean optional )
{
// TODO: can refactor - inherited artifactScope calculation belongs in the collector, use artifactScope handler
String desiredScope = Artifact.SCOPE_RUNTIME;
if ( inheritedScope == null )
{
desiredScope = scope;
}
else if ( Artifact.SCOPE_TEST.equals( scope ) || Artifact.SCOPE_PROVIDED.equals( scope ) )
{
return null;
}
else if ( Artifact.SCOPE_COMPILE.equals( scope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
{
// added to retain compile artifactScope. Remove if you want compile inherited as runtime
desiredScope = Artifact.SCOPE_COMPILE;
}
if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
{
desiredScope = Artifact.SCOPE_TEST;
}
if ( Artifact.SCOPE_PROVIDED.equals( inheritedScope ) )
{
desiredScope = Artifact.SCOPE_PROVIDED;
}
if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
{
// system scopes come through unchanged...
desiredScope = Artifact.SCOPE_SYSTEM;
}
ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( type );
return new DefaultArtifact( groupId, artifactId, versionRange, desiredScope, type, classifier, handler,
optional );
}
}

View File

@ -0,0 +1,43 @@
package org.apache.maven.artifact.handler;
/*
* 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.
*/
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public interface ArtifactHandler
{
String ROLE = ArtifactHandler.class.getName();
String getExtension();
String getDirectory();
String getClassifier();
String getPackaging();
boolean isIncludesDependencies();
String getLanguage();
boolean isAddedToClasspath();
}

View File

@ -0,0 +1,112 @@
package org.apache.maven.artifact.handler;
/*
* 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.
*/
/**
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @author Jason van Zyl
* @version $Id$
* @plexus.component
*/
public class DefaultArtifactHandler
implements ArtifactHandler
{
private String extension;
private String type;
private String classifier;
private String directory;
private String packaging;
private boolean includesDependencies;
private String language;
private boolean addedToClasspath;
public DefaultArtifactHandler()
{
}
public DefaultArtifactHandler( String type )
{
this.type = type;
}
public String getExtension()
{
if ( extension == null )
{
extension = type;
}
return extension;
}
public String getType()
{
return type;
}
public String getClassifier()
{
return classifier;
}
public String getDirectory()
{
if ( directory == null )
{
directory = getPackaging() + "s";
}
return directory;
}
public String getPackaging()
{
if ( packaging == null )
{
packaging = type;
}
return packaging;
}
public boolean isIncludesDependencies()
{
return includesDependencies;
}
public String getLanguage()
{
if ( language == null )
{
language = "none";
}
return language;
}
public boolean isAddedToClasspath()
{
return addedToClasspath;
}
}

View File

@ -0,0 +1,37 @@
package org.apache.maven.artifact.handler.manager;
/*
* 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.apache.maven.artifact.handler.ArtifactHandler;
import java.util.Map;
/**
* @author Jason van Zyl
* @version $Id$
*/
public interface ArtifactHandlerManager
{
String ROLE = ArtifactHandlerManager.class.getName();
ArtifactHandler getArtifactHandler( String type );
void addHandlers( Map<String,ArtifactHandler> handlers );
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.artifact.handler.manager;
/*
* 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.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import java.util.Map;
import java.util.Set;
/**
* @author Jason van Zyl
* @version $Id$
* @plexus.component
*/
public class DefaultArtifactHandlerManager
implements ArtifactHandlerManager
{
/** @plexus.requirement role="org.apache.maven.artifact.handler.ArtifactHandler" */
private Map<String,ArtifactHandler> artifactHandlers;
public ArtifactHandler getArtifactHandler( String type )
{
ArtifactHandler handler = artifactHandlers.get( type );
if ( handler == null )
{
handler = new DefaultArtifactHandler( type );
}
return handler;
}
public void addHandlers( Map<String,ArtifactHandler> handlers )
{
artifactHandlers.putAll( handlers );
}
public Set<String> getHandlerTypes()
{
return artifactHandlers.keySet();
}
}

View File

@ -0,0 +1,44 @@
package org.apache.maven.artifact.installer;
/*
* 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.
*/
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public class ArtifactInstallationException
extends Exception
{
public ArtifactInstallationException( String message )
{
super( message );
}
public ArtifactInstallationException( Throwable cause )
{
super( cause );
}
public ArtifactInstallationException( String message,
Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,66 @@
package org.apache.maven.artifact.installer;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.io.File;
/**
* @author <a href="michal@codehaus.org">Michal Maczka</a>
* @version $Id$
*/
public interface ArtifactInstaller
{
String ROLE = ArtifactInstaller.class.getName();
/**
* Install an artifact from a particular directory. The artifact handler is used to determine the filename
* of the source file.
*
* @param basedir the directory where the artifact is stored
* @param finalName the name of the artifact sans extension
* @param artifact the artifact definition
* @param localRepository the local repository to install into
* @throws ArtifactInstallationException if an error occurred installing the artifact
* @deprecated to be removed before 2.0 after the instlal/deploy plugins use the alternate method
*/
@Deprecated
void install( String basedir,
String finalName,
Artifact artifact,
ArtifactRepository localRepository )
throws ArtifactInstallationException;
/**
* Install an artifact from a particular file.
*
* @param source the file to install
* @param artifact the artifact definition
* @param localRepository the local repository to install into
* @throws ArtifactInstallationException if an error occurred installing the artifact
*/
void install( File source,
Artifact artifact,
ArtifactRepository localRepository )
throws ArtifactInstallationException;
}

View File

@ -0,0 +1,98 @@
package org.apache.maven.artifact.installer;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataInstallationException;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.artifact.transform.ArtifactTransformationManager;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.IOException;
/**
* @author Jason van Zyl
* @plexus.component
*/
public class DefaultArtifactInstaller
extends AbstractLogEnabled
implements ArtifactInstaller
{
/** @plexus.requirement */
private ArtifactTransformationManager transformationManager;
/** @plexus.requirement */
private RepositoryMetadataManager repositoryMetadataManager;
/** @deprecated we want to use the artifact method only, and ensure artifact.file is set correctly. */
@Deprecated
public void install( String basedir, String finalName, Artifact artifact, ArtifactRepository localRepository )
throws ArtifactInstallationException
{
String extension = artifact.getArtifactHandler().getExtension();
File source = new File( basedir, finalName + "." + extension );
install( source, artifact, localRepository );
}
public void install( File source, Artifact artifact, ArtifactRepository localRepository )
throws ArtifactInstallationException
{
try
{
transformationManager.transformForInstall( artifact, localRepository );
String localPath = localRepository.pathOf( artifact );
// TODO: use a file: wagon and the wagon manager?
File destination = new File( localRepository.getBasedir(), localPath );
if ( !destination.getParentFile().exists() )
{
destination.getParentFile().mkdirs();
}
getLogger().info( "Installing " + source.getPath() + " to " + destination );
FileUtils.copyFile( source, destination );
// must be after the artifact is installed
for ( ArtifactMetadata metadata : artifact.getMetadataList() )
{
repositoryMetadataManager.install( metadata, localRepository );
}
// TODO: would like to flush this, but the plugin metadata is added in advance, not as an install/deploy
// transformation
// This would avoid the need to merge and clear out the state during deployment
// artifact.getMetadataList().clear();
}
catch ( IOException e )
{
throw new ArtifactInstallationException( "Error installing artifact: " + e.getMessage(), e );
}
catch ( RepositoryMetadataInstallationException e )
{
throw new ArtifactInstallationException( "Error installing artifact's metadata: " + e.getMessage(), e );
}
}
}

View File

@ -0,0 +1,43 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.wagon.TransferFailedException;
/**
* Occurs when a download checksum fails.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ChecksumFailedException
extends TransferFailedException
{
public ChecksumFailedException( String s )
{
super( s );
}
public ChecksumFailedException( String message,
Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,75 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.wagon.authentication.AuthenticationInfo;
public class CredentialsChangeRequest
{
private String resourceId;
private AuthenticationInfo authInfo;
private String oldPassword;
public CredentialsChangeRequest()
{
}
public CredentialsChangeRequest( String resourceId,
AuthenticationInfo authInfo,
String oldPassword )
{
super();
this.resourceId = resourceId;
this.authInfo = authInfo;
this.oldPassword = oldPassword;
}
public String getResourceId()
{
return resourceId;
}
public void setResourceId( String resourceId )
{
this.resourceId = resourceId;
}
public AuthenticationInfo getAuthInfo()
{
return authInfo;
}
public void setAuthInfo( AuthenticationInfo authInfo )
{
this.authInfo = authInfo;
}
public String getOldPassword()
{
return oldPassword;
}
public void setOldPassword( String oldPassword )
{
this.oldPassword = oldPassword;
}
}

View File

@ -0,0 +1,56 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.wagon.authentication.AuthenticationInfo;
/**
* A wrapper class around setting/retrieving/caching authentication
* info by resource ID. Typical usage - accessing server authentication for
* by it's ID
*
* @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
*/
public interface CredentialsDataSource
{
public static final String ROLE = CredentialsDataSource.class.getName();
/**
* find, if not found, prompt and create Authentication info
* for a given resource
*
* @param resourceId resource ID for which authentication is required
* @return resource AuthenticationInfo. Should always exist.
* @throws CredentialsDataSourceException
*/
AuthenticationInfo get( String resourceId )
throws CredentialsDataSourceException;
/**
* set, if not found, prompt and create Authentication info
* for a given resource. This one uses the old password
* member of AuthenticationInfo
*
* @throws CredentialsDataSourceException
*/
void set( CredentialsChangeRequest req )
throws CredentialsDataSourceException;
}

View File

@ -0,0 +1,46 @@
package org.apache.maven.artifact.manager;
/*
* 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.
*/
public class CredentialsDataSourceException
extends Exception
{
public CredentialsDataSourceException()
{
}
public CredentialsDataSourceException( String message )
{
super( message );
}
public CredentialsDataSourceException( Throwable cause )
{
super( cause );
}
public CredentialsDataSourceException( String message,
Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,359 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Date;
import java.util.Properties;
/** @plexus.component */
public class DefaultUpdateCheckManager
extends AbstractLogEnabled
implements UpdateCheckManager
{
public DefaultUpdateCheckManager()
{
}
public DefaultUpdateCheckManager( Logger logger )
{
enableLogging( logger );
}
public static final String LAST_UPDATE_TAG = ".lastUpdated";
private static final String TOUCHFILE_NAME = "resolver-status.properties";
public boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository )
{
// Update intervals are never used for release artifacts. These intervals
// only exist on the release section of the repository definition in the POM for one reason:
// to specify how often artifact METADATA is checked. Here, we simply shortcut for non-snapshot
// artifacts.
if ( !artifact.isSnapshot() )
{
return false;
}
// we can safely assume that we're calculating based on the snapshot policy here if we've made it past the
// release-artifact short circuit above.
ArtifactRepositoryPolicy policy = repository.getSnapshots();
return isUpdateRequired( artifact, repository, policy );
}
private boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository, ArtifactRepositoryPolicy policy )
{
File file = artifact.getFile();
if ( !policy.isEnabled() )
{
return false;
}
if ( file == null )
{
// TODO throw something instead?
return true;
}
Date lastCheckDate;
if ( file.exists() )
{
lastCheckDate = new Date ( file.lastModified() );
}
else
{
File touchfile = getTouchfile( artifact );
lastCheckDate = readLastUpdated( touchfile, repository.getId() );
}
return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
}
public boolean isUpdateRequired( RepositoryMetadata metadata, ArtifactRepository repository, File file )
{
// Here, we need to determine which policy to use. Release updateInterval will be used when
// the metadata refers to a release artifact or meta-version, and snapshot updateInterval will be used when
// it refers to a snapshot artifact or meta-version.
// NOTE: Release metadata includes version information about artifacts that have been released, to allow
// meta-versions like RELEASE and LATEST to resolve, and also to allow retrieval of the range of valid, released
// artifacts available.
ArtifactRepositoryPolicy policy = metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
if ( !policy.isEnabled() )
{
return false;
}
if ( file == null )
{
// TODO throw something instead?
return true;
}
Date lastCheckDate = readLastUpdated( metadata, repository, file );
return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
}
public Date readLastUpdated( RepositoryMetadata metadata, ArtifactRepository repository, File file )
{
File touchfile = getTouchfile( metadata, file );
String key = getMetadataKey( repository, file );
return readLastUpdated( touchfile, key );
}
public void touch( Artifact artifact, ArtifactRepository repository )
{
File file = artifact.getFile();
File touchfile = getTouchfile( artifact );
if ( file.exists() )
{
touchfile.delete();
}
else
{
writeLastUpdated( touchfile, repository.getId() );
}
}
public void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file )
{
File touchfile = getTouchfile( metadata, file );
String key = getMetadataKey( repository, file );
writeLastUpdated( touchfile, key );
}
public String getMetadataKey( ArtifactRepository repository, File file )
{
return repository.getId() + "." + file.getName() + LAST_UPDATE_TAG;
}
private void writeLastUpdated( File touchfile, String key )
{
synchronized ( touchfile.getAbsolutePath().intern() )
{
if ( !touchfile.getParentFile().exists() && !touchfile.getParentFile().mkdirs() )
{
getLogger().debug( "Failed to create directory: " + touchfile.getParent() +
" for tracking artifact metadata resolution." );
return;
}
FileChannel channel = null;
FileLock lock = null;
try
{
Properties props = new Properties();
channel = new RandomAccessFile( touchfile, "rw" ).getChannel();
lock = channel.lock( 0, channel.size(), false );
if ( touchfile.canRead() )
{
getLogger().debug( "Reading resolution-state from: " + touchfile );
ByteBuffer buffer = ByteBuffer.allocate( (int) channel.size() );
channel.read( buffer );
buffer.flip();
ByteArrayInputStream stream = new ByteArrayInputStream( buffer.array() );
props.load( stream );
}
props.setProperty( key, Long.toString( System.currentTimeMillis() ) );
ByteArrayOutputStream stream = new ByteArrayOutputStream();
getLogger().debug( "Writing resolution-state to: " + touchfile );
props.store( stream, "Last modified on: " + new Date() );
byte[] data = stream.toByteArray();
ByteBuffer buffer = ByteBuffer.allocate( data.length );
buffer.put( data );
buffer.flip();
channel.position( 0 );
channel.write( buffer );
}
catch ( IOException e )
{
getLogger().debug( "Failed to record lastUpdated information for resolution.\nFile: " +
touchfile.toString() + "; key: " + key, e );
}
finally
{
if ( lock != null )
{
try
{
lock.release();
}
catch ( IOException e )
{
getLogger().debug( "Error releasing exclusive lock for resolution tracking file: " +
touchfile, e );
}
}
if ( channel != null )
{
try
{
channel.close();
}
catch ( IOException e )
{
getLogger().debug( "Error closing FileChannel for resolution tracking file: " +
touchfile, e );
}
}
}
}
}
public Date readLastUpdated( File touchfile, String key )
{
if ( !touchfile.canRead() )
{
return null;
}
synchronized ( touchfile.getAbsolutePath().intern() )
{
getLogger().debug( "Searching for: " + key + " in touchfile." );
Date result = null;
FileInputStream stream = null;
FileLock lock = null;
FileChannel channel = null;
try
{
Properties props = new Properties();
stream = new FileInputStream( touchfile );
channel = stream.getChannel();
lock = channel.lock( 0, channel.size(), true );
getLogger().debug( "Reading resolution-state from: " + touchfile );
props.load( stream );
String rawVal = props.getProperty( key );
if ( rawVal != null )
{
try
{
result = new Date( Long.parseLong( rawVal ) );
}
catch ( NumberFormatException e )
{
getLogger().debug( "Cannot parse lastUpdated date: \'" + rawVal + "\'. Ignoring.", e );
result = null;
}
}
}
catch ( IOException e )
{
getLogger().debug( "Failed to read lastUpdated information.\nFile: " +
touchfile.toString() + "; key: " + key, e );
}
finally
{
if ( lock != null )
{
try
{
lock.release();
}
catch ( IOException e )
{
getLogger().debug( "Error releasing shared lock for resolution tracking file: " +
touchfile, e );
}
}
if ( channel != null )
{
try
{
channel.close();
}
catch ( IOException e )
{
getLogger().debug( "Error closing FileChannel for resolution tracking file: " +
touchfile, e );
}
}
}
return result;
}
}
public File getTouchfile( Artifact artifact )
{
StringBuffer sb = new StringBuffer();
sb.append( artifact.getArtifactId() );
sb.append( '-' ).append( artifact.getBaseVersion() );
if ( artifact.getClassifier() != null )
{
sb.append( '-' ).append( artifact.getClassifier() );
}
sb.append( '.' ).append( artifact.getType() ).append( LAST_UPDATE_TAG );
return new File( artifact.getFile().getParentFile(), sb.toString() );
}
public File getTouchfile( RepositoryMetadata metadata, File file )
{
return new File( file.getParent(), TOUCHFILE_NAME );
}
public boolean isPomUpdateRequired( Artifact artifact, ArtifactRepository repository )
{
return isUpdateRequired( artifact, repository, repository.getReleases() );
}
}

View File

@ -0,0 +1,42 @@
package org.apache.maven.artifact.manager;
/*
* 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 org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
public interface UpdateCheckManager {
String ROLE = UpdateCheckManager.class.getName();
boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository );
void touch( Artifact artifact, ArtifactRepository repository );
boolean isUpdateRequired( RepositoryMetadata metadata, ArtifactRepository repository, File file );
void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file );
boolean isPomUpdateRequired( Artifact artifact, ArtifactRepository repository );
}

View File

@ -0,0 +1,63 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.wagon.TransferFailedException;
public class WagonConfigurationException
extends TransferFailedException
{
static final long serialVersionUID = 1;
private final String originalMessage;
private final String repositoryId;
public WagonConfigurationException( String repositoryId,
String message,
Throwable cause )
{
super( "While configuring wagon for \'" + repositoryId + "\': " + message, cause );
this.repositoryId = repositoryId;
this.originalMessage = message;
}
public WagonConfigurationException( String repositoryId,
String message )
{
super( "While configuring wagon for \'" + repositoryId + "\': " + message );
this.repositoryId = repositoryId;
this.originalMessage = message;
}
public final String getRepositoryId()
{
return repositoryId;
}
public final String getOriginalMessage()
{
return originalMessage;
}
}

View File

@ -0,0 +1,176 @@
package org.apache.maven.artifact.manager;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.events.TransferListener;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.apache.maven.wagon.repository.RepositoryPermissions;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Manages <a href="http://maven.apache.org/wagon">Wagon</a> related operations in Maven.
*
* @author <a href="michal.maczka@dimatics.com">Michal Maczka </a>
* @version $Id$
*/
public interface WagonManager
{
String ROLE = WagonManager.class.getName();
/**
* Get a Wagon provider that understands the protocol passed as argument.
* It doesn't configure the Wagon.
*
* @param protocol the protocol the {@link Wagon} will handle
* @return the {@link Wagon} instance able to handle the protocol provided
* @throws UnsupportedProtocolException if there is no provider able to handle the protocol
* @deprecated prone to errors. use {@link #getWagon(Repository)} instead.
*/
Wagon getWagon( String protocol )
throws UnsupportedProtocolException;
/**
* Get a Wagon provider for the provided repository.
* It will configure the Wagon for that repository.
*
* @param repository the repository
* @return the {@link Wagon} instance that can be used to connect to the repository
* @throws UnsupportedProtocolException if there is no provider able to handle the protocol
* @throws WagonConfigurationException if the wagon can't be configured for the repository
*/
Wagon getWagon( Repository repository )
throws UnsupportedProtocolException, WagonConfigurationException;
void getArtifact( Artifact artifact,
List<ArtifactRepository> remoteRepositories )
throws TransferFailedException, ResourceDoesNotExistException;
void getArtifact( Artifact artifact,
List<ArtifactRepository> remoteRepositories,
boolean forceUpdateCheck )
throws TransferFailedException, ResourceDoesNotExistException;
void getArtifact( Artifact artifact,
ArtifactRepository repository )
throws TransferFailedException, ResourceDoesNotExistException;
void getArtifact( Artifact artifact,
ArtifactRepository repository,
boolean forceUpdateCheck )
throws TransferFailedException, ResourceDoesNotExistException;
void putArtifact( File source,
Artifact artifact,
ArtifactRepository deploymentRepository )
throws TransferFailedException;
void putArtifactMetadata( File source,
ArtifactMetadata artifactMetadata,
ArtifactRepository repository )
throws TransferFailedException;
void getArtifactMetadata( ArtifactMetadata metadata,
ArtifactRepository remoteRepository,
File destination,
String checksumPolicy )
throws TransferFailedException, ResourceDoesNotExistException;
void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository remoteRepository,
File file, String checksumPolicyWarn )
throws TransferFailedException, ResourceDoesNotExistException;
void setOnline( boolean online );
boolean isOnline();
void addProxy( String protocol,
String host,
int port,
String username,
String password,
String nonProxyHosts );
void registerCredentialsDataSource( CredentialsDataSource cds );
public void addAuthenticationCredentials( String repositoryId,
String username,
String password,
String privateKey,
String passphrase )
throws CredentialsDataSourceException;
void addAuthenticationInfo( String repositoryId,
String username,
String password,
String privateKey,
String passphrase );
void addMirror( String id,
String mirrorOf,
String url );
void setDownloadMonitor( TransferListener downloadMonitor );
void addPermissionInfo( String repositoryId,
String filePermissions,
String directoryPermissions );
ProxyInfo getProxy( String protocol );
AuthenticationInfo getAuthenticationInfo( String id )
throws CredentialsDataSourceException;
/**
* Set the configuration for a repository
*
* @param repositoryId id of the repository to set the configuration to
* @param configuration dom tree of the xml with the configuration for the {@link Wagon}
*/
void addConfiguration( String repositoryId,
Xpp3Dom configuration );
void setInteractive( boolean interactive );
@Deprecated
void registerWagons( Collection wagons,
PlexusContainer extensionContainer );
void findAndRegisterWagons( PlexusContainer container );
void setDefaultRepositoryPermissions( RepositoryPermissions permissions );
ArtifactRepository getMirrorRepository( ArtifactRepository repository );
}

View File

@ -0,0 +1,66 @@
package org.apache.maven.artifact.metadata;
/*
* 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.apache.maven.artifact.Artifact;
/**
* Common elements of artifact metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public abstract class AbstractArtifactMetadata
implements ArtifactMetadata
{
protected Artifact artifact;
protected AbstractArtifactMetadata( Artifact artifact )
{
this.artifact = artifact;
}
public boolean storedInGroupDirectory()
{
return false;
}
public String getGroupId()
{
return artifact.getGroupId();
}
public String getArtifactId()
{
return artifact.getArtifactId();
}
public String extendedToString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( "\nArtifact Metadata\n--------------------------" );
buffer.append( "\nGroupId: " ).append( getGroupId() );
buffer.append( "\nArtifactId: " ).append( getArtifactId() );
buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
return buffer.toString();
}
}

View File

@ -0,0 +1,84 @@
package org.apache.maven.artifact.metadata;
/*
* 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.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
/**
* Contains metadata about an artifact, and methods to retrieve/store it from an artifact repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
* @todo merge with artifactmetadatasource
* @todo retrieval exception not appropriate for store
*/
public interface ArtifactMetadata
{
/** Whether this metadata should be stored alongside the artifact. */
boolean storedInArtifactVersionDirectory();
/** Whether this metadata should be stored alongside the group. */
boolean storedInGroupDirectory();
String getGroupId();
String getArtifactId();
String getBaseVersion();
Object getKey();
/**
* Get the filename of this metadata on the local repository.
*
* @param repository the remote repository it came from
* @return the filename
*/
String getLocalFilename( ArtifactRepository repository );
/**
* Get the filename of this metadata on the remote repository.
*
* @return the filename
*/
String getRemoteFilename();
/**
* Merge a new metadata set into this piece of metadata.
*
* @param metadata the new metadata
* @todo this should only be needed on the repository metadata
*/
void merge( ArtifactMetadata metadata );
/**
* Store the metadata in the local repository.
*
* @param localRepository the local repository
* @param remoteRepository the remote repository it came from
* @todo this should only be needed on the repository metadata
*/
void storeInLocalRepository( ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws RepositoryMetadataStoreException;
String extendedToString();
}

View File

@ -0,0 +1,69 @@
package org.apache.maven.artifact.metadata;
/*
* 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.apache.maven.artifact.Artifact;
/**
* Error while retrieving repository metadata from the repository.
*
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public class ArtifactMetadataRetrievalException
extends Exception
{
private Artifact artifact;
/** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
@Deprecated
public ArtifactMetadataRetrievalException( String message )
{
this( message, null, null );
}
/** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
@Deprecated
public ArtifactMetadataRetrievalException( Throwable cause )
{
this( null, cause, null );
}
/** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
@Deprecated
public ArtifactMetadataRetrievalException( String message,
Throwable cause )
{
this( message, cause, null );
}
public ArtifactMetadataRetrievalException( String message,
Throwable cause,
Artifact artifact )
{
super( message, cause );
this.artifact = artifact;
}
public Artifact getArtifact()
{
return artifact;
}
}

View File

@ -0,0 +1,85 @@
package org.apache.maven.artifact.metadata;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import java.util.List;
/**
* Provides some metadata operations, like querying the remote repository for a list of versions available for an
* artifact.
*
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
* @version $Id$
*/
public interface ArtifactMetadataSource
{
String ROLE = ArtifactMetadataSource.class.getName();
ResolutionGroup retrieve( Artifact artifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories )
throws ArtifactMetadataRetrievalException;
/**
* Resolve all relocations in the POM for this artifact, and return the new artifact coordinate.
*/
Artifact retrieveRelocatedArtifact( Artifact artifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories )
throws ArtifactMetadataRetrievalException;
/**
* Get a list of available versions for an artifact in the remote repository
*
* @param artifact artifact we are interested in. Only <code>groupid</code> and <code>artifactId</code>
* are needed, for instance the following code will work
* <code>artifactFactory.createProjectArtifact( "org.apache.maven", "maven", "" )</code>
* @param localRepository local repository
* @param remoteRepositories remote repositories, {@link List} $lt; {@link ArtifactRepository} >
* @return {@link List} $lt; {@link ArtifactVersion} >
* @throws ArtifactMetadataRetrievalException
* in case of error while retrieving repository metadata from the repository.
*/
List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories )
throws ArtifactMetadataRetrievalException;
/**
* Get a list of available versions for an artifact in the remote deployment repository. This ignores any update
* policy checks and mirrors and always retrieves the latest information from the given repository.
*
* @param artifact artifact we are interested in. Only <code>groupid</code> and <code>artifactId</code> are
* needed, for instance the following code will work
* <code>artifactFactory.createProjectArtifact( "org.apache.maven", "maven", "" )</code>
* @param localRepository local repository
* @param deploymentRepository remote repository
* @return {@link List} $lt; {@link ArtifactVersion} >
* @throws ArtifactMetadataRetrievalException
* in case of error while retrieving repository metadata from the repository.
*/
List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
ArtifactRepository localRepository,
ArtifactRepository remoteRepository ) throws ArtifactMetadataRetrievalException;
}

View File

@ -0,0 +1,61 @@
package org.apache.maven.artifact.metadata;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.util.List;
import java.util.Set;
public class ResolutionGroup
{
private final Set<Artifact> artifacts;
private final List<ArtifactRepository> resolutionRepositories;
private final Artifact pomArtifact;
public ResolutionGroup( Artifact pomArtifact,
Set<Artifact> artifacts,
List<ArtifactRepository> resolutionRepositories )
{
this.pomArtifact = pomArtifact;
this.artifacts = artifacts;
this.resolutionRepositories = resolutionRepositories;
}
public Artifact getPomArtifact()
{
return pomArtifact;
}
public Set<Artifact> getArtifacts()
{
return artifacts;
}
public List<ArtifactRepository> getResolutionRepositories()
{
return resolutionRepositories;
}
}

View File

@ -0,0 +1,62 @@
package org.apache.maven.artifact.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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
/**
* Specifies the repository used for artifact handling.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface ArtifactRepository
{
String pathOf( Artifact artifact );
String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata );
String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository );
String getUrl();
String getBasedir();
String getProtocol();
String getId();
ArtifactRepositoryPolicy getSnapshots();
ArtifactRepositoryPolicy getReleases();
ArtifactRepositoryLayout getLayout();
String getKey();
boolean isUniqueVersion();
void setBlacklisted( boolean blackListed );
boolean isBlacklisted();
}

View File

@ -0,0 +1,70 @@
package org.apache.maven.artifact.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.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.UnknownRepositoryLayoutException;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import java.io.File;
/** @author jdcasey */
public interface ArtifactRepositoryFactory
{
String ROLE = ArtifactRepositoryFactory.class.getName();
String DEFAULT_LAYOUT_ID = "default";
String LOCAL_REPOSITORY_ID = "local";
ArtifactRepository createLocalRepository( File localRepositoryDirectory )
throws InvalidRepositoryException;
ArtifactRepositoryLayout getLayout( String layoutId )
throws UnknownRepositoryLayoutException;
ArtifactRepository createDeploymentArtifactRepository( String id,
String url,
String layoutId,
boolean uniqueVersion )
throws UnknownRepositoryLayoutException;
ArtifactRepository createDeploymentArtifactRepository( String id,
String url,
ArtifactRepositoryLayout layout,
boolean uniqueVersion );
ArtifactRepository createArtifactRepository( String id,
String url,
String layoutId,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases )
throws UnknownRepositoryLayoutException;
ArtifactRepository createArtifactRepository( String id,
String url,
ArtifactRepositoryLayout repositoryLayout,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases );
void setGlobalUpdatePolicy( String snapshotPolicy );
void setGlobalChecksumPolicy( String checksumPolicy );
}

View File

@ -0,0 +1,145 @@
package org.apache.maven.artifact.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.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
* Describes a set of policies for a repository to use under certain conditions.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ArtifactRepositoryPolicy
{
public static final String UPDATE_POLICY_NEVER = "never";
public static final String UPDATE_POLICY_ALWAYS = "always";
public static final String UPDATE_POLICY_DAILY = "daily";
public static final String UPDATE_POLICY_INTERVAL = "interval";
public static final String CHECKSUM_POLICY_FAIL = "fail";
public static final String CHECKSUM_POLICY_WARN = "warn";
public static final String CHECKSUM_POLICY_IGNORE = "ignore";
private boolean enabled;
private String updatePolicy;
private String checksumPolicy;
public ArtifactRepositoryPolicy()
{
this( true, null, null );
}
public ArtifactRepositoryPolicy( boolean enabled,
String updatePolicy,
String checksumPolicy )
{
this.enabled = enabled;
if ( updatePolicy == null )
{
updatePolicy = UPDATE_POLICY_DAILY;
}
this.updatePolicy = updatePolicy;
if ( checksumPolicy == null )
{
checksumPolicy = CHECKSUM_POLICY_WARN;
}
this.checksumPolicy = checksumPolicy;
}
public void setEnabled( boolean enabled )
{
this.enabled = enabled;
}
public void setUpdatePolicy( String updatePolicy )
{
this.updatePolicy = updatePolicy;
}
public void setChecksumPolicy( String checksumPolicy )
{
this.checksumPolicy = checksumPolicy;
}
public boolean isEnabled()
{
return enabled;
}
public String getUpdatePolicy()
{
return updatePolicy;
}
public String getChecksumPolicy()
{
return checksumPolicy;
}
public boolean checkOutOfDate( Date lastModified )
{
boolean checkForUpdates = false;
if ( UPDATE_POLICY_ALWAYS.equals( updatePolicy ) )
{
checkForUpdates = true;
}
else if ( UPDATE_POLICY_DAILY.equals( updatePolicy ) )
{
// Get midnight boundary
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) );
cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 0 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.MILLISECOND, 0 );
if ( cal.getTime().after( lastModified ) )
{
checkForUpdates = true;
}
}
else if ( updatePolicy.startsWith( UPDATE_POLICY_INTERVAL ) )
{
String s = updatePolicy.substring( UPDATE_POLICY_INTERVAL.length() + 1 );
int minutes = Integer.valueOf(s);
Calendar cal = Calendar.getInstance();
cal.add( Calendar.MINUTE, -minutes );
if ( cal.getTime().after( lastModified ) )
{
checkForUpdates = true;
}
}
// else assume "never"
return checkForUpdates;
}
}

View File

@ -0,0 +1,171 @@
package org.apache.maven.artifact.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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.wagon.repository.Repository;
/**
* This class is an abstraction of the location from/to resources can be
* transfered.
*
* @author <a href="michal.maczka@dimatics.com">Michal Maczka </a>
* @version $Id$
*/
public class DefaultArtifactRepository
extends Repository
implements ArtifactRepository
{
private ArtifactRepositoryLayout layout;
private ArtifactRepositoryPolicy snapshots;
private ArtifactRepositoryPolicy releases;
private boolean uniqueVersion;
private boolean blacklisted;
/**
* Create a local repository or a test repository.
*
* @param id the unique identifier of the repository
* @param url the URL of the repository
* @param layout the layout of the repository
*/
public DefaultArtifactRepository( String id,
String url,
ArtifactRepositoryLayout layout )
{
this( id, url, layout, null, null );
}
/**
* Create a remote deployment repository.
*
* @param id the unique identifier of the repository
* @param url the URL of the repository
* @param layout the layout of the repository
* @param uniqueVersion whether to assign each snapshot a unique version
*/
public DefaultArtifactRepository( String id,
String url,
ArtifactRepositoryLayout layout,
boolean uniqueVersion )
{
super( id, url );
this.layout = layout;
this.uniqueVersion = uniqueVersion;
}
/**
* Create a remote download repository.
*
* @param id the unique identifier of the repository
* @param url the URL of the repository
* @param layout the layout of the repository
* @param snapshots the policies to use for snapshots
* @param releases the policies to use for releases
*/
public DefaultArtifactRepository( String id,
String url,
ArtifactRepositoryLayout layout,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases )
{
super( id, url );
this.layout = layout;
if ( snapshots == null )
{
snapshots = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
}
this.snapshots = snapshots;
if ( releases == null )
{
releases = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
}
this.releases = releases;
}
public String pathOf( Artifact artifact )
{
return layout.pathOf( artifact );
}
public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
{
return layout.pathOfRemoteRepositoryMetadata( artifactMetadata );
}
public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository )
{
return layout.pathOfLocalRepositoryMetadata( metadata, repository );
}
public ArtifactRepositoryLayout getLayout()
{
return layout;
}
public ArtifactRepositoryPolicy getSnapshots()
{
return snapshots;
}
public void setReleases( ArtifactRepositoryPolicy releases )
{
this.releases = releases;
}
public ArtifactRepositoryPolicy getReleases()
{
return releases;
}
public String getKey()
{
return getId();
}
public boolean isUniqueVersion()
{
return uniqueVersion;
}
public boolean isBlacklisted()
{
return blacklisted;
}
public void setBlacklisted( boolean blacklisted )
{
this.blacklisted = blacklisted;
}
}

View File

@ -0,0 +1,183 @@
package org.apache.maven.artifact.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.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.UnknownRepositoryLayoutException;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
/**
* @author jdcasey
* @plexus.component
*/
public class DefaultArtifactRepositoryFactory
implements ArtifactRepositoryFactory
{
// TODO: use settings?
private String globalUpdatePolicy;
private String globalChecksumPolicy;
// FIXME: This is a non-ThreadLocal cache!!
private final Map<String,ArtifactRepository> artifactRepositories = new HashMap<String,ArtifactRepository>();
/** @plexus.requirement role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" */
private Map<String,ArtifactRepositoryLayout> repositoryLayouts;
public ArtifactRepositoryLayout getLayout( String layoutId )
throws UnknownRepositoryLayoutException
{
return repositoryLayouts.get( layoutId );
}
public ArtifactRepository createDeploymentArtifactRepository( String id,
String url,
String layoutId,
boolean uniqueVersion )
throws UnknownRepositoryLayoutException
{
ArtifactRepositoryLayout layout = repositoryLayouts.get( layoutId );
checkLayout( id, layoutId, layout );
return createDeploymentArtifactRepository( id, url, layout, uniqueVersion );
}
private void checkLayout( String repositoryId,
String layoutId,
ArtifactRepositoryLayout layout )
throws UnknownRepositoryLayoutException
{
if ( layout == null )
{
throw new UnknownRepositoryLayoutException( repositoryId, layoutId );
}
}
public ArtifactRepository createDeploymentArtifactRepository( String id,
String url,
ArtifactRepositoryLayout repositoryLayout,
boolean uniqueVersion )
{
return new DefaultArtifactRepository( id, url, repositoryLayout, uniqueVersion );
}
public ArtifactRepository createArtifactRepository( String id,
String url,
String layoutId,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases )
throws UnknownRepositoryLayoutException
{
ArtifactRepositoryLayout layout = repositoryLayouts.get( layoutId );
checkLayout( id, layoutId, layout );
return createArtifactRepository( id, url, layout, snapshots, releases );
}
public ArtifactRepository createArtifactRepository( String id,
String url,
ArtifactRepositoryLayout repositoryLayout,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases )
{
boolean blacklisted = false;
if ( artifactRepositories.containsKey( id ) )
{
ArtifactRepository repository = artifactRepositories.get( id );
// TODO: this should be an if there are duplicates?
if ( repository.getUrl().equals( url ) )
{
blacklisted = repository.isBlacklisted();
}
}
if ( snapshots == null )
{
snapshots = new ArtifactRepositoryPolicy();
}
if ( releases == null )
{
releases = new ArtifactRepositoryPolicy();
}
if ( globalUpdatePolicy != null )
{
snapshots.setUpdatePolicy( globalUpdatePolicy );
releases.setUpdatePolicy( globalUpdatePolicy );
}
if ( globalChecksumPolicy != null )
{
snapshots.setChecksumPolicy( globalChecksumPolicy );
releases.setChecksumPolicy( globalChecksumPolicy );
}
DefaultArtifactRepository repository = new DefaultArtifactRepository( id, url, repositoryLayout, snapshots, releases );
repository.setBlacklisted( blacklisted );
artifactRepositories.put( id, repository );
return repository;
}
public void setGlobalUpdatePolicy( String updatePolicy )
{
globalUpdatePolicy = updatePolicy;
}
public void setGlobalChecksumPolicy( String checksumPolicy )
{
globalChecksumPolicy = checksumPolicy;
}
public ArtifactRepository createLocalRepository( File localRepositoryDirectory )
throws InvalidRepositoryException
{
ArtifactRepositoryLayout layout = getLayout( DEFAULT_LAYOUT_ID );
DefaultArtifactRepository repo;
try
{
repo = new DefaultArtifactRepository( LOCAL_REPOSITORY_ID,
localRepositoryDirectory.toURI()
.toURL()
.toExternalForm(),
layout, new ArtifactRepositoryPolicy(),
new ArtifactRepositoryPolicy() );
}
catch ( MalformedURLException e )
{
throw new InvalidRepositoryException( "Invalid local repository directory: "
+ localRepositoryDirectory
+ ". Cannot render URL.", LOCAL_REPOSITORY_ID, e );
}
repo.setBasedir( localRepositoryDirectory.getAbsolutePath() );
return repo;
}
}

View File

@ -0,0 +1,37 @@
package org.apache.maven.artifact.repository.layout;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
/** @author jdcasey */
public interface ArtifactRepositoryLayout
{
String ROLE = ArtifactRepositoryLayout.class.getName();
String pathOf( Artifact artifact );
String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository );
String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata );
}

View File

@ -0,0 +1,101 @@
package org.apache.maven.artifact.repository.layout;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* @author jdcasey
* @plexus.component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" role-hint="default"
*/
public class DefaultRepositoryLayout
implements ArtifactRepositoryLayout
{
private static final char PATH_SEPARATOR = '/';
private static final char GROUP_SEPARATOR = '.';
private static final char ARTIFACT_SEPARATOR = '-';
public String pathOf( Artifact artifact )
{
ArtifactHandler artifactHandler = artifact.getArtifactHandler();
StringBuffer path = new StringBuffer();
path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
if ( artifact.hasClassifier() )
{
path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
}
if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
{
path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
}
return path.toString();
}
public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository )
{
return pathOfRepositoryMetadata( metadata, metadata.getLocalFilename( repository ) );
}
private String pathOfRepositoryMetadata( ArtifactMetadata metadata,
String filename )
{
StringBuffer path = new StringBuffer();
path.append( formatAsDirectory( metadata.getGroupId() ) ).append( PATH_SEPARATOR );
if ( !metadata.storedInGroupDirectory() )
{
path.append( metadata.getArtifactId() ).append( PATH_SEPARATOR );
if ( metadata.storedInArtifactVersionDirectory() )
{
path.append( metadata.getBaseVersion() ).append( PATH_SEPARATOR );
}
}
path.append( filename );
return path.toString();
}
public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
{
return pathOfRepositoryMetadata( metadata, metadata.getRemoteFilename() );
}
private String formatAsDirectory( String directory )
{
return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
}
}

View File

@ -0,0 +1,62 @@
package org.apache.maven.artifact.repository.layout;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* The code in this class is taken from DefaultRepositorylayout, located at:
* http://svn.apache.org/viewvc/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java
*
* @version $Id$
* @plexus.component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" role-hint="flat"
*/
public class FlatRepositoryLayout
implements ArtifactRepositoryLayout
{
private static final char ARTIFACT_SEPARATOR = '-';
private static final char GROUP_SEPARATOR = '.';
public String pathOf( Artifact artifact )
{
ArtifactHandler artifactHandler = artifact.getArtifactHandler();
StringBuffer path = new StringBuffer();
path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
if ( artifact.hasClassifier() )
{
path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
}
if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
{
path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
}
return path.toString();
}
public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository )
{
return pathOfRepositoryMetadata( metadata.getLocalFilename( repository ) );
}
private String pathOfRepositoryMetadata( String filename )
{
StringBuffer path = new StringBuffer();
path.append( filename );
return path.toString();
}
public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
{
return pathOfRepositoryMetadata( metadata.getRemoteFilename() );
}
}

View File

@ -0,0 +1,82 @@
package org.apache.maven.artifact.repository.layout;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* @author jdcasey
* @plexus.component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" role-hint="legacy"
*/
public class LegacyRepositoryLayout
implements ArtifactRepositoryLayout
{
private static final String PATH_SEPARATOR = "/";
public String pathOf( Artifact artifact )
{
ArtifactHandler artifactHandler = artifact.getArtifactHandler();
StringBuffer path = new StringBuffer();
path.append( artifact.getGroupId() ).append( '/' );
path.append( artifactHandler.getDirectory() ).append( '/' );
path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
if ( artifact.hasClassifier() )
{
path.append( '-' ).append( artifact.getClassifier() );
}
if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
{
path.append( '.' ).append( artifactHandler.getExtension() );
}
return path.toString();
}
public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
ArtifactRepository repository )
{
return pathOfRepositoryMetadata( metadata, metadata.getLocalFilename( repository ) );
}
private String pathOfRepositoryMetadata( ArtifactMetadata metadata,
String filename )
{
StringBuffer path = new StringBuffer();
path.append( metadata.getGroupId() ).append( PATH_SEPARATOR ).append( "poms" ).append( PATH_SEPARATOR );
path.append( filename );
return path.toString();
}
public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
{
return pathOfRepositoryMetadata( metadata, metadata.getRemoteFilename() );
}
}

View File

@ -0,0 +1,210 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/**
* Shared methods of the repository metadata handling.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public abstract class AbstractRepositoryMetadata
implements RepositoryMetadata
{
private Metadata metadata;
protected AbstractRepositoryMetadata( Metadata metadata )
{
this.metadata = metadata;
}
public String getRemoteFilename()
{
return "maven-metadata.xml";
}
public String getLocalFilename( ArtifactRepository repository )
{
return "maven-metadata-" + repository.getKey() + ".xml";
}
public void storeInLocalRepository( ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws RepositoryMetadataStoreException
{
try
{
updateRepositoryMetadata( localRepository, remoteRepository );
}
catch ( IOException e )
{
throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
}
catch ( XmlPullParserException e )
{
throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
}
}
protected void updateRepositoryMetadata( ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws IOException, XmlPullParserException
{
MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
Metadata metadata = null;
File metadataFile = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( this, remoteRepository ) );
if ( metadataFile.length() == 0 )
{
metadataFile.delete();
}
else if ( metadataFile.exists() )
{
Reader reader = null;
try
{
reader = ReaderFactory.newXmlReader( metadataFile );
metadata = mappingReader.read( reader, false );
}
finally
{
IOUtil.close( reader );
}
}
boolean changed;
// If file could not be found or was not valid, start from scratch
if ( metadata == null )
{
metadata = this.metadata;
changed = true;
}
else
{
changed = metadata.merge( this.metadata );
}
// beware meta-versions!
String version = metadata.getVersion();
if ( version != null && ( Artifact.LATEST_VERSION.equals( version ) || Artifact.RELEASE_VERSION.equals(
version ) ) )
{
// meta-versions are not valid <version/> values...don't write them.
metadata.setVersion( null );
}
if ( changed || !metadataFile.exists() )
{
Writer writer = null;
try
{
metadataFile.getParentFile().mkdirs();
writer = WriterFactory.newXmlWriter( metadataFile );
MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer();
mappingWriter.write( writer, metadata );
}
finally
{
IOUtil.close( writer );
}
}
else
{
metadataFile.setLastModified( System.currentTimeMillis() );
}
}
public String toString()
{
return "repository metadata for: \'" + getKey() + "\'";
}
protected static Metadata createMetadata( Artifact artifact,
Versioning versioning )
{
Metadata metadata = new Metadata();
metadata.setGroupId( artifact.getGroupId() );
metadata.setArtifactId( artifact.getArtifactId() );
metadata.setVersion( artifact.getVersion() );
metadata.setVersioning( versioning );
return metadata;
}
protected static Versioning createVersioning( Snapshot snapshot )
{
Versioning versioning = new Versioning();
versioning.setSnapshot( snapshot );
versioning.updateTimestamp();
return versioning;
}
public void setMetadata( Metadata metadata )
{
this.metadata = metadata;
}
public Metadata getMetadata()
{
return metadata;
}
public void merge( ArtifactMetadata metadata )
{
// TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
this.metadata.merge( repoMetadata.getMetadata() );
}
public String extendedToString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( "\nRepository Metadata\n--------------------------" );
buffer.append( "\nGroupId: " ).append( getGroupId() );
buffer.append( "\nArtifactId: " ).append( getArtifactId() );
buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
return buffer.toString();
}
}

View File

@ -0,0 +1,89 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* Metadata for the artifact directory of the repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ArtifactRepositoryMetadata
extends AbstractRepositoryMetadata
{
private Artifact artifact;
public ArtifactRepositoryMetadata( Artifact artifact )
{
this( artifact, null );
}
public ArtifactRepositoryMetadata( Artifact artifact,
Versioning versioning )
{
super( createMetadata( artifact, versioning ) );
this.artifact = artifact;
}
public boolean storedInGroupDirectory()
{
return false;
}
public boolean storedInArtifactVersionDirectory()
{
return false;
}
public String getGroupId()
{
return artifact.getGroupId();
}
public String getArtifactId()
{
return artifact.getArtifactId();
}
public String getBaseVersion()
{
// Don't want the artifact's version in here, as this is stored in the directory above that
return null;
}
public Object getKey()
{
return "artifact " + artifact.getGroupId() + ":" + artifact.getArtifactId();
}
public boolean isSnapshot()
{
// Don't consider the artifact's version in here, as this is stored in the directory above that
return false;
}
public void setRepository( ArtifactRepository remoteRepository )
{
artifact.setRepository( remoteRepository );
}
}

View File

@ -0,0 +1,409 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.manager.UpdateCheckManager;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* @author Jason van Zyl
* @plexus.component
*/
public class DefaultRepositoryMetadataManager
extends AbstractLogEnabled
implements RepositoryMetadataManager
{
/** @plexus.requirement */
private WagonManager wagonManager;
/** @plexus.requirement */
private UpdateCheckManager updateCheckManager;
protected DefaultRepositoryMetadataManager( WagonManager wagonManager, UpdateCheckManager updateCheckManager, Logger logger )
{
this.wagonManager = wagonManager;
this.updateCheckManager = updateCheckManager;
enableLogging( logger );
}
public DefaultRepositoryMetadataManager()
{
}
public void resolve( RepositoryMetadata metadata,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws RepositoryMetadataResolutionException
{
for (ArtifactRepository repository : remoteRepositories) {
ArtifactRepositoryPolicy policy =
metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
File file = new File(localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata(metadata, repository));
if (wagonManager.isOnline()) {
if (updateCheckManager.isUpdateRequired(metadata, repository, file)) {
getLogger().info(metadata.getKey() + ": checking for updates from " + repository.getId());
try {
wagonManager.getArtifactMetadata(metadata, repository, file, policy.getChecksumPolicy());
}
catch (ResourceDoesNotExistException e) {
getLogger().debug(metadata + " could not be found on repository: " + repository.getId());
// delete the local copy so the old details aren't used.
if (file.exists()) {
file.delete();
}
}
catch (TransferFailedException e) {
getLogger().warn(metadata + " could not be retrieved from repository: " + repository.getId() +
" due to an error: " + e.getMessage());
getLogger().debug("Exception", e);
getLogger().info("Repository '" + repository.getId() + "' will be blacklisted");
repository.setBlacklisted(true);
// TODO: [jc; 08-Nov-2005] revisit this for 2.1
// suppressing logging to avoid logging this error twice.
}
finally {
updateCheckManager.touch(metadata, repository, file);
}
}
} else {
getLogger().debug(
"System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n");
}
// TODO: should this be inside the above check?
// touch file so that this is not checked again until interval has passed
if (file.exists()) {
file.setLastModified(System.currentTimeMillis());
}
}
try
{
mergeMetadata( metadata, remoteRepositories, localRepository );
}
catch ( RepositoryMetadataStoreException e )
{
throw new RepositoryMetadataResolutionException(
"Unable to store local copy of metadata: " + e.getMessage(), e );
}
catch ( RepositoryMetadataReadException e )
{
throw new RepositoryMetadataResolutionException( "Unable to read local copy of metadata: " + e.getMessage(),
e );
}
}
private void mergeMetadata( RepositoryMetadata metadata,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws RepositoryMetadataStoreException, RepositoryMetadataReadException
{
// TODO: currently this is first wins, but really we should take the latest by comparing either the
// snapshot timestamp, or some other timestamp later encoded into the metadata.
// TODO: this needs to be repeated here so the merging doesn't interfere with the written metadata
// - we'd be much better having a pristine input, and an ongoing metadata for merging instead
Map<ArtifactRepository,Metadata> previousMetadata = new HashMap<ArtifactRepository,Metadata>();
ArtifactRepository selected = null;
for (ArtifactRepository repository : remoteRepositories) {
ArtifactRepositoryPolicy policy =
metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
if ((policy.isEnabled() && !repository.isBlacklisted())
&& (loadMetadata(metadata, repository, localRepository, previousMetadata))) {
metadata.setRepository(repository);
selected = repository;
}
}
if ( loadMetadata( metadata, localRepository, localRepository, previousMetadata ) )
{
metadata.setRepository( null );
selected = localRepository;
}
updateSnapshotMetadata( metadata, previousMetadata, selected, localRepository );
}
private void updateSnapshotMetadata( RepositoryMetadata metadata,
Map<ArtifactRepository,Metadata> previousMetadata,
ArtifactRepository selected,
ArtifactRepository localRepository )
throws RepositoryMetadataStoreException
{
// TODO: this could be a lot nicer... should really be in the snapshot transformation?
if ( metadata.isSnapshot() )
{
Metadata prevMetadata = metadata.getMetadata();
for (ArtifactRepository repository : previousMetadata.keySet()) {
Metadata m = previousMetadata.get(repository);
if (repository.equals(selected)) {
if (m.getVersioning() == null) {
m.setVersioning(new Versioning());
}
if (m.getVersioning().getSnapshot() == null) {
m.getVersioning().setSnapshot(new Snapshot());
}
} else {
if ((m.getVersioning() != null) && (m.getVersioning().getSnapshot() != null) &&
m.getVersioning().getSnapshot().isLocalCopy()) {
m.getVersioning().getSnapshot().setLocalCopy(false);
metadata.setMetadata(m);
metadata.storeInLocalRepository(localRepository, repository);
}
}
}
metadata.setMetadata( prevMetadata );
}
}
private boolean loadMetadata( RepositoryMetadata repoMetadata,
ArtifactRepository remoteRepository,
ArtifactRepository localRepository,
Map<ArtifactRepository,Metadata> previousMetadata )
throws RepositoryMetadataReadException
{
boolean setRepository = false;
File metadataFile = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( repoMetadata, remoteRepository ) );
if ( metadataFile.exists() )
{
Metadata metadata = readMetadata( metadataFile );
if ( repoMetadata.isSnapshot() && ( previousMetadata != null ) )
{
previousMetadata.put( remoteRepository, metadata );
}
if ( repoMetadata.getMetadata() != null )
{
setRepository = repoMetadata.getMetadata().merge( metadata );
}
else
{
repoMetadata.setMetadata( metadata );
setRepository = true;
}
}
return setRepository;
}
/** @todo share with DefaultPluginMappingManager. */
protected static Metadata readMetadata( File mappingFile )
throws RepositoryMetadataReadException
{
Metadata result;
Reader reader = null;
try
{
reader = ReaderFactory.newXmlReader( mappingFile );
MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
result = mappingReader.read( reader, false );
}
catch ( FileNotFoundException e )
{
throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "'", e );
}
catch ( IOException e )
{
throw new RepositoryMetadataReadException(
"Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e );
}
catch ( XmlPullParserException e )
{
throw new RepositoryMetadataReadException(
"Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e );
}
finally
{
IOUtil.close( reader );
}
return result;
}
public void resolveAlways( RepositoryMetadata metadata,
ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws RepositoryMetadataResolutionException
{
if ( !wagonManager.isOnline() )
{
// metadata is required for deployment, can't be offline
throw new RepositoryMetadataResolutionException(
"System is offline. Cannot resolve required metadata:\n" + metadata.extendedToString() );
}
File file;
try
{
file = getArtifactMetadataFromDeploymentRepository( metadata, localRepository, remoteRepository );
}
catch ( TransferFailedException e )
{
throw new RepositoryMetadataResolutionException( metadata + " could not be retrieved from repository: " +
remoteRepository.getId() + " due to an error: " + e.getMessage(), e );
}
try
{
if ( file.exists() )
{
Metadata prevMetadata = readMetadata( file );
metadata.setMetadata( prevMetadata );
}
}
catch ( RepositoryMetadataReadException e )
{
throw new RepositoryMetadataResolutionException( e.getMessage(), e );
}
}
private File getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata,
ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws TransferFailedException
{
File file = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( metadata, remoteRepository ) );
try
{
wagonManager.getArtifactMetadataFromDeploymentRepository( metadata, remoteRepository, file,
ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
}
catch ( ResourceDoesNotExistException e )
{
getLogger().info(
metadata + " could not be found on repository: " + remoteRepository.getId() + ", so will be created" );
// delete the local copy so the old details aren't used.
if ( file.exists() )
{
file.delete();
}
}
finally
{
if ( metadata instanceof RepositoryMetadata )
{
updateCheckManager.touch( (RepositoryMetadata) metadata, remoteRepository, file );
}
}
return file;
}
public void deploy( ArtifactMetadata metadata,
ArtifactRepository localRepository,
ArtifactRepository deploymentRepository )
throws RepositoryMetadataDeploymentException
{
if ( !wagonManager.isOnline() )
{
// deployment shouldn't silently fail when offline
throw new RepositoryMetadataDeploymentException(
"System is offline. Cannot deploy metadata:\n" + metadata.extendedToString() );
}
File file;
if ( metadata instanceof RepositoryMetadata )
{
getLogger().info( "Retrieving previous metadata from " + deploymentRepository.getId() );
try
{
file = getArtifactMetadataFromDeploymentRepository( metadata, localRepository, deploymentRepository );
}
catch ( TransferFailedException e )
{
throw new RepositoryMetadataDeploymentException( metadata +
" could not be retrieved from repository: " + deploymentRepository.getId() + " due to an error: " +
e.getMessage(), e );
}
}
else
{
// It's a POM - we don't need to retrieve it first
file = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( metadata, deploymentRepository ) );
}
try
{
metadata.storeInLocalRepository( localRepository, deploymentRepository );
}
catch ( RepositoryMetadataStoreException e )
{
throw new RepositoryMetadataDeploymentException( "Error installing metadata: " + e.getMessage(), e );
}
try
{
wagonManager.putArtifactMetadata( file, metadata, deploymentRepository );
}
catch ( TransferFailedException e )
{
throw new RepositoryMetadataDeploymentException( "Error while deploying metadata: " + e.getMessage(), e );
}
}
public void install( ArtifactMetadata metadata,
ArtifactRepository localRepository )
throws RepositoryMetadataInstallationException
{
try
{
metadata.storeInLocalRepository( localRepository, localRepository );
}
catch ( RepositoryMetadataStoreException e )
{
throw new RepositoryMetadataInstallationException( "Error installing metadata: " + e.getMessage(), e );
}
}
}

View File

@ -0,0 +1,115 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.repository.ArtifactRepository;
import java.util.Iterator;
import java.util.List;
/**
* Metadata for the group directory of the repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class GroupRepositoryMetadata
extends AbstractRepositoryMetadata
{
private final String groupId;
public GroupRepositoryMetadata( String groupId )
{
super( new Metadata() );
this.groupId = groupId;
}
public boolean storedInGroupDirectory()
{
return true;
}
public boolean storedInArtifactVersionDirectory()
{
return false;
}
public String getGroupId()
{
return groupId;
}
public String getArtifactId()
{
return null;
}
public String getBaseVersion()
{
return null;
}
public void addPluginMapping( String goalPrefix,
String artifactId )
{
addPluginMapping( goalPrefix, artifactId, artifactId );
}
public void addPluginMapping( String goalPrefix,
String artifactId,
String name )
{
List plugins = getMetadata().getPlugins();
boolean found = false;
for ( Iterator i = plugins.iterator(); i.hasNext() && !found; )
{
Plugin plugin = (Plugin) i.next();
if ( plugin.getPrefix().equals( goalPrefix ) )
{
found = true;
}
}
if ( !found )
{
Plugin plugin = new Plugin();
plugin.setPrefix( goalPrefix );
plugin.setArtifactId( artifactId );
plugin.setName( name );
getMetadata().addPlugin( plugin );
}
}
public Object getKey()
{
return groupId;
}
public boolean isSnapshot()
{
return false;
}
public void setRepository( ArtifactRepository remoteRepository )
{
// intentionally blank
}
}

View File

@ -0,0 +1,62 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* Describes repository directory metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
* @todo not happy about the store method - they use "this"
*/
public interface RepositoryMetadata
extends ArtifactMetadata
{
/**
* Set the repository the metadata was located in.
*
* @param remoteRepository the repository
*/
void setRepository( ArtifactRepository remoteRepository );
/**
* Get the repository metadata associated with this marker.
*
* @return the metadata, or <code>null</code> if none loaded
*/
Metadata getMetadata();
/**
* Set the metadata contents.
*
* @param metadata the metadata
*/
void setMetadata( Metadata metadata );
/**
* Whether this represents a snapshot.
*
* @return if it is a snapshot
*/
boolean isSnapshot();
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.
*/
/**
* Error while deploying repository metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadataDeploymentException
extends Throwable
{
public RepositoryMetadataDeploymentException( String message )
{
super( message );
}
public RepositoryMetadataDeploymentException( String message,
Exception e )
{
super( message, e );
}
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.
*/
/**
* Error while installing repository metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadataInstallationException
extends Throwable
{
public RepositoryMetadataInstallationException( String message )
{
super( message );
}
public RepositoryMetadataInstallationException( String message,
Exception e )
{
super( message, e );
}
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.util.List;
public interface RepositoryMetadataManager
{
void resolve( RepositoryMetadata repositoryMetadata,
List<ArtifactRepository> repositories,
ArtifactRepository localRepository )
throws RepositoryMetadataResolutionException;
void resolveAlways( RepositoryMetadata metadata,
ArtifactRepository localRepository,
ArtifactRepository remoteRepository )
throws RepositoryMetadataResolutionException;
/**
* Deploy metadata to the remote repository.
*
* @param metadata the metadata to deploy
* @param localRepository the local repository to install to first
* @param deploymentRepository the remote repository to deploy to
*/
void deploy( ArtifactMetadata metadata,
ArtifactRepository localRepository,
ArtifactRepository deploymentRepository )
throws RepositoryMetadataDeploymentException;
/**
* Install the metadata in the local repository.
*
* @param metadata the metadata
* @param localRepository the local repository
*/
void install( ArtifactMetadata metadata,
ArtifactRepository localRepository )
throws RepositoryMetadataInstallationException;
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.
*/
/**
* Problem storing the repository metadata in the local repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadataReadException
extends Exception
{
public RepositoryMetadataReadException( String message )
{
super( message );
}
public RepositoryMetadataReadException( String message,
Exception e )
{
super( message, e );
}
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.
*/
/**
* Error while retrieving repository metadata from the repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadataResolutionException
extends Exception
{
public RepositoryMetadataResolutionException( String message )
{
super( message );
}
public RepositoryMetadataResolutionException( String message,
Exception e )
{
super( message, e );
}
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.
*/
/**
* Problem storing the repository metadata in the local repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadataStoreException
extends Exception
{
public RepositoryMetadataStoreException( String message )
{
super( message );
}
public RepositoryMetadataStoreException( String message,
Exception e )
{
super( message, e );
}
}

View File

@ -0,0 +1,89 @@
package org.apache.maven.artifact.repository.metadata;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* Metadata for the artifact version directory of the repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
* @todo split instantiation (versioning, plugin mappings) from definition
*/
public class SnapshotArtifactRepositoryMetadata
extends AbstractRepositoryMetadata
{
private Artifact artifact;
public SnapshotArtifactRepositoryMetadata( Artifact artifact )
{
super( createMetadata( artifact, null ) );
this.artifact = artifact;
}
public SnapshotArtifactRepositoryMetadata( Artifact artifact,
Snapshot snapshot )
{
super( createMetadata( artifact, createVersioning( snapshot ) ) );
this.artifact = artifact;
}
public boolean storedInGroupDirectory()
{
return false;
}
public boolean storedInArtifactVersionDirectory()
{
return true;
}
public String getGroupId()
{
return artifact.getGroupId();
}
public String getArtifactId()
{
return artifact.getArtifactId();
}
public String getBaseVersion()
{
return artifact.getBaseVersion();
}
public Object getKey()
{
return "snapshot " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getBaseVersion();
}
public boolean isSnapshot()
{
return artifact.isSnapshot();
}
public void setRepository( ArtifactRepository remoteRepository )
{
artifact.setRepository( remoteRepository );
}
}

View File

@ -0,0 +1,321 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
/**
* Base class for artifact resolution exceptions.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class AbstractArtifactResolutionException
extends Exception
{
private String groupId;
private String artifactId;
private String version;
private String type;
private String classifier;
private Artifact artifact;
private List<ArtifactRepository> remoteRepositories;
private final String originalMessage;
private final String path;
static final String LS = System.getProperty( "line.separator" );
protected AbstractArtifactResolutionException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
List path )
{
this( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, null );
}
protected AbstractArtifactResolutionException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
List path,
Throwable t )
{
super( constructMessageBase( message, groupId, artifactId, version, type, remoteRepositories, path ), t );
this.originalMessage = message;
this.groupId = groupId;
this.artifactId = artifactId;
this.type = type;
this.classifier = classifier;
this.version = version;
this.remoteRepositories = remoteRepositories;
this.path = constructArtifactPath( path, "" );
}
protected AbstractArtifactResolutionException( String message,
Artifact artifact )
{
this( message, artifact, null );
}
protected AbstractArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories )
{
this( message, artifact, remoteRepositories, null );
}
protected AbstractArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
Throwable t )
{
this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
artifact.getClassifier(), remoteRepositories, artifact.getDependencyTrail(), t );
this.artifact = artifact;
}
public Artifact getArtifact()
{
return artifact;
}
public String getGroupId()
{
return groupId;
}
public String getArtifactId()
{
return artifactId;
}
public String getVersion()
{
return version;
}
public String getType()
{
return type;
}
/** @return the classifier */
public String getClassifier()
{
return this.classifier;
}
/** @return the path */
public String getPath()
{
return this.path;
}
public List getRemoteRepositories()
{
return remoteRepositories;
}
public String getOriginalMessage()
{
return originalMessage;
}
protected static String constructArtifactPath( List path,
String indentation )
{
StringBuffer sb = new StringBuffer();
if ( path != null )
{
sb.append( LS );
sb.append( indentation );
sb.append( "Path to dependency: " );
sb.append( LS );
int num = 1;
for ( Iterator i = path.iterator(); i.hasNext(); num++ )
{
sb.append( indentation );
sb.append( "\t" );
sb.append( num );
sb.append( ") " );
sb.append( i.next() );
sb.append( LS );
}
}
return sb.toString();
}
private static String constructMessageBase( String message,
String groupId,
String artifactId,
String version,
String type,
List remoteRepositories,
List path )
{
StringBuffer sb = new StringBuffer();
sb.append( message );
sb.append( LS );
sb.append( " " + groupId + ":" + artifactId + ":" + type + ":" + version );
sb.append( LS );
if ( remoteRepositories != null && !remoteRepositories.isEmpty() )
{
sb.append( LS );
sb.append( "from the specified remote repositories:" );
sb.append( LS + " " );
for ( Iterator i = new HashSet( remoteRepositories ).iterator(); i.hasNext(); )
{
ArtifactRepository remoteRepository = (ArtifactRepository) i.next();
sb.append( remoteRepository.getId() );
sb.append( " (" );
sb.append( remoteRepository.getUrl() );
sb.append( ")" );
if ( i.hasNext() )
{
sb.append( ",\n " );
}
}
}
sb.append( constructArtifactPath( path, "" ) );
sb.append( LS );
return sb.toString();
}
protected static String constructMissingArtifactMessage( String message,
String indentation,
String groupId,
String artifactId,
String version,
String type,
String classifier,
String downloadUrl,
List path )
{
StringBuffer sb = new StringBuffer( message );
if ( !"pom".equals( type ) )
{
if ( downloadUrl != null )
{
sb.append( LS );
sb.append( LS );
sb.append( indentation );
sb.append( "Try downloading the file manually from: " );
sb.append( LS );
sb.append( indentation );
sb.append( " " );
sb.append( downloadUrl );
}
else
{
sb.append( LS );
sb.append( LS );
sb.append( indentation );
sb.append( "Try downloading the file manually from the project website." );
}
sb.append( LS );
sb.append( LS );
sb.append( indentation );
sb.append( "Then, install it using the command: " );
sb.append( LS );
sb.append( indentation );
sb.append( " mvn install:install-file -DgroupId=" );
sb.append( groupId );
sb.append( " -DartifactId=" );
sb.append( artifactId );
sb.append( " -Dversion=" );
sb.append( version );
//insert classifier only if it was used in the artifact
if ( classifier != null && !classifier.equals( "" ) )
{
sb.append( " -Dclassifier=" );
sb.append( classifier );
}
sb.append( " -Dpackaging=" );
sb.append( type );
sb.append( " -Dfile=/path/to/file" );
sb.append( LS );
// If people want to deploy it
sb.append( LS );
sb.append( indentation );
sb.append( "Alternatively, if you host your own repository you can deploy the file there: " );
sb.append( LS );
sb.append( indentation );
sb.append( " mvn deploy:deploy-file -DgroupId=" );
sb.append( groupId );
sb.append( " -DartifactId=" );
sb.append( artifactId );
sb.append( " -Dversion=" );
sb.append( version );
//insert classifier only if it was used in the artifact
if ( classifier != null && !classifier.equals( "" ) )
{
sb.append( " -Dclassifier=" );
sb.append( classifier );
}
sb.append( " -Dpackaging=" );
sb.append( type );
sb.append( " -Dfile=/path/to/file" );
sb.append( " -Durl=[url] -DrepositoryId=[id]" );
sb.append( LS );
}
sb.append( constructArtifactPath( path, indentation ) );
sb.append( LS );
return sb.toString();
}
public String getArtifactPath()
{
return path;
}
}

View File

@ -0,0 +1,78 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Artifact collector - takes a set of original artifacts and resolves all of the best versions to use
* along with their metadata. No artifacts are downloaded.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface ArtifactCollector
{
/**
* The plexus role for this component.
*
* @since 3.0
*/
String ROLE = ArtifactCollector.class.getName();
// TODO: deprecate since conflict resolvers should always be specified
ArtifactResolutionResult collect( Set<Artifact> artifacts,
Artifact originatingArtifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter,
List<ResolutionListener> listeners );
// TODO: deprecate since conflict resolvers should always be specified
ArtifactResolutionResult collect( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter,
List<ResolutionListener> listeners );
/** @since 3.0 */
ArtifactResolutionResult collect( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter,
List<ResolutionListener> listeners,
List<ConflictResolver> conflictResolvers )
throws ArtifactResolutionException;
}

View File

@ -0,0 +1,131 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import java.util.List;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public class ArtifactNotFoundException
extends AbstractArtifactResolutionException
{
private String downloadUrl;
protected ArtifactNotFoundException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories )
{
super( message, artifact, remoteRepositories );
}
public ArtifactNotFoundException( String message,
Artifact artifact )
{
this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
artifact.getClassifier(), null, artifact.getDownloadUrl(), artifact.getDependencyTrail() );
}
protected ArtifactNotFoundException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
ResourceDoesNotExistException cause )
{
this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
artifact.getClassifier(),
remoteRepositories, artifact.getDownloadUrl(), artifact.getDependencyTrail(), cause );
}
@Deprecated
protected ArtifactNotFoundException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
Throwable cause )
{
this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
artifact.getClassifier(),
remoteRepositories, artifact.getDownloadUrl(), artifact.getDependencyTrail(), cause );
}
@Deprecated
public ArtifactNotFoundException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
String downloadUrl,
List path,
Throwable cause )
{
super( constructMissingArtifactMessage( message, "", groupId, artifactId, version, type, classifier,
downloadUrl, path ), groupId, artifactId,
version, type, classifier, remoteRepositories, null, cause );
this.downloadUrl = downloadUrl;
}
public ArtifactNotFoundException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
String downloadUrl,
List path,
ResourceDoesNotExistException cause )
{
super( constructMissingArtifactMessage( message, "", groupId, artifactId, version, type, classifier,
downloadUrl, path ), groupId, artifactId,
version, type, classifier, remoteRepositories, null, cause );
this.downloadUrl = downloadUrl;
}
private ArtifactNotFoundException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
String downloadUrl,
List path )
{
super( constructMissingArtifactMessage( message, "", groupId, artifactId, version, type, classifier,
downloadUrl, path ), groupId, artifactId,
version, type, classifier, remoteRepositories, null );
this.downloadUrl = downloadUrl;
}
public String getDownloadUrl()
{
return downloadUrl;
}
}

View File

@ -0,0 +1,125 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.wagon.TransferFailedException;
import java.io.IOException;
import java.util.List;
/**
* @author Jason van Zyl
* @version $Id$
*/
public class ArtifactResolutionException
extends AbstractArtifactResolutionException
{
public ArtifactResolutionException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
List<ArtifactRepository> remoteRepositories,
List path,
Throwable t )
{
super( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, t );
}
public ArtifactResolutionException( String message,
String groupId,
String artifactId,
String version,
String type,
String classifier,
Throwable t )
{
super( message, groupId, artifactId, version, type, classifier, null, null, t );
}
public ArtifactResolutionException( String message,
Artifact artifact )
{
super( message, artifact );
}
public ArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories )
{
super( message, artifact, remoteRepositories );
}
public ArtifactResolutionException( String message,
Artifact artifact,
ArtifactMetadataRetrievalException cause )
{
super( message, artifact, null, cause );
}
@Deprecated
public ArtifactResolutionException( String message, Artifact artifact, Throwable cause )
{
super( message, artifact, null, cause );
}
protected ArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataRetrievalException cause )
{
super( message, artifact, remoteRepositories, cause );
}
@Deprecated
protected ArtifactResolutionException( String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories, Throwable cause )
{
super( message, artifact, remoteRepositories, cause );
}
protected ArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
TransferFailedException cause )
{
super( message, artifact, remoteRepositories, cause );
}
protected ArtifactResolutionException( String message,
Artifact artifact,
List<ArtifactRepository> remoteRepositories,
IOException cause )
{
super( message, artifact, remoteRepositories, cause );
}
public ArtifactResolutionException( String message,
Artifact artifact,
RepositoryMetadataResolutionException cause )
{
super( message, artifact, null, cause );
}
}

View File

@ -0,0 +1,226 @@
package org.apache.maven.artifact.resolver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A resolution request allows you to either use an existing MavenProject, or a coordinate (gid:aid:version)
* to process a POMs dependencies.
*
* @author Jason van Zyl
*/
public class ArtifactResolutionRequest
{
private Artifact artifact;
private Set<Artifact> artifactDependencies;
private String groupId;
private String artifactId;
private String version;
private ArtifactRepository localRepository;
private List<ArtifactRepository> remoteRepostories;
private ArtifactFilter filter;
private List<ResolutionListener> listeners = new ArrayList<ResolutionListener>();
// This should really be a component. Different impls can can be composed to account for different forms of metadata.
private ArtifactMetadataSource metadataSource;
private Map managedVersionMap;
private List<ConflictResolver> conflictResolvers;
public Artifact getArtifact()
{
return artifact;
}
public ArtifactResolutionRequest setArtifact( Artifact artifact )
{
this.artifact = artifact;
return this;
}
public boolean hasArtifact()
{
return artifact != null;
}
public ArtifactResolutionRequest setArtifactDependencies( Set<Artifact> artifactDependencies )
{
this.artifactDependencies = artifactDependencies;
return this;
}
public Set<Artifact> getArtifactDependencies()
{
return artifactDependencies;
}
public String getGroupId()
{
if ( artifact != null )
{
return artifact.getGroupId();
}
return groupId;
}
public ArtifactResolutionRequest setGroupId( String groupId )
{
this.groupId = groupId;
return this;
}
public String getArtifactId()
{
if ( artifact != null )
{
return artifact.getArtifactId();
}
return artifactId;
}
public ArtifactResolutionRequest setArtifactId( String artifactId )
{
this.artifactId = artifactId;
return this;
}
public String getVersion()
{
if ( artifact != null )
{
return artifact.getVersion();
}
return version;
}
public ArtifactResolutionRequest setVersion( String version )
{
this.version = version;
return this;
}
public ArtifactRepository getLocalRepository()
{
return localRepository;
}
public ArtifactResolutionRequest setLocalRepository( ArtifactRepository localRepository )
{
this.localRepository = localRepository;
return this;
}
public List<ArtifactRepository> getRemoteRepostories()
{
return remoteRepostories;
}
public ArtifactResolutionRequest setRemoteRepostories( List<ArtifactRepository> remoteRepostories )
{
this.remoteRepostories = remoteRepostories;
return this;
}
public ArtifactFilter getFilter()
{
return filter;
}
public ArtifactResolutionRequest setFilter( ArtifactFilter filter )
{
this.filter = filter;
return this;
}
public List<ResolutionListener> getListeners()
{
return listeners;
}
public ArtifactResolutionRequest addListener( ResolutionListener listener )
{
listeners.add( listener );
return this;
}
// ------------------------------------------------------------------------
//
// ------------------------------------------------------------------------
public ArtifactMetadataSource getMetadataSource()
{
return metadataSource;
}
public ArtifactResolutionRequest setMetadataSource( ArtifactMetadataSource metadataSource )
{
this.metadataSource = metadataSource;
return this;
}
public Map getManagedVersionMap()
{
return managedVersionMap;
}
public ArtifactResolutionRequest setManagedVersionMap( Map managedVersionMap )
{
this.managedVersionMap = managedVersionMap;
return this;
}
public List<ConflictResolver> getConflictResolvers()
{
return conflictResolvers;
}
public ArtifactResolutionRequest setConflictResolvers( List<ConflictResolver> conflictResolvers )
{
this.conflictResolvers = conflictResolvers;
return this;
}
public String toString()
{
StringBuffer sb = new StringBuffer()
.append(getGroupId())
.append(":")
.append(getArtifactId())
.append(":")
.append(getVersion());
return sb.toString();
}
}

View File

@ -0,0 +1,286 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* Specific problems during resolution that we want to account for:
* <p/>
* - missing metadata
* - version range violations
* - version circular dependencies
* - missing artifacts
* - network/transfer errors
* - file system errors: permissions
*
* @author Jason van Zyl
* @version $Id$
* @TODO carlos: all these possible has*Exceptions and get*Exceptions methods make the clients too
* complex requiring a long list of checks, need to create a parent/interfact/encapsulation
* for the types of exceptions
*/
public class ArtifactResolutionResult
{
private Artifact originatingArtifact;
private List<Exception> versionRangeViolations;
private List<ArtifactResolutionException> metadataResolutionExceptions;
private List<Artifact> missingArtifacts;
private List<CyclicDependencyException> circularDependencyExceptions;
private List<ArtifactResolutionException> errorArtifactExceptions;
// file system errors
private List<ArtifactRepository> repositories;
private Set<ResolutionNode> resolutionNodes;
private Set<Artifact> artifacts;
public Artifact getOriginatingArtifact()
{
return originatingArtifact;
}
public ArtifactResolutionResult ListOriginatingArtifact( final Artifact originatingArtifact )
{
this.originatingArtifact = originatingArtifact;
return this;
}
public Set<Artifact> getArtifacts()
{
if ( artifacts == null )
{
artifacts = new LinkedHashSet<Artifact>();
for (ResolutionNode node : resolutionNodes) {
artifacts.add(node.getArtifact());
}
}
return artifacts;
}
public Set<ResolutionNode> getArtifactResolutionNodes()
{
if (resolutionNodes == null) {
return Collections.emptySet();
}
return resolutionNodes;
}
public void setArtifactResolutionNodes( final Set<ResolutionNode> resolutionNodes )
{
this.resolutionNodes = resolutionNodes;
// clear the cache
this.artifacts = null;
}
public List getMissingArtifacts()
{
return missingArtifacts == null ? Collections.EMPTY_LIST : missingArtifacts;
}
public ArtifactResolutionResult addMissingArtifact( Artifact artifact )
{
missingArtifacts = initList( missingArtifacts );
missingArtifacts.add( artifact );
return this;
}
public ArtifactResolutionResult setUnresolvedArtifacts( final List<Artifact> unresolvedArtifacts )
{
this.missingArtifacts = unresolvedArtifacts;
return this;
}
// ------------------------------------------------------------------------
// Version Range Violations
// ------------------------------------------------------------------------
public boolean hasVersionRangeViolations()
{
return versionRangeViolations != null;
}
/**
* @TODO this needs to accept a {@link OverConstrainedVersionException} as returned by
* {@link #getVersionRangeViolation(int)} but it's not used like that in
* {@link DefaultArtifactCollector}
*/
public ArtifactResolutionResult addVersionRangeViolation( Exception e )
{
versionRangeViolations = initList( versionRangeViolations );
versionRangeViolations.add( e );
return this;
}
public OverConstrainedVersionException getVersionRangeViolation( int i )
{
return (OverConstrainedVersionException) versionRangeViolations.get( i );
}
public List getVersionRangeViolations()
{
return versionRangeViolations == null ? Collections.EMPTY_LIST : versionRangeViolations;
}
// ------------------------------------------------------------------------
// Metadata Resolution Exceptions: ArtifactResolutionExceptions
// ------------------------------------------------------------------------
public boolean hasMetadataResolutionExceptions()
{
return metadataResolutionExceptions != null;
}
public ArtifactResolutionResult addMetadataResolutionException( ArtifactResolutionException e )
{
metadataResolutionExceptions = initList( metadataResolutionExceptions );
metadataResolutionExceptions.add( e );
return this;
}
public ArtifactResolutionException getMetadataResolutionException( int i )
{
return metadataResolutionExceptions.get( i );
}
public List getMetadataResolutionExceptions()
{
return metadataResolutionExceptions == null ? Collections.EMPTY_LIST : metadataResolutionExceptions;
}
// ------------------------------------------------------------------------
// ErrorArtifactExceptions: ArtifactResolutionExceptions
// ------------------------------------------------------------------------
public boolean hasErrorArtifactExceptions()
{
return errorArtifactExceptions != null;
}
public ArtifactResolutionResult addErrorArtifactException( ArtifactResolutionException e )
{
errorArtifactExceptions = initList( errorArtifactExceptions );
errorArtifactExceptions.add( e );
return this;
}
public List<ArtifactResolutionException> getErrorArtifactExceptions()
{
if (errorArtifactExceptions == null) {
return Collections.emptyList();
}
return errorArtifactExceptions;
}
// ------------------------------------------------------------------------
// Circular Dependency Exceptions
// ------------------------------------------------------------------------
public boolean hasCircularDependencyExceptions()
{
return circularDependencyExceptions != null;
}
public ArtifactResolutionResult addCircularDependencyException( CyclicDependencyException e )
{
circularDependencyExceptions = initList( circularDependencyExceptions );
circularDependencyExceptions.add( e );
return this;
}
public CyclicDependencyException getCircularDependencyException( int i )
{
return circularDependencyExceptions.get( i );
}
public List<CyclicDependencyException> getCircularDependencyExceptions()
{
if (circularDependencyExceptions == null) {
return Collections.emptyList();
}
return circularDependencyExceptions;
}
// ------------------------------------------------------------------------
// Repositories
// ------------------------------------------------------------------------
public List<ArtifactRepository> getRepositories()
{
if (repositories == null) {
return Collections.emptyList();
}
return repositories;
}
public ArtifactResolutionResult setRepositories( final List<ArtifactRepository> repositories )
{
this.repositories = repositories;
return this;
}
//
// Internal
//
private <T> List<T> initList( final List<T> l )
{
if ( l == null )
{
return new ArrayList<T>();
}
return l;
}
}

View File

@ -0,0 +1,141 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* I want to use it for hidding the fact that sometime artifact must be
* downloaded. I am just asking LocalRepository for given artifact and I don't
* care if it is alredy there or how it will get there.
*
* @author Michal Maczka
* @author Jason van Zyl
* @version $Id$
*/
public interface ArtifactResolver
{
String ROLE = ArtifactResolver.class.getName();
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
void resolve( Artifact artifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository,
ArtifactMetadataSource source )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository,
ArtifactMetadataSource source,
List<ResolutionListener> listeners )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter,
List<ResolutionListener> listeners )
throws ArtifactResolutionException, ArtifactNotFoundException;
/**
* @since 3.0
* @deprecated use {@link #resolve(ArtifactResolutionRequest)}
*/
@Deprecated
ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts,
Artifact originatingArtifact,
Map managedVersions,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source,
ArtifactFilter filter,
List<ResolutionListener> listeners,
List<ConflictResolver> conflictResolvers )
throws ArtifactResolutionException, ArtifactNotFoundException;
/** @deprecated use {@link #resolve(ArtifactResolutionRequest)} */
@Deprecated
void resolveAlways( Artifact artifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, ArtifactNotFoundException;
// New API
/** @since 3.0 */
ArtifactResolutionResult resolve( ArtifactResolutionRequest request );
}

View File

@ -0,0 +1,46 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
/**
* Indiciates a cycle in the dependency graph.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class CyclicDependencyException
extends ArtifactResolutionException
{
private Artifact artifact;
public CyclicDependencyException( String message,
Artifact artifact )
{
super( message, artifact );
this.artifact = artifact;
}
public Artifact getArtifact()
{
return artifact;
}
}

View File

@ -0,0 +1,178 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.VersionRange;
import org.codehaus.plexus.logging.Logger;
import java.util.Set;
import java.util.HashSet;
/**
* Send resolution events to the debug log.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class DebugResolutionListener
implements ResolutionListener, ResolutionListenerForDepMgmt
{
private Logger logger;
private String indent = "";
private static Set<Artifact> ignoredArtifacts = new HashSet<Artifact>();
public DebugResolutionListener( Logger logger )
{
this.logger = logger;
}
public void testArtifact( Artifact node )
{
}
public void startProcessChildren( Artifact artifact )
{
indent += " ";
}
public void endProcessChildren( Artifact artifact )
{
indent = indent.substring( 2 );
}
public void includeArtifact( Artifact artifact )
{
logger.debug( indent + artifact + " (selected for " + artifact.getScope() + ")" );
}
public void omitForNearer( Artifact omitted,
Artifact kept )
{
String omittedVersion = omitted.getVersion();
String keptVersion = kept.getVersion();
if ( omittedVersion != null ? !omittedVersion.equals( keptVersion ) : keptVersion != null )
{
logger.debug( indent + omitted + " (removed - nearer found: " + kept.getVersion() + ")" );
}
}
public void omitForCycle( Artifact omitted )
{
logger.debug( indent + omitted + " (removed - causes a cycle in the graph)" );
}
public void updateScopeCurrentPom( Artifact artifact,
String ignoredScope )
{
logger.debug(
indent + artifact + " (not setting artifactScope to: " + ignoredScope + "; local artifactScope " + artifact.getScope() +
" wins)" );
// TODO: better way than static? this might hide messages in a reactor
if ( !ignoredArtifacts.contains( artifact ) )
{
logger.warn( "\n\tArtifact " + artifact + " retains local artifactScope '" + artifact.getScope() +
"' overriding broader artifactScope '" + ignoredScope + "'\n" +
"\tgiven by a dependency. If this is not intended, modify or remove the local artifactScope.\n" );
ignoredArtifacts.add( artifact );
}
}
public void updateScope( Artifact artifact,
String scope )
{
logger.debug( indent + artifact + " (setting artifactScope to: " + scope + ")" );
}
public void selectVersionFromRange( Artifact artifact )
{
logger.debug( indent + artifact + " (setting version to: " + artifact.getVersion() + " from range: " +
artifact.getVersionRange() + ")" );
}
public void restrictRange( Artifact artifact,
Artifact replacement,
VersionRange newRange )
{
logger.debug( indent + artifact + " (range restricted from: " + artifact.getVersionRange() + " and: " +
replacement.getVersionRange() + " to: " + newRange + " )" );
}
/**
* The logic used here used to be a copy of the logic used in the DefaultArtifactCollector, and this method was
* called right before the actual version/artifactScope changes were done. However, a different set of conditionals (and
* more information) is needed to be able to determine when and if the version and/or artifactScope changes. See the two
* added methods, manageArtifactVersion and manageArtifactScope.
*/
public void manageArtifact( Artifact artifact,
Artifact replacement )
{
String msg = indent + artifact;
msg += " (";
if ( replacement.getVersion() != null )
{
msg += "applying version: " + replacement.getVersion() + ";";
}
if ( replacement.getScope() != null )
{
msg += "applying artifactScope: " + replacement.getScope();
}
msg += ")";
logger.debug( msg );
}
public void manageArtifactVersion( Artifact artifact,
Artifact replacement )
{
// only show msg if a change is actually taking place
if ( !replacement.getVersion().equals( artifact.getVersion() ) )
{
String msg = indent + artifact + " (applying version: " + replacement.getVersion() + ")";
logger.debug( msg );
}
}
public void manageArtifactScope( Artifact artifact,
Artifact replacement )
{
// only show msg if a change is actually taking place
if ( !replacement.getScope().equals( artifact.getScope() ) )
{
String msg = indent + artifact + " (applying artifactScope: " + replacement.getScope() + ")";
logger.debug( msg );
}
}
public void manageArtifactSystemPath( Artifact artifact,
Artifact replacement )
{
// only show msg if a change is actually taking place
if ( !replacement.getScope().equals( artifact.getScope() ) )
{
String msg = indent + artifact + " (applying system path: " + replacement.getFile() + ")";
logger.debug( msg );
}
}
}

View File

@ -0,0 +1,749 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.ManagedVersionMap;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Default implementation of the artifact collector.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @author Jason van Zyl
* @version $Id$
* @todo This needs to collect all errors and not die on the first error. If there are problems retrieving the metadata
* then we need all the information so that we can tell users about what we attempted to do.
* @todo there 8 places where we can can range exceptions which is bad, again the result of not using a graph.
* @plexus.component
*/
public class DefaultArtifactCollector
implements ArtifactCollector, LogEnabled
{
/**
* The conflict resolver to use when none is specified.
*
* @plexus.requirement role-hint="nearest"
*/
private ConflictResolver defaultConflictResolver;
private Logger logger;
public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
List<ResolutionListener> listeners )
{
return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories,
source, filter, listeners );
}
public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
List<ResolutionListener> listeners )
{
return collect( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source,
filter, listeners, null );
}
public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
List<ResolutionListener> listeners,
List<ConflictResolver> conflictResolvers )
{
ArtifactResolutionResult result = new ArtifactResolutionResult();
result.ListOriginatingArtifact( originatingArtifact );
if ( conflictResolvers == null )
{
// TODO: warn that we're using the default conflict resolver
conflictResolvers = Collections.singletonList( defaultConflictResolver );
}
Map<Object, List<ResolutionNode>> resolvedArtifacts = new LinkedHashMap<Object, List<ResolutionNode>>();
ResolutionNode root = new ResolutionNode( originatingArtifact, remoteRepositories );
try
{
root.addDependencies( artifacts, remoteRepositories, filter );
}
catch ( CyclicDependencyException e )
{
result.addCircularDependencyException( e );
return result;
}
catch ( OverConstrainedVersionException e )
{
result.addVersionRangeViolation( e );
return result;
}
ManagedVersionMap versionMap = getManagedVersionsMap( originatingArtifact, managedVersions );
try
{
recurse( result, root, resolvedArtifacts, versionMap, localRepository, remoteRepositories, source, filter,
listeners, conflictResolvers );
}
catch ( CyclicDependencyException e )
{
logger.debug( "While recursing: " + e.getMessage(), e );
result.addCircularDependencyException( e );
}
catch ( OverConstrainedVersionException e )
{
logger.debug( "While recursing: " + e.getMessage(), e );
result.addVersionRangeViolation( e );
}
catch ( ArtifactResolutionException e )
{
logger.debug( "While recursing: " + e.getMessage(), e );
result.addErrorArtifactException( e );
}
Set<ResolutionNode> set = new LinkedHashSet<ResolutionNode>();
for ( List<ResolutionNode> nodes : resolvedArtifacts.values() )
{
for ( ResolutionNode node : nodes )
{
if ( !node.equals( root ) && node.isActive() )
{
Artifact artifact = node.getArtifact();
try
{
if ( node.filterTrail( filter ) )
{
// If it was optional and not a direct dependency,
// we don't add it or its children, just allow the update of the version and artifactScope
if ( node.isChildOfRootNode() || !artifact.isOptional() )
{
artifact.setDependencyTrail( node.getDependencyTrail() );
set.add( node );
}
}
}
catch ( OverConstrainedVersionException e )
{
result.addVersionRangeViolation( e );
}
}
}
}
result.setArtifactResolutionNodes( set );
return result;
}
/**
* Get the map of managed versions, removing the originating artifact if it is also in managed versions
*
* @param originatingArtifact artifact we are processing
* @param managedVersions original managed versions
*/
private ManagedVersionMap getManagedVersionsMap( Artifact originatingArtifact, Map managedVersions )
{
ManagedVersionMap versionMap;
if ( ( managedVersions != null ) && ( managedVersions instanceof ManagedVersionMap ) )
{
versionMap = (ManagedVersionMap) managedVersions;
}
else
{
versionMap = new ManagedVersionMap( managedVersions );
}
/* remove the originating artifact if it is also in managed versions to avoid being modified during resolution */
Artifact managedOriginatingArtifact = (Artifact) versionMap.get( originatingArtifact.getDependencyConflictId() );
if ( managedOriginatingArtifact != null )
{
// TODO we probably want to warn the user that he is building an artifact with
// different values than in dependencyManagement
if ( managedVersions instanceof ManagedVersionMap )
{
/* avoid modifying the managedVersions parameter creating a new map */
versionMap = new ManagedVersionMap( managedVersions );
}
versionMap.remove( originatingArtifact.getDependencyConflictId() );
}
return versionMap;
}
private void recurse( ArtifactResolutionResult result, ResolutionNode node,
Map<Object, List<ResolutionNode>> resolvedArtifacts, ManagedVersionMap managedVersions,
ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter, List<ResolutionListener> listeners,
List<ConflictResolver> conflictResolvers )
throws ArtifactResolutionException
{
fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node );
Object key = node.getKey();
// TODO: Does this check need to happen here? Had to add the same call
// below when we iterate on child nodes -- will that suffice?
if ( managedVersions.containsKey( key ) )
{
manageArtifact( node, managedVersions, listeners );
}
List<ResolutionNode> previousNodes = resolvedArtifacts.get( key );
if ( previousNodes != null )
{
for ( ResolutionNode previous : previousNodes )
{
try
{
if ( previous.isActive() )
{
// Version mediation
VersionRange previousRange = previous.getArtifact().getVersionRange();
VersionRange currentRange = node.getArtifact().getVersionRange();
if ( ( previousRange != null ) && ( currentRange != null ) )
{
// TODO: shouldn't need to double up on this work, only done for simplicity of handling
// recommended
// version but the restriction is identical
VersionRange newRange = previousRange.restrict( currentRange );
// TODO: ick. this forces the OCE that should have come from the previous call. It is still
// correct
if ( newRange.isSelectedVersionKnown( previous.getArtifact() ) )
{
fireEvent( ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(),
newRange );
}
previous.getArtifact().setVersionRange( newRange );
node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) );
// Select an appropriate available version from the (now restricted) range
// Note this version was selected before to get the appropriate POM
// But it was reset by the call to setVersionRange on restricting the version
ResolutionNode[] resetNodes = { previous, node };
for ( int j = 0; j < 2; j++ )
{
Artifact resetArtifact = resetNodes[j].getArtifact();
// MNG-2123: if the previous node was not a range, then it wouldn't have any available
// versions. We just clobbered the selected version above. (why? i have no idea.)
// So since we are here and this is ranges we must go figure out the version (for a
// third time...)
if ( resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null )
{
// go find the version. This is a total hack. See previous comment.
List<ArtifactVersion> versions = resetArtifact.getAvailableVersions();
if ( versions == null )
{
try
{
versions =
source.retrieveAvailableVersions( resetArtifact, localRepository,
remoteRepositories );
resetArtifact.setAvailableVersions( versions );
}
catch ( ArtifactMetadataRetrievalException e )
{
resetArtifact.setDependencyTrail( node.getDependencyTrail() );
throw new ArtifactResolutionException(
"Unable to get dependency information: "
+ e.getMessage(), resetArtifact,
remoteRepositories, e );
}
}
// end hack
// MNG-2861: match version can return null
ArtifactVersion selectedVersion =
resetArtifact.getVersionRange().matchVersion(
resetArtifact.getAvailableVersions() );
if ( selectedVersion != null )
{
resetArtifact.selectVersion( selectedVersion.toString() );
}
else
{
throw new OverConstrainedVersionException( " Unable to find a version in "
+ resetArtifact.getAvailableVersions() + " to match the range "
+ resetArtifact.getVersionRange(), resetArtifact );
}
fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j] );
}
}
}
// Conflict Resolution
ResolutionNode resolved = null;
for ( Iterator j = conflictResolvers.iterator(); ( resolved == null ) && j.hasNext(); )
{
ConflictResolver conflictResolver = (ConflictResolver) j.next();
resolved = conflictResolver.resolveConflict( previous, node );
}
if ( resolved == null )
{
// TODO: add better exception that can detail the two conflicting artifacts
result.addVersionRangeViolation( new ArtifactResolutionException(
"Cannot resolve artifact version conflict between "
+ previous.getArtifact().getVersion()
+ " and "
+ node.getArtifact().getVersion(),
previous.getArtifact() ) );
}
if ( ( resolved != previous ) && ( resolved != node ) )
{
// TODO: add better exception
result.addVersionRangeViolation( new ArtifactResolutionException(
"Conflict resolver returned unknown resolution node: ",
resolved.getArtifact() ) );
}
// TODO: should this be part of mediation?
// previous one is more dominant
ResolutionNode nearest;
ResolutionNode farthest;
if ( resolved == previous )
{
nearest = previous;
farthest = node;
}
else
{
nearest = node;
farthest = previous;
}
if ( checkScopeUpdate( farthest, nearest, listeners ) )
{
// if we need to update artifactScope of nearest to use farthest artifactScope, use the
// nearest version, but farthest artifactScope
nearest.disable();
farthest.getArtifact().setVersion( nearest.getArtifact().getVersion() );
fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, nearest, farthest.getArtifact() );
}
else
{
farthest.disable();
fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, farthest, nearest.getArtifact() );
}
}
}
catch ( OverConstrainedVersionException e )
{
result.addVersionRangeViolation( e );
}
}
}
else
{
previousNodes = new ArrayList<ResolutionNode>();
resolvedArtifacts.put( key, previousNodes );
}
previousNodes.add( node );
if ( node.isActive() )
{
fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node );
}
// don't pull in the transitive deps of a system-scoped dependency.
if ( node.isActive() && !Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) )
{
fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node );
for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
{
ResolutionNode child = (ResolutionNode) i.next();
try
{
// We leave in optional ones, but don't pick up its dependencies
if ( !child.isResolved() && ( !child.getArtifact().isOptional() || child.isChildOfRootNode() ) )
{
Artifact artifact = child.getArtifact();
List<ArtifactRepository> childRemoteRepositories = child.getRemoteRepositories();
try
{
Object childKey;
do
{
childKey = child.getKey();
if ( managedVersions.containsKey( childKey ) )
{
// If this child node is a managed dependency, ensure
// we are using the dependency management version
// of this child if applicable b/c we want to use the
// managed version's POM, *not* any other version's POM.
// We retrieve the POM below in the retrieval step.
manageArtifact( child, managedVersions, listeners );
// Also, we need to ensure that any exclusions it presents are
// added to the artifact before we retrive the metadata
// for the artifact; otherwise we may end up with unwanted
// dependencies.
Artifact ma = (Artifact) managedVersions.get( childKey );
ArtifactFilter managedExclusionFilter = ma.getDependencyFilter();
if ( null != managedExclusionFilter )
{
if ( null != artifact.getDependencyFilter() )
{
AndArtifactFilter aaf = new AndArtifactFilter();
aaf.add( artifact.getDependencyFilter() );
aaf.add( managedExclusionFilter );
artifact.setDependencyFilter( aaf );
}
else
{
artifact.setDependencyFilter( managedExclusionFilter );
}
}
}
if ( artifact.getVersion() == null )
{
// set the recommended version
// TODO: maybe its better to just pass the range through to retrieval and use a
// transformation?
ArtifactVersion version;
if ( !artifact.isSelectedVersionKnown() )
{
List<ArtifactVersion> versions = artifact.getAvailableVersions();
if ( versions == null )
{
versions =
source.retrieveAvailableVersions( artifact, localRepository,
childRemoteRepositories );
artifact.setAvailableVersions( versions );
}
Collections.sort( versions );
VersionRange versionRange = artifact.getVersionRange();
version = versionRange.matchVersion( versions );
if ( version == null )
{
// Getting the dependency trail so it can be logged in the exception
artifact.setDependencyTrail( node.getDependencyTrail() );
if ( versions.isEmpty() )
{
throw new OverConstrainedVersionException(
"No versions are present in the repository for the artifact with a range "
+ versionRange, artifact,
childRemoteRepositories );
}
throw new OverConstrainedVersionException( "Couldn't find a version in "
+ versions + " to match range " + versionRange, artifact,
childRemoteRepositories );
}
}
else
{
version = artifact.getSelectedVersion();
}
artifact.selectVersion( version.toString() );
fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child );
}
Artifact relocated = source.retrieveRelocatedArtifact( artifact, localRepository, childRemoteRepositories );
if ( !artifact.equals( relocated ) )
{
artifact = relocated;
child.setArtifact( artifact );
}
}
while( !childKey.equals( child.getKey() ) );
artifact.setDependencyTrail( node.getDependencyTrail() );
ResolutionGroup rGroup = source.retrieve( artifact, localRepository, childRemoteRepositories );
// TODO might be better to have source.retrieve() throw a specific exception for this
// situation
// and catch here rather than have it return null
if ( rGroup == null )
{
// relocated dependency artifact is declared excluded, no need to add and recurse
// further
continue;
}
child.addDependencies( rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter );
}
catch ( CyclicDependencyException e )
{
// would like to throw this, but we have crappy stuff in the repo
fireEvent( ResolutionListener.OMIT_FOR_CYCLE, listeners,
new ResolutionNode( e.getArtifact(), childRemoteRepositories, child ) );
}
catch ( ArtifactMetadataRetrievalException e )
{
artifact.setDependencyTrail( node.getDependencyTrail() );
throw new ArtifactResolutionException( "Unable to get dependency information: "
+ e.getMessage(), artifact, childRemoteRepositories, e );
}
recurse( result, child, resolvedArtifacts, managedVersions, localRepository,
childRemoteRepositories, source, filter, listeners, conflictResolvers );
}
}
catch ( OverConstrainedVersionException e )
{
result.addVersionRangeViolation( e );
}
catch ( ArtifactResolutionException e )
{
result.addMetadataResolutionException( e );
}
}
fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node );
}
}
private void manageArtifact( ResolutionNode node, ManagedVersionMap managedVersions,
List<ResolutionListener> listeners )
{
Artifact artifact = (Artifact) managedVersions.get( node.getKey() );
// Before we update the version of the artifact, we need to know
// whether we are working on a transitive dependency or not. This
// allows depMgmt to always override transitive dependencies, while
// explicit child override depMgmt (viz. depMgmt should only
// provide defaults to children, but should override transitives).
// We can do this by calling isChildOfRootNode on the current node.
if ( ( artifact.getVersion() != null )
&& ( !node.isChildOfRootNode() || node.getArtifact().getVersion() == null ) )
{
fireEvent( ResolutionListener.MANAGE_ARTIFACT_VERSION, listeners, node, artifact );
node.getArtifact().setVersion( artifact.getVersion() );
}
if ( ( artifact.getScope() != null ) && ( !node.isChildOfRootNode() || node.getArtifact().getScope() == null ) )
{
fireEvent( ResolutionListener.MANAGE_ARTIFACT_SCOPE, listeners, node, artifact );
node.getArtifact().setScope( artifact.getScope() );
}
if ( Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) && ( node.getArtifact().getFile() == null )
&& ( artifact.getFile() != null ) )
{
fireEvent( ResolutionListener.MANAGE_ARTIFACT_SYSTEM_PATH, listeners, node, artifact );
node.getArtifact().setFile( artifact.getFile() );
}
}
/**
* Check if the artifactScope needs to be updated. <a
* href="http://docs.codehaus.org/x/IGU#DependencyMediationandConflictResolution-Scoperesolution">More info</a>.
*
* @param farthest farthest resolution node
* @param nearest nearest resolution node
* @param listeners
*/
boolean checkScopeUpdate( ResolutionNode farthest, ResolutionNode nearest, List<ResolutionListener> listeners )
{
boolean updateScope = false;
Artifact farthestArtifact = farthest.getArtifact();
Artifact nearestArtifact = nearest.getArtifact();
/* farthest is runtime and nearest has lower priority, change to runtime */
if ( Artifact.SCOPE_RUNTIME.equals( farthestArtifact.getScope() )
&& ( Artifact.SCOPE_TEST.equals( nearestArtifact.getScope() ) || Artifact.SCOPE_PROVIDED.equals( nearestArtifact.getScope() ) ) )
{
updateScope = true;
}
/* farthest is compile and nearest is not (has lower priority), change to compile */
if ( Artifact.SCOPE_COMPILE.equals( farthestArtifact.getScope() )
&& !Artifact.SCOPE_COMPILE.equals( nearestArtifact.getScope() ) )
{
updateScope = true;
}
/* current POM rules all, if nearest is in current pom, do not update its artifactScope */
if ( ( nearest.getDepth() < 2 ) && updateScope )
{
updateScope = false;
fireEvent( ResolutionListener.UPDATE_SCOPE_CURRENT_POM, listeners, nearest, farthestArtifact );
}
if ( updateScope )
{
fireEvent( ResolutionListener.UPDATE_SCOPE, listeners, nearest, farthestArtifact );
// previously we cloned the artifact, but it is more effecient to just update the artifactScope
// if problems are later discovered that the original object needs its original artifactScope value, cloning
// may
// again be appropriate
nearestArtifact.setScope( farthestArtifact.getScope() );
}
return updateScope;
}
private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node )
{
fireEvent( event, listeners, node, null );
}
private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node, Artifact replacement )
{
fireEvent( event, listeners, node, replacement, null );
}
private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node, Artifact replacement,
VersionRange newRange )
{
for ( ResolutionListener listener : listeners )
{
switch ( event )
{
case ResolutionListener.TEST_ARTIFACT:
listener.testArtifact( node.getArtifact() );
break;
case ResolutionListener.PROCESS_CHILDREN:
listener.startProcessChildren( node.getArtifact() );
break;
case ResolutionListener.FINISH_PROCESSING_CHILDREN:
listener.endProcessChildren( node.getArtifact() );
break;
case ResolutionListener.INCLUDE_ARTIFACT:
listener.includeArtifact( node.getArtifact() );
break;
case ResolutionListener.OMIT_FOR_NEARER:
listener.omitForNearer( node.getArtifact(), replacement );
break;
case ResolutionListener.OMIT_FOR_CYCLE:
listener.omitForCycle( node.getArtifact() );
break;
case ResolutionListener.UPDATE_SCOPE:
listener.updateScope( node.getArtifact(), replacement.getScope() );
break;
case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
listener.updateScopeCurrentPom( node.getArtifact(), replacement.getScope() );
break;
case ResolutionListener.MANAGE_ARTIFACT_VERSION:
if ( listener instanceof ResolutionListenerForDepMgmt )
{
ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
asImpl.manageArtifactVersion( node.getArtifact(), replacement );
}
else
{
listener.manageArtifact( node.getArtifact(), replacement );
}
break;
case ResolutionListener.MANAGE_ARTIFACT_SCOPE:
if ( listener instanceof ResolutionListenerForDepMgmt )
{
ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
asImpl.manageArtifactScope( node.getArtifact(), replacement );
}
else
{
listener.manageArtifact( node.getArtifact(), replacement );
}
break;
case ResolutionListener.MANAGE_ARTIFACT_SYSTEM_PATH:
if ( listener instanceof ResolutionListenerForDepMgmt )
{
ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
asImpl.manageArtifactSystemPath( node.getArtifact(), replacement );
}
else
{
listener.manageArtifact( node.getArtifact(), replacement );
}
break;
case ResolutionListener.SELECT_VERSION_FROM_RANGE:
listener.selectVersionFromRange( node.getArtifact() );
break;
case ResolutionListener.RESTRICT_RANGE:
if ( node.getArtifact().getVersionRange().hasRestrictions()
|| replacement.getVersionRange().hasRestrictions() )
{
listener.restrictRange( node.getArtifact(), replacement, newRange );
}
break;
default:
throw new IllegalStateException( "Unknown event: " + event );
}
}
}
public void enableLogging( Logger logger )
{
this.logger = logger;
}
}

View File

@ -0,0 +1,486 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
import org.apache.maven.artifact.repository.metadata.Versioning;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
import org.apache.maven.artifact.transform.ArtifactTransformationManager;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Jason van Zyl
* @plexus.component
*/
public class DefaultArtifactResolver
extends AbstractLogEnabled
implements ArtifactResolver
{
// ----------------------------------------------------------------------
// Components
// ----------------------------------------------------------------------
/** @plexus.requirement */
private WagonManager wagonManager;
/** @plexus.requirement */
private ArtifactTransformationManager transformationManager;
/** @plexus.requirement */
protected ArtifactFactory artifactFactory;
/** @plexus.requirement */
private ArtifactCollector artifactCollector;
// ----------------------------------------------------------------------
// Implementation
// ----------------------------------------------------------------------
public void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, ArtifactNotFoundException
{
resolve( artifact, remoteRepositories, localRepository, false );
}
public void resolveAlways( Artifact artifact, List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, ArtifactNotFoundException
{
resolve( artifact, remoteRepositories, localRepository, true );
}
private void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository, boolean force )
throws ArtifactResolutionException, ArtifactNotFoundException
{
if ( artifact == null )
{
return;
}
if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
{
File systemFile = artifact.getFile();
if ( systemFile == null )
{
throw new ArtifactNotFoundException( "System artifact: " + artifact + " has no file attached", artifact );
}
if ( !systemFile.exists() )
{
throw new ArtifactNotFoundException( "System artifact: " + artifact + " not found in path: "
+ systemFile, artifact );
}
if ( !systemFile.isFile() )
{
throw new ArtifactNotFoundException( "System artifact: " + artifact + " is not a file: " + systemFile,
artifact );
}
artifact.setResolved( true );
}
else if ( !artifact.isResolved() )
{
// ----------------------------------------------------------------------
// Check for the existence of the artifact in the specified local
// ArtifactRepository. If it is present then simply return as the
// request for resolution has been satisfied.
// ----------------------------------------------------------------------
String localPath = localRepository.pathOf( artifact );
artifact.setFile( new File( localRepository.getBasedir(), localPath ) );
transformationManager.transformForResolve( artifact, remoteRepositories, localRepository );
boolean localCopy = isLocalCopy( artifact );
File destination = artifact.getFile();
boolean resolved = false;
if ( !wagonManager.isOnline() )
{
if ( !destination.exists() )
{
throw new ArtifactNotFoundException( "System is offline.", artifact );
}
}
// There are three conditions in which we'll go after the artifact here:
// 1. the force flag is set.
// 2. the artifact's file doesn't exist (this would be true for release or snapshot artifacts)
// 3. the artifact is a snapshot and is not a locally installed snapshot
// TODO: Should it matter whether it's a locally installed snapshot??
else if ( force || !destination.exists() || ( artifact.isSnapshot() && !localCopy ) )
{
try
{
if ( artifact.getRepository() != null )
{
// the transformations discovered the artifact - so use it exclusively
wagonManager.getArtifact( artifact, artifact.getRepository(), force );
}
else
{
wagonManager.getArtifact( artifact, remoteRepositories, force );
}
if ( !artifact.isResolved() && !destination.exists() )
{
throw new ArtifactResolutionException(
"Failed to resolve artifact, possibly due to a repository list that is not appropriately equipped for this artifact's metadata.",
artifact, getMirroredRepositories( remoteRepositories ) );
}
}
catch ( ResourceDoesNotExistException e )
{
throw new ArtifactNotFoundException( e.getMessage(), artifact,
getMirroredRepositories( remoteRepositories ), e );
}
catch ( TransferFailedException e )
{
throw new ArtifactResolutionException( e.getMessage(), artifact,
getMirroredRepositories( remoteRepositories ), e );
}
resolved = true;
}
if ( destination.exists() )
{
// locally resolved...no need to hit the remote repo.
artifact.setResolved( true );
}
if ( artifact.isSnapshot() && !artifact.getBaseVersion().equals( artifact.getVersion() ) )
{
String version = artifact.getVersion();
artifact.selectVersion( artifact.getBaseVersion() );
File copy = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
if ( resolved || !copy.exists() )
{
// recopy file if it was reresolved, or doesn't exist.
try
{
FileUtils.copyFile( destination, copy );
copy.setLastModified( destination.lastModified() );
}
catch ( IOException e )
{
throw new ArtifactResolutionException( "Unable to copy resolved artifact for local use: "
+ e.getMessage(), artifact, getMirroredRepositories( remoteRepositories ), e );
}
}
artifact.setFile( copy );
artifact.selectVersion( version );
}
}
}
private boolean isLocalCopy( Artifact artifact )
{
boolean localCopy = false;
for ( ArtifactMetadata m : artifact.getMetadataList() )
{
if ( m instanceof SnapshotArtifactRepositoryMetadata )
{
SnapshotArtifactRepositoryMetadata snapshotMetadata = (SnapshotArtifactRepositoryMetadata) m;
Metadata metadata = snapshotMetadata.getMetadata();
if ( metadata != null )
{
Versioning versioning = metadata.getVersioning();
if ( versioning != null )
{
Snapshot snapshot = versioning.getSnapshot();
if ( snapshot != null )
{
// TODO is it possible to have more than one SnapshotArtifactRepositoryMetadata
localCopy = snapshot.isLocalCopy();
}
}
}
}
}
return localCopy;
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository,
remoteRepositories, source, filter );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
remoteRepositories, source, null );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
remoteRepositories, source, filter, null );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository,
ArtifactMetadataSource source )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact, localRepository, remoteRepositories, source, null );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
List<ArtifactRepository> remoteRepositories,
ArtifactRepository localRepository,
ArtifactMetadataSource source,
List<ResolutionListener> listeners )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact,
Collections.EMPTY_MAP, localRepository, remoteRepositories, source, null, listeners );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
List<ResolutionListener> listeners )
throws ArtifactResolutionException, ArtifactNotFoundException
{
return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
remoteRepositories, source, filter, listeners, null );
}
public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
Map managedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
List<ResolutionListener> listeners,
List<ConflictResolver> conflictResolvers )
throws ArtifactResolutionException, ArtifactNotFoundException
{
if ( listeners == null )
{
// TODO: this is simplistic.
listeners = new ArrayList<ResolutionListener>();
if ( getLogger().isDebugEnabled() )
{
listeners.add( new DebugResolutionListener( getLogger() ) );
}
listeners.add( new WarningResolutionListener( getLogger() ) );
}
ArtifactResolutionResult result;
result =
artifactCollector.collect( artifacts, originatingArtifact, managedVersions, localRepository,
remoteRepositories, source, filter, listeners, conflictResolvers );
// We have collected all the problems so let's mimic the way the old code worked and just blow up right here.
// That's right lets just let it rip right here and send a big incomprehensible blob of text at unsuspecting
// users. Bad dog!
// Metadata cannot be found
if ( result.hasMetadataResolutionExceptions() )
{
throw result.getMetadataResolutionException( 0 );
}
// Metadata cannot be retrieved
// Cyclic Dependency Error
if ( result.hasCircularDependencyExceptions() )
{
throw result.getCircularDependencyException( 0 );
}
// Version Range Violation
if ( result.hasVersionRangeViolations() )
{
throw result.getVersionRangeViolation( 0 );
}
List<Artifact> resolvedArtifacts = new ArrayList<Artifact>();
List<Artifact> missingArtifacts = new ArrayList<Artifact>();
for ( ResolutionNode node : result.getArtifactResolutionNodes() )
{
try
{
resolve( node.getArtifact(), node.getRemoteRepositories(), localRepository );
resolvedArtifacts.add( node.getArtifact() );
}
catch ( ArtifactNotFoundException anfe )
{
getLogger().debug( anfe.getMessage(), anfe );
missingArtifacts.add( node.getArtifact() );
}
}
if ( missingArtifacts.size() > 0 )
{
throw new MultipleArtifactsNotFoundException( originatingArtifact, resolvedArtifacts, missingArtifacts,
getMirroredRepositories( remoteRepositories ) );
}
return result;
}
private List<ArtifactRepository> getMirroredRepositories( List<ArtifactRepository> remoteRepositories )
{
Map<String, ArtifactRepository> repos = new HashMap<String, ArtifactRepository>();
for ( ArtifactRepository repository : remoteRepositories )
{
ArtifactRepository repo = wagonManager.getMirrorRepository( repository );
repos.put( repo.getId(), repo );
}
return new ArrayList<ArtifactRepository>( repos.values() );
}
// ------------------------------------------------------------------------
//
// ------------------------------------------------------------------------
public ArtifactResolutionResult resolve( ArtifactResolutionRequest request )
{
Artifact originatingArtifact = request.getArtifact();
Set<Artifact> artifacts = request.getArtifactDependencies();
Map managedVersions = request.getManagedVersionMap();
ArtifactRepository localRepository = request.getLocalRepository();
List<ArtifactRepository> remoteRepositories = request.getRemoteRepostories();
ArtifactMetadataSource source = request.getMetadataSource();
List<ResolutionListener> listeners = request.getListeners();
ArtifactFilter filter = request.getFilter();
// This is an attempt to get the metadata for the artifacts we are ultimately trying to resolve.
// We still
ArtifactResolutionResult result =
artifactCollector.collect( artifacts, originatingArtifact, managedVersions, localRepository,
remoteRepositories, source, filter, listeners );
// Let's grab all the repositories that were gleaned. This we should know up front. I'm not sure
// what the metadata source is doing. Repositories in POMs are deadly.
result.setRepositories( remoteRepositories );
// We have metadata retrieval problems, or there are cycles that have been detected
// so we give this back to the calling code and let them deal with this information
// appropriately.
if ( result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() )
{
return result;
}
for ( ResolutionNode node : result.getArtifactResolutionNodes() )
{
try
{
resolve( node.getArtifact(), node.getRemoteRepositories(), localRepository );
}
catch ( ArtifactNotFoundException anfe )
{
// These are cases where the artifact just isn't present in any of the remote repositories
// because it wasn't deployed, or it was deployed in the wrong place.
result.addMissingArtifact( node.getArtifact() );
}
catch ( ArtifactResolutionException e )
{
// This is really a wagon TransferFailedException so something went wrong after we successfully
// retrieved the metadata.
result.addErrorArtifactException( e );
}
}
return result;
}
}

View File

@ -0,0 +1,122 @@
package org.apache.maven.artifact.resolver;
/*
* 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.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
/**
* Exception caused when one or more artifacts can not be resolved because they are not found in the
* local or remote repositories.
*/
public class MultipleArtifactsNotFoundException
extends ArtifactResolutionException
{
private final List<Artifact> resolvedArtifacts;
private final List<Artifact> missingArtifacts;
/** @deprecated use {@link #MultipleArtifactsNotFoundException(Artifact, List, List, List)} */
@Deprecated
public MultipleArtifactsNotFoundException( Artifact originatingArtifact,
List<Artifact> missingArtifacts,
List<ArtifactRepository> remoteRepositories )
{
this( originatingArtifact, new ArrayList<Artifact>(), missingArtifacts, remoteRepositories );
}
/**
* Create an instance of the exception with allrequired information.
*
* @param originatingArtifact the artifact that was being resolved
* @param resolvedArtifacts artifacts that could be resolved
* @param missingArtifacts artifacts that could not be resolved
* @param remoteRepositories remote repositories where the missing artifacts were not found
*/
public MultipleArtifactsNotFoundException( Artifact originatingArtifact,
List<Artifact> resolvedArtifacts,
List<Artifact> missingArtifacts,
List<ArtifactRepository> remoteRepositories )
{
super( constructMessage( missingArtifacts ), originatingArtifact, remoteRepositories );
this.resolvedArtifacts = resolvedArtifacts;
this.missingArtifacts = missingArtifacts;
}
/**
* artifacts that could be resolved
*
* @return {@link List} of {@link Artifact}
*/
public List<Artifact> getResolvedArtifacts()
{
return resolvedArtifacts;
}
/**
* artifacts that could NOT be resolved
*
* @return {@link List} of {@link Artifact}
*/
public List<Artifact> getMissingArtifacts()
{
return missingArtifacts;
}
private static String constructMessage( List<Artifact> artifacts )
{
StringBuffer buffer = new StringBuffer( "Missing:\n" );
buffer.append( "----------\n" );
int counter = 0;
for (Artifact artifact : artifacts) {
String message = (++counter) + ") " + artifact.getId();
buffer.append(constructMissingArtifactMessage(message, " ", artifact.getGroupId(), artifact
.getArtifactId(), artifact.getVersion(), artifact.getType(), artifact.getClassifier(),
artifact.getDownloadUrl(), artifact
.getDependencyTrail()));
}
buffer.append( "----------\n" );
int size = artifacts.size();
buffer.append( size ).append( " required artifact" );
if ( size > 1 )
{
buffer.append( "s are" );
}
else
{
buffer.append( " is" );
}
buffer.append( " missing.\n\nfor artifact: " );
return buffer.toString();
}
}

View File

@ -0,0 +1,110 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.VersionRange;
/**
* Listens to the resolution process and handles events.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface ResolutionListener
{
String ROLE = ResolutionListener.class.getName();
int TEST_ARTIFACT = 1;
int PROCESS_CHILDREN = 2;
int FINISH_PROCESSING_CHILDREN = 3;
int INCLUDE_ARTIFACT = 4;
int OMIT_FOR_NEARER = 5;
int UPDATE_SCOPE = 6;
@Deprecated
int MANAGE_ARTIFACT = 7;
int OMIT_FOR_CYCLE = 8;
/**
* this event means that the artifactScope has NOT been updated to a farther node artifactScope because current
* node is in the first level pom
*/
int UPDATE_SCOPE_CURRENT_POM = 9;
int SELECT_VERSION_FROM_RANGE = 10;
int RESTRICT_RANGE = 11;
int MANAGE_ARTIFACT_VERSION = 12;
int MANAGE_ARTIFACT_SCOPE = 13;
int MANAGE_ARTIFACT_SYSTEM_PATH = 14;
void testArtifact( Artifact node );
void startProcessChildren( Artifact artifact );
void endProcessChildren( Artifact artifact );
void includeArtifact( Artifact artifact );
void omitForNearer( Artifact omitted,
Artifact kept );
void updateScope( Artifact artifact,
String scope );
@Deprecated
void manageArtifact( Artifact artifact,
Artifact replacement );
// TODO Use the following two instead of manageArtifact
// TODO Remove ResolutionListenerDM interface
//void manageArtifactVersion( Artifact artifact, Artifact replacement );
//void manageArtifactScope( Artifact artifact, Artifact replacement );
void omitForCycle( Artifact artifact );
/**
* This event means that the artifactScope has NOT been updated to a farther node artifactScope because current
* node is in the first level pom
*
* @param artifact current node artifact, the one in the first level pom
* @param ignoredScope artifactScope that was ignored because artifact was in first level pom
*/
void updateScopeCurrentPom( Artifact artifact,
String ignoredScope );
void selectVersionFromRange( Artifact artifact );
void restrictRange( Artifact artifact,
Artifact replacement,
VersionRange newRange );
}

View File

@ -0,0 +1,43 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
/**
* Do not use!
* <p/>
* Should only be implmemented by DebugResolutionListener. Remove this
* when the ResolutionListener interface deprecation of the manageArtifact
* method (and the [yet to be done] addition of these methods to that
* interface) has had a chance to propagate to all interested plugins.
*/
@Deprecated
public interface ResolutionListenerForDepMgmt
{
void manageArtifactVersion( Artifact artifact,
Artifact replacement );
void manageArtifactScope( Artifact artifact,
Artifact replacement );
void manageArtifactSystemPath( Artifact artifact,
Artifact replacement );
}

View File

@ -0,0 +1,252 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class ResolutionNode
{
private Artifact artifact;
private List<ResolutionNode> children;
private final List<Object> parents;
private final int depth;
private final ResolutionNode parent;
private final List<ArtifactRepository> remoteRepositories;
private boolean active = true;
private List<Artifact> trail;
public ResolutionNode( Artifact artifact, List<ArtifactRepository> remoteRepositories )
{
this.artifact = artifact;
this.remoteRepositories = remoteRepositories;
depth = 0;
parents = Collections.emptyList();
parent = null;
}
public ResolutionNode( Artifact artifact, List<ArtifactRepository> remoteRepositories, ResolutionNode parent )
{
this.artifact = artifact;
this.remoteRepositories = remoteRepositories;
depth = parent.depth + 1;
parents = new ArrayList<Object>();
parents.addAll( parent.parents );
parents.add( parent.getKey() );
this.parent = parent;
}
public Artifact getArtifact()
{
return artifact;
}
public Object getKey()
{
return artifact.getDependencyConflictId();
}
public void addDependencies( Set<Artifact> artifacts, List<ArtifactRepository> remoteRepositories,
ArtifactFilter filter )
throws CyclicDependencyException, OverConstrainedVersionException
{
if ( !artifacts.isEmpty() )
{
children = new ArrayList<ResolutionNode>( artifacts.size() );
for ( Artifact a : artifacts )
{
if ( parents.contains( a.getDependencyConflictId() ) )
{
a.setDependencyTrail( getDependencyTrail() );
throw new CyclicDependencyException( "A dependency has introduced a cycle", a );
}
children.add( new ResolutionNode( a, remoteRepositories, this ) );
}
}
else
{
children = Collections.emptyList();
}
trail = null;
}
/**
* @return {@link List} &lt; {@link String} > with artifact ids
* @throws OverConstrainedVersionException
*/
public List<String> getDependencyTrail()
throws OverConstrainedVersionException
{
List<Artifact> trial = getTrail();
List<String> ret = new ArrayList<String>( trial.size() );
for ( Artifact artifact : trial )
{
ret.add( artifact.getId() );
}
return ret;
}
private List<Artifact> getTrail()
throws OverConstrainedVersionException
{
if ( trail == null )
{
List<Artifact> ids = new LinkedList<Artifact>();
ResolutionNode node = this;
while ( node != null )
{
Artifact artifact = node.getArtifact();
if ( artifact.getVersion() == null )
{
// set the recommended version
ArtifactVersion selected = artifact.getSelectedVersion();
// MNG-2123: null is a valid response to getSelectedVersion, don't
// assume it won't ever be.
if ( selected != null )
{
artifact.selectVersion( selected.toString() );
}
else
{
throw new OverConstrainedVersionException( "Unable to get a selected Version for "
+ artifact.getArtifactId(), artifact );
}
}
ids.add( 0, artifact );
node = node.parent;
}
trail = ids;
}
return trail;
}
public boolean isResolved()
{
return children != null;
}
/**
* Test whether the node is direct or transitive dependency.
*/
public boolean isChildOfRootNode()
{
return parent != null && parent.parent == null;
}
public Iterator<ResolutionNode> getChildrenIterator()
{
return children.iterator();
}
public int getDepth()
{
return depth;
}
public List<ArtifactRepository> getRemoteRepositories()
{
return remoteRepositories;
}
public boolean isActive()
{
return active;
}
public void enable()
{
active = true;
// TODO: if it was null, we really need to go find them now... or is this taken care of by the ordering?
if ( children != null )
{
for ( ResolutionNode node : children )
{
node.enable();
}
}
}
public void disable()
{
active = false;
if ( children != null )
{
for ( ResolutionNode node : children )
{
node.disable();
}
}
}
public boolean filterTrail( ArtifactFilter filter )
throws OverConstrainedVersionException
{
boolean success = true;
if ( filter != null )
{
for ( Iterator i = getTrail().iterator(); i.hasNext() && success; )
{
Artifact artifact = (Artifact) i.next();
if ( !filter.include( artifact ) )
{
success = false;
}
}
}
return success;
}
@Override
public String toString()
{
return artifact.toString() + " (" + depth + "; " + ( active ? "enabled" : "disabled" ) + ")";
}
public void setArtifact( Artifact artifact )
{
this.artifact = artifact;
}
}

View File

@ -0,0 +1,47 @@
package org.apache.maven.artifact.resolver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.util.List;
/**
* A simple recording of the Artifacts that could not be resolved for a given resolution request, along with
* the remote repositories where attempts were made to resolve the artifacts.
*
* @author Jason van Zyl
*/
public class UnresolvedArtifacts
{
private Artifact originatingArtifact;
private List<Artifact> artifacts;
private List<ArtifactRepository> remoteRepositories;
public UnresolvedArtifacts( Artifact originatingArtifact,
List<Artifact> artifacts,
List<ArtifactRepository> remoteRepositories )
{
this.originatingArtifact = originatingArtifact;
this.artifacts = artifacts;
this.remoteRepositories = remoteRepositories;
}
public Artifact getOriginatingArtifact()
{
return originatingArtifact;
}
public List<Artifact> getArtifacts()
{
return artifacts;
}
public List<ArtifactRepository> getRemoteRepositories()
{
return remoteRepositories;
}
}

View File

@ -0,0 +1,94 @@
package org.apache.maven.artifact.resolver;
/*
* 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.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.VersionRange;
import org.codehaus.plexus.logging.Logger;
import java.util.HashSet;
import java.util.Set;
/**
* Send resolution warning events to the warning log.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class WarningResolutionListener
implements ResolutionListener
{
private Logger logger;
public WarningResolutionListener( Logger logger )
{
this.logger = logger;
}
public void testArtifact( Artifact node )
{
}
public void startProcessChildren( Artifact artifact )
{
}
public void endProcessChildren( Artifact artifact )
{
}
public void includeArtifact( Artifact artifact )
{
}
public void omitForNearer( Artifact omitted,
Artifact kept )
{
}
public void omitForCycle( Artifact omitted )
{
}
public void updateScopeCurrentPom( Artifact artifact,
String scope )
{
}
public void updateScope( Artifact artifact,
String scope )
{
}
public void manageArtifact( Artifact artifact,
Artifact replacement )
{
}
public void selectVersionFromRange( Artifact artifact )
{
}
public void restrictRange( Artifact artifact,
Artifact replacement,
VersionRange newRange )
{
}
}

View File

@ -0,0 +1,46 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.resolver.ResolutionNode;
/**
* Determines which version of an artifact to use when there are conflicting declarations.
*
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
*/
public interface ConflictResolver
{
static String ROLE = ConflictResolver.class.getName();
/**
* Determines which of the specified versions of an artifact to use when there are conflicting declarations.
*
* @param node1 the first artifact declaration
* @param node2 the second artifact declaration
* @return the artifact declaration to use: <code>node1</code>; <code>node2</code>; or <code>null</code>if
* this conflict cannot be resolved
* @since 3.0
*/
ResolutionNode resolveConflict( ResolutionNode node1,
ResolutionNode node2 );
}

View File

@ -0,0 +1,49 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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 factory that produces conflict resolvers of various types.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @see ConflictResolver
* @since 3.0
*/
public interface ConflictResolverFactory
{
// constants --------------------------------------------------------------
/** The plexus role for this component. */
String ROLE = ConflictResolverFactory.class.getName();
// methods ----------------------------------------------------------------
/**
* Gets a conflict resolver of the specified type.
*
* @param type the type of conflict resolver to obtain
* @return the conflict resolver
* @throws ConflictResolverNotFoundException
* if the specified type was not found
*/
ConflictResolver getConflictResolver( String type )
throws ConflictResolverNotFoundException;
}

View File

@ -0,0 +1,48 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.
*/
/**
* Indicates that a specified conflict resolver implementation could not be found.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @since 3.0
*/
public class ConflictResolverNotFoundException
extends Exception
{
// constants --------------------------------------------------------------
/** The serial version ID. */
private static final long serialVersionUID = 3372412184339653914L;
// constructors -----------------------------------------------------------
/**
* Creates a new <code>ConflictResolverNotFoundException</code> with the specified message.
*
* @param message the message
*/
public ConflictResolverNotFoundException( String message )
{
super( message );
}
}

View File

@ -0,0 +1,35 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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 default conflict resolver that delegates to the nearest strategy.
*
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
* @see NearestConflictResolver
* @deprecated As of 3.0, use a specific implementation instead, e.g. {@link NearestConflictResolver}
* @plexus.component
*/
@Deprecated
public class DefaultConflictResolver
extends NearestConflictResolver
{
}

View File

@ -0,0 +1,81 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
/**
* A conflict resolver factory that obtains instances from a plexus container.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @plexus.component
* @todo you don't need the container in here with the active maps (jvz).
* @since 3.0
*/
public class DefaultConflictResolverFactory
implements ConflictResolverFactory,
Contextualizable
{
// fields -----------------------------------------------------------------
/**
* The plexus container used to obtain instances from.
*
* @plexus.requirement
*/
private PlexusContainer container;
// ConflictResolverFactory methods ----------------------------------------
/*
* @see org.apache.maven.artifact.resolver.conflict.ConflictResolverFactory#getConflictResolver(java.lang.String)
*/
public ConflictResolver getConflictResolver( String type )
throws ConflictResolverNotFoundException
{
try
{
return (ConflictResolver) container.lookup( ConflictResolver.ROLE, type );
}
catch ( ComponentLookupException exception )
{
throw new ConflictResolverNotFoundException( "Cannot find conflict resolver of type: " + type );
}
}
// Contextualizable methods -----------------------------------------------
/*
* @see org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable#contextualize(org.codehaus.plexus.context.Context)
*/
public void contextualize( Context context )
throws ContextException
{
container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
}
}

View File

@ -0,0 +1,54 @@
package org.apache.maven.artifact.resolver.conflict;
import org.apache.maven.artifact.resolver.metadata.MetadataGraphEdge;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
/**
*
* @plexus.component
*
* @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
*
* @version $Id$
*/
public class DefaultGraphConflictResolutionPolicy
implements GraphConflictResolutionPolicy
{
/**
* artifact, closer to the entry point, is selected
*
* @plexus.configuration default-value="true"
*/
private boolean closerFirst = true;
/**
* newer artifact is selected
*
* @plexus.configuration default-value="true"
*/
private boolean newerFirst = true;
public MetadataGraphEdge apply(MetadataGraphEdge e1, MetadataGraphEdge e2)
{
int depth1 = e1.getDepth();
int depth2 = e2.getDepth();
if( depth1 == depth2 ) {
ArtifactVersion v1 = new DefaultArtifactVersion( e1.getVersion() );
ArtifactVersion v2 = new DefaultArtifactVersion( e2.getVersion() );
if( newerFirst )
return v1.compareTo(v2) > 0 ? e1 : e2;
return v1.compareTo(v2) > 0 ? e2 : e1;
}
if( closerFirst )
return depth1 < depth2 ? e1 : e2;
return depth1 < depth2 ? e2 : e1;
}
}

View File

@ -0,0 +1,224 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.ArtifactScopeEnum;
import org.apache.maven.artifact.resolver.metadata.ArtifactMetadata;
import org.apache.maven.artifact.resolver.metadata.MetadataGraph;
import org.apache.maven.artifact.resolver.metadata.MetadataGraphEdge;
import org.apache.maven.artifact.resolver.metadata.MetadataGraphVertex;
import org.apache.maven.artifact.resolver.metadata.MetadataResolutionException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
/**
* Default conflict resolver.Implements closer newer first policy by default, but could be configured via plexus
*
* @plexus.component
* @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
* @version $Id$
*/
public class DefaultGraphConflictResolver
implements GraphConflictResolver
{
/**
* artifact, closer to the entry point, is selected
*
* @plexus.requirement role="org.apache.maven.artifact.resolver.conflict.GraphConflictResolutionPolicy"
*/
protected GraphConflictResolutionPolicy policy;
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
public MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
throws GraphConflictResolutionException
{
if ( policy == null )
throw new GraphConflictResolutionException( "no GraphConflictResolutionPolicy injected" );
if ( graph == null )
return null;
final MetadataGraphVertex entry = graph.getEntry();
if ( entry == null )
return null;
if ( graph.isEmpty() )
throw new GraphConflictResolutionException( "graph with an entry, but not vertices do not exist" );
if ( graph.isEmptyEdges() )
return null; // no edges - nothing to worry about
final TreeSet<MetadataGraphVertex> vertices = graph.getVertices();
try
{
// edge case - single vertex graph
if ( vertices.size() == 1 )
return new MetadataGraph( entry );
final ArtifactScopeEnum requestedScope = ArtifactScopeEnum.checkScope( scope );
MetadataGraph res = new MetadataGraph( vertices.size() );
res.setVersionedVertices( false );
res.setScopedVertices( false );
MetadataGraphVertex resEntry = res.addVertex( entry.getMd() );
res.setEntry( resEntry );
res.setScope( requestedScope );
for ( MetadataGraphVertex v : vertices )
{
final List<MetadataGraphEdge> ins = graph.getIncidentEdges( v );
final MetadataGraphEdge edge = cleanEdges( v, ins, requestedScope );
if ( edge == null )
{ // no edges - don't need this vertex any more
if ( entry.equals( v ) )
{ // unless it's an entry point.
// currently processing the entry point - it should not have any entry incident edges
res.getEntry().getMd().setWhy( "This is a graph entry point. No links." );
}
else
{
// System.out.println("--->"+v.getMd().toDomainString()
// +" has been terminated on this entry set\n-------------------\n"
// +ins
// +"\n-------------------\n"
// );
}
}
else
{
// System.out.println("+++>"+v.getMd().toDomainString()+" still has "+edge.toString() );
// fill in domain md with actual version data
ArtifactMetadata md = v.getMd();
ArtifactMetadata newMd =
new ArtifactMetadata( md.getGroupId(), md.getArtifactId(), edge.getVersion(), md.getType(),
md.getScopeAsEnum(), md.getClassifier(), edge.getArtifactUri(),
edge.getSource() == null ? "" : edge.getSource().getMd().toString(),
edge.isResolved(), edge.getTarget() == null ? null
: edge.getTarget().getMd().getError() );
MetadataGraphVertex newV = res.addVertex( newMd );
MetadataGraphVertex sourceV = res.addVertex( edge.getSource().getMd() );
res.addEdge( sourceV, newV, edge );
}
}
MetadataGraph linkedRes = findLinkedSubgraph( res );
// System.err.println("Original graph("+graph.getVertices().size()+"):\n"+graph.toString());
// System.err.println("Cleaned("+requestedScope+") graph("+res.getVertices().size()+"):\n"+res.toString());
// System.err.println("Linked("+requestedScope+")
// subgraph("+linkedRes.getVertices().size()+"):\n"+linkedRes.toString());
return linkedRes;
}
catch ( MetadataResolutionException e )
{
throw new GraphConflictResolutionException( e );
}
}
// -------------------------------------------------------------------------------------
private MetadataGraph findLinkedSubgraph( MetadataGraph g )
{
if ( g.getVertices().size() == 1 )
return g;
List<MetadataGraphVertex> visited = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
visit( g.getEntry(), visited, g );
List<MetadataGraphVertex> dropList = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
// collect drop list
for ( MetadataGraphVertex v : g.getVertices() )
{
if ( !visited.contains( v ) )
dropList.add( v );
}
if ( dropList.size() < 1 )
return g;
// now - drop vertices
TreeSet<MetadataGraphVertex> vertices = g.getVertices();
for ( MetadataGraphVertex v : dropList )
{
vertices.remove( v );
}
return g;
}
// -------------------------------------------------------------------------------------
private void visit( MetadataGraphVertex from, List<MetadataGraphVertex> visited, MetadataGraph graph )
{
if ( visited.contains( from ) )
return;
visited.add( from );
List<MetadataGraphEdge> exitList = graph.getExcidentEdges( from );
// String s = "|---> "+from.getMd().toString()+" - "+(exitList == null ? -1 : exitList.size()) + " exit links";
if ( exitList != null && exitList.size() > 0 )
{
for ( MetadataGraphEdge e : graph.getExcidentEdges( from ) )
{
visit( e.getTarget(), visited, graph );
}
}
}
// -------------------------------------------------------------------------------------
private MetadataGraphEdge cleanEdges( MetadataGraphVertex v, List<MetadataGraphEdge> edges, ArtifactScopeEnum scope )
{
if ( edges == null || edges.isEmpty() )
return null;
if ( edges.size() == 1 )
{
MetadataGraphEdge e = edges.get( 0 );
if ( scope.encloses( e.getScope() ) )
return e;
return null;
}
MetadataGraphEdge res = null;
for ( MetadataGraphEdge e : edges )
{
if ( !scope.encloses( e.getScope() ) )
continue;
if ( res == null )
res = e;
else
res = policy.apply( e, res );
}
return res;
}
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
}

View File

@ -0,0 +1,48 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.resolver.ResolutionNode;
/**
* Resolves conflicting artifacts by always selecting the <em>farthest</em> declaration. Farthest is defined as the
* declaration that has the most transitive steps away from the project being built.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @since 3.0
* @plexus.component role-hint="farthest"
*/
public class FarthestConflictResolver
implements ConflictResolver
{
// ConflictResolver methods -----------------------------------------------
/*
* @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
* org.apache.maven.artifact.resolver.ResolutionNode)
*/
public ResolutionNode resolveConflict( ResolutionNode node1,
ResolutionNode node2 )
{
return node1.getDepth() >= node2.getDepth() ? node1 : node2;
}
}

View File

@ -0,0 +1,34 @@
package org.apache.maven.artifact.resolver.conflict;
/**
*
* @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
*
* @version $Id$
*/
public class GraphConflictResolutionException
extends Exception
{
private static final long serialVersionUID = 2677613140287940255L;
public GraphConflictResolutionException()
{
}
public GraphConflictResolutionException(String message)
{
super(message);
}
public GraphConflictResolutionException(Throwable cause)
{
super(cause);
}
public GraphConflictResolutionException(String message, Throwable cause)
{
super(message, cause);
}
}

View File

@ -0,0 +1,22 @@
package org.apache.maven.artifact.resolver.conflict;
import org.apache.maven.artifact.resolver.metadata.MetadataGraphEdge;
/**
* MetadataGraph edge selection policy. Complements
* GraphConflictResolver by being injected into it
*
* @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
*
* @version $Id$
*/
public interface GraphConflictResolutionPolicy
{
static String ROLE = GraphConflictResolutionPolicy.class.getName();
public MetadataGraphEdge apply(
MetadataGraphEdge e1
, MetadataGraphEdge e2
);
}

View File

@ -0,0 +1,50 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.ArtifactScopeEnum;
import org.apache.maven.artifact.resolver.metadata.MetadataGraph;
/**
* Resolves conflicts in the supplied dependency graph.
* Different implementations will implement different conflict resolution policies.
*
* @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
* @version $Id$
*/
public interface GraphConflictResolver
{
static String ROLE = GraphConflictResolver.class.getName();
/**
* Cleanses the supplied graph by leaving only one directed versioned edge\
* between any two nodes, if multiple exists. Uses scope relationships, defined
* in <code>ArtifactScopeEnum</code>
*
* @param graph the "dirty" graph to be simplified via conflict resolution
* @param scope scope for which the graph should be resolved
*
* @return resulting "clean" graph for the specified scope
*
* @since 3.0
*/
MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
throws GraphConflictResolutionException;
}

View File

@ -0,0 +1,49 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.resolver.ResolutionNode;
/**
* Resolves conflicting artifacts by always selecting the <em>nearest</em> declaration. Nearest is defined as the
* declaration that has the least transitive steps away from the project being built.
*
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @since 3.0
* @plexus.component role-hint="nearest"
*/
public class NearestConflictResolver
implements ConflictResolver
{
// ConflictResolver methods -----------------------------------------------
/*
* @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
* org.apache.maven.artifact.resolver.ResolutionNode)
*/
public ResolutionNode resolveConflict( ResolutionNode node1,
ResolutionNode node2 )
{
return node1.getDepth() <= node2.getDepth() ? node1 : node2;
}
}

View File

@ -0,0 +1,63 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.resolver.ResolutionNode;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
/**
* Resolves conflicting artifacts by always selecting the <em>newest</em> declaration. Newest is defined as the
* declaration whose version is greater according to <code>ArtifactVersion.compareTo</code>.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @see ArtifactVersion#compareTo(Object)
* @since 3.0
* @plexus.component role-hint="newest"
*/
public class NewestConflictResolver
implements ConflictResolver
{
// ConflictResolver methods -----------------------------------------------
/*
* @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
* org.apache.maven.artifact.resolver.ResolutionNode)
*/
public ResolutionNode resolveConflict( ResolutionNode node1,
ResolutionNode node2 )
{
try
{
ArtifactVersion version1 = node1.getArtifact().getSelectedVersion();
ArtifactVersion version2 = node2.getArtifact().getSelectedVersion();
return version1.compareTo( version2 ) > 0 ? node1 : node2;
}
catch ( OverConstrainedVersionException exception )
{
// TODO: log message or throw exception?
return null;
}
}
}

View File

@ -0,0 +1,63 @@
package org.apache.maven.artifact.resolver.conflict;
/*
* 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.apache.maven.artifact.resolver.ResolutionNode;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
/**
* Resolves conflicting artifacts by always selecting the <em>oldest</em> declaration. Oldest is defined as the
* declaration whose version is less according to <code>ArtifactVersion.compareTo</code>.
*
* @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
* @version $Id$
* @see ArtifactVersion#compareTo(Object)
* @since 3.0
* @plexus.component role-hint="oldest"
*/
public class OldestConflictResolver
implements ConflictResolver
{
// ConflictResolver methods -----------------------------------------------
/*
* @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
* org.apache.maven.artifact.resolver.ResolutionNode)
*/
public ResolutionNode resolveConflict( ResolutionNode node1,
ResolutionNode node2 )
{
try
{
ArtifactVersion version1 = node1.getArtifact().getSelectedVersion();
ArtifactVersion version2 = node2.getArtifact().getSelectedVersion();
return version1.compareTo( version2 ) <= 0 ? node1 : node2;
}
catch ( OverConstrainedVersionException exception )
{
// TODO: log message or throw exception?
return null;
}
}
}

View File

@ -0,0 +1,57 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Apply multiple filters.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class AndArtifactFilter
implements ArtifactFilter
{
private final List<ArtifactFilter> filters = new ArrayList<ArtifactFilter>();
public boolean include( Artifact artifact )
{
boolean include = true;
for ( Iterator<ArtifactFilter> i = filters.iterator(); i.hasNext() && include; )
{
ArtifactFilter filter = i.next();
if ( !filter.include( artifact ) )
{
include = false;
}
}
return include;
}
public void add( ArtifactFilter artifactFilter )
{
filters.add( artifactFilter );
}
}

View File

@ -0,0 +1,31 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public interface ArtifactFilter
{
boolean include( Artifact artifact );
}

View File

@ -0,0 +1,45 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
import java.util.List;
/**
* Filter to exclude from a list of artifact patterns.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
* @todo I think this is equiv. to exclusion set filter in maven-core
*/
public class ExcludesArtifactFilter
extends IncludesArtifactFilter
{
public ExcludesArtifactFilter( List<String> patterns )
{
super( patterns );
}
public boolean include( Artifact artifact )
{
return !super.include( artifact );
}
}

View File

@ -0,0 +1,51 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$
*/
public class ExclusionSetFilter
implements ArtifactFilter
{
private Set<String> excludes;
public ExclusionSetFilter( String[] excludes )
{
this.excludes = new HashSet<String>( Arrays.asList( excludes ) );
}
public ExclusionSetFilter( Set<String> excludes )
{
this.excludes = excludes;
}
public boolean include( Artifact artifact )
{
return !excludes.contains(artifact.getArtifactId());
}
}

View File

@ -0,0 +1,58 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
import java.util.Iterator;
import java.util.List;
/**
* Filter to include from a list of artifact patterns.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class IncludesArtifactFilter
implements ArtifactFilter
{
private final List<String> patterns;
public IncludesArtifactFilter( List<String> patterns )
{
this.patterns = patterns;
}
public boolean include( Artifact artifact )
{
String id = artifact.getGroupId() + ":" + artifact.getArtifactId();
boolean matched = false;
for ( Iterator<String> i = patterns.iterator(); i.hasNext() & !matched; )
{
// TODO: what about wildcards? Just specifying groups? versions?
if ( id.equals( i.next() ) )
{
matched = true;
}
}
return matched;
}
}

View File

@ -0,0 +1,38 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
public class InversionArtifactFilter
implements ArtifactFilter
{
private final ArtifactFilter toInvert;
public InversionArtifactFilter( ArtifactFilter toInvert )
{
this.toInvert = toInvert;
}
public boolean include( Artifact artifact )
{
return !toInvert.include( artifact );
}
}

View File

@ -0,0 +1,106 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
/**
* Filter to only retain objects in the given artifactScope or better.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ScopeArtifactFilter
implements ArtifactFilter
{
private final boolean compileScope;
private final boolean runtimeScope;
private final boolean testScope;
private final boolean providedScope;
private final boolean systemScope;
public ScopeArtifactFilter( String scope )
{
if ( Artifact.SCOPE_COMPILE.equals( scope ) )
{
systemScope = true;
providedScope = true;
compileScope = true;
runtimeScope = false;
testScope = false;
}
else if ( Artifact.SCOPE_RUNTIME.equals( scope ) )
{
systemScope = false;
providedScope = false;
compileScope = true;
runtimeScope = true;
testScope = false;
}
else if ( Artifact.SCOPE_TEST.equals( scope ) )
{
systemScope = true;
providedScope = true;
compileScope = true;
runtimeScope = true;
testScope = true;
}
else
{
systemScope = false;
providedScope = false;
compileScope = false;
runtimeScope = false;
testScope = false;
}
}
public boolean include( Artifact artifact )
{
if ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
{
return compileScope;
}
else if ( Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
{
return runtimeScope;
}
else if ( Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
{
return testScope;
}
else if ( Artifact.SCOPE_PROVIDED.equals( artifact.getScope() ) )
{
return providedScope;
}
else if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
{
return systemScope;
}
else
{
return true;
}
}
}

View File

@ -0,0 +1,39 @@
package org.apache.maven.artifact.resolver.filter;
/*
* 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.apache.maven.artifact.Artifact;
/** Artifact Filter which filters on artifact type */
public class TypeArtifactFilter
implements ArtifactFilter
{
private String type = "jar";
public TypeArtifactFilter( String type )
{
this.type = type;
}
public boolean include( Artifact artifact )
{
return type.equals( artifact.getType() );
}
}

View File

@ -0,0 +1,374 @@
package org.apache.maven.artifact.resolver.metadata;
import java.util.Collection;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactScopeEnum;
/**
* Artifact Metadata that is resolved independent of Artifact itself.
*
* @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
*
*/
public class ArtifactMetadata
{
/**
* standard glorified artifact coordinates
*/
protected String groupId;
protected String artifactId;
protected String version;
protected String type;
protected ArtifactScopeEnum artifactScope;
protected String classifier;
/**
* explanation: why this MD was chosen over it's siblings
* in the resulting structure (classpath for now)
*/
protected String why;
/** dependencies of the artifact behind this metadata */
protected Collection<ArtifactMetadata> dependencies;
/** metadata URI */
protected String uri;
/** is metadata found anywhere */
protected boolean resolved = false;
/** does the actual artifact for this metadata exists */
protected boolean artifactExists = false;
/** artifact URI */
protected String artifactUri;
/** error message */
private String error;
//------------------------------------------------------------------
/**
*
*/
public ArtifactMetadata( String name )
{
if( name == null )
return;
int ind1 = name.indexOf(':');
int ind2 = name.lastIndexOf(':');
if( ind1 == -1 || ind2 == -1 )
return;
this.groupId = name.substring(0, ind1);
if( ind1 == ind2 )
{
this.artifactId = name.substring(ind1+1);
}
else
{
this.artifactId = name.substring( ind1+1, ind2 );
this.version = name.substring( ind2+1 );
}
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId,
String name,
String version )
{
this( groupId, name, version, null );
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId,
String name,
String version,
String type )
{
this( groupId, name, version, type, null );
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId,
String name,
String version,
String type,
ArtifactScopeEnum artifactScope )
{
this( groupId, name, version, type, artifactScope, null );
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId,
String name,
String version,
String type,
ArtifactScopeEnum artifactScope,
String classifier )
{
this( groupId, name, version, type, artifactScope, classifier, null );
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId,
String name,
String version,
String type,
ArtifactScopeEnum artifactScope,
String classifier
, String artifactUri
)
{
this( groupId, name, version, type, artifactScope, classifier, artifactUri, null, true, null );
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId
, String name
, String version
, String type
, ArtifactScopeEnum artifactScope
, String classifier
, String artifactUri
, String why
, boolean resolved
, String error
)
{
this.groupId = groupId;
this.artifactId = name;
this.version = version;
this.type = type;
this.artifactScope = artifactScope;
this.classifier = classifier;
this.artifactUri = artifactUri;
this.why = why;
this.resolved = resolved;
this.error = error;
}
//------------------------------------------------------------------
public ArtifactMetadata( String groupId
, String name
, String version
, String type
, String scopeString
, String classifier
, String artifactUri
, String why
, boolean resolved
, String error
)
{
this( groupId
, name
, version
, type
, scopeString == null ? ArtifactScopeEnum.DEFAULT_SCOPE : ArtifactScopeEnum.valueOf(scopeString)
, classifier
, artifactUri
, why
, resolved
, error
);
}
//------------------------------------------------------------------
public ArtifactMetadata( Artifact af )
{
/*
if ( af != null )
{
init( af );
}
*/
}
//------------------------------------------------------------------
// public void init( ArtifactMetadata af )
// {
// setGroupId( af.getGroupId() );
// setArtifactId( af.getArtifactId() );
// setVersion( af.getVersion() );
// setType( af.getType() );
// setScope( af.getScope() );
// setClassifier( af.getClassifier() );
// //setUri( af.getDownloadUrl() );
//
// this.resolved = af.isResolved();
// }
//------------------------------------------------------------------
@Override
public String toString()
{
return groupId + ":" + artifactId + ":" + version;
}
//------------------------------------------------------------------
public String toDomainString()
{
return groupId + ":" + artifactId;
}
//------------------------------------------------------------------
public String getGroupId()
{
return groupId;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public String getArtifactId()
{
return artifactId;
}
public void setArtifactId( String name )
{
this.artifactId = name;
}
public String getVersion()
{
return version;
}
public void setVersion( String version )
{
this.version = version;
}
public String getType()
{
return type;
}
public String getCheckedType()
{
return type == null ? "jar" : type;
}
public void setType( String type )
{
this.type = type;
}
public ArtifactScopeEnum getArtifactScope()
{
return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
}
public void setArtifactScope( ArtifactScopeEnum artifactScope )
{
this.artifactScope = artifactScope;
}
public void setScope( String scope )
{
this.artifactScope = scope == null
? ArtifactScopeEnum.DEFAULT_SCOPE
: ArtifactScopeEnum.valueOf( scope )
;
}
public String getClassifier()
{
return classifier;
}
public void setClassifier( String classifier )
{
this.classifier = classifier;
}
public boolean isResolved()
{
return resolved;
}
public void setResolved( boolean resolved )
{
this.resolved = resolved;
}
public String getUri()
{
return uri;
}
public void setUri( String uri )
{
this.uri = uri;
}
public String getScope()
{
return getArtifactScope().getScope();
}
public ArtifactScopeEnum getScopeAsEnum()
{
return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
}
public boolean isArtifactExists()
{
return artifactExists;
}
public void setArtifactExists(boolean artifactExists)
{
this.artifactExists = artifactExists;
}
public Collection<ArtifactMetadata> getDependencies()
{
return dependencies;
}
public void setDependencies(Collection<ArtifactMetadata> dependencies)
{
this.dependencies = dependencies;
}
public String getArtifactUri()
{
return artifactUri;
}
public void setArtifactUri(String artifactUri)
{
this.artifactUri = artifactUri;
}
public String getWhy()
{
return why;
}
public void setWhy(String why)
{
this.why = why;
}
//-------------------------------------------------------------------
public String getError()
{
return error;
}
public void setError(String error)
{
this.error = error;
}
public boolean isError()
{
return error == null;
}
//------------------------------------------------------------------
public String getDependencyConflictId()
{
return groupId + ":" + artifactId;
}
//------------------------------------------------------------------
//------------------------------------------------------------------
}

View File

@ -0,0 +1,226 @@
package org.apache.maven.artifact.resolver.metadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.conflict.GraphConflictResolver;
import org.apache.maven.artifact.transform.ClasspathTransformation;
import org.codehaus.plexus.logging.AbstractLogEnabled;
/**
* default implementation of the metadata resolver
*
* @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
*
* @plexus.component
*
*/
public class DefaultMetadataResolver
extends AbstractLogEnabled
implements MetadataResolver
{
//------------------------------------------------------------------------
/** @plexus.requirement */
ArtifactResolver artifactResolver;
/** @plexus.requirement */
ArtifactFactory artifactFactory;
/** @plexus.requirement */
MetadataSource metadataSource;
/** @plexus.requirement */
GraphConflictResolver conflictResolver;
/** @plexus.requirement */
ClasspathTransformation classpathTransformation;
//------------------------------------------------------------------------
public MetadataResolutionResult resolveMetadata( MetadataResolutionRequest req )
throws MetadataResolutionException
{
try
{
getLogger().debug( "Received request for: " + req.getQuery() );
MetadataResolutionResult res = new MetadataResolutionResult();
MetadataTreeNode tree = resolveMetadataTree( req.getQuery()
, null
, req.getLocalRepository()
, req.getRemoteRepositories()
);
res.setTree( tree );
return res;
}
catch ( MetadataResolutionException mrEx )
{
throw mrEx;
}
catch ( Exception anyEx )
{
throw new MetadataResolutionException( anyEx );
}
}
//------------------------------------------------------------------------
private MetadataTreeNode resolveMetadataTree( ArtifactMetadata query
, MetadataTreeNode parent
, ArtifactRepository localRepository
, List<ArtifactRepository> remoteRepositories
)
throws MetadataResolutionException
{
try
{
Artifact pomArtifact = artifactFactory.createArtifact(
query.getGroupId()
, query.getArtifactId()
, query.getVersion()
, query.getScope()
, query.getType() == null ? "jar" : query.getType()
);
getLogger().debug( "resolveMetadata request:"
+ "\n> artifact : " + pomArtifact.toString()
+ "\n> remoteRepos: " + remoteRepositories
+ "\n> localRepo : " + localRepository
);
String error = null;
try
{
ArtifactResolutionRequest arr = new ArtifactResolutionRequest();
arr.setArtifact( pomArtifact );
arr.setLocalRepository( localRepository );
arr.setRemoteRepostories( remoteRepositories );
artifactResolver.resolve( pomArtifact, remoteRepositories , localRepository );
//System.out.println("Resolved "+query+" : "+pomArtifact.isResolved() );
if ( !pomArtifact.isResolved() )
{
getLogger().info( "*************> Did not resolve " + pomArtifact.toString()
+ "\nURL: " + pomArtifact.getDownloadUrl()
+ "\nRepos: " + remoteRepositories
+ "\nLocal: " + localRepository
);
}
}
catch ( ArtifactResolutionException are )
{
pomArtifact.setResolved( false );
error = are.getMessage();
}
catch ( ArtifactNotFoundException anfe )
{
pomArtifact.setResolved( false );
error = anfe.getMessage();
}
if( error != null )
{
getLogger().info( "*************> Did not resolve " + pomArtifact.toString()
+ "\nRepos: " + remoteRepositories
+ "\nLocal: " + localRepository
+ "\nerror: " + error
);
}
if( pomArtifact.isResolved() )
{
MetadataResolution metadataResolution = metadataSource.retrieve(
query
, localRepository
, remoteRepositories
);
ArtifactMetadata found = metadataResolution.getArtifactMetadata();
if( pomArtifact.getFile() != null && pomArtifact.getFile().toURI() != null )
found.setArtifactUri( pomArtifact.getFile().toURI().toString() );
MetadataTreeNode node = new MetadataTreeNode( found
, parent
, true
, found.getScopeAsEnum()
);
Collection<ArtifactMetadata> dependencies
= metadataResolution.getArtifactMetadata().getDependencies();
if( dependencies != null && dependencies.size() > 0 )
{
int nKids = dependencies.size();
node.setNChildren(nKids);
int kidNo = 0;
for ( ArtifactMetadata a : dependencies )
{
MetadataTreeNode kidNode = resolveMetadataTree( a
, node
, localRepository
, remoteRepositories
);
node.addChild( kidNo++, kidNode );
}
}
return node;
} else {
return new MetadataTreeNode( pomArtifact, parent, false, query.getArtifactScope() );
}
}
catch( Exception anyEx )
{
throw new MetadataResolutionException( anyEx );
}
}
//------------------------------------------------------------------------
public List<Artifact> resolveArtifact(
List<ArtifactMetadata> mdCollection
, ArtifactRepository localRepository
, List<ArtifactRepository> remoteRepositories
)
throws ArtifactResolutionException
{
if( mdCollection == null || mdCollection.isEmpty() )
return null;
ArrayList<Artifact> res = new ArrayList<Artifact>( mdCollection.size() );
Artifact artifact = null;
try {
// TODO: optimize retrieval by zipping returns from repo managers (nexus)
for( ArtifactMetadata md : mdCollection )
{
artifact = artifactFactory.createArtifact(
md.getGroupId()
, md.getArtifactId()
, md.getVersion()
, md.getScope()
, md.getType() == null ? "jar" : md.getType()
);
artifactResolver.resolve( artifact, remoteRepositories , localRepository );
res.add(artifact);
}
return res;
} catch (ArtifactNotFoundException e) {
e.printStackTrace();
throw new ArtifactResolutionException( e.getMessage()
, artifact
, remoteRepositories
);
}
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
}

View File

@ -0,0 +1,461 @@
package org.apache.maven.artifact.resolver.metadata;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.apache.maven.artifact.ArtifactScopeEnum;
/**
* maven dependency metadata graph
*
* @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
*
*/
public class MetadataGraph
{
public static int DEFAULT_VERTICES = 32;
public static int DEFAULT_EDGES = 64;
// flags to indicate the granularity of vertices
private boolean versionedVertices = false;
private boolean scopedVertices = false;
/**
* the entry point we started building the graph from
*/
MetadataGraphVertex entry;
// graph vertices
TreeSet< MetadataGraphVertex > vertices;
/**
* incident and excident edges per node
*/
Map<MetadataGraphVertex, List<MetadataGraphEdge>> incidentEdges;
Map<MetadataGraphVertex, List<MetadataGraphEdge>> excidentEdges;
/**
* null in dirty graph, actual
* scope for conflict-resolved graph
*/
ArtifactScopeEnum scope;
//------------------------------------------------------------------------
/**
* init graph
*/
public MetadataGraph( int nVertices )
{
init( nVertices, 2*nVertices );
}
public MetadataGraph( int nVertices, int nEdges )
{
init( nVertices, nEdges );
}
//------------------------------------------------------------------------
/**
* construct a single vertex
*/
public MetadataGraph( MetadataGraphVertex entry )
throws MetadataResolutionException
{
checkVertex(entry);
checkVertices(1);
entry.setCompareVersion( versionedVertices );
entry.setCompareScope( scopedVertices );
vertices.add( entry );
this.entry = entry;
}
//------------------------------------------------------------------------
/**
* construct graph from a "dirty" tree
*/
public MetadataGraph( MetadataTreeNode tree )
throws MetadataResolutionException
{
this( tree, false, false );
}
//------------------------------------------------------------------------
/**
* construct graph from a "dirty" tree
*
* @param tree "dirty" tree root
* @param versionedVertices true if graph nodes should be versioned (different versions -> different nodes)
* @param scopedVertices true if graph nodes should be versioned and scoped (different versions and/or scopes -> different nodes)
*
*/
public MetadataGraph( MetadataTreeNode tree, boolean versionedVertices, boolean scopedVertices )
throws MetadataResolutionException
{
if ( tree == null )
{
throw new MetadataResolutionException( "tree is null" );
}
setVersionedVertices(versionedVertices);
setScopedVertices(scopedVertices);
this.versionedVertices = scopedVertices || versionedVertices;
this.scopedVertices = scopedVertices;
int count = countNodes( tree );
init( count, count + ( count / 2 ) );
processTreeNodes( null, tree, 0, 0 );
}
//------------------------------------------------------------------------
private void processTreeNodes( MetadataGraphVertex parentVertex
, MetadataTreeNode node
, int depth
, int pomOrder
)
throws MetadataResolutionException
{
if ( node == null )
{
return;
}
MetadataGraphVertex vertex = new MetadataGraphVertex( node.md, versionedVertices, scopedVertices );
if( ! vertices.contains(vertex) )
{
vertices.add(vertex);
}
if( parentVertex != null ) // then create the edge
{
ArtifactMetadata md = node.getMd();
MetadataGraphEdge e = new MetadataGraphEdge( md.version, md.resolved, md.artifactScope, md.artifactUri, depth, pomOrder );
addEdge( parentVertex, vertex, e);
}
else
{
entry = vertex;
}
MetadataTreeNode[] kids = node.getChildren();
if ( kids == null || kids.length < 1 )
{
return;
}
for( int i = 0; i< kids.length; i++ )
{
MetadataTreeNode n = kids[i];
processTreeNodes( vertex, n, depth + 1, i );
}
}
//------------------------------------------------------------------------
public MetadataGraphVertex findVertex( ArtifactMetadata md )
{
if( md == null || vertices == null || vertices.size() < 1 )
return null;
MetadataGraphVertex v = new MetadataGraphVertex(md);
v.setCompareVersion(versionedVertices);
v.setCompareScope(scopedVertices);
for( MetadataGraphVertex gv : vertices )
{
if( gv.equals(v) )
return gv;
}
return null;
}
//------------------------------------------------------------------------
public MetadataGraphVertex addVertex( ArtifactMetadata md )
{
if( md == null )
return null;
checkVertices();
MetadataGraphVertex v = findVertex(md);
if( v != null)
return v;
v = new MetadataGraphVertex(md);
v.setCompareVersion(versionedVertices);
v.setCompareScope(scopedVertices);
vertices.add( v );
return v;
}
//------------------------------------------------------------------------
/**
* init graph
*/
private void init( int nVertices, int nEdges )
{
int nV = nVertices;
if( nVertices < 1 )
nV = 1;
checkVertices(nV);
int nE = nVertices;
if( nEdges <= nV )
nE = 2*nE;
checkEdges(nE);
}
private void checkVertices()
{
checkVertices(DEFAULT_VERTICES);
}
private void checkVertices( int nVertices )
{
if( vertices == null )
vertices = new TreeSet<MetadataGraphVertex>();
}
private void checkEdges()
{
int count = DEFAULT_EDGES;
if( vertices != null )
count = vertices.size() + vertices.size() / 2;
checkEdges( count );
}
private void checkEdges( int nEdges )
{
if( incidentEdges == null )
incidentEdges = new HashMap<MetadataGraphVertex, List<MetadataGraphEdge>>( nEdges );
if( excidentEdges == null )
excidentEdges = new HashMap<MetadataGraphVertex, List<MetadataGraphEdge>>( nEdges );
}
//------------------------------------------------------------------------
private static void checkVertex( MetadataGraphVertex v )
throws MetadataResolutionException
{
if( v == null )
throw new MetadataResolutionException( "null vertex" );
if( v.getMd() == null )
throw new MetadataResolutionException( "vertex without metadata" );
}
//------------------------------------------------------------------------
private static void checkEdge( MetadataGraphEdge e )
throws MetadataResolutionException
{
if( e == null )
throw new MetadataResolutionException( "badly formed edge" );
}
//------------------------------------------------------------------------
public List<MetadataGraphEdge> getEdgesBetween(
MetadataGraphVertex vFrom
, MetadataGraphVertex vTo
)
{
List<MetadataGraphEdge> edges = getIncidentEdges(vTo);
if( edges == null || edges.isEmpty() )
return null;
List<MetadataGraphEdge> res = new ArrayList<MetadataGraphEdge>( edges.size() );
for( MetadataGraphEdge e : edges )
{
if( e.getSource().equals(vFrom) )
res.add(e);
}
return res;
}
//------------------------------------------------------------------------
public MetadataGraph addEdge( MetadataGraphVertex vFrom
, MetadataGraphVertex vTo
, MetadataGraphEdge e
)
throws MetadataResolutionException
{
checkVertex(vFrom);
checkVertex(vTo);
checkVertices();
checkEdge(e);
checkEdges();
e.setSource(vFrom);
e.setTarget(vTo);
vFrom.setCompareVersion(versionedVertices);
vFrom.setCompareScope(scopedVertices);
List<MetadataGraphEdge> exList = excidentEdges.get(vFrom);
if( exList == null ) {
exList = new ArrayList<MetadataGraphEdge>();
excidentEdges.put( vFrom, exList );
}
if( !exList.contains(e) )
exList.add(e);
List<MetadataGraphEdge> inList = incidentEdges.get(vTo);
if( inList == null ) {
inList = new ArrayList<MetadataGraphEdge>();
incidentEdges.put( vTo, inList );
}
if( !inList.contains(e) )
inList.add(e);
return this;
}
//------------------------------------------------------------------------
public MetadataGraph removeVertex( MetadataGraphVertex v )
{
if( vertices!= null && v != null )
vertices.remove(v);
if( incidentEdges!= null )
incidentEdges.remove(v);
if( excidentEdges!= null )
excidentEdges.remove(v);
return this;
}
//------------------------------------------------------------------------
private static int countNodes( MetadataTreeNode tree )
{
if ( tree == null )
{
return 0;
}
int count = 1;
MetadataTreeNode[] kids = tree.getChildren();
if ( kids == null || kids.length < 1 )
{
return count;
}
for ( MetadataTreeNode n : kids )
{
count += countNodes( n );
}
return count;
}
//------------------------------------------------------------------------
public MetadataGraphVertex getEntry()
{
return entry;
}
public void setEntry( MetadataGraphVertex entry )
{
this.entry = entry;
}
public TreeSet<MetadataGraphVertex> getVertices()
{
return vertices;
}
public List<MetadataGraphEdge> getIncidentEdges( MetadataGraphVertex vertex )
{
checkEdges();
return incidentEdges.get(vertex);
}
public List<MetadataGraphEdge> getExcidentEdges( MetadataGraphVertex vertex )
{
checkEdges();
return excidentEdges.get(vertex);
}
public boolean isVersionedVertices()
{
return versionedVertices;
}
public void setVersionedVertices(boolean versionedVertices)
{
this.versionedVertices = versionedVertices;
}
public boolean isScopedVertices()
{
return scopedVertices;
}
public void setScopedVertices(boolean scopedVertices)
{
this.scopedVertices = scopedVertices;
// scoped graph is versioned by definition
if( scopedVertices )
versionedVertices = true;
}
public ArtifactScopeEnum getScope()
{
return scope;
}
public void setScope(ArtifactScopeEnum scope)
{
this.scope = scope;
}
//------------------------------------------------------------------------
public boolean isEmpty()
{
return
entry == null
|| vertices == null
|| vertices.isEmpty()
;
}
//------------------------------------------------------------------------
public boolean isEmptyEdges()
{
return
isEmpty()
|| incidentEdges == null
|| incidentEdges.isEmpty()
;
}
//------------------------------------------------------------------------
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(512);
if( isEmpty() )
return "empty";
for( MetadataGraphVertex v : vertices )
{
sb.append("Vertex: "+v.getMd().toString()+ "\n");
List<MetadataGraphEdge> ins = getIncidentEdges(v);
if( ins != null )
for( MetadataGraphEdge e : ins )
{
sb.append(" from : "+e.toString()+"\n");
}
else
sb.append(" no entries\n");
List<MetadataGraphEdge> outs = getExcidentEdges(v);
if( outs != null )
for( MetadataGraphEdge e : outs )
{
sb.append(" to : "+e.toString()+ "\n");
}
else
sb.append(" no exit\n");
sb.append("-------------------------------------------------\n");
}
sb.append("=============================================================\n");
return sb.toString();
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
}

Some files were not shown because too many files have changed in this diff Show More