diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java index 68330d3d23..2820fb0f66 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java @@ -17,6 +17,7 @@ package org.apache.maven.artifact; */ import org.apache.maven.artifact.metadata.ArtifactMetadata; +import org.apache.maven.artifact.repository.ArtifactRepository; import java.io.File; import java.util.List; @@ -68,4 +69,8 @@ public interface Artifact void addMetadata( ArtifactMetadata metadata ); List getMetadataList(); + + void setRepository( ArtifactRepository remoteRepository ); + + ArtifactRepository getRepository(); } \ No newline at end of file diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java index 70684b0236..e76fcaabc5 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java @@ -17,6 +17,7 @@ package org.apache.maven.artifact; */ import org.apache.maven.artifact.metadata.ArtifactMetadata; +import org.apache.maven.artifact.repository.ArtifactRepository; import org.codehaus.plexus.util.StringUtils; import java.io.File; @@ -48,6 +49,8 @@ public class DefaultArtifact private File file; + private ArtifactRepository repository; + /** * !!! WARNING !!! Never put in the POM. It is for mojo use * only. Classifier is for specifying derived artifacts, like ejb-client. @@ -133,6 +136,16 @@ public class DefaultArtifact return file; } + public ArtifactRepository getRepository() + { + return repository; + } + + public void setRepository( ArtifactRepository repository ) + { + this.repository = repository; + } + // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- @@ -172,13 +185,49 @@ public class DefaultArtifact public int hashCode() { - return getId().hashCode(); + int result = 17; + result = 37 * result + groupId.hashCode(); + result = 37 * result + artifactId.hashCode(); + result = 37 * result + type.hashCode(); + result = 37 * result + version.hashCode(); + result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 ); + return result; } public boolean equals( Object o ) { - Artifact other = (Artifact) o; + if ( o == this ) + { + return true; + } - return getId().equals( other.getId() ); + 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 ( classifier == null ? a.getClassifier() != null : !a.getClassifier().equals( classifier ) ) + { + return false; + } + return true; } } \ No newline at end of file diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java index 22a8ec30a0..1c33fdc432 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java @@ -168,7 +168,7 @@ public class DefaultWagonManager } public void getArtifact( Artifact artifact, List remoteRepositories, File destination ) - throws TransferFailedException + throws TransferFailedException, ResourceDoesNotExistException { // TODO [BP]: The exception handling here needs some work boolean successful = false; @@ -176,20 +176,9 @@ public class DefaultWagonManager { ArtifactRepository repository = (ArtifactRepository) iter.next(); - String remotePath = null; try { - remotePath = repository.pathOf( artifact ); - } - catch ( ArtifactPathFormatException e ) - { - // TODO may be more appropriate to propogate the APFE - throw new TransferFailedException( "Failed to determine path for artifact", e ); - } - - try - { - getRemoteFile( repository, destination, remotePath ); + getArtifact( artifact, repository, destination ); successful = true; } @@ -204,10 +193,27 @@ public class DefaultWagonManager if ( !successful ) { - throw new TransferFailedException( "Unable to download the artifact from any repository" ); + throw new ResourceDoesNotExistException( "Unable to download the artifact from any repository" ); } } + public void getArtifact( Artifact artifact, ArtifactRepository repository, File destination ) + throws TransferFailedException, ResourceDoesNotExistException + { + String remotePath = null; + try + { + remotePath = repository.pathOf( artifact ); + } + catch ( ArtifactPathFormatException e ) + { + // TODO may be more appropriate to propogate the APFE + throw new TransferFailedException( "Failed to determine path for artifact", e ); + } + + getRemoteFile( repository, destination, remotePath ); + } + public void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository remoteRepository, File destination ) throws TransferFailedException, ResourceDoesNotExistException { diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/WagonManager.java b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/WagonManager.java index f637bd360d..25118b92e2 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/WagonManager.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/WagonManager.java @@ -40,7 +40,10 @@ public interface WagonManager throws UnsupportedProtocolException; void getArtifact( Artifact artifact, List remoteRepositories, File destination ) - throws TransferFailedException; + throws TransferFailedException, ResourceDoesNotExistException; + + public void getArtifact( Artifact artifact, ArtifactRepository repository, File destination ) + throws TransferFailedException, ResourceDoesNotExistException; void putArtifact( File source, Artifact artifact, ArtifactRepository deploymentRepository ) throws TransferFailedException; diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/SnapshotArtifactMetadata.java b/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/SnapshotArtifactMetadata.java index b362468e5c..e974951f2b 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/SnapshotArtifactMetadata.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/SnapshotArtifactMetadata.java @@ -40,6 +40,7 @@ import java.util.TimeZone; */ public class SnapshotArtifactMetadata extends AbstractArtifactMetadata + implements Comparable { private String timestamp = null; @@ -58,6 +59,19 @@ public class SnapshotArtifactMetadata super( artifact, filename ); } + public static SnapshotArtifactMetadata readLocalSnapshotMetadata( Artifact artifact, + ArtifactRepository localRepository ) + throws ArtifactPathFormatException, IOException + { + SnapshotArtifactMetadata metadata = new SnapshotArtifactMetadata( artifact, SNAPSHOT_VERSION_LOCAL_FILE ); + File f = metadata.getLocalRepositoryLocation( localRepository ); + if ( f.exists() ) + { + metadata.readFromFile( f ); + } + return metadata; + } + public static SnapshotArtifactMetadata createLocalSnapshotMetadata( Artifact artifact ) { return new SnapshotArtifactMetadata( artifact, SNAPSHOT_VERSION_LOCAL_FILE ); @@ -77,7 +91,7 @@ public class SnapshotArtifactMetadata { timestamp = getUtcDateFormatter().format( new Date() ); } - String path = new File( localRepository.getBasedir(), localRepository.pathOfMetadata( this ) ).getPath(); + String path = getLocalRepositoryLocation( localRepository ).getPath(); FileUtils.fileWrite( path, getVersion() ); } catch ( IOException e ) @@ -90,6 +104,12 @@ public class SnapshotArtifactMetadata } } + private File getLocalRepositoryLocation( ArtifactRepository localRepository ) + throws ArtifactPathFormatException + { + return new File( localRepository.getBasedir(), localRepository.pathOfMetadata( this ) ); + } + public String getVersion() { String version = artifact.getVersion(); @@ -122,17 +142,7 @@ public class SnapshotArtifactMetadata return; } - String version = FileUtils.fileRead( destination ); - - int index = version.lastIndexOf( "-" ); - timestamp = version.substring( 0, index ); - buildNumber = Integer.valueOf( version.substring( index + 1 ) ).intValue(); - index = version.indexOf( "-" ); - if ( index >= 0 ) - { - // ignore starting version part, will be prepended later - timestamp = timestamp.substring( index + 1 ); - } + readFromFile( destination ); } catch ( TransferFailedException e ) { @@ -144,6 +154,22 @@ public class SnapshotArtifactMetadata } } + private void readFromFile( File destination ) + throws IOException + { + String version = FileUtils.fileRead( destination ); + + int index = version.lastIndexOf( "-" ); + timestamp = version.substring( 0, index ); + buildNumber = Integer.valueOf( version.substring( index + 1 ) ).intValue(); + index = version.indexOf( "-" ); + if ( index >= 0 ) + { + // ignore starting version part, will be prepended later + timestamp = timestamp.substring( index + 1 ); + } + } + public String getTimestamp() { return timestamp; @@ -161,4 +187,23 @@ public class SnapshotArtifactMetadata this.buildNumber++; timestamp = getUtcDateFormatter().format( new Date() ); } + + + public int compareTo( Object o ) + { + SnapshotArtifactMetadata metadata = (SnapshotArtifactMetadata) o; + + if ( buildNumber > metadata.buildNumber ) + { + return 1; + } + else if ( timestamp == null ) + { + return -1; + } + else + { + return timestamp.compareTo( metadata.timestamp ); + } + } } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java index 3d249c5e0f..4d519589c3 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java @@ -20,12 +20,14 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.construction.ArtifactConstructionSupport; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.manager.WagonManager; +import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.transform.ArtifactTransformation; +import org.apache.maven.wagon.ResourceDoesNotExistException; import org.apache.maven.wagon.TransferFailedException; import org.codehaus.plexus.logging.AbstractLogEnabled; import org.codehaus.plexus.logging.Logger; @@ -81,7 +83,14 @@ public class DefaultArtifactResolver for ( Iterator i = artifactTransformations.iterator(); i.hasNext(); ) { ArtifactTransformation transform = (ArtifactTransformation) i.next(); - artifact = transform.transformForResolve( artifact ); + try + { + artifact = transform.transformForResolve( artifact, remoteRepositories, localRepository ); + } + catch ( ArtifactMetadataRetrievalException e ) + { + throw new ArtifactResolutionException( "Unable to transform artifact", e ); + } } String localPath; @@ -105,11 +114,34 @@ public class DefaultArtifactResolver try { - wagonManager.getArtifact( artifact, remoteRepositories, destination ); + if ( artifact.getRepository() != null ) + { + // the transformations discovered the artifact - so use it exclusively + wagonManager.getArtifact( artifact, artifact.getRepository(), destination ); + } + else + { + wagonManager.getArtifact( artifact, remoteRepositories, destination ); + } + + // must be after the artifact is downloaded + for ( Iterator i = artifact.getMetadataList().iterator(); i.hasNext(); ) + { + ArtifactMetadata metadata = (ArtifactMetadata) i.next(); + metadata.storeInLocalRepository( localRepository ); + } + } + catch ( ResourceDoesNotExistException e ) + { + throw new ArtifactResolutionException( artifactNotFound( localPath, remoteRepositories ), e ); } catch ( TransferFailedException e ) { - throw new ArtifactResolutionException( artifactNotFound( localPath, remoteRepositories ), e ); + throw new ArtifactResolutionException( "Error downloading artifact " + artifact, e ); + } + catch ( ArtifactMetadataRetrievalException e ) + { + throw new ArtifactResolutionException( "Error downloading artifact " + artifact, e ); } return artifact; diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/transform/ArtifactTransformation.java b/maven-artifact/src/main/java/org/apache/maven/artifact/transform/ArtifactTransformation.java index 75ecfe792f..f74ead2a31 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/transform/ArtifactTransformation.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/transform/ArtifactTransformation.java @@ -20,6 +20,8 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.repository.ArtifactRepository; +import java.util.List; + /** * @author Jason van Zyl * @version $Id: ArtifactTransformation.java,v 1.1 2005/03/03 15:37:25 @@ -33,10 +35,14 @@ public interface ArtifactTransformation * Take in a artifact and return the transformed artifact for locating in the remote repository. If no * transformation has occured the original artifact is returned. * - * @param artifact Artifact to be transformed. + * @param artifact Artifact to be transformed. + * @param remoteRepositories the repositories to check + * @param localRepository the local repository * @return The transformed Artifact */ - Artifact transformForResolve( Artifact artifact ); + public Artifact transformForResolve( Artifact artifact, List remoteRepositories, + ArtifactRepository localRepository ) + throws ArtifactMetadataRetrievalException; /** * Take in a artifact and return the transformed artifact for locating in the local repository. If no diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/transform/SnapshotTransformation.java b/maven-artifact/src/main/java/org/apache/maven/artifact/transform/SnapshotTransformation.java index b221283f35..9074524c7b 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/transform/SnapshotTransformation.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/transform/SnapshotTransformation.java @@ -24,8 +24,10 @@ import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.SnapshotArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; /** * @author Brett Porter @@ -38,165 +40,74 @@ public class SnapshotTransformation { private WagonManager wagonManager; -/* TODO: use and remove - public Artifact transform( Artifact artifact, ArtifactRepository localRepository, List repositories, - Map parameters ) - throws Exception + /** + * @todo very primitve. Probably we can resolvedArtifactCache artifacts themselves in a central location, as well as reset the flag over time in a long running process. + */ + private static Set resolvedArtifactCache = new HashSet(); + + public Artifact transformForResolve( Artifact artifact, List remoteRepositories, + ArtifactRepository localRepository ) + throws ArtifactMetadataRetrievalException { - Date localVersion = getLocalVersion( artifact, localRepository ); - - Date remoteVersion = getRemoteVersion( artifact, repositories, localRepository ); - - if ( remoteVersion != null ) + if ( isSnapshot( artifact ) && !alreadyResolved( artifact ) ) { - //if local version is unknown (null) it means that - //we don't have this file locally. so we will be happy - // to have any snapshot. - // we wil download in two cases: - // a) we don't have any snapot in local repo - // b) we have found newer version in remote repository - if ( localVersion == null || localVersion.before( remoteVersion ) ) + // TODO: this mostly works, however... + // - poms and jars are different, so both are checked individually + // - when a pom is downloaded, it prevents the JAR getting downloaded because of the timestamp + // - need to gather first, group them all up by groupId/artifactId, then go after them +/* + SnapshotArtifactMetadata localMetadata; + try { - // here we know that we have artifact like foo-1.2-SNAPSHOT.jar - // and the remote timestamp is something like 20010304.121212 - // so we might as well fetch foo-1.2-20010304.121212.jar - // but we are just going to fetch foo-1.2-SNAPSHOT.jar. - // We can change the strategy which is used here later on + localMetadata = SnapshotArtifactMetadata.readLocalSnapshotMetadata( artifact, localRepository ); + } + catch ( ArtifactPathFormatException e ) + { + throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e ); + } + catch ( IOException e ) + { + throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e ); + } - // @todo we will delete old file first. - //it is not really a right thing to do. Artifact Dowloader - // should - // fetch to temprary file and replace the old file with the new - // one once download was finished + boolean foundRemote = false; + for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); ) + { + ArtifactRepository remoteRepository = (ArtifactRepository) i.next(); - artifact.getFile().delete(); + SnapshotArtifactMetadata remoteMetadata = SnapshotArtifactMetadata.createRemoteSnapshotMetadata( + artifact ); + remoteMetadata.retrieveFromRemoteRepository( remoteRepository, wagonManager ); - artifactResolver.resolve( artifact, repositories, localRepository ); - - File snapshotVersionFile = getSnapshotVersionFile( artifact, localRepository ); - - String timestamp = getTimestamp( remoteVersion ); - - // delete old one - if ( snapshotVersionFile.exists() ) + if ( remoteMetadata.compareTo( localMetadata ) > 0 ) { - snapshotVersionFile.delete(); + // TODO: investigate transforming this in place, in which case resolve can return void + artifact = createArtifactCopy( artifact, remoteMetadata ); + artifact.setRepository( remoteRepository ); + + localMetadata = remoteMetadata; + foundRemote = true; } - - FileUtils.fileWrite( snapshotVersionFile.getPath(), timestamp ); } - } + if ( foundRemote ) + { + artifact.addMetadata( localMetadata ); + } +*/ + resolvedArtifactCache.add( getCacheKey( artifact ) ); + } return artifact; } - private File getSnapshotVersionFile( Artifact artifact, ArtifactRepository localRepository ) + private boolean alreadyResolved( Artifact artifact ) { - return null; - //return new File( localRepository.fullArtifactPath( artifact ) ); + return resolvedArtifactCache.contains( getCacheKey( artifact ) ); } - private Date getRemoteVersion( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) - throws Exception + private static String getCacheKey( Artifact artifact ) { - Date retValue = null; - - artifactResolver.resolve( artifact, remoteRepositories, localRepository ); - - String timestamp = FileUtils.fileRead( artifact.getPath() ); - - retValue = parseTimestamp( timestamp ); - - return retValue; - } - - private Date getLocalVersion( Artifact artifact, ArtifactRepository localRepository ) - { - //assert artifact.exists(); - - Date retValue = null; - - try - { - File file = getSnapshotVersionFile( artifact, localRepository ); - - if ( file.exists() ) - { - String timestamp = FileUtils.fileRead( file ); - - retValue = parseTimestamp( timestamp ); - - } - } - catch ( Exception e ) - { - // ignore - } - - if ( retValue == null ) - { - //try "traditional method" used in maven1 for obtaining snapshot - // version - - File file = artifact.getFile(); - - if ( file.exists() ) - { - retValue = new Date( file.lastModified() ); - - //@todo we should "normalize" the time. - - // - // TimeZone gmtTimeZone = TimeZone.getTimeZone( "GMT" ); - // TimeZone userTimeZone = TimeZone.getDefault(); long diff = - // - } - } - - return retValue; - } - - private final static String DATE_FORMAT = "yyyyMMdd.HHmmss"; - - private static SimpleDateFormat getFormatter() - { - SimpleDateFormat formatter = new SimpleDateFormat( DATE_FORMAT ); - - formatter.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); - - return formatter; - } - - public static String getTimestamp() - { - Date now = new Date(); - - SimpleDateFormat formatter = getFormatter(); - - String retValue = formatter.format( now ); - - return retValue; - } - - public static Date parseTimestamp( String timestamp ) - throws ParseException - { - Date retValue = getFormatter().parse( timestamp ); - - return retValue; - } - - public static String getTimestamp( Date snapshotVersion ) - { - String retValue = getFormatter().format( snapshotVersion ); - - return retValue; - } - */ - public Artifact transformForResolve( Artifact artifact ) - { - // TODO: implement - return artifact; + return artifact.getConflictId(); } public Artifact transformForInstall( Artifact artifact, ArtifactRepository localRepository ) @@ -221,20 +132,26 @@ public class SnapshotTransformation // TODO: note, we could currently transform this in place, as it is only used through the deploy mojo, // which creates the artifact and then disposes of it - List list = artifact.getMetadataList(); - artifact = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), metadata.getVersion(), - artifact.getScope(), artifact.getType(), artifact.getClassifier() ); - for ( Iterator i = list.iterator(); i.hasNext(); ) - { - ArtifactMetadata m = (ArtifactMetadata) i.next(); - m.setArtifact( artifact ); - artifact.addMetadata( m ); - } + artifact = createArtifactCopy( artifact, metadata ); artifact.addMetadata( metadata ); } return artifact; } + private Artifact createArtifactCopy( Artifact artifact, SnapshotArtifactMetadata metadata ) + { + List list = artifact.getMetadataList(); + artifact = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), metadata.getVersion(), + artifact.getScope(), artifact.getType(), artifact.getClassifier() ); + for ( Iterator i = list.iterator(); i.hasNext(); ) + { + ArtifactMetadata m = (ArtifactMetadata) i.next(); + m.setArtifact( artifact ); + artifact.addMetadata( m ); + } + return artifact; + } + private static boolean isSnapshot( Artifact artifact ) { return artifact.getVersion().endsWith( "SNAPSHOT" ); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java index 3c531bc2bb..1b206cd975 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java @@ -159,10 +159,10 @@ public class DefaultPluginManager MojoDescriptor mojoDescriptor = mavenMojoDescriptor.getMojoDescriptor(); mojoDescriptors.put( mojoDescriptor.getId(), mojoDescriptor ); - - String key = constructPluginKey( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId() ); - pluginDescriptors.put( key, pluginDescriptor ); } + + String key = constructPluginKey( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId() ); + pluginDescriptors.put( key, pluginDescriptor ); } // ---------------------------------------------------------------------- @@ -267,9 +267,8 @@ public class DefaultPluginManager artifactFactory = (ArtifactFactory) container.lookup( ArtifactFactory.ROLE ); - Artifact pluginArtifact = artifactFactory.createArtifact( AbstractPlugin.getDefaultPluginGroupId(), - artifactId, version, null, MAVEN_PLUGIN, - null ); + Artifact pluginArtifact = artifactFactory.createArtifact( groupId, artifactId, version, null, + MAVEN_PLUGIN, null ); addPlugin( pluginArtifact, session ); }