This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.consumers.core.repository;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.admin.model.RepositoryAdminException;
023import org.apache.archiva.admin.model.beans.ManagedRepository;
024import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
025import org.apache.archiva.common.utils.VersionComparator;
026import org.apache.archiva.common.utils.VersionUtil;
027import org.apache.archiva.metadata.repository.MetadataRepository;
028import org.apache.archiva.metadata.repository.MetadataRepositoryException;
029import org.apache.archiva.metadata.repository.RepositorySession;
030import org.apache.archiva.model.ArtifactReference;
031import org.apache.archiva.model.ProjectReference;
032import org.apache.archiva.model.VersionedReference;
033import org.apache.archiva.repository.ContentNotFoundException;
034import org.apache.archiva.repository.ManagedRepositoryContent;
035import org.apache.archiva.repository.RepositoryContentFactory;
036import org.apache.archiva.repository.RepositoryException;
037import org.apache.archiva.repository.RepositoryNotFoundException;
038import org.apache.archiva.repository.events.RepositoryListener;
039import org.apache.archiva.repository.layout.LayoutException;
040import org.apache.archiva.repository.metadata.MetadataTools;
041import org.apache.archiva.repository.metadata.RepositoryMetadataException;
042
043import java.io.File;
044import java.io.IOException;
045import java.util.ArrayList;
046import java.util.Collections;
047import java.util.List;
048
049/**
050 * <p>
051 * This will look in a single managed repository, and purge any snapshots that are present
052 * that have a corresponding released version on the same repository.
053 * </p>
054 * <p>
055 * So, if you have the following (presented in the m2/default layout form) ...
056 * <pre>
057 *   /com/foo/foo-tool/1.0-SNAPSHOT/foo-tool-1.0-SNAPSHOT.jar
058 *   /com/foo/foo-tool/1.1-SNAPSHOT/foo-tool-1.1-SNAPSHOT.jar
059 *   /com/foo/foo-tool/1.2.1-SNAPSHOT/foo-tool-1.2.1-SNAPSHOT.jar
060 *   /com/foo/foo-tool/1.2.1/foo-tool-1.2.1.jar
061 *   /com/foo/foo-tool/2.0-SNAPSHOT/foo-tool-2.0-SNAPSHOT.jar
062 *   /com/foo/foo-tool/2.0/foo-tool-2.0.jar
063 *   /com/foo/foo-tool/2.1-SNAPSHOT/foo-tool-2.1-SNAPSHOT.jar
064 * </pre>
065 * then the current highest ranked released (non-snapshot) version is 2.0, which means
066 * the snapshots from 1.0-SNAPSHOT, 1.1-SNAPSHOT, 1.2.1-SNAPSHOT, and 2.0-SNAPSHOT can
067 * be purged.  Leaving 2.1-SNAPSHOT in alone.
068 */
069public class CleanupReleasedSnapshotsRepositoryPurge
070    extends AbstractRepositoryPurge
071{
072    private MetadataTools metadataTools;
073
074    private ManagedRepositoryAdmin managedRepositoryAdmin;
075
076    private RepositoryContentFactory repoContentFactory;
077
078    public CleanupReleasedSnapshotsRepositoryPurge( ManagedRepositoryContent repository, MetadataTools metadataTools,
079                                                    ManagedRepositoryAdmin managedRepositoryAdmin,
080                                                    RepositoryContentFactory repoContentFactory,
081                                                    RepositorySession repositorySession,
082                                                    List<RepositoryListener> listeners )
083    {
084        super( repository, repositorySession, listeners );
085        this.metadataTools = metadataTools;
086        this.managedRepositoryAdmin = managedRepositoryAdmin;
087        this.repoContentFactory = repoContentFactory;
088    }
089
090    @Override
091    public void process( String path )
092        throws RepositoryPurgeException
093    {
094        try
095        {
096            File artifactFile = new File( repository.getRepoRoot( ), path );
097
098            if ( !artifactFile.exists( ) )
099            {
100                // Nothing to do here, file doesn't exist, skip it.
101                return;
102            }
103
104            ArtifactReference artifactRef = repository.toArtifactReference( path );
105
106            if ( !VersionUtil.isSnapshot( artifactRef.getVersion( ) ) )
107            {
108                // Nothing to do here, not a snapshot, skip it.
109                return;
110            }
111
112            ProjectReference reference = new ProjectReference( );
113            reference.setGroupId( artifactRef.getGroupId( ) );
114            reference.setArtifactId( artifactRef.getArtifactId( ) );
115
116            // Gether the released versions
117            List<String> releasedVersions = new ArrayList<>( );
118
119            List<ManagedRepository> repos = managedRepositoryAdmin.getManagedRepositories( );
120            for ( ManagedRepository repo : repos )
121            {
122                if ( repo.isReleases( ) )
123                {
124                    try
125                    {
126                        ManagedRepositoryContent repoContent =
127                            repoContentFactory.getManagedRepositoryContent( repo.getId( ) );
128                        for ( String version : repoContent.getVersions( reference ) )
129                        {
130                            if ( !VersionUtil.isSnapshot( version ) )
131                            {
132                                releasedVersions.add( version );
133                            }
134                        }
135                    }
136                    catch ( RepositoryNotFoundException e )
137                    {
138                        // swallow
139                    }
140                    catch ( RepositoryException e )
141                    {
142                        // swallow
143                    }
144                }
145            }
146
147            Collections.sort( releasedVersions, VersionComparator.getInstance( ) );
148
149            // Now clean out any version that is earlier than the highest released version.
150            boolean needsMetadataUpdate = false;
151
152            VersionedReference versionRef = new VersionedReference( );
153            versionRef.setGroupId( artifactRef.getGroupId( ) );
154            versionRef.setArtifactId( artifactRef.getArtifactId( ) );
155
156            MetadataRepository metadataRepository = repositorySession.getRepository( );
157
158            if ( releasedVersions.contains( VersionUtil.getReleaseVersion( artifactRef.getVersion( ) ) ) )
159            {
160                versionRef.setVersion( artifactRef.getVersion( ) );
161                repository.deleteVersion( versionRef );
162
163                for ( RepositoryListener listener : listeners )
164                {
165                    listener.deleteArtifact( metadataRepository, repository.getId( ), artifactRef.getGroupId( ),
166                        artifactRef.getArtifactId( ), artifactRef.getVersion( ),
167                        artifactFile.getName( ) );
168                }
169                metadataRepository.removeProjectVersion( repository.getId( ), artifactRef.getGroupId( ),
170                    artifactRef.getArtifactId( ), artifactRef.getVersion( ) );
171
172                needsMetadataUpdate = true;
173            }
174
175            if ( needsMetadataUpdate )
176            {
177                updateMetadata( artifactRef );
178            }
179        }
180        catch ( RepositoryAdminException e )
181        {
182            throw new RepositoryPurgeException( e.getMessage( ), e );
183        }
184        catch ( LayoutException e )
185        {
186            log.debug( "Not processing file that is not an artifact: {}", e.getMessage( ) );
187        }
188        catch ( ContentNotFoundException e )
189        {
190            throw new RepositoryPurgeException( e.getMessage( ), e );
191        }
192        catch ( MetadataRepositoryException e )
193        {
194            log.error( "Could not remove metadata during cleanup of released snapshots of {}", path, e );
195        }
196    }
197
198    private void updateMetadata( ArtifactReference artifact )
199    {
200        VersionedReference versionRef = new VersionedReference( );
201        versionRef.setGroupId( artifact.getGroupId( ) );
202        versionRef.setArtifactId( artifact.getArtifactId( ) );
203        versionRef.setVersion( artifact.getVersion( ) );
204
205        ProjectReference projectRef = new ProjectReference( );
206        projectRef.setGroupId( artifact.getGroupId( ) );
207        projectRef.setArtifactId( artifact.getArtifactId( ) );
208
209        try
210        {
211            metadataTools.updateMetadata( repository, versionRef );
212        }
213        catch ( ContentNotFoundException e )
214        {
215            // Ignore. (Just means we have no snapshot versions left to reference).
216        }
217        catch ( RepositoryMetadataException e )
218        {
219            // Ignore. 
220        }
221        catch ( IOException e )
222        {
223            // Ignore. 
224        }
225        catch ( LayoutException e )
226        {
227            // Ignore.
228        }
229
230        try
231        {
232            metadataTools.updateMetadata( repository, projectRef );
233        }
234        catch ( ContentNotFoundException e )
235        {
236            // Ignore. (Just means we have no snapshot versions left to reference).
237        }
238        catch ( RepositoryMetadataException e )
239        {
240            // Ignore. 
241        }
242        catch ( IOException e )
243        {
244            // Ignore. 
245        }
246        catch ( LayoutException e )
247        {
248            // Ignore.
249        }
250    }
251}