]> source.dussan.org Git - archiva.git/blob
e08a282dcbe2bdee5c313761326716a1ec70fa30
[archiva.git] /
1 package org.apache.maven.archiva.consumers.core.repository;
2
3 /*
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
11 *
12 *  http://www.apache.org/licenses/LICENSE-2.0
13 *
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
19 * under the License.
20 */
21
22 import org.apache.commons.lang.time.DateUtils;
23 import org.apache.maven.archiva.common.utils.VersionComparator;
24 import org.apache.maven.archiva.common.utils.VersionUtil;
25 import org.apache.maven.archiva.database.ArtifactDAO;
26 import org.apache.maven.archiva.indexer.RepositoryContentIndex;
27 import org.apache.maven.archiva.model.ArtifactReference;
28 import org.apache.maven.archiva.model.VersionedReference;
29 import org.apache.maven.archiva.repository.ContentNotFoundException;
30 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
31 import org.apache.maven.archiva.repository.layout.LayoutException;
32
33 import java.io.File;
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.Calendar;
38 import java.util.Collections;
39 import java.util.Date;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Set;
43 import java.util.regex.Matcher;
44
45 /**
46  * Purge from repository all snapshots older than the specified days in the repository configuration.
47  *
48  * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
49  */
50 public class DaysOldRepositoryPurge
51     extends AbstractRepositoryPurge
52 {
53     private SimpleDateFormat timestampParser;
54
55     private int daysOlder;
56     
57     private int retentionCount;
58     
59     public DaysOldRepositoryPurge( ManagedRepositoryContent repository, ArtifactDAO artifactDao,
60                                    int daysOlder, int retentionCount, Map<String, RepositoryContentIndex> indices )
61     {
62         super( repository, artifactDao, indices );
63         this.daysOlder = daysOlder;
64         this.retentionCount = retentionCount;
65         timestampParser = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
66         timestampParser.setTimeZone( DateUtils.UTC_TIME_ZONE );
67     }
68
69     public void process( String path )
70         throws RepositoryPurgeException
71     {
72         try
73         {
74             File artifactFile = new File( repository.getRepoRoot(), path );
75
76             if ( !artifactFile.exists() )
77             {
78                 return;
79             }
80
81             ArtifactReference artifact = repository.toArtifactReference( path );
82
83             Calendar olderThanThisDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
84             olderThanThisDate.add( Calendar.DATE, -daysOlder );
85
86             // respect retention count
87             VersionedReference reference = new VersionedReference();
88             reference.setGroupId( artifact.getGroupId() );
89             reference.setArtifactId( artifact.getArtifactId() );
90             reference.setVersion( artifact.getVersion() );
91
92             List<String> versions = new ArrayList<String>( repository.getVersions( reference ) );
93
94             Collections.sort( versions, VersionComparator.getInstance() );
95             
96             
97             // Is this a generic snapshot "1.0-SNAPSHOT" ?
98             if ( VersionUtil.isGenericSnapshot( artifact.getVersion() ) )
99             {
100                 if ( artifactFile.lastModified() < olderThanThisDate.getTimeInMillis() )
101                 {                    
102                     if ( retentionCount > versions.size() )
103                     {
104                         // Done. nothing to do here. skip it.
105                         return;
106                     }
107                                         
108                     purgeArtifact( versions, artifactFile );
109                 }
110             }
111             // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
112             else if ( VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
113             {
114                 Calendar timestampCal = uniqueSnapshotToCalendar( artifact.getVersion() );
115
116                 if ( timestampCal.getTimeInMillis() < olderThanThisDate.getTimeInMillis() )
117                 {                    
118                     if ( retentionCount > versions.size() )
119                     {
120                         // Done. nothing to do here. skip it.
121                         return;
122                     }
123                     
124                     purgeArtifact( versions, artifactFile );                    
125                 }
126                 else if ( artifactFile.lastModified() < olderThanThisDate.getTimeInMillis() )
127                 {                    
128
129                     if ( retentionCount > versions.size() )
130                     {
131                         // Done. nothing to do here. skip it.
132                         return;
133                     }
134                     
135                     purgeArtifact( versions, artifactFile );                    
136                 }
137             }
138         }
139         catch ( LayoutException le )
140         {
141             throw new RepositoryPurgeException( le.getMessage() );
142         }
143         catch ( ContentNotFoundException e )
144         {
145             throw new RepositoryPurgeException( e.getMessage() );
146         }
147     }
148
149     private Calendar uniqueSnapshotToCalendar( String version )
150     {
151         // The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8"
152         // This needs to be broken down into ${base}-${timestamp}-${build_number}
153
154         Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( version );
155         if ( m.matches() )
156         {
157             Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
158             if ( mtimestamp.matches() )
159             {
160                 String tsDate = mtimestamp.group( 1 );
161                 String tsTime = mtimestamp.group( 2 );
162
163                 Date versionDate;
164                 try
165                 {
166                     versionDate = timestampParser.parse( tsDate + "." + tsTime );
167                     Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
168                     cal.setTime( versionDate );
169
170                     return cal;
171                 }
172                 catch ( ParseException e )
173                 {
174                     // Invalid Date/Time
175                     return null;
176                 }
177             }
178         }
179         return null;
180     }
181
182     private void doPurgeAllRelated( File artifactFile ) throws LayoutException
183     {
184         ArtifactReference reference = repository.toArtifactReference( artifactFile.getAbsolutePath() );
185         
186         try
187         {
188             Set<ArtifactReference> related = repository.getRelatedArtifacts( reference );
189             purge( related );
190         }
191         catch ( ContentNotFoundException e )
192         {
193             // Nothing to do here.
194             // TODO: Log this?
195         }
196     }
197     
198     private void purgeArtifact( List<String> versions, File artifactFile )
199         throws LayoutException
200     {
201         int countToPurge = versions.size() - retentionCount;
202
203         while( versions.iterator().hasNext() )
204         {
205             if ( countToPurge-- <= 0 )
206             {
207                 break;
208             }
209             doPurgeAllRelated( artifactFile );
210         }
211     }
212 }