@@ -28,6 +28,8 @@ import org.apache.archiva.model.ArtifactReference; | |||
import org.apache.archiva.repository.ContentNotFoundException; | |||
import org.apache.archiva.repository.ManagedRepositoryContent; | |||
import org.apache.archiva.metadata.audit.RepositoryListener; | |||
import org.apache.archiva.repository.content.Artifact; | |||
import org.apache.archiva.repository.content.ItemNotFoundException; | |||
import org.apache.archiva.repository.storage.StorageAsset; | |||
import org.apache.archiva.repository.storage.util.StorageUtil; | |||
import org.apache.commons.lang3.StringUtils; | |||
@@ -183,63 +185,57 @@ public abstract class AbstractRepositoryPurge | |||
* | |||
* @param references | |||
*/ | |||
protected void purge( Set<ArtifactReference> references ) | |||
protected void purge( Set<Artifact> references ) | |||
{ | |||
if ( references != null && !references.isEmpty( ) ) | |||
{ | |||
MetadataRepository metadataRepository = repositorySession.getRepository( ); | |||
Map<ArtifactInfo, ArtifactMetadata> metaRemovalList = new HashMap<>( ); | |||
Map<String, Collection<ArtifactMetadata>> metaResolved = new HashMap<>( ); | |||
for ( ArtifactReference reference : references ) | |||
for ( Artifact reference : references ) | |||
{ | |||
String baseVersion = VersionUtil.getBaseVersion( reference.getVersion( ) ); | |||
String baseVersion = reference.getVersion( ).getVersion( ); | |||
String namespace = reference.getVersion( ).getProject( ).getNamespace( ).getNamespace( ); | |||
// Needed for tracking in the hashmap | |||
String metaBaseId = reference.getGroupId( ) + "/" + reference.getArtifactId( ) + "/" + baseVersion; | |||
String metaBaseId = reference.toKey(); | |||
if ( !metaResolved.containsKey( metaBaseId ) ) | |||
{ | |||
try | |||
{ | |||
metaResolved.put( metaBaseId, metadataRepository.getArtifacts(repositorySession, repository.getId( ), | |||
reference.getGroupId( ), reference.getArtifactId( ), baseVersion ) ); | |||
namespace, reference.getId( ), baseVersion ) ); | |||
} | |||
catch ( MetadataResolutionException e ) | |||
{ | |||
log.error( "Error during metadata retrieval {}: {}", metaBaseId, e.getMessage( ) ); | |||
} | |||
} | |||
StorageAsset artifactFile = repository.toFile( reference ); | |||
StorageAsset artifactFile = reference.getAsset(); | |||
for ( RepositoryListener listener : listeners ) | |||
{ | |||
listener.deleteArtifact( metadataRepository, repository.getId( ), reference.getGroupId( ), | |||
reference.getArtifactId( ), reference.getVersion( ), | |||
listener.deleteArtifact( metadataRepository, repository.getId( ), namespace, | |||
reference.getId( ), reference.getVersion( ).getVersion(), | |||
artifactFile.getName( )); | |||
} | |||
try | |||
if (reference.exists()) | |||
{ | |||
artifactFile.getStorage().removeAsset(artifactFile); | |||
log.debug( "File deleted: {}", artifactFile ); | |||
} | |||
catch ( IOException e ) | |||
{ | |||
log.error( "Could not delete file {}: {}", artifactFile.toString(), e.getMessage( ), e ); | |||
continue; | |||
} | |||
try | |||
{ | |||
repository.deleteArtifact( reference ); | |||
} | |||
catch ( ContentNotFoundException e ) | |||
{ | |||
log.warn( "skip error deleting artifact {}: {}", reference, e.getMessage( ) ); | |||
} | |||
catch ( org.apache.archiva.repository.ContentAccessException e ) | |||
{ | |||
e.printStackTrace( ); | |||
try | |||
{ | |||
repository.deleteItem( reference ); | |||
} | |||
catch ( org.apache.archiva.repository.ContentAccessException e ) | |||
{ | |||
log.error( "Error while trying to delete artifact {}: {}", reference.toString( ), e.getMessage( ), e ); | |||
} | |||
catch ( ItemNotFoundException e ) | |||
{ | |||
log.error( "Asset deleted from background other thread: {}", e.getMessage( ) ); | |||
} | |||
} | |||
boolean snapshotVersion = VersionUtil.isSnapshot( reference.getVersion( ) ); | |||
boolean snapshotVersion = VersionUtil.isSnapshot( baseVersion ); | |||
// If this is a snapshot we have to search for artifacts with the same version. And remove all of them. | |||
@@ -253,7 +249,7 @@ public abstract class AbstractRepositoryPurge | |||
for ( ArtifactMetadata artifactMetadata : artifacts ) | |||
{ | |||
// Artifact metadata and reference version should match. | |||
if ( artifactMetadata.getVersion( ).equals( reference.getVersion( ) ) ) | |||
if ( artifactMetadata.getVersion( ).equals( reference.getArtifactVersion( ) ) ) | |||
{ | |||
ArtifactInfo info = new ArtifactInfo( artifactMetadata.getNamespace( ), artifactMetadata.getProject( ), artifactMetadata.getProjectVersion( ), artifactMetadata.getVersion( ) ); | |||
if ( StringUtils.isNotBlank( reference.getClassifier( ) ) ) | |||
@@ -272,15 +268,15 @@ public abstract class AbstractRepositoryPurge | |||
} | |||
else // otherwise we delete the artifact version | |||
{ | |||
ArtifactInfo info = new ArtifactInfo( reference.getGroupId( ), reference.getArtifactId( ), baseVersion, reference.getVersion( ) ); | |||
ArtifactInfo info = new ArtifactInfo( namespace, reference.getId( ), baseVersion, reference.getArtifactVersion() ); | |||
for ( ArtifactMetadata metadata : metaResolved.get( metaBaseId ) ) | |||
{ | |||
metaRemovalList.put( info, metadata ); | |||
} | |||
} | |||
triggerAuditEvent( repository.getRepository( ).getId( ), ArtifactReference.toKey( reference ), | |||
triggerAuditEvent( repository.getRepository( ).getId( ), reference.toKey(), | |||
AuditEvent.PURGE_ARTIFACT ); | |||
purgeSupportFiles( artifactFile ); | |||
// purgeSupportFiles( artifactFile ); | |||
} | |||
purgeMetadata( metadataRepository, metaRemovalList ); | |||
try |
@@ -21,22 +21,31 @@ package org.apache.archiva.consumers.core.repository; | |||
import org.apache.archiva.common.utils.VersionComparator; | |||
import org.apache.archiva.common.utils.VersionUtil; | |||
import org.apache.archiva.metadata.audit.RepositoryListener; | |||
import org.apache.archiva.metadata.repository.RepositorySession; | |||
import org.apache.archiva.model.ArtifactReference; | |||
import org.apache.archiva.model.VersionedReference; | |||
import org.apache.archiva.repository.ContentNotFoundException; | |||
import org.apache.archiva.repository.LayoutException; | |||
import org.apache.archiva.repository.ManagedRepositoryContent; | |||
import org.apache.archiva.metadata.audit.RepositoryListener; | |||
import org.apache.archiva.repository.content.Artifact; | |||
import org.apache.archiva.repository.content.ContentItem; | |||
import org.apache.archiva.repository.content.ItemNotFoundException; | |||
import org.apache.archiva.repository.content.base.ArchivaItemSelector; | |||
import org.apache.archiva.repository.storage.StorageAsset; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.*; | |||
import java.util.Calendar; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.TimeZone; | |||
import java.util.regex.Matcher; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
/** | |||
* Purge from repository all snapshots older than the specified days in the repository configuration. | |||
@@ -57,7 +66,7 @@ public class DaysOldRepositoryPurge | |||
this.retentionPeriod = retentionPeriod; | |||
this.retentionCount = retentionCount; | |||
timestampParser = new SimpleDateFormat( "yyyyMMdd.HHmmss" ); | |||
timestampParser.setTimeZone( TimeZone.getTimeZone("UTC")); | |||
timestampParser.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); | |||
} | |||
@Override | |||
@@ -66,74 +75,101 @@ public class DaysOldRepositoryPurge | |||
{ | |||
try | |||
{ | |||
Path artifactFile = Paths.get( repository.getRepoRoot( ), path ); | |||
if ( !Files.exists(artifactFile) ) | |||
ContentItem item = repository.toItem( path ); | |||
if ( item instanceof Artifact ) | |||
{ | |||
return; | |||
} | |||
ArtifactReference artifact = repository.toArtifactReference( path ); | |||
Calendar olderThanThisDate = Calendar.getInstance( TimeZone.getTimeZone("UTC") ); | |||
olderThanThisDate.add( Calendar.DATE, -retentionPeriod ); | |||
Artifact artifactItem = (Artifact) item; | |||
// respect retention count | |||
VersionedReference reference = new VersionedReference( ); | |||
reference.setGroupId( artifact.getGroupId( ) ); | |||
reference.setArtifactId( artifact.getArtifactId( ) ); | |||
reference.setVersion( artifact.getVersion( ) ); | |||
List<String> versions = new ArrayList<>( repository.getVersions( reference ) ); | |||
Collections.sort( versions, VersionComparator.getInstance( ) ); | |||
if ( !artifactItem.exists( ) ) | |||
{ | |||
return; | |||
} | |||
if ( retentionCount > versions.size( ) ) | |||
{ | |||
// Done. nothing to do here. skip it. | |||
return; | |||
} | |||
// ArtifactReference artifact = repository.toArtifactReference( path ); | |||
Calendar olderThanThisDate = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); | |||
olderThanThisDate.add( Calendar.DATE, -retentionPeriod ); | |||
// respect retention count | |||
// VersionedReference reference = new VersionedReference( ); | |||
// reference.setGroupId( artifact.getGroupId( ) ); | |||
// reference.setArtifactId( artifact.getArtifactId( ) ); | |||
// reference.setVersion( artifact.getVersion( ) ); | |||
ArchivaItemSelector selector = ArchivaItemSelector.builder( ) | |||
.withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getNamespace( ) ) | |||
.withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) ) | |||
.withVersion( artifactItem.getVersion( ).getVersion( ) ) | |||
.withClassifier( "*" ) | |||
.includeRelatedArtifacts( ) | |||
.build( ); | |||
List<String> artifactVersions; | |||
try( Stream<? extends Artifact> stream = repository.newArtifactStream( selector )){ | |||
artifactVersions = stream.map( a -> a.getArtifactVersion( ) ) | |||
.filter( StringUtils::isNotEmpty ) | |||
.distinct() | |||
.collect( Collectors.toList( ) ); | |||
} | |||
int countToPurge = versions.size( ) - retentionCount; | |||
Collections.sort( artifactVersions, VersionComparator.getInstance( ) ); | |||
Set<ArtifactReference> artifactsToDelete = new HashSet<>( ); | |||
for ( String version : versions ) | |||
{ | |||
if ( countToPurge-- <= 0 ) | |||
if ( retentionCount > artifactVersions.size( ) ) | |||
{ | |||
break; | |||
// Done. nothing to do here. skip it. | |||
return; | |||
} | |||
ArtifactReference newArtifactReference = repository.toArtifactReference( | |||
artifactFile.toAbsolutePath( ).toString() ); | |||
newArtifactReference.setVersion( version ); | |||
int countToPurge = artifactVersions.size( ) - retentionCount; | |||
StorageAsset newArtifactFile = repository.toFile( newArtifactReference ); | |||
// Is this a generic snapshot "1.0-SNAPSHOT" ? | |||
if ( VersionUtil.isGenericSnapshot( newArtifactReference.getVersion( ) ) ) | |||
ArchivaItemSelector.Builder artifactSelectorBuilder = ArchivaItemSelector.builder( ) | |||
.withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getNamespace( ) ) | |||
.withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) ) | |||
.withVersion( artifactItem.getVersion( ).getVersion( ) ) | |||
.withArtifactId( artifactItem.getId() ) | |||
.withClassifier( "*" ) | |||
.includeRelatedArtifacts( ); | |||
Set<Artifact> artifactsToDelete = new HashSet<>( ); | |||
for ( String version : artifactVersions ) | |||
{ | |||
if ( newArtifactFile.getModificationTime().toEpochMilli() < olderThanThisDate.getTimeInMillis( ) ) | |||
if ( countToPurge-- <= 0 ) | |||
{ | |||
artifactsToDelete.addAll( repository.getRelatedArtifacts( repository.toVersion(newArtifactReference) ) ); | |||
break; | |||
} | |||
} | |||
// Is this a timestamp snapshot "1.0-20070822.123456-42" ? | |||
else if ( VersionUtil.isUniqueSnapshot( newArtifactReference.getVersion( ) ) ) | |||
{ | |||
Calendar timestampCal = uniqueSnapshotToCalendar( newArtifactReference.getVersion( ) ); | |||
if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) ) | |||
ArchivaItemSelector artifactSelector = artifactSelectorBuilder.withArtifactVersion( version ).build( ); | |||
try | |||
{ | |||
artifactsToDelete.addAll( repository.getRelatedArtifacts( repository.toVersion(newArtifactReference) ) ); | |||
// Is this a generic snapshot "1.0-SNAPSHOT" ? | |||
if ( VersionUtil.isGenericSnapshot( version ) ) | |||
{ | |||
List<? extends Artifact> artifactList = repository.getArtifacts( artifactSelector ); | |||
if ( artifactList.size()>0 && artifactList.get(0).getAsset().getModificationTime( ).toEpochMilli( ) < olderThanThisDate.getTimeInMillis( ) ) | |||
{ | |||
artifactsToDelete.addAll( artifactList ); | |||
} | |||
} | |||
// Is this a timestamp snapshot "1.0-20070822.123456-42" ? | |||
else if ( VersionUtil.isUniqueSnapshot( version ) ) | |||
{ | |||
Calendar timestampCal = uniqueSnapshotToCalendar( version ); | |||
if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) ) | |||
{ | |||
artifactsToDelete.addAll( repository.getArtifacts( artifactSelector ) ); | |||
} | |||
} | |||
} catch ( IllegalArgumentException e ) { | |||
log.error( "Bad selector for artifact: {}", e.getMessage( ), e ); | |||
// continue | |||
} | |||
} | |||
purge( artifactsToDelete ); | |||
} | |||
purge( artifactsToDelete ); | |||
} | |||
catch ( ContentNotFoundException e ) | |||
{ | |||
throw new RepositoryPurgeException( e.getMessage( ), e ); | |||
} | |||
catch ( LayoutException e ) | |||
{ | |||
@@ -163,7 +199,7 @@ public class DaysOldRepositoryPurge | |||
try | |||
{ | |||
versionDate = timestampParser.parse( tsDate + "." + tsTime ); | |||
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("UTC") ); | |||
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); | |||
cal.setTime( versionDate ); | |||
return cal; |
@@ -28,6 +28,12 @@ import org.apache.archiva.repository.ContentNotFoundException; | |||
import org.apache.archiva.repository.LayoutException; | |||
import org.apache.archiva.repository.ManagedRepositoryContent; | |||
import org.apache.archiva.metadata.audit.RepositoryListener; | |||
import org.apache.archiva.repository.content.Artifact; | |||
import org.apache.archiva.repository.content.ContentItem; | |||
import org.apache.archiva.repository.content.ItemSelector; | |||
import org.apache.archiva.repository.content.Version; | |||
import org.apache.archiva.repository.content.base.ArchivaItemSelector; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
@@ -37,6 +43,8 @@ import java.util.Collections; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
/** | |||
* Purge the repository by retention count. Retain only the specified number of snapshots. | |||
@@ -59,58 +67,78 @@ public class RetentionCountRepositoryPurge | |||
{ | |||
try | |||
{ | |||
Path artifactFile = Paths.get( repository.getRepoRoot( ), path ); | |||
if ( !Files.exists(artifactFile) ) | |||
ContentItem item = repository.toItem( path ); | |||
if (item instanceof Artifact ) | |||
{ | |||
return; | |||
} | |||
Artifact artifact = (Artifact) item; | |||
if (!artifact.exists()) { | |||
return; | |||
} | |||
ArtifactReference artifact = repository.toArtifactReference( path ); | |||
if ( VersionUtil.isSnapshot( artifact.getVersion( ).getVersion() ) ) | |||
{ | |||
ArchivaItemSelector selector = ArchivaItemSelector.builder( ) | |||
.withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getNamespace( ) ) | |||
.withProjectId( artifact.getVersion( ).getProject( ).getId( ) ) | |||
.withArtifactId( artifact.getId( ) ) | |||
.withVersion( artifact.getVersion( ).getVersion( ) ) | |||
.withClassifier( "*" ) | |||
.includeRelatedArtifacts() | |||
.build( ); | |||
if ( VersionUtil.isSnapshot( artifact.getVersion( ) ) ) | |||
{ | |||
VersionedReference reference = new VersionedReference( ); | |||
reference.setGroupId( artifact.getGroupId( ) ); | |||
reference.setArtifactId( artifact.getArtifactId( ) ); | |||
reference.setVersion( artifact.getVersion( ) ); | |||
List<String> versions = new ArrayList<>( repository.getVersions( reference ) ); | |||
List<String> versions; | |||
try( Stream<? extends Artifact> stream = repository.newArtifactStream( selector) ){ | |||
versions = stream.map( a -> a.getArtifactVersion( ) ) | |||
.filter( StringUtils::isNotEmpty ) | |||
.distinct() | |||
.collect( Collectors.toList( ) ); | |||
} | |||
Collections.sort( versions, VersionComparator.getInstance( ) ); | |||
Collections.sort( versions, VersionComparator.getInstance( ) ); | |||
if ( retentionCount > versions.size( ) ) | |||
{ | |||
log.trace( "No deletion, because retention count is higher than actual number of artifacts." ); | |||
// Done. nothing to do here. skip it. | |||
return; | |||
} | |||
if ( retentionCount > versions.size( ) ) | |||
{ | |||
log.trace( "No deletion, because retention count is higher than actual number of artifacts." ); | |||
// Done. nothing to do here. skip it. | |||
return; | |||
} | |||
int countToPurge = versions.size( ) - retentionCount; | |||
Set<ArtifactReference> artifactsToDelete = new HashSet<>( ); | |||
for ( String version : versions ) | |||
{ | |||
if ( countToPurge-- <= 0 ) | |||
ArchivaItemSelector.Builder selectorBuilder = ArchivaItemSelector.builder( ) | |||
.withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getNamespace( ) ) | |||
.withProjectId( artifact.getVersion( ).getProject( ).getId( ) ) | |||
.withArtifactId( artifact.getId( ) ) | |||
.withClassifier( "*" ) | |||
.includeRelatedArtifacts() | |||
.withVersion( artifact.getVersion( ).getVersion( ) ); | |||
int countToPurge = versions.size( ) - retentionCount; | |||
Set<Artifact> artifactsToDelete = new HashSet<>( ); | |||
for ( String version : versions ) | |||
{ | |||
break; | |||
if ( countToPurge-- <= 0 ) | |||
{ | |||
break; | |||
} | |||
List<? extends Artifact> delArtifacts = repository.getArtifacts( selectorBuilder.withArtifactVersion( version ).build( ) ); | |||
if (delArtifacts!=null && delArtifacts.size()>0) | |||
{ | |||
artifactsToDelete.addAll( delArtifacts ); | |||
} | |||
} | |||
VersionedReference ref = repository.toVersion( getNewArtifactReference( artifact, version ) ); | |||
artifactsToDelete.addAll( repository.getRelatedArtifacts( ref ) ); | |||
purge( artifactsToDelete ); | |||
} | |||
purge( artifactsToDelete ); | |||
} else { | |||
throw new RepositoryPurgeException( "Bad artifact path " + path ); | |||
} | |||
} | |||
catch ( LayoutException le ) | |||
{ | |||
throw new RepositoryPurgeException( le.getMessage( ), le ); | |||
} | |||
catch ( ContentNotFoundException e ) | |||
{ | |||
log.error( "Repostory artifact not found {}", path ); | |||
} | |||
catch ( org.apache.archiva.repository.ContentAccessException e ) | |||
{ | |||
e.printStackTrace( ); | |||
log.error( "Error while accessing the repository data: {}", e.getMessage( ), e ); | |||
throw new RepositoryPurgeException( e.getMessage( ), e ); | |||
} | |||
} | |||
@@ -109,10 +109,10 @@ public class DaysOldRepositoryPurgeTest | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-install-plugin", "2.2-SNAPSHOT", "maven-install-plugin-2.2-SNAPSHOT.pom"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-install-plugin", "2.2-20061118.060401-2", | |||
"maven-install-plugin", "2.2-SNAPSHOT", | |||
"maven-install-plugin-2.2-20061118.060401-2.jar"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-install-plugin", "2.2-20061118.060401-2", | |||
"maven-install-plugin", "2.2-SNAPSHOT", | |||
"maven-install-plugin-2.2-20061118.060401-2.pom"+exts[i]); | |||
} | |||
listenerControl.replay(); | |||
@@ -203,10 +203,10 @@ public class DaysOldRepositoryPurgeTest | |||
String[] exts = {".md5",".sha1",""}; | |||
for (int i=0; i<exts.length; i++) { | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.jar"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom"+exts[i]); | |||
} | |||
listenerControl.replay(); | |||
@@ -313,9 +313,9 @@ public class DaysOldRepositoryPurgeTest | |||
for (int i=0; i<exts.length; i++) { | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.codehaus.plexus", "plexus-utils", | |||
"1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.jar"+exts[i]); | |||
"1.4.3-SNAPSHOT", "plexus-utils-1.4.3-20070113.163208-4.jar"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.codehaus.plexus", "plexus-utils", | |||
"1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.pom"+exts[i]); | |||
"1.4.3-SNAPSHOT", "plexus-utils-1.4.3-20070113.163208-4.pom"+exts[i]); | |||
} | |||
listenerControl.replay(); | |||
@@ -100,27 +100,27 @@ public class RetentionCountRepositoryPurgeTest | |||
String[] exts = { ".md5", ".sha1", ""}; | |||
for (int i=0 ; i<exts.length; i++) { | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.153317-1", "jruby-rake-plugin-1.0RC1-20070504.153317-1.jar"+exts[i]); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.153317-1.jar"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.153317-1", "jruby-rake-plugin-1.0RC1-20070504.153317-1.pom"+exts[i]); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.153317-1.pom"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2.jar"+exts[i]); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.160758-2.jar"+exts[i]); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2.pom"+exts[i]); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.160758-2.pom"+exts[i]); | |||
} | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2-javadoc.jar"); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.160758-2-javadoc.jar"); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2-javadoc.zip"); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.160758-2-javadoc.zip"); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.153317-1", "jruby-rake-plugin-1.0RC1-20070504.153317-1-javadoc.jar"); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.153317-1-javadoc.jar"); | |||
listener.deleteArtifact(metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin", | |||
"1.0RC1-20070504.153317-1", "jruby-rake-plugin-1.0RC1-20070504.153317-1-javadoc.zip"); | |||
"1.0RC1-SNAPSHOT", "jruby-rake-plugin-1.0RC1-20070504.153317-1-javadoc.zip"); | |||
listenerControl.replay(); | |||
@@ -198,17 +198,17 @@ public class RetentionCountRepositoryPurgeTest | |||
// test listeners for the correct artifacts | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.jar.md5" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.jar.md5" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.jar.sha1" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.jar.sha1" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.jar" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.jar" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.pom.md5" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.pom.md5" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.pom.sha1" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.pom.sha1" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks", | |||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.pom" ); | |||
"1.1.2-SNAPSHOT", "castor-anttasks-1.1.2-20070427.065136-1.pom" ); | |||
listenerControl.replay(); | |||
// Provide the metadata list | |||
@@ -280,22 +280,22 @@ public class RetentionCountRepositoryPurgeTest | |||
// test listeners for the correct artifacts | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.jar.md5" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.jar" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom.md5" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom.sha1" ); | |||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins", | |||
"maven-assembly-plugin", "1.1.2-20070427.065136-1", | |||
"maven-assembly-plugin", "1.1.2-SNAPSHOT", | |||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom" ); | |||
listenerControl.replay(); | |||
@@ -28,7 +28,7 @@ | |||
default-lazy-init="true"> | |||
<context:annotation-config/> | |||
<context:component-scan base-package="org.apache.archiva.metadata.repository"/> | |||
<context:component-scan base-package="org.apache.archiva.metadata.repository,org.apache.archiva.repository.maven.content"/> | |||
<!-- for testing repo purge using retention count --> | |||
@@ -27,7 +27,7 @@ | |||
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" | |||
default-lazy-init="true"> | |||
<context:annotation-config/> | |||
<context:component-scan base-package="org.apache.archiva.metadata.repository"/> | |||
<context:component-scan base-package="org.apache.archiva.metadata.repository,org.apache.archiva.repository.maven.content,org.apache.archiva.metadata.maven"/> | |||
<bean name="commons-configuration" class="org.apache.archiva.components.registry.commons.CommonsConfigurationRegistry"> | |||
<property name="initialConfiguration"> |
@@ -156,7 +156,7 @@ public interface ManagedRepositoryContent extends RepositoryContent | |||
* | |||
* @param selector the selector with the artifact coordinates | |||
* @return a artifact object | |||
* @throws ItemNotFoundException if the selector coordinates do not specify a artifact | |||
* @throws IllegalArgumentException if the selector coordinates do not specify a artifact | |||
* @throws ContentAccessException if the access to the underlying storage failed | |||
*/ | |||
Artifact getArtifact(ItemSelector selector) throws ContentAccessException; | |||
@@ -168,7 +168,7 @@ public interface ManagedRepositoryContent extends RepositoryContent | |||
* | |||
* @param selector the selector for the artifacts | |||
* @return a list of artifacts. | |||
* @throws ItemNotFoundException if the specified coordinates cannot be found in the repository | |||
* @throws IllegalArgumentException if the specified coordinates cannot be found in the repository | |||
* @throws ContentAccessException if the access to the underlying storage failed | |||
*/ | |||
List<? extends Artifact> getArtifacts( ItemSelector selector) throws ContentAccessException; | |||
@@ -304,14 +304,6 @@ public interface ManagedRepositoryContent extends RepositoryContent | |||
VersionedReference toVersion( String groupId, String artifactId, String version ); | |||
/** | |||
* Returns the version reference that represents the generic version, which means that | |||
* snapshot versions are converted to <VERSION>-SNAPSHOT | |||
* @param artifactReference the artifact reference | |||
* @return the generic version | |||
*/ | |||
VersionedReference toGenericVersion( ArtifactReference artifactReference ); | |||
/** | |||
* Return the version reference that matches exactly the version string of the artifact | |||
* |
@@ -19,6 +19,8 @@ package org.apache.archiva.repository.content; | |||
* under the License. | |||
*/ | |||
import org.apache.archiva.model.ArtifactReference; | |||
/** | |||
* Represents a artifact of a repository. This object contains unique coordinates of the | |||
* artifact. A artifact has exactly one file representation in the repository. | |||
@@ -131,4 +133,12 @@ public interface Artifact extends ContentItem | |||
*/ | |||
ArtifactType getArtifactType(); | |||
/** | |||
* Returns a unique key | |||
* @return | |||
*/ | |||
String toKey(); | |||
} |
@@ -175,6 +175,29 @@ public class ArchivaArtifact extends ArchivaContentItem implements Artifact | |||
return sb.toString( ); | |||
} | |||
public static String defaultString( String value ) | |||
{ | |||
if ( value == null ) | |||
{ | |||
return ""; | |||
} | |||
return value.trim(); | |||
} | |||
public String toKey( ) | |||
{ | |||
StringBuilder key = new StringBuilder(); | |||
key.append( defaultString( getVersion().getProject().getNamespace().getNamespace() )).append( ":" ); | |||
key.append( defaultString( getId() ) ).append( ":" ); | |||
key.append( defaultString( getVersion().getVersion() ) ).append( ":" ); | |||
key.append( defaultString( getClassifier() ) ).append( ":" ); | |||
key.append( defaultString( getType() ) ); | |||
return key.toString(); | |||
} | |||
private static class Builder | |||
extends ContentItemBuilder<ArchivaArtifact, ArtifactOptBuilder, WithVersionObjectBuilder> | |||
implements ArtifactVersionBuilder, WithVersionObjectBuilder, ArtifactWithIdBuilder, ArtifactOptBuilder |
@@ -19,7 +19,12 @@ package org.apache.archiva.repository.content.base; | |||
* under the License. | |||
*/ | |||
import org.apache.archiva.repository.content.Artifact; | |||
import org.apache.archiva.repository.content.ContentItem; | |||
import org.apache.archiva.repository.content.ItemSelector; | |||
import org.apache.archiva.repository.content.Namespace; | |||
import org.apache.archiva.repository.content.Project; | |||
import org.apache.archiva.repository.content.Version; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.util.Collections; | |||
@@ -59,6 +64,34 @@ public class ArchivaItemSelector implements ItemSelector | |||
{ | |||
private final ArchivaItemSelector selector = new ArchivaItemSelector( ); | |||
public Builder withItem( ContentItem item ) { | |||
if (item instanceof Namespace ) { | |||
Namespace ns = (Namespace) item; | |||
selector.namespace = ns.getNamespace(); | |||
} else if (item instanceof Project ) { | |||
Project proj = (Project)item; | |||
selector.namespace = proj.getNamespace( ).getNamespace( ); | |||
selector.projectId = proj.getId( ); | |||
} else if (item instanceof Version) { | |||
Version version = (Version)item; | |||
selector.namespace = version.getProject( ).getNamespace( ).getNamespace( ); | |||
selector.projectId = version.getProject( ).getId( ); | |||
selector.version = version.getVersion( ); | |||
} else if (item instanceof Artifact ) { | |||
Artifact artifact = (Artifact)item; | |||
selector.namespace = artifact.getVersion( ).getProject( ).getNamespace( ).getNamespace( ); | |||
selector.projectId = artifact.getVersion( ).getProject( ).getId( ); | |||
selector.version = artifact.getVersion( ).getVersion( ); | |||
selector.artifactId = artifact.getId( ); | |||
selector.artifactVersion = artifact.getArtifactVersion( ); | |||
selector.extension = artifact.getExtension( ); | |||
} | |||
for (Map.Entry<String, String> att : item.getAttributes().entrySet()) { | |||
selector.setAttribute( att.getKey( ), att.getValue( ) ); | |||
} | |||
return this; | |||
} | |||
public Builder withNamespace( String namespace ) | |||
{ | |||
if (namespace!=null) |
@@ -57,12 +57,6 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toGenericVersion( ArtifactReference artifactReference ) | |||
{ | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toVersion( ArtifactReference artifactReference ) | |||
{ |
@@ -73,12 +73,6 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toGenericVersion( ArtifactReference artifactReference ) | |||
{ | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toVersion( ArtifactReference artifactReference ) | |||
{ |
@@ -77,12 +77,6 @@ public class ManagedRepositoryContentMock implements ManagedRepositoryContent | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toGenericVersion( ArtifactReference artifactReference ) | |||
{ | |||
return null; | |||
} | |||
@Override | |||
public VersionedReference toVersion( ArtifactReference artifactReference ) | |||
{ |
@@ -702,7 +702,7 @@ public class ManagedDefaultRepositoryContent | |||
fileNamePattern.append( Pattern.quote( extension ) ); | |||
} | |||
} else { | |||
fileNamePattern.append( "[A-Za-z0-9]+" ); | |||
fileNamePattern.append( "[A-Za-z0-9.]+" ); | |||
} | |||
final Pattern pattern = Pattern.compile( fileNamePattern.toString() ); | |||
return p.and( a -> pattern.matcher( a.getName( ) ).matches()); | |||
@@ -918,12 +918,6 @@ public class ManagedDefaultRepositoryContent | |||
return new VersionedReference().groupId( groupId ).artifactId( artifactId ).version( version ); | |||
} | |||
@Override | |||
public VersionedReference toGenericVersion( ArtifactReference artifactReference ) | |||
{ | |||
return toVersion( artifactReference.getGroupId( ), artifactReference.getArtifactId( ), VersionUtil.getBaseVersion( artifactReference.getVersion( ) )); | |||
} | |||
/** | |||
* Return the version the artifact is part of | |||
* @param artifactReference |
@@ -56,6 +56,9 @@ public class MavenContentProvider implements RepositoryContentProvider | |||
@Inject | |||
protected List<? extends ArtifactMappingProvider> artifactMappingProviders; | |||
@Inject | |||
@Named("MavenContentHelper") | |||
MavenContentHelper mavenContentHelper; | |||
private static final Set<RepositoryType> REPOSITORY_TYPES = new HashSet<>( ); | |||
static { | |||
@@ -104,6 +107,7 @@ public class MavenContentProvider implements RepositoryContentProvider | |||
throw new RepositoryException( "Repository layout "+repository.getLayout()+" is not supported by this implementation." ); | |||
} | |||
ManagedDefaultRepositoryContent content = new ManagedDefaultRepositoryContent(repository, artifactMappingProviders, filetypes ,fileLockManager); | |||
content.setMavenContentHelper( mavenContentHelper ); | |||
return content; | |||
} | |||
@@ -28,8 +28,8 @@ | |||
default-lazy-init="true"> | |||
<context:annotation-config/> | |||
<context:component-scan base-package="org.apache.archiva.dependency.tree.maven2,org.apache.archiva.metadata.repository.storage.maven2, | |||
org.apache.archiva.repository.content.maven2"/> | |||
<context:component-scan base-package="org.apache.archiva.repository.maven.dependency.tree,org.apache.archiva.repository.maven.metadata.storage, | |||
org.apache.archiva.repository.maven.content"/> | |||