]> source.dussan.org Git - archiva.git/blob
069730689e928f9039ff0cef1ddcdd44a0f1cd3f
[archiva.git] /
1 package org.apache.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.archiva.common.utils.VersionComparator;
23 import org.apache.archiva.common.utils.VersionUtil;
24 import org.apache.archiva.metadata.repository.MetadataRepository;
25 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
26 import org.apache.archiva.metadata.repository.RepositorySession;
27 import org.apache.archiva.model.ArtifactReference;
28 import org.apache.archiva.model.ProjectReference;
29 import org.apache.archiva.model.VersionedReference;
30 import org.apache.archiva.repository.ContentNotFoundException;
31 import org.apache.archiva.repository.ManagedRepositoryContent;
32 import org.apache.archiva.repository.LayoutException;
33 import org.apache.archiva.repository.BaseRepositoryContentLayout;
34 import org.apache.archiva.repository.ReleaseScheme;
35 import org.apache.archiva.repository.RepositoryRegistry;
36 import org.apache.archiva.metadata.audit.RepositoryListener;
37 import org.apache.archiva.repository.content.ItemSelector;
38 import org.apache.archiva.repository.content.Project;
39 import org.apache.archiva.repository.content.Version;
40 import org.apache.archiva.repository.content.base.ArchivaItemSelector;
41 import org.apache.archiva.repository.metadata.base.MetadataTools;
42 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
43 import org.apache.archiva.repository.storage.StorageAsset;
44
45 import java.io.IOException;
46 import java.util.ArrayList;
47 import java.util.Collection;
48 import java.util.Collections;
49 import java.util.List;
50
51 /**
52  * <p>
53  * This will look in a single managed repository, and purge any snapshots that are present
54  * that have a corresponding released version on the same repository.
55  * </p>
56  * <p>
57  * So, if you have the following (presented in the m2/default layout form) ...
58  * <pre>
59  *   /com/foo/foo-tool/1.0-SNAPSHOT/foo-tool-1.0-SNAPSHOT.jar
60  *   /com/foo/foo-tool/1.1-SNAPSHOT/foo-tool-1.1-SNAPSHOT.jar
61  *   /com/foo/foo-tool/1.2.1-SNAPSHOT/foo-tool-1.2.1-SNAPSHOT.jar
62  *   /com/foo/foo-tool/1.2.1/foo-tool-1.2.1.jar
63  *   /com/foo/foo-tool/2.0-SNAPSHOT/foo-tool-2.0-SNAPSHOT.jar
64  *   /com/foo/foo-tool/2.0/foo-tool-2.0.jar
65  *   /com/foo/foo-tool/2.1-SNAPSHOT/foo-tool-2.1-SNAPSHOT.jar
66  * </pre>
67  * then the current highest ranked released (non-snapshot) version is 2.0, which means
68  * the snapshots from 1.0-SNAPSHOT, 1.1-SNAPSHOT, 1.2.1-SNAPSHOT, and 2.0-SNAPSHOT can
69  * be purged.  Leaving 2.1-SNAPSHOT in alone.
70  */
71 public class CleanupReleasedSnapshotsRepositoryPurge
72     extends AbstractRepositoryPurge
73 {
74     private MetadataTools metadataTools;
75
76     private RepositoryRegistry repositoryRegistry;
77
78     public CleanupReleasedSnapshotsRepositoryPurge( ManagedRepositoryContent repository, MetadataTools metadataTools,
79                                                     RepositoryRegistry repositoryRegistry,
80                                                     RepositorySession repositorySession,
81                                                     List<RepositoryListener> listeners )
82     {
83         super( repository, repositorySession, listeners );
84         this.metadataTools = metadataTools;
85         this.repositoryRegistry = repositoryRegistry;
86     }
87
88     @Override
89     public void process( String path )
90         throws RepositoryPurgeException
91     {
92         try
93         {
94             StorageAsset artifactFile = repository.getRepository( ).getAsset( "" ).resolve( path );
95             BaseRepositoryContentLayout layout = repository.getLayout( BaseRepositoryContentLayout.class );
96
97             if ( !artifactFile.exists() )
98             {
99                 // Nothing to do here, file doesn't exist, skip it.
100                 return;
101             }
102
103             ArtifactReference artifactRef = repository.toArtifactReference( path );
104
105             if ( !VersionUtil.isSnapshot( artifactRef.getVersion( ) ) )
106             {
107                 // Nothing to do here, not a snapshot, skip it.
108                 return;
109             }
110
111             ItemSelector selector = ArchivaItemSelector.builder( )
112                 .withNamespace( artifactRef.getGroupId( ) )
113                 .withProjectId( artifactRef.getArtifactId( ) )
114                 .build();
115
116
117             // Gether the released versions
118             List<String> releasedVersions = new ArrayList<>( );
119
120             Collection<org.apache.archiva.repository.ManagedRepository> repos = repositoryRegistry.getManagedRepositories( );
121             for ( org.apache.archiva.repository.ManagedRepository repo : repos )
122             {
123
124                 if ( repo.getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE ))
125                 {
126                     BaseRepositoryContentLayout repoContent = repo.getContent().getLayout( BaseRepositoryContentLayout.class );
127                     Project proj = repoContent.getProject( selector );
128                     for ( Version version : repoContent.getVersions( proj ) )
129                     {
130                         if ( !VersionUtil.isSnapshot( version.getVersion() ) )
131                         {
132                             releasedVersions.add( version.getVersion() );
133                         }
134                     }
135                 }
136             }
137
138             Collections.sort( releasedVersions, VersionComparator.getInstance( ) );
139
140             // Now clean out any version that is earlier than the highest released version.
141             boolean needsMetadataUpdate = false;
142
143             VersionedReference versionRef = new VersionedReference( );
144             versionRef.setGroupId( artifactRef.getGroupId( ) );
145             versionRef.setArtifactId( artifactRef.getArtifactId( ) );
146
147             MetadataRepository metadataRepository = repositorySession.getRepository( );
148
149             if ( releasedVersions.contains( VersionUtil.getReleaseVersion( artifactRef.getVersion( ) ) ) )
150             {
151                 versionRef.setVersion( artifactRef.getVersion( ) );
152                 layout.deleteVersion( versionRef );
153
154                 for ( RepositoryListener listener : listeners )
155                 {
156                     listener.deleteArtifact( metadataRepository, repository.getId( ), artifactRef.getGroupId( ),
157                         artifactRef.getArtifactId( ), artifactRef.getVersion( ),
158                         artifactFile.getName() );
159                 }
160                 metadataRepository.removeProjectVersion( repositorySession, repository.getId( ),
161                     artifactRef.getGroupId( ), artifactRef.getArtifactId( ), artifactRef.getVersion( ) );
162
163                 needsMetadataUpdate = true;
164             }
165
166             if ( needsMetadataUpdate )
167             {
168                 updateMetadata( artifactRef );
169             }
170         }
171         catch ( LayoutException e )
172         {
173             log.debug( "Not processing file that is not an artifact: {}", e.getMessage( ) );
174         }
175         catch ( ContentNotFoundException e )
176         {
177             throw new RepositoryPurgeException( e.getMessage( ), e );
178         }
179         catch ( MetadataRepositoryException e )
180         {
181             log.error( "Could not remove metadata during cleanup of released snapshots of {}", path, e );
182         }
183         catch ( org.apache.archiva.repository.ContentAccessException e )
184         {
185             e.printStackTrace( );
186         }
187     }
188
189
190     /*
191      * TODO: Uses a deprecated API, but if we use the API with location string, it does not work as expected
192      * -> not sure what needs to be changed here.
193      */
194     @SuppressWarnings( "deprecation" )
195     private void updateMetadata( ArtifactReference artifact )
196     {
197         VersionedReference versionRef = new VersionedReference( );
198         versionRef.setGroupId( artifact.getGroupId( ) );
199         versionRef.setArtifactId( artifact.getArtifactId( ) );
200         versionRef.setVersion( artifact.getVersion( ) );
201
202         ProjectReference projectRef = new ProjectReference( );
203         projectRef.setGroupId( artifact.getGroupId( ) );
204         projectRef.setArtifactId( artifact.getArtifactId( ) );
205
206         try
207         {
208             metadataTools.updateMetadata( repository, versionRef );
209         }
210         catch ( ContentNotFoundException e )
211         {
212             // Ignore. (Just means we have no snapshot versions left to reference).
213         }
214         catch ( RepositoryMetadataException e )
215         {
216             // Ignore.
217         }
218         catch ( IOException e )
219         {
220             // Ignore.
221         }
222         catch ( LayoutException e )
223         {
224             // Ignore.
225         }
226
227         try
228         {
229             metadataTools.updateMetadata( repository, projectRef );
230         }
231         catch ( ContentNotFoundException e )
232         {
233             // Ignore. (Just means we have no snapshot versions left to reference).
234         }
235         catch ( RepositoryMetadataException e )
236         {
237             // Ignore.
238         }
239         catch ( IOException e )
240         {
241             // Ignore.
242         }
243         catch ( LayoutException e )
244         {
245             // Ignore.
246         }
247     }
248 }