1 package org.apache.archiva.repository.scanner;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import org.apache.archiva.admin.model.RepositoryAdminException;
23 import org.apache.archiva.admin.model.admin.ArchivaAdministration;
24 import org.apache.archiva.admin.model.beans.ManagedRepository;
25 import org.apache.archiva.common.utils.BaseFile;
26 import org.apache.archiva.configuration.ArchivaConfiguration;
27 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
28 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
29 import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
30 import org.apache.archiva.redback.components.registry.RegistryListener;
31 import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
32 import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure;
33 import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
34 import org.apache.commons.collections.Closure;
35 import org.apache.commons.collections.CollectionUtils;
36 import org.apache.commons.collections.functors.IfClosure;
37 import org.springframework.beans.BeansException;
38 import org.springframework.context.ApplicationContext;
39 import org.springframework.context.ApplicationContextAware;
40 import org.springframework.stereotype.Service;
42 import javax.inject.Inject;
44 import java.util.ArrayList;
45 import java.util.Date;
46 import java.util.HashMap;
47 import java.util.List;
51 * RepositoryContentConsumerUtil
53 @Service("repositoryContentConsumers")
54 public class RepositoryContentConsumers
55 implements ApplicationContextAware
59 private ApplicationContext applicationContext;
61 private ArchivaAdministration archivaAdministration;
63 private List<KnownRepositoryContentConsumer> selectedKnownConsumers;
65 private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers;
68 private ArchivaConfiguration archivaConfiguration;
71 public RepositoryContentConsumers( ArchivaAdministration archivaAdministration )
73 this.archivaAdministration = archivaAdministration;
77 public void setApplicationContext( ApplicationContext applicationContext )
80 this.applicationContext = applicationContext;
85 * Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have
86 * been selected in the configuration to execute.
89 * NOTE: This list can be larger and contain entries that might not exist or be available
90 * in the classpath, or as a component.
93 * @return the list of consumer ids that have been selected by the configuration.
95 public List<String> getSelectedKnownConsumerIds()
96 throws RepositoryAdminException
98 return archivaAdministration.getKnownContentConsumers();
103 * Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have
104 * been selected in the configuration to execute.
107 * NOTE: This list can be larger and contain entries that might not exist or be available
108 * in the classpath, or as a component.
111 * @return the list of consumer ids that have been selected by the configuration.
113 public List<String> getSelectedInvalidConsumerIds()
114 throws RepositoryAdminException
116 return archivaAdministration.getInvalidContentConsumers();
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.
123 * @return the map of String ids to {@link KnownRepositoryContentConsumer} objects.
125 public Map<String, KnownRepositoryContentConsumer> getSelectedKnownConsumersMap()
126 throws RepositoryAdminException
128 Map<String, KnownRepositoryContentConsumer> consumerMap = new HashMap<>();
130 for ( KnownRepositoryContentConsumer consumer : getSelectedKnownConsumers() )
132 consumerMap.put( consumer.getId(), consumer );
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.
142 * @return the map of String ids to {@link InvalidRepositoryContentConsumer} objects.
144 public Map<String, InvalidRepositoryContentConsumer> getSelectedInvalidConsumersMap()
145 throws RepositoryAdminException
147 Map<String, InvalidRepositoryContentConsumer> consumerMap = new HashMap<>();
149 for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() )
151 consumerMap.put( consumer.getId(), consumer );
158 * Get the list of {@link KnownRepositoryContentConsumer} objects that are
159 * selected according to the active configuration.
161 * @return the list of {@link KnownRepositoryContentConsumer} that have been selected
162 * by the active configuration.
164 public List<KnownRepositoryContentConsumer> getSelectedKnownConsumers()
165 throws RepositoryAdminException
167 // FIXME only for testing
168 if ( selectedKnownConsumers != null )
170 return selectedKnownConsumers;
172 List<KnownRepositoryContentConsumer> ret = new ArrayList<>();
174 List<String> knownSelected = getSelectedKnownConsumerIds();
176 for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() )
178 if ( knownSelected.contains( consumer.getId() ) )
186 public void releaseSelectedKnownConsumers( List<KnownRepositoryContentConsumer> repositoryContentConsumers )
188 if ( repositoryContentConsumers == null )
192 for ( KnownRepositoryContentConsumer knownRepositoryContentConsumer : repositoryContentConsumers )
194 if ( RegistryListener.class.isAssignableFrom( knownRepositoryContentConsumer.getClass() ) )
196 archivaConfiguration.removeChangeListener(
197 RegistryListener.class.cast( knownRepositoryContentConsumer ) );
203 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are
204 * selected according to the active configuration.
206 * @return the list of {@link InvalidRepositoryContentConsumer} that have been selected
207 * by the active configuration.
209 public synchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers()
210 throws RepositoryAdminException
213 // FIXME only for testing
214 if ( selectedInvalidConsumers != null )
216 return selectedInvalidConsumers;
219 List<InvalidRepositoryContentConsumer> ret = new ArrayList<>();
221 List<String> invalidSelected = getSelectedInvalidConsumerIds();
223 for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() )
225 if ( invalidSelected.contains( consumer.getId() ) )
235 * Get the list of {@link KnownRepositoryContentConsumer} objects that are
236 * available and present in the classpath and as components in the IoC.
238 * @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath
239 * and as a component in the IoC.
241 public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers()
243 return new ArrayList<>( applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() );
247 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are
248 * available and present in the classpath and as components in the IoC.
250 * @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath
251 * and as a component in the IoC.
253 public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers()
255 return new ArrayList<>( applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() );
259 * A convienence method to execute all of the active selected consumers for a
260 * particular arbitrary file.
261 * NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent
262 * the index writer/reader of the current index-content consumer executing from getting closed. For an example,
263 * see ArchivaDavResource#executeConsumers( File ).
265 * @param repository the repository configuration to use.
266 * @param localFile the local file to execute the consumers against.
267 * @param updateRelatedArtifacts TODO
269 public void executeConsumers( ManagedRepository repository, File localFile, boolean updateRelatedArtifacts )
270 throws RepositoryAdminException
272 List<KnownRepositoryContentConsumer> selectedKnownConsumers = null;
273 // Run the repository consumers
276 Closure triggerBeginScan = new TriggerBeginScanClosure( repository, getStartTime(), false );
278 selectedKnownConsumers = getSelectedKnownConsumers();
281 // - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven
282 if ( !updateRelatedArtifacts )
284 List<KnownRepositoryContentConsumer> clone = new ArrayList<>();
285 clone.addAll( selectedKnownConsumers );
287 for ( KnownRepositoryContentConsumer consumer : clone )
289 if ( consumer.getId().equals( "create-missing-checksums" ) || consumer.getId().equals(
290 "metadata-updater" ) )
292 selectedKnownConsumers.remove( consumer );
297 List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers();
298 CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan );
299 CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan );
301 // yuck. In case you can't read this, it says
302 // "process the file if the consumer has it in the includes list, and not in the excludes list"
303 BaseFile baseFile = new BaseFile( repository.getLocation(), localFile );
304 ConsumerWantsFilePredicate predicate = new ConsumerWantsFilePredicate( repository );
305 predicate.setBasefile( baseFile );
306 predicate.setCaseSensitive( false );
308 ConsumerProcessFileClosure closure = new ConsumerProcessFileClosure();
309 closure.setBasefile( baseFile );
310 closure.setExecuteOnEntireRepo( false );
312 Closure processIfWanted = IfClosure.getInstance( predicate, closure );
314 CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted );
316 if ( predicate.getWantedFileCount() <= 0 )
318 // Nothing known processed this file. It is invalid!
319 CollectionUtils.forAllDo( selectedInvalidConsumers, closure );
322 TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository, false );
324 CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure );
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 );
332 releaseSelectedKnownConsumers( selectedKnownConsumers );
336 public void setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers )
338 this.selectedKnownConsumers = selectedKnownConsumers;
341 public void setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers )
343 this.selectedInvalidConsumers = selectedInvalidConsumers;
346 protected Date getStartTime()
348 return new Date( System.currentTimeMillis() );
351 public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
353 this.archivaAdministration = archivaAdministration;