package org.apache.archiva.consumers.core.repository;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.MetadataResolutionException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.events.RepositoryListener;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Base class for all repository purge tasks.
*/
public abstract class AbstractRepositoryPurge
implements RepositoryPurge
{
protected Logger log = LoggerFactory.getLogger( getClass() );
protected final ManagedRepositoryContent repository;
protected final RepositorySession repositorySession;
protected final List<RepositoryListener> listeners;
private Logger logger = LoggerFactory.getLogger( "org.apache.archiva.AuditLog" );
private static final char DELIM = ' ';
public AbstractRepositoryPurge( ManagedRepositoryContent repository, RepositorySession repositorySession,
List<RepositoryListener> listeners )
{
this.repository = repository;
this.repositorySession = repositorySession;
this.listeners = listeners;
}
/**
* Purge the repo. Update db and index of removed artifacts.
*
* @param references
*/
protected void purge( Set<ArtifactReference> references )
{
if ( references != null && !references.isEmpty() )
{
MetadataRepository metadataRepository = repositorySession.getRepository();
for ( ArtifactReference reference : references )
{
File artifactFile = repository.toFile( reference );
for ( RepositoryListener listener : listeners )
{
listener.deleteArtifact( metadataRepository, repository.getId(), reference.getGroupId(),
reference.getArtifactId(), reference.getVersion(),
artifactFile.getName() );
}
// TODO: this needs to be logged
artifactFile.delete();
try
{
repository.deleteArtifact( reference );
}
catch ( ContentNotFoundException e )
{
log.warn( "skip error deleting artifact {}: {}", reference, e.getMessage() );
}
try
{
metadataRepository.removeProjectVersion( repository.getId(), reference.getGroupId(),
reference.getArtifactId(), reference.getVersion() );
}
catch ( MetadataRepositoryException e )
{
log.warn( "skip error removeProjectVersion artifact {}: {}", reference, e.getMessage() );
}
boolean snapshotVersion = VersionUtil.isSnapshot( reference.getVersion() );
try
{
if ( snapshotVersion )
{
String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
Collection<ArtifactMetadata> artifacts =
metadataRepository.getArtifacts( repository.getId(), reference.getGroupId(),
reference.getArtifactId(), baseVersion );
if ( artifacts != null )
{
// cleanup snapshots metadata
for ( ArtifactMetadata artifactMetadata : artifacts )
{
// TODO: mismatch between artifact (snapshot) version and project (base) version here
if ( artifactMetadata.getVersion().equals( reference.getVersion() ) )
{
if ( StringUtils.isNotBlank( reference.getClassifier() ) )
{
// cleanup facet which contains classifier information
MavenArtifactFacet mavenArtifactFacet =
(MavenArtifactFacet) artifactMetadata.getFacet(
MavenArtifactFacet.FACET_ID );
if ( StringUtils.equals( reference.getClassifier(),
mavenArtifactFacet.getClassifier() ) )
{
artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
String groupId = reference.getGroupId(), artifactId =
reference.getArtifactId(),
version = reference.getVersion();
MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet();
mavenArtifactFacetToCompare.setClassifier( reference.getClassifier() );
metadataRepository.removeArtifact( repository.getId(), groupId, artifactId,
version, mavenArtifactFacetToCompare );
metadataRepository.save();
}
}
else
{
metadataRepository.removeArtifact( artifactMetadata, VersionUtil.getBaseVersion(
reference.getVersion() ) );
}
}
}
}
}
}
catch ( MetadataResolutionException e )
{
log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() );
}
catch ( MetadataRepositoryException e )
{
log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() );
}
repositorySession.save();
triggerAuditEvent( repository.getRepository().getId(), ArtifactReference.toKey( reference ),
AuditEvent.PURGE_ARTIFACT );
purgeSupportFiles( artifactFile );
}
}
}
/**
* <p>
* This find support files for the artifactFile and deletes them.
* </p>
* <p>
* Support Files are things like ".sha1", ".md5", ".asc", etc.
* </p>
*
* @param artifactFile the file to base off of.
*/
private void purgeSupportFiles( File artifactFile )
{
File parentDir = artifactFile.getParentFile();
if ( !parentDir.exists() )
{
return;
}
FilenameFilter filter = new ArtifactFilenameFilter( artifactFile.getName() );
File[] files = parentDir.listFiles( filter );
for ( File file : files )
{
if ( file.exists() && file.isFile() )
{
String fileName = file.getName();
file.delete();
// TODO: log that it was deleted
triggerAuditEvent( repository.getRepository().getId(), fileName, AuditEvent.PURGE_FILE );
}
}
}
private void triggerAuditEvent( String repoId, String resource, String action )
{
String msg =
repoId + DELIM + "<system-purge>" + DELIM + "<system>" + DELIM + '\"' + resource + '\"' + DELIM + '\"' +
action + '\"';
logger.info( msg );
}
}