1 package org.apache.archiva.consumers.core.repository;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.common.utils.VersionComparator;
23 import org.apache.archiva.common.utils.VersionUtil;
24 import org.apache.archiva.metadata.repository.RepositorySession;
25 import org.apache.archiva.model.ArtifactReference;
26 import org.apache.archiva.model.VersionedReference;
27 import org.apache.archiva.repository.ContentNotFoundException;
28 import org.apache.archiva.repository.LayoutException;
29 import org.apache.archiva.repository.ManagedRepositoryContent;
30 import org.apache.archiva.metadata.audit.RepositoryListener;
31 import org.apache.archiva.repository.storage.StorageAsset;
33 import java.nio.file.Files;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.text.ParseException;
37 import java.text.SimpleDateFormat;
39 import java.util.regex.Matcher;
42 * Purge from repository all snapshots older than the specified days in the repository configuration.
44 public class DaysOldRepositoryPurge
45 extends AbstractRepositoryPurge
47 private SimpleDateFormat timestampParser;
49 private int retentionPeriod;
51 private int retentionCount;
53 public DaysOldRepositoryPurge( ManagedRepositoryContent repository, int retentionPeriod, int retentionCount,
54 RepositorySession repositorySession, List<RepositoryListener> listeners )
56 super( repository, repositorySession, listeners );
57 this.retentionPeriod = retentionPeriod;
58 this.retentionCount = retentionCount;
59 timestampParser = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
60 timestampParser.setTimeZone( TimeZone.getTimeZone("UTC"));
64 public void process( String path )
65 throws RepositoryPurgeException
69 Path artifactFile = Paths.get( repository.getRepoRoot( ), path );
71 if ( !Files.exists(artifactFile) )
76 ArtifactReference artifact = repository.toArtifactReference( path );
78 Calendar olderThanThisDate = Calendar.getInstance( TimeZone.getTimeZone("UTC") );
79 olderThanThisDate.add( Calendar.DATE, -retentionPeriod );
81 // respect retention count
82 VersionedReference reference = new VersionedReference( );
83 reference.setGroupId( artifact.getGroupId( ) );
84 reference.setArtifactId( artifact.getArtifactId( ) );
85 reference.setVersion( artifact.getVersion( ) );
87 List<String> versions = new ArrayList<>( repository.getVersions( reference ) );
89 Collections.sort( versions, VersionComparator.getInstance( ) );
91 if ( retentionCount > versions.size( ) )
93 // Done. nothing to do here. skip it.
97 int countToPurge = versions.size( ) - retentionCount;
99 Set<ArtifactReference> artifactsToDelete = new HashSet<>( );
100 for ( String version : versions )
102 if ( countToPurge-- <= 0 )
107 ArtifactReference newArtifactReference = repository.toArtifactReference(
108 artifactFile.toAbsolutePath( ).toString() );
109 newArtifactReference.setVersion( version );
111 StorageAsset newArtifactFile = repository.toFile( newArtifactReference );
113 // Is this a generic snapshot "1.0-SNAPSHOT" ?
114 if ( VersionUtil.isGenericSnapshot( newArtifactReference.getVersion( ) ) )
116 if ( newArtifactFile.getModificationTime().toEpochMilli() < olderThanThisDate.getTimeInMillis( ) )
118 artifactsToDelete.addAll( repository.getRelatedArtifacts( newArtifactReference ) );
121 // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
122 else if ( VersionUtil.isUniqueSnapshot( newArtifactReference.getVersion( ) ) )
124 Calendar timestampCal = uniqueSnapshotToCalendar( newArtifactReference.getVersion( ) );
126 if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) )
128 artifactsToDelete.addAll( repository.getRelatedArtifacts( newArtifactReference ) );
132 purge( artifactsToDelete );
134 catch ( ContentNotFoundException e )
136 throw new RepositoryPurgeException( e.getMessage( ), e );
138 catch ( LayoutException e )
140 log.debug( "Not processing file that is not an artifact: {}", e.getMessage( ) );
144 private Calendar uniqueSnapshotToCalendar( String version )
146 // The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8"
147 // This needs to be broken down into ${base}-${timestamp}-${build_number}
149 Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( version );
152 Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
153 if ( mtimestamp.matches( ) )
155 String tsDate = mtimestamp.group( 1 );
156 String tsTime = mtimestamp.group( 2 );
161 versionDate = timestampParser.parse( tsDate + "." + tsTime );
162 Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("UTC") );
163 cal.setTime( versionDate );
167 catch ( ParseException e )