PR: MNG-192

Add "RELEASE" notation so that plugins without a version can be discovered

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@169303 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-05-09 12:30:10 +00:00
parent 26622164f4
commit 05affa0a65
20 changed files with 713 additions and 330 deletions

View File

@ -17,7 +17,9 @@ package org.apache.maven.artifact;
*/
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import java.io.File;
import java.util.List;
@ -85,4 +87,7 @@ public interface Artifact
void setRepository( ArtifactRepository remoteRepository );
ArtifactRepository getRepository();
void updateVersion( String version, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException;
}

View File

@ -17,7 +17,9 @@ package org.apache.maven.artifact;
*/
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
@ -294,4 +296,18 @@ public class DefaultArtifact
}
return result;
}
public void updateVersion( String version, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
setVersion( version );
try
{
setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
}
}

View File

@ -42,13 +42,28 @@ public abstract class AbstractArtifactMetadata
this.artifact = artifact;
}
public Artifact getArtifact()
{
return artifact;
}
public String getFilename()
{
return filename;
}
public String getGroupId()
{
return artifact.getGroupId();
}
public String getArtifactId()
{
return artifact.getArtifactId();
}
public String getVersion()
{
return artifact.getVersion();
}
public String getBaseVersion()
{
return artifact.getBaseVersion();
}
}

View File

@ -0,0 +1,131 @@
package org.apache.maven.artifact.metadata;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.Date;
/**
* Base version artifact metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public abstract class AbstractVersionArtifactMetadata
extends AbstractArtifactMetadata
implements VersionArtifactMetadata
{
protected static final String SNAPSHOT_VERSION_FILE = "version.txt";
protected long lastModified = 0;
public AbstractVersionArtifactMetadata( Artifact artifact, String filename )
{
super( artifact, filename );
}
protected File getLocalRepositoryLocation( ArtifactRepository localRepository )
throws ArtifactPathFormatException
{
return new File( localRepository.getBasedir(), localRepository.pathOfMetadata( this ) );
}
private void readFromFile( File file )
throws IOException
{
setContent( FileUtils.fileRead( file ) );
lastModified = file.lastModified();
}
protected abstract void setContent( String content );
// TODO: share
public boolean checkedSinceDate( Date date )
{
// Note that if last modified is 0, it didn't exist, so this will be true
return !date.after( new Date( lastModified ) );
}
public boolean exists()
{
return lastModified > 0;
}
public void readFromLocalRepository( ArtifactRepository localRepository )
throws ArtifactPathFormatException, IOException
{
File f = getLocalRepositoryLocation( localRepository );
if ( f.exists() )
{
readFromFile( f );
}
}
public void retrieveFromRemoteRepository( ArtifactRepository remoteRepository, WagonManager wagonManager )
throws ArtifactMetadataRetrievalException, ResourceDoesNotExistException
{
try
{
// TODO: shouldn't need a file intermediatary - improve wagon to take a stream
File destination = File.createTempFile( "maven-artifact", null );
destination.deleteOnExit();
wagonManager.getArtifactMetadata( this, remoteRepository, destination );
readFromFile( destination );
}
catch ( TransferFailedException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
}
public void storeInLocalRepository( ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
try
{
String path = getLocalRepositoryLocation( localRepository ).getPath();
File file = new File( path );
// TODO: this should be centralised before the resolution of the artifact
file.getParentFile().mkdirs();
FileUtils.fileWrite( path, constructVersion() );
lastModified = file.lastModified();
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
}
}

View File

@ -19,6 +19,9 @@ package org.apache.maven.artifact.metadata;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import java.io.File;
import java.util.Date;
/**
* Contains metadata about an artifact, and methods to retrieve/store it from an artifact repository.
*
@ -38,13 +41,6 @@ public interface ArtifactMetadata
void storeInLocalRepository( ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException;
/**
* Get the associated artifact.
*
* @return the artifact
*/
Artifact getArtifact();
/**
* Get the filename of this metadata.
*
@ -52,7 +48,6 @@ public interface ArtifactMetadata
*/
String getFilename();
/**
* Set the associated artifact.
*
@ -60,4 +55,18 @@ public interface ArtifactMetadata
* @todo prefer not to have this, and just modify the artifacts as they are transformed
*/
void setArtifact( Artifact artifact );
/**
* Whether the artifact metadata exists.
* @return true or false
*/
boolean exists();
String getGroupId();
String getArtifactId();
String getVersion();
String getBaseVersion();
}

View File

@ -0,0 +1,92 @@
package org.apache.maven.artifact.metadata;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.transform.ReleaseArtifactTransformation;
import java.io.File;
/**
* Contains the information stored for a release.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ReleaseArtifactMetadata
extends AbstractVersionArtifactMetadata
implements Comparable
{
private String version;
public ReleaseArtifactMetadata( Artifact artifact )
{
super( artifact, artifact.getArtifactId() + "-RELEASE." + SNAPSHOT_VERSION_FILE );
}
public String constructVersion()
{
return version;
}
public int compareTo( Object o )
{
ReleaseArtifactMetadata metadata = (ReleaseArtifactMetadata) o;
if ( version == null )
{
if ( metadata.version == null )
{
return 0;
}
else
{
return -1;
}
}
// TODO: we need some more complicated version comparison
return version.compareTo( metadata.version );
}
public boolean newerThanFile( File file )
{
long fileTime = file.lastModified();
return ( lastModified > fileTime );
}
public String toString()
{
return "release information for " + artifact.getArtifactId();
}
protected void setContent( String content )
{
this.version = content.trim();
}
public void setVersion( String version )
{
this.version = version;
}
public String getBaseVersion()
{
return ReleaseArtifactTransformation.RELEASE_VERSION;
}
}

View File

@ -16,17 +16,10 @@ package org.apache.maven.artifact.metadata;
* limitations under the License.
*/
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;
import org.apache.maven.artifact.Artifact;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -41,21 +34,16 @@ import java.util.regex.Pattern;
* @version $Id$
*/
public class SnapshotArtifactMetadata
extends AbstractArtifactMetadata
implements Comparable
extends AbstractVersionArtifactMetadata
{
private String timestamp = null;
private int buildNumber = 0;
private static final String SNAPSHOT_VERSION_FILE = "version.txt";
private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
private static final String UTC_TIMESTAMP_PATTERN = "yyyyMMdd.HHmmss";
private long lastModified = 0;
public static final Pattern VERSION_FILE_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}.[0-9]{6})-([0-9]+)$" );
// TODO: very quick and nasty hack to get the same timestamp across a build - not embedder friendly
@ -66,51 +54,6 @@ public class SnapshotArtifactMetadata
super( artifact, artifact.getArtifactId() + "-" + artifact.getBaseVersion() + "." + SNAPSHOT_VERSION_FILE );
}
public static SnapshotArtifactMetadata readFromLocalRepository( Artifact artifact,
ArtifactRepository localRepository )
throws ArtifactPathFormatException, IOException
{
SnapshotArtifactMetadata metadata = new SnapshotArtifactMetadata( artifact );
File f = metadata.getLocalRepositoryLocation( localRepository );
if ( f.exists() )
{
metadata.readFromFile( f );
}
return metadata;
}
public void storeInLocalRepository( ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
try
{
if ( timestamp == null )
{
timestamp = getSessionTimestamp();
}
String path = getLocalRepositoryLocation( localRepository ).getPath();
File file = new File( path );
// TODO: this should be centralised before the resolution of the artifact
file.getParentFile().mkdirs();
FileUtils.fileWrite( path, constructVersion() );
lastModified = file.lastModified();
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
}
private File getLocalRepositoryLocation( ArtifactRepository localRepository )
throws ArtifactPathFormatException
{
return new File( localRepository.getBasedir(), localRepository.pathOfMetadata( this ) );
}
public String constructVersion()
{
String version = artifact.getBaseVersion();
@ -129,53 +72,9 @@ public class SnapshotArtifactMetadata
return version;
}
/**
* Retrieve the metadata from the remote repository into the local repository.
*
* @param remoteRepository the remote repository
* @param wagonManager the wagon manager to use to retrieve the metadata
*/
public static SnapshotArtifactMetadata retrieveFromRemoteRepository( Artifact artifact,
ArtifactRepository remoteRepository,
WagonManager wagonManager )
throws ArtifactMetadataRetrievalException
protected void setContent( String content )
{
SnapshotArtifactMetadata snapshotMetadata = new SnapshotArtifactMetadata( artifact );
try
{
// TODO: shouldn't need a file intermediatary - improve wagon to take a stream
File destination = File.createTempFile( "maven-artifact", null );
destination.deleteOnExit();
wagonManager.getArtifactMetadata( snapshotMetadata, remoteRepository, destination );
snapshotMetadata.readFromFile( destination );
}
catch ( ResourceDoesNotExistException e )
{
// No problem...
// this just means that there is no snapshot version file, so we keep timestamp = null, build = 0
}
catch ( TransferFailedException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Unable to retrieve metadata", e );
}
return snapshotMetadata;
}
private void readFromFile( File file )
throws IOException
{
String version = FileUtils.fileRead( file );
lastModified = file.lastModified();
Matcher matcher = VERSION_FILE_PATTERN.matcher( version );
Matcher matcher = VERSION_FILE_PATTERN.matcher( content );
if ( matcher.matches() )
{
timestamp = matcher.group( 2 );
@ -237,11 +136,6 @@ public class SnapshotArtifactMetadata
}
}
public long getLastModified()
{
return lastModified;
}
public boolean newerThanFile( File file )
{
long fileTime = file.lastModified();

View File

@ -0,0 +1,48 @@
package org.apache.maven.artifact.metadata;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.util.Date;
/**
* Contains metadata about a versioned artifact.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface VersionArtifactMetadata
extends ArtifactMetadata, Comparable
{
/**
* Determine if the metadata is considered newer than a given date.
* @return whether it is newer
*/
boolean checkedSinceDate( Date date );
/**
* Determine if the metadata is considered newer than a given file.
* @return whether it is newer
*/
boolean newerThanFile( File file );
/**
* Get the resolved version from the metadata.
* @return the resolved version
*/
String constructVersion();
}

View File

@ -21,6 +21,7 @@ import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerNotFoundException;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.transform.ReleaseArtifactTransformation;
/**
* @author jdcasey
@ -72,15 +73,16 @@ public class DefaultRepositoryLayout
public String pathOfMetadata( ArtifactMetadata metadata )
throws ArtifactPathFormatException
{
Artifact artifact = metadata.getArtifact();
StringBuffer path = new StringBuffer();
path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
// if ( !artifact.getType().equals( "pom" ) )
// {
path.append( artifact.getArtifactId() ).append( '/' );
path.append( artifact.getBaseVersion() ).append( '/' );
path.append( metadata.getArtifactId() ).append( '/' );
if ( !metadata.getBaseVersion().equals( ReleaseArtifactTransformation.RELEASE_VERSION ) )
{
path.append( metadata.getBaseVersion() ).append( '/' );
}
// }
path.append( metadata.getFilename() );

View File

@ -68,11 +68,9 @@ public class LegacyRepositoryLayout
public String pathOfMetadata( ArtifactMetadata metadata )
throws ArtifactPathFormatException
{
Artifact artifact = metadata.getArtifact();
StringBuffer path = new StringBuffer();
path.append( artifact.getGroupId() ).append( "/poms/" );
path.append( metadata.getGroupId() ).append( "/poms/" );
path.append( metadata.getFilename() );
return path.toString();

View File

@ -85,7 +85,7 @@ public class DefaultArtifactResolver
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactResolutionException( "Error resolving artifact: ", e );
throw new ArtifactResolutionException( e.getMessage(), e );
}
artifact.setFile( new File( localRepository.getBasedir(), localPath ) );
@ -100,7 +100,7 @@ public class DefaultArtifactResolver
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new ArtifactResolutionException( "Unable to transform artifact", e );
throw new ArtifactResolutionException( e.getMessage(), e );
}
}

View File

@ -0,0 +1,201 @@
package org.apache.maven.artifact.transform;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.VersionArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Describes a version transformation during artifact resolution.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public abstract class AbstractVersionTransformation
extends AbstractLogEnabled
implements ArtifactTransformation
{
protected WagonManager wagonManager;
/**
* @todo very primitve. Probably we can cache 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();
protected String resolveVersion( Artifact artifact, ArtifactRepository localRepository, List remoteRepositories )
throws ArtifactMetadataRetrievalException
{
VersionArtifactMetadata localMetadata;
try
{
localMetadata = readFromLocalRepository( artifact, localRepository );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
boolean alreadyResolved = alreadyResolved( artifact );
if ( !alreadyResolved )
{
boolean checkedUpdates = false;
for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); )
{
ArtifactRepository remoteRepository = (ArtifactRepository) i.next();
String snapshotPolicy = remoteRepository.getSnapshotPolicy();
// TODO: should be able to calculate this less often
boolean checkForUpdates = false;
if ( ArtifactRepository.SNAPSHOT_POLICY_ALWAYS.equals( snapshotPolicy ) )
{
checkForUpdates = true;
}
else if ( ArtifactRepository.SNAPSHOT_POLICY_DAILY.equals( snapshotPolicy ) )
{
if ( !localMetadata.checkedSinceDate( getMidnightBoundary() ) )
{
checkForUpdates = true;
}
}
else if ( snapshotPolicy.startsWith( ArtifactRepository.SNAPSHOT_POLICY_INTERVAL ) )
{
String s = snapshotPolicy.substring( ArtifactRepository.SNAPSHOT_POLICY_INTERVAL.length() + 1 );
int minutes = Integer.valueOf( s ).intValue();
Calendar cal = Calendar.getInstance();
cal.add( Calendar.MINUTE, -minutes );
if ( !localMetadata.checkedSinceDate( cal.getTime() ) )
{
checkForUpdates = true;
}
}
// else assume "never"
if ( checkForUpdates )
{
getLogger().info(
artifact.getArtifactId() + ": checking for updates from " + remoteRepository.getId() );
VersionArtifactMetadata remoteMetadata = retrieveFromRemoteRepository( artifact, remoteRepository );
int difference = remoteMetadata.compareTo( localMetadata );
if ( difference > 0 )
{
// remote is newer
artifact.setRepository( remoteRepository );
localMetadata = remoteMetadata;
checkedUpdates = true;
}
else if ( difference == 0 )
{
// Identical, simply touch the file to prevent re-checking
checkedUpdates = true;
}
}
}
if ( checkedUpdates )
{
localMetadata.storeInLocalRepository( localRepository );
}
resolvedArtifactCache.add( getCacheKey( artifact ) );
}
String version = localMetadata.constructVersion();
// TODO: if the POM and JAR are inconsistent, this might mean that different version of each are used
if ( !artifact.getFile().exists() || localMetadata.newerThanFile( artifact.getFile() ) )
{
if ( getLogger().isInfoEnabled() && !alreadyResolved )
{
if ( !version.equals( artifact.getBaseVersion() ) )
{
String message = artifact.getArtifactId() + ": resolved to version " + version;
if ( artifact.getRepository() != null )
{
message += " from repository " + artifact.getRepository().getId();
}
else
{
message += " from local repository";
}
getLogger().info( message );
}
}
return version;
}
else
{
if ( getLogger().isInfoEnabled() && !alreadyResolved )
{
// Locally installed file is newer, don't use the resolved version
getLogger().info( artifact.getArtifactId() + ": using locally installed snapshot" );
}
return artifact.getVersion();
}
}
protected abstract VersionArtifactMetadata retrieveFromRemoteRepository( Artifact artifact,
ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException;
protected abstract VersionArtifactMetadata readFromLocalRepository( Artifact artifact,
ArtifactRepository localRepository )
throws IOException, ArtifactPathFormatException;
private Date getMidnightBoundary()
{
Calendar cal = Calendar.getInstance();
cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 0 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.MILLISECOND, 0 );
return cal.getTime();
}
private boolean alreadyResolved( Artifact artifact )
{
return resolvedArtifactCache.contains( getCacheKey( artifact ) );
}
private static String getCacheKey( Artifact artifact )
{
// No type - one per POM
return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getBaseVersion();
}
}

View File

@ -0,0 +1,106 @@
package org.apache.maven.artifact.transform;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.AbstractVersionArtifactMetadata;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ReleaseArtifactMetadata;
import org.apache.maven.artifact.metadata.VersionArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import java.io.IOException;
import java.util.List;
/**
* Change the version <code>RELEASE</code> to the appropriate release version from the remote repository.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class ReleaseArtifactTransformation
extends AbstractVersionTransformation
{
public static final String RELEASE_VERSION = "RELEASE";
private static boolean isRelease( Artifact artifact )
{
return artifact.getVersion().equals( RELEASE_VERSION );
}
public void transformForResolve( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
if ( isRelease( artifact ) )
{
String version = resolveVersion( artifact, localRepository, remoteRepositories );
if ( !version.equals( artifact.getVersion() ) )
{
artifact.setBaseVersion( version );
artifact.updateVersion( version, localRepository );
}
}
}
public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
// TODO: this is implemented like a SNAPSHOT - it should be at release time only when we have that concept
ReleaseArtifactMetadata metadata = new ReleaseArtifactMetadata( artifact );
metadata.setVersion( artifact.getVersion() );
artifact.addMetadata( metadata );
}
public void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException
{
// TODO: this is implemented like a SNAPSHOT - it should be at release time only when we have that concept
ReleaseArtifactMetadata metadata = new ReleaseArtifactMetadata( artifact );
metadata.setVersion( artifact.getVersion() );
artifact.addMetadata( metadata );
}
protected VersionArtifactMetadata retrieveFromRemoteRepository( Artifact artifact,
ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException
{
AbstractVersionArtifactMetadata metadata = new ReleaseArtifactMetadata( artifact );
try
{
metadata.retrieveFromRemoteRepository( remoteRepository, wagonManager );
}
catch ( ResourceDoesNotExistException e )
{
throw new ArtifactMetadataRetrievalException( "No releases could be detected for the artifact", e );
}
return metadata;
}
protected VersionArtifactMetadata readFromLocalRepository( Artifact artifact, ArtifactRepository localRepository )
throws IOException, ArtifactPathFormatException
{
AbstractVersionArtifactMetadata metadata = new ReleaseArtifactMetadata( artifact );
metadata.readFromLocalRepository( localRepository );
return metadata;
}
}

View File

@ -17,21 +17,16 @@ package org.apache.maven.artifact.transform;
*/
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.SnapshotArtifactMetadata;
import org.apache.maven.artifact.metadata.VersionArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactPathFormatException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
/**
@ -41,15 +36,9 @@ import java.util.regex.Matcher;
* jvanzyl Exp $
*/
public class SnapshotTransformation
extends AbstractLogEnabled
implements ArtifactTransformation
extends AbstractVersionTransformation
{
private WagonManager wagonManager;
/**
* @todo very primitve. Probably we can cache 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 static final String SNAPSHOT_VERSION = "SNAPSHOT";
public void transformForResolve( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
@ -58,172 +47,27 @@ public class SnapshotTransformation
if ( m.matches() )
{
// This corrects the base version, but ensure it is not resolved again
artifact.setBaseVersion( m.group( 1 ) + "-SNAPSHOT" );
artifact.setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION );
}
else if ( isSnapshot( artifact ) )
{
SnapshotArtifactMetadata localMetadata;
try
{
localMetadata = SnapshotArtifactMetadata.readFromLocalRepository( artifact, localRepository );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
catch ( IOException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
boolean alreadyResolved = alreadyResolved( artifact );
if ( !alreadyResolved )
{
boolean checkedUpdates = false;
for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); )
{
ArtifactRepository remoteRepository = (ArtifactRepository) i.next();
String snapshotPolicy = remoteRepository.getSnapshotPolicy();
// TODO: should be able to calculate this less often
boolean checkForUpdates = false;
if ( ArtifactRepository.SNAPSHOT_POLICY_ALWAYS.equals( snapshotPolicy ) )
{
checkForUpdates = true;
}
else if ( ArtifactRepository.SNAPSHOT_POLICY_DAILY.equals( snapshotPolicy ) )
{
// Note that if last modified is 0, it didn't exist, so this will be true
if ( getMidnightBoundary().after( new Date( localMetadata.getLastModified() ) ) )
{
checkForUpdates = true;
}
}
else if ( snapshotPolicy.startsWith( ArtifactRepository.SNAPSHOT_POLICY_INTERVAL ) )
{
String s = snapshotPolicy.substring( ArtifactRepository.SNAPSHOT_POLICY_INTERVAL.length() + 1 );
int minutes = Integer.valueOf( s ).intValue();
Calendar cal = Calendar.getInstance();
cal.add( Calendar.MINUTE, -minutes );
// Note that if last modified is 0, it didn't exist, so this will be true
if ( cal.getTime().after( new Date( localMetadata.getLastModified() ) ) )
{
checkForUpdates = true;
}
}
// else assume "never"
if ( checkForUpdates )
{
getLogger().info(
artifact.getArtifactId() + ": checking for updates from " + remoteRepository.getId() );
SnapshotArtifactMetadata remoteMetadata = SnapshotArtifactMetadata.retrieveFromRemoteRepository(
artifact, remoteRepository, wagonManager );
int difference = remoteMetadata.compareTo( localMetadata );
if ( difference > 0 )
{
// remote is newer
artifact.setRepository( remoteRepository );
localMetadata = remoteMetadata;
checkedUpdates = true;
}
else if ( difference == 0 )
{
// Identical, simply touch the file to prevent re-checking
checkedUpdates = true;
}
}
}
if ( checkedUpdates )
{
localMetadata.storeInLocalRepository( localRepository );
}
resolvedArtifactCache.add( getCacheKey( artifact ) );
}
String version = localMetadata.constructVersion();
// TODO: if the POM and JAR are inconsistent, this might mean that different version of each are used
if ( !artifact.getFile().exists() || localMetadata.newerThanFile( artifact.getFile() ) )
{
if ( getLogger().isInfoEnabled() && !alreadyResolved )
{
if ( !version.equals( artifact.getBaseVersion() ) )
{
String message = artifact.getArtifactId() + ": resolved to version " + version;
if ( artifact.getRepository() != null )
{
message += " from repository " + artifact.getRepository().getId();
}
else
{
message += " from local repository";
}
getLogger().info( message );
}
}
artifact.setVersion( version );
try
{
artifact.setFile( new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) ) );
}
catch ( ArtifactPathFormatException e )
{
throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e );
}
}
else
{
if ( getLogger().isInfoEnabled() && !alreadyResolved )
{
// Locally installed file is newer, don't use the resolved version
getLogger().info( artifact.getArtifactId() + ": using locally installed snapshot" );
}
}
String version = resolveVersion( artifact, localRepository, remoteRepositories );
artifact.updateVersion( version, localRepository );
}
}
private Date getMidnightBoundary()
{
Calendar cal = Calendar.getInstance();
cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 0 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.MILLISECOND, 0 );
return cal.getTime();
}
private boolean alreadyResolved( Artifact artifact )
{
return resolvedArtifactCache.contains( getCacheKey( artifact ) );
}
private static String getCacheKey( Artifact artifact )
{
// No type - one per POM
return artifact.getGroupId() + ":" + artifact.getArtifactId();
}
public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
throws ArtifactMetadataRetrievalException
{
Matcher m = SnapshotArtifactMetadata.VERSION_FILE_PATTERN.matcher( artifact.getBaseVersion() );
if ( m.matches() )
{
artifact.setBaseVersion( m.group( 1 ) + "-SNAPSHOT" );
artifact.setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION );
}
try
{
SnapshotArtifactMetadata metadata = SnapshotArtifactMetadata.readFromLocalRepository( artifact,
localRepository );
if ( metadata.getLastModified() == 0 )
VersionArtifactMetadata metadata = readFromLocalRepository( artifact, localRepository );
if ( !metadata.exists() )
{
// doesn't exist - create to avoid an old snapshot download later
metadata.storeInLocalRepository( localRepository );
@ -246,13 +90,12 @@ public class SnapshotTransformation
if ( m.matches() )
{
// This corrects the base version, but ensure it is not updated again
artifact.setBaseVersion( m.group( 1 ) + "-SNAPSHOT" );
artifact.setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION );
}
else if ( isSnapshot( artifact ) )
{
SnapshotArtifactMetadata metadata = SnapshotArtifactMetadata.retrieveFromRemoteRepository( artifact,
remoteRepository,
wagonManager );
SnapshotArtifactMetadata metadata = (SnapshotArtifactMetadata) retrieveFromRemoteRepository( artifact,
remoteRepository );
metadata.update();
artifact.setVersion( metadata.constructVersion() );
@ -263,6 +106,31 @@ public class SnapshotTransformation
private static boolean isSnapshot( Artifact artifact )
{
return artifact.getVersion().endsWith( "SNAPSHOT" );
return artifact.getVersion().endsWith( SNAPSHOT_VERSION );
}
protected VersionArtifactMetadata retrieveFromRemoteRepository( Artifact artifact,
ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException
{
SnapshotArtifactMetadata metadata = new SnapshotArtifactMetadata( artifact );
try
{
metadata.retrieveFromRemoteRepository( remoteRepository, wagonManager );
}
catch ( ResourceDoesNotExistException e )
{
// No problem...
// this just means that there is no snapshot version file, so we keep timestamp = null, build = 0
}
return metadata;
}
protected VersionArtifactMetadata readFromLocalRepository( Artifact artifact, ArtifactRepository localRepository )
throws IOException, ArtifactPathFormatException
{
SnapshotArtifactMetadata metadata = new SnapshotArtifactMetadata( artifact );
metadata.readFromLocalRepository( localRepository );
return metadata;
}
}

View File

@ -22,6 +22,7 @@
-->
<component>
<role>org.apache.maven.artifact.transform.ArtifactTransformation</role>
<role-hint>snapshot</role-hint>
<implementation>org.apache.maven.artifact.transform.SnapshotTransformation</implementation>
<requirements>
<requirement>
@ -30,6 +31,16 @@
</requirements>
</component>
<component>
<role>org.apache.maven.artifact.transform.ArtifactTransformation</role>
<role-hint>release</role-hint>
<implementation>org.apache.maven.artifact.transform.ReleaseArtifactTransformation</implementation>
<requirements>
<requirement>
<role>org.apache.maven.artifact.manager.WagonManager</role>
</requirement>
</requirements>
</component>
<!--
|
| Resolver

View File

@ -24,6 +24,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.artifact.transform.ReleaseArtifactTransformation;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
@ -70,7 +71,6 @@ public class DefaultPluginManager
extends AbstractLogEnabled
implements PluginManager, ComponentDiscoveryListener, Initializable, Contextualizable
{
protected Map pluginDescriptors;
protected Map pluginDescriptorsByPrefix;
@ -211,8 +211,7 @@ public class DefaultPluginManager
{
if ( StringUtils.isEmpty( pluginConfig.getVersion() ) )
{
// TODO: this is where we go searching the repo for more information
version = PluginDescriptor.getDefaultPluginVersion();
version = ReleaseArtifactTransformation.RELEASE_VERSION;
}
else
{
@ -221,14 +220,16 @@ public class DefaultPluginManager
}
}
// TODO: this might result in an artifact "RELEASE" being resolved continuously
if ( !isPluginInstalled( groupId, artifactId, version ) )
{
try
{
Artifact pluginArtifact = artifactFactory.createArtifact( groupId, artifactId, version, null,
MojoDescriptor.MAVEN_PLUGIN, null );
addPlugin( pluginArtifact, session );
version = pluginArtifact.getBaseVersion();
}
catch ( ArtifactEnabledContainerException e )
{

View File

@ -149,14 +149,6 @@ public class PluginDescriptor
}
}
/**
* @todo remove - harcoding. What about clashes?
*/
public static String getDefaultPluginVersion()
{
return "1.0-SNAPSHOT";
}
public String getGoalPrefix()
{
return goalPrefix;

View File

@ -499,15 +499,6 @@ public class DefaultMavenProjectBuilder
}
}
/**
* @return
* @todo remove
*/
public ArtifactResolver getArtifactResolver()
{
return artifactResolver;
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------

View File

@ -57,6 +57,4 @@ public interface MavenProjectBuilder
MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
throws ProjectBuildingException;
ArtifactResolver getArtifactResolver();
}

View File

@ -53,7 +53,12 @@ public class ProjectArtifactMetadata
public String getFilename()
{
return getArtifact().getArtifactId() + "-" + getArtifact().getVersion() + ".pom";
return getArtifactId() + "-" + getVersion() + ".pom";
}
public boolean exists()
{
return file.exists();
}
public void storeInLocalRepository( ArtifactRepository localRepository )
@ -80,7 +85,7 @@ public class ProjectArtifactMetadata
MavenXpp3Reader modelReader = new MavenXpp3Reader();
Model model = modelReader.read( reader );
model.setVersion( getArtifact().getVersion() );
model.setVersion( getVersion() );
MavenXpp3Writer modelWriter = new MavenXpp3Writer();
modelWriter.write( writer, model );