package org.apache.maven.archiva.repository.scanner;
/*
* 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 java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.IfClosure;
import org.apache.maven.archiva.common.utils.BaseFile;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.RepositoryScanningConfiguration;
import org.apache.maven.archiva.consumers.InvalidRepositoryContentConsumer;
import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer;
import org.apache.maven.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
import org.apache.maven.archiva.repository.scanner.functors.ConsumerWantsFilePredicate;
import org.apache.maven.archiva.repository.scanner.functors.TriggerBeginScanClosure;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* RepositoryContentConsumerUtil
*
* @version $Id: RepositoryContentConsumers.java 798403 2009-07-28 05:04:44Z oching $
*/
public class RepositoryContentConsumers
implements ApplicationContextAware
{
private ApplicationContext applicationContext;
private ArchivaConfiguration archivaConfiguration;
private List<KnownRepositoryContentConsumer> selectedKnownConsumers;
private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers;
public RepositoryContentConsumers( ArchivaConfiguration archivaConfiguration )
{
this.archivaConfiguration = archivaConfiguration;
}
public void setApplicationContext( ApplicationContext applicationContext )
throws BeansException
{
this.applicationContext = applicationContext;
}
/**
* <p>
* Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have been selected in the
* configuration to execute.
* </p>
* <p>
* NOTE: This list can be larger and contain entries that might not exist or be available in the classpath, or as a
* component.
* </p>
*
* @return the list of consumer ids that have been selected by the configuration.
*/
public List<String> getSelectedKnownConsumerIds()
{
RepositoryScanningConfiguration scanning = archivaConfiguration.getConfiguration().getRepositoryScanning();
return scanning.getKnownContentConsumers();
}
/**
* <p>
* Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have been selected in the
* configuration to execute.
* </p>
* <p>
* NOTE: This list can be larger and contain entries that might not exist or be available in the classpath, or as a
* component.
* </p>
*
* @return the list of consumer ids that have been selected by the configuration.
*/
public List<String> getSelectedInvalidConsumerIds()
{
RepositoryScanningConfiguration scanning = archivaConfiguration.getConfiguration().getRepositoryScanning();
return scanning.getInvalidContentConsumers();
}
/**
* Get the map of {@link String} ids to {@link KnownRepositoryContentConsumer} implementations, for those consumers
* that have been selected according to the active configuration.
*
* @return the map of String ids to {@link KnownRepositoryContentConsumer} objects.
*/
public Map<String, KnownRepositoryContentConsumer> getSelectedKnownConsumersMap()
{
Map<String, KnownRepositoryContentConsumer> consumerMap = new HashMap<String, KnownRepositoryContentConsumer>();
for ( KnownRepositoryContentConsumer consumer : getSelectedKnownConsumers() )
{
consumerMap.put( consumer.getId(), consumer );
}
return consumerMap;
}
/**
* Get the map of {@link String} ids to {@link InvalidRepositoryContentConsumer} implementations, for those
* consumers that have been selected according to the active configuration.
*
* @return the map of String ids to {@link InvalidRepositoryContentConsumer} objects.
*/
public Map<String, InvalidRepositoryContentConsumer> getSelectedInvalidConsumersMap()
{
Map<String, InvalidRepositoryContentConsumer> consumerMap =
new HashMap<String, InvalidRepositoryContentConsumer>();
for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() )
{
consumerMap.put( consumer.getId(), consumer );
}
return consumerMap;
}
/**
* Get the list of {@link KnownRepositoryContentConsumer} objects that are selected according to the active
* configuration.
*
* @return the list of {@link KnownRepositoryContentConsumer} that have been selected by the active configuration.
*/
public synchronized List<KnownRepositoryContentConsumer> getSelectedKnownConsumers()
{
if ( selectedKnownConsumers == null )
{
List<KnownRepositoryContentConsumer> ret = new ArrayList<KnownRepositoryContentConsumer>();
List<String> knownSelected = getSelectedKnownConsumerIds();
for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() )
{
if ( knownSelected.contains( consumer.getId() ) || consumer.isPermanent() )
{
ret.add( consumer );
}
}
this.selectedKnownConsumers = ret;
}
return selectedKnownConsumers;
}
/**
* Get the list of {@link InvalidRepositoryContentConsumer} objects that are selected according to the active
* configuration.
*
* @return the list of {@link InvalidRepositoryContentConsumer} that have been selected by the active configuration.
*/
public synchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers()
{
if ( selectedInvalidConsumers == null )
{
List<InvalidRepositoryContentConsumer> ret = new ArrayList<InvalidRepositoryContentConsumer>();
List<String> invalidSelected = getSelectedInvalidConsumerIds();
for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() )
{
if ( invalidSelected.contains( consumer.getId() ) || consumer.isPermanent() )
{
ret.add( consumer );
}
}
selectedInvalidConsumers = ret;
}
return selectedInvalidConsumers;
}
/**
* Get the list of {@link KnownRepositoryContentConsumer} objects that are available and present in the classpath
* and as components in the IoC.
*
* @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath and as a
* component in the IoC.
*/
@SuppressWarnings("unchecked")
public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers()
{
return new ArrayList<KnownRepositoryContentConsumer>( applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() );
}
/**
* Get the list of {@link InvalidRepositoryContentConsumer} objects that are available and present in the classpath
* and as components in the IoC.
*
* @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath and as a
* component in the IoC.
*/
@SuppressWarnings("unchecked")
public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers()
{
return new ArrayList<InvalidRepositoryContentConsumer>( applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() );
}
/**
* A convenience method to execute all of the active selected consumers for a particular arbitrary file.
* NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent
* the index writer/reader of the current index-content consumer executing from getting closed. For an example,
* see ArchivaDavResource#executeConsumers( File ).
*
* @param repository the repository configuration to use.
* @param localFile the local file to execute the consumers against.
* @param updateRelatedArtifacts TODO
*/
public void executeConsumers( ManagedRepositoryConfiguration repository, File localFile, boolean updateRelatedArtifacts )
{
// Run the repository consumers
try
{
Closure triggerBeginScan = new TriggerBeginScanClosure( repository, getStartTime() );
List<KnownRepositoryContentConsumer> selectedKnownConsumers = getSelectedKnownConsumers();
// MRM-1212/MRM-1197
// - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven
if( updateRelatedArtifacts == false )
{
List<KnownRepositoryContentConsumer> clone = new ArrayList<KnownRepositoryContentConsumer>();
clone.addAll( selectedKnownConsumers );
for( KnownRepositoryContentConsumer consumer : clone )
{
if( consumer.getId().equals( "create-missing-checksums" ) ||
consumer.getId().equals( "metadata-updater" ) )
{
selectedKnownConsumers.remove( consumer );
}
}
}
List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers();
CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan );
CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan );
// yuck. In case you can't read this, it says
// "process the file if the consumer has it in the includes list, and not in the excludes list"
BaseFile baseFile = new BaseFile( repository.getLocation(), localFile );
ConsumerWantsFilePredicate predicate = new ConsumerWantsFilePredicate();
predicate.setBasefile( baseFile );
ConsumerProcessFileClosure closure = new ConsumerProcessFileClosure();
closure.setBasefile( baseFile );
predicate.setCaseSensitive( false );
Closure processIfWanted = IfClosure.getInstance( predicate, closure );
CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted );
if ( predicate.getWantedFileCount() <= 0 )
{
// Nothing known processed this file. It is invalid!
CollectionUtils.forAllDo( selectedInvalidConsumers, closure );
}
TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository );
CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure );
}
finally
{
/*
* TODO: This is never called by the repository scanner instance, so not calling here either - but it
* probably should be? CollectionUtils.forAllDo( availableKnownConsumers, triggerCompleteScan );
* CollectionUtils.forAllDo( availableInvalidConsumers, triggerCompleteScan );
*/
}
}
public void setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers )
{
this.selectedKnownConsumers = selectedKnownConsumers;
}
public void setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers )
{
this.selectedInvalidConsumers = selectedInvalidConsumers;
}
protected Date getStartTime()
{
return new Date( System.currentTimeMillis() );
}
public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
{
this.archivaConfiguration = archivaConfiguration;
}
}