1package org.apache.archiva.repository.scanner;
23/*4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122import org.apache.archiva.admin.model.RepositoryAdminException;
23import org.apache.archiva.admin.model.admin.ArchivaAdministration;
24import org.apache.archiva.admin.model.beans.ManagedRepository;
25import org.apache.archiva.common.utils.BaseFile;
26import org.apache.archiva.configuration.ArchivaConfiguration;
27import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
28import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
29import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
30import org.apache.archiva.redback.components.registry.RegistryListener;
31import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
32import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure;
33import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
34import org.apache.commons.collections.Closure;
35import org.apache.commons.collections.CollectionUtils;
36import org.apache.commons.collections.functors.IfClosure;
37import org.springframework.beans.BeansException;
38import org.springframework.context.ApplicationContext;
39import org.springframework.context.ApplicationContextAware;
40import org.springframework.stereotype.Service;
4142import javax.inject.Inject;
43import java.io.File;
44import java.util.ArrayList;
45import java.util.Date;
46import java.util.HashMap;
47import java.util.List;
48import java.util.Map;
4950/**51 * RepositoryContentConsumerUtil52 */53 @Service("repositoryContentConsumers")
54publicclassRepositoryContentConsumers55implements ApplicationContextAware
56 {
5758 @Inject
59private ApplicationContext applicationContext;
6061privateArchivaAdministration archivaAdministration;
6263private List<KnownRepositoryContentConsumer> selectedKnownConsumers;
6465private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers;
6667 @Inject
68privateArchivaConfiguration archivaConfiguration;
6970 @Inject
71publicRepositoryContentConsumers( ArchivaAdministration archivaAdministration )
72 {
73this.archivaAdministration = archivaAdministration;
74 }
7576 @Override
77publicvoid setApplicationContext( ApplicationContext applicationContext )
78throws BeansException
79 {
80this.applicationContext = applicationContext;
81 }
8283/**84 * <p>85 * Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have86 * been selected in the configuration to execute.87 * </p>88 * <p>89 * NOTE: This list can be larger and contain entries that might not exist or be available90 * in the classpath, or as a component.91 * </p>92 *93 * @return the list of consumer ids that have been selected by the configuration.94 */95public List<String> getSelectedKnownConsumerIds()
96throwsRepositoryAdminException97 {
98return archivaAdministration.getKnownContentConsumers();
99 }
100101/**102 * <p>103 * Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have104 * been selected in the configuration to execute.105 * </p>106 * <p>107 * NOTE: This list can be larger and contain entries that might not exist or be available108 * in the classpath, or as a component.109 * </p>110 *111 * @return the list of consumer ids that have been selected by the configuration.112 */113public List<String> getSelectedInvalidConsumerIds()
114throwsRepositoryAdminException115 {
116return archivaAdministration.getInvalidContentConsumers();
117 }
118119/**120 * Get the map of {@link String} ids to {@link KnownRepositoryContentConsumer} implementations,121 * for those consumers that have been selected according to the active configuration.122 *123 * @return the map of String ids to {@link KnownRepositoryContentConsumer} objects.124 */125public Map<String, KnownRepositoryContentConsumer> getSelectedKnownConsumersMap()
126throwsRepositoryAdminException127 {
128 Map<String, KnownRepositoryContentConsumer> consumerMap = new HashMap<>();
129130for ( KnownRepositoryContentConsumer consumer : getSelectedKnownConsumers() )
131 {
132 consumerMap.put( consumer.getId(), consumer );
133 }
134135return consumerMap;
136 }
137138/**139 * Get the map of {@link String} ids to {@link InvalidRepositoryContentConsumer} implementations,140 * for those consumers that have been selected according to the active configuration.141 *142 * @return the map of String ids to {@link InvalidRepositoryContentConsumer} objects.143 */144public Map<String, InvalidRepositoryContentConsumer> getSelectedInvalidConsumersMap()
145throwsRepositoryAdminException146 {
147 Map<String, InvalidRepositoryContentConsumer> consumerMap = new HashMap<>();
148149for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() )
150 {
151 consumerMap.put( consumer.getId(), consumer );
152 }
153154return consumerMap;
155 }
156157/**158 * Get the list of {@link KnownRepositoryContentConsumer} objects that are159 * selected according to the active configuration.160 *161 * @return the list of {@link KnownRepositoryContentConsumer} that have been selected162 * by the active configuration.163 */164public List<KnownRepositoryContentConsumer> getSelectedKnownConsumers()
165throwsRepositoryAdminException166 {
167// FIXME only for testing168if ( selectedKnownConsumers != null )
169 {
170return selectedKnownConsumers;
171 }
172 List<KnownRepositoryContentConsumer> ret = new ArrayList<>();
173174 List<String> knownSelected = getSelectedKnownConsumerIds();
175176for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() )
177 {
178if ( knownSelected.contains( consumer.getId() ) )
179 {
180 ret.add( consumer );
181 }
182 }
183return ret;
184 }
185186publicvoid releaseSelectedKnownConsumers( List<KnownRepositoryContentConsumer> repositoryContentConsumers )
187 {
188if ( repositoryContentConsumers == null )
189 {
190return;
191 }
192for ( KnownRepositoryContentConsumer knownRepositoryContentConsumer : repositoryContentConsumers )
193 {
194if ( RegistryListener.class.isAssignableFrom( knownRepositoryContentConsumer.getClass() ) )
195 {
196 archivaConfiguration.removeChangeListener(
197 RegistryListener.class.cast( knownRepositoryContentConsumer ) );
198 }
199 }
200 }
201202/**203 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are204 * selected according to the active configuration.205 *206 * @return the list of {@link InvalidRepositoryContentConsumer} that have been selected207 * by the active configuration.208 */209publicsynchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers()
210throwsRepositoryAdminException211 {
212213// FIXME only for testing214if ( selectedInvalidConsumers != null )
215 {
216return selectedInvalidConsumers;
217 }
218219 List<InvalidRepositoryContentConsumer> ret = new ArrayList<>();
220221 List<String> invalidSelected = getSelectedInvalidConsumerIds();
222223for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() )
224 {
225if ( invalidSelected.contains( consumer.getId() ) )
226 {
227 ret.add( consumer );
228 }
229 }
230return ret;
231 }
232233234/**235 * Get the list of {@link KnownRepositoryContentConsumer} objects that are236 * available and present in the classpath and as components in the IoC.237 *238 * @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath239 * and as a component in the IoC.240 */241public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers()
242 {
243returnnew ArrayList<>( applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() );
244 }
245246/**247 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are248 * available and present in the classpath and as components in the IoC.249 *250 * @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath251 * and as a component in the IoC.252 */253public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers()
254 {
255returnnew ArrayList<>( applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() );
256 }
257258/**259 * A convienence method to execute all of the active selected consumers for a260 * particular arbitrary file.261 * NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent262 * the index writer/reader of the current index-content consumer executing from getting closed. For an example,263 * see ArchivaDavResource#executeConsumers( File ).264 *265 * @param repository the repository configuration to use.266 * @param localFile the local file to execute the consumers against.267 * @param updateRelatedArtifacts TODO268 */269publicvoid executeConsumers( ManagedRepository repository, File localFile, boolean updateRelatedArtifacts )
270throwsRepositoryAdminException271 {
272 List<KnownRepositoryContentConsumer> selectedKnownConsumers = null;
273// Run the repository consumers274try275 {
276 Closure triggerBeginScan = newTriggerBeginScanClosure( repository, getStartTime(), false );
277278 selectedKnownConsumers = getSelectedKnownConsumers();
279280// MRM-1212/MRM-1197 281// - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven282if ( !updateRelatedArtifacts )
283 {
284 List<KnownRepositoryContentConsumer> clone = new ArrayList<>();
285 clone.addAll( selectedKnownConsumers );
286287for ( KnownRepositoryContentConsumer consumer : clone )
288 {
289if ( consumer.getId().equals( "create-missing-checksums" ) || consumer.getId().equals(
290"metadata-updater" ) )
291 {
292 selectedKnownConsumers.remove( consumer );
293 }
294 }
295 }
296297 List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers();
298 CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan );
299 CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan );
300301// yuck. In case you can't read this, it says302// "process the file if the consumer has it in the includes list, and not in the excludes list"303BaseFile baseFile = newBaseFile( repository.getLocation(), localFile );
304ConsumerWantsFilePredicate predicate = newConsumerWantsFilePredicate( repository );
305 predicate.setBasefile( baseFile );
306 predicate.setCaseSensitive( false );
307308ConsumerProcessFileClosure closure = newConsumerProcessFileClosure();
309 closure.setBasefile( baseFile );
310 closure.setExecuteOnEntireRepo( false );
311312 Closure processIfWanted = IfClosure.getInstance( predicate, closure );
313314 CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted );
315316if ( predicate.getWantedFileCount() <= 0 )
317 {
318// Nothing known processed this file. It is invalid!319 CollectionUtils.forAllDo( selectedInvalidConsumers, closure );
320 }
321322TriggerScanCompletedClosure scanCompletedClosure = newTriggerScanCompletedClosure( repository, false );
323324 CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure );
325 }
326finally327 {
328/* TODO: This is never called by the repository scanner instance, so not calling here either - but it probably should be?329 CollectionUtils.forAllDo( availableKnownConsumers, triggerCompleteScan );330 CollectionUtils.forAllDo( availableInvalidConsumers, triggerCompleteScan );331 */332 releaseSelectedKnownConsumers( selectedKnownConsumers );
333 }
334 }
335336publicvoid setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers )
337 {
338this.selectedKnownConsumers = selectedKnownConsumers;
339 }
340341publicvoid setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers )
342 {
343this.selectedInvalidConsumers = selectedInvalidConsumers;
344 }
345346protected Date getStartTime()
347 {
348returnnew Date( System.currentTimeMillis() );
349 }
350351publicvoid setArchivaAdministration( ArchivaAdministration archivaAdministration )
352 {
353this.archivaAdministration = archivaAdministration;
354 }
355 }