]> source.dussan.org Git - archiva.git/blob
04720762dd2a5bed379a5077ad2a80ef1c518061
[archiva.git] /
1 package org.apache.maven.archiva.reporting.processor;
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.maven.archiva.reporting.database.ReportingDatabase;
23 import org.apache.maven.artifact.Artifact;
24 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
25 import org.apache.maven.artifact.repository.ArtifactRepository;
26 import org.apache.maven.model.Model;
27
28 import java.io.File;
29 import java.io.FilenameFilter;
30 import java.text.ParseException;
31 import java.text.SimpleDateFormat;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.regex.Matcher;
38
39 /**
40  * Find snapshot artifacts in the repository that are considered old.
41  *
42  * @plexus.component role="org.apache.maven.archiva.reporting.processor.ArtifactReportProcessor" role-hint="old-snapshot-artifact"
43  * @todo make this configurable from the web interface
44  */
45 public class OldSnapshotArtifactReportProcessor
46     implements ArtifactReportProcessor
47 {
48     private static final String ROLE_HINT = "old-snapshot-artifact";
49
50     /**
51      * The maximum age of an artifact before it is reported old, specified in seconds. The default is 1 year.
52      *
53      * @plexus.configuration default-value="31536000"
54      */
55     private int maxAge;
56
57     /**
58      * The maximum number of snapshots to retain within a given version. The default is 0, which keeps all snapshots
59      * that are within the age limits.
60      *
61      * @plexus.configuration default-value="0"
62      */
63     private int maxSnapshots;
64
65     public void processArtifact( final Artifact artifact, Model model, ReportingDatabase reporter )
66     {
67         ArtifactRepository repository = artifact.getRepository();
68
69         if ( !"file".equals( repository.getProtocol() ) )
70         {
71             // We can't check other types of URLs yet. Need to use Wagon, with an exists() method.
72             throw new UnsupportedOperationException(
73                 "Can't process repository '" + repository.getUrl() + "'. Only file based repositories are supported" );
74         }
75
76         adjustDistributionArtifactHandler( artifact );
77
78         String artifactPath = repository.pathOf( artifact );
79
80         //get the location of the artifact itself
81         File file = new File( repository.getBasedir(), artifactPath );
82
83         if ( file.exists() )
84         {
85             if ( artifact.isSnapshot() )
86             {
87                 Matcher m = Artifact.VERSION_FILE_PATTERN.matcher( artifact.getVersion() );
88                 if ( m.matches() )
89                 {
90                     long timestamp;
91                     try
92                     {
93                         timestamp = new SimpleDateFormat( "yyyyMMdd.HHmmss" ).parse( m.group( 2 ) ).getTime();
94                     }
95                     catch ( ParseException e )
96                     {
97                         throw new IllegalStateException(
98                             "Shouldn't match timestamp pattern and not be able to parse it: " + m.group( 2 ) );
99                     }
100
101                     if ( System.currentTimeMillis() - timestamp > maxAge * 1000 )
102                     {
103                         addNotice( reporter, artifact, "snapshot-expired-time",
104                                    "The artifact is older than the maximum age of " + maxAge + " seconds." );
105                     }
106                     else if ( maxSnapshots > 0 )
107                     {
108                         File[] files = file.getParentFile().listFiles( new FilenameFilter()
109                         {
110                             public boolean accept( File file, String string )
111                             {
112                                 return string.startsWith( artifact.getArtifactId() + "-" ) &&
113                                     string.endsWith( "." + artifact.getArtifactHandler().getExtension() );
114                             }
115                         } );
116
117                         List/*<Integer>*/ buildNumbers = new ArrayList();
118                         Integer currentBuild = null;
119                         for ( Iterator i = Arrays.asList( files ).iterator(); i.hasNext(); )
120                         {
121                             File f = (File) i.next();
122
123                             // trim to version
124                             int startIndex = artifact.getArtifactId().length() + 1;
125                             int extensionLength = artifact.getArtifactHandler().getExtension().length() + 1;
126                             int endIndex = f.getName().length() - extensionLength;
127                             String name = f.getName().substring( startIndex, endIndex );
128
129                             Matcher matcher = Artifact.VERSION_FILE_PATTERN.matcher( name );
130
131                             if ( matcher.matches() )
132                             {
133                                 Integer buildNumber = Integer.valueOf( matcher.group( 3 ) );
134
135                                 buildNumbers.add( buildNumber );
136                                 if ( name.equals( artifact.getVersion() ) )
137                                 {
138                                     currentBuild = buildNumber;
139                                 }
140                             }
141                         }
142
143                         // Prune back to expired build numbers
144                         Collections.sort( buildNumbers );
145                         for ( int i = 0; i < maxSnapshots && !buildNumbers.isEmpty(); i++ )
146                         {
147                             buildNumbers.remove( buildNumbers.size() - 1 );
148                         }
149
150                         if ( buildNumbers.contains( currentBuild ) )
151                         {
152                             addNotice( reporter, artifact, "snapshot-expired-count",
153                                        "The artifact is older than the maximum number of retained snapshot builds." );
154                         }
155                     }
156                 }
157             }
158         }
159         else
160         {
161             throw new IllegalStateException( "Couldn't find artifact " + file );
162         }
163     }
164
165     private static void addNotice( ReportingDatabase reporter, Artifact artifact, String problem, String reason )
166     {
167         // TODO: reason could be an i18n key derived from the processor and the problem ID and the
168         reporter.addNotice( artifact, ROLE_HINT, problem, reason );
169     }
170
171     private static void adjustDistributionArtifactHandler( Artifact artifact )
172     {
173         // need to tweak these as they aren't currently in the known type converters. TODO - add them in Maven
174         if ( "distribution-zip".equals( artifact.getType() ) )
175         {
176             artifact.setArtifactHandler( new DefaultArtifactHandler( "zip" ) );
177         }
178         else if ( "distribution-tgz".equals( artifact.getType() ) )
179         {
180             artifact.setArtifactHandler( new DefaultArtifactHandler( "tar.gz" ) );
181         }
182     }
183 }