]> source.dussan.org Git - archiva.git/blob
ec54b041edf2309dff668370593c3dec12d8ba40
[archiva.git] /
1 package org.apache.maven.archiva.repository.scanner;
2
3 /*
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
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
30 import org.apache.commons.collections.Closure;
31 import org.apache.commons.collections.CollectionUtils;
32 import org.apache.commons.collections.functors.IfClosure;
33 import org.apache.maven.archiva.common.utils.BaseFile;
34 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
35 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
36 import org.apache.maven.archiva.configuration.RepositoryScanningConfiguration;
37 import org.apache.maven.archiva.consumers.InvalidRepositoryContentConsumer;
38 import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer;
39 import org.apache.maven.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
40 import org.apache.maven.archiva.repository.scanner.functors.ConsumerWantsFilePredicate;
41 import org.apache.maven.archiva.repository.scanner.functors.TriggerBeginScanClosure;
42 import org.springframework.beans.BeansException;
43 import org.springframework.context.ApplicationContext;
44 import org.springframework.context.ApplicationContextAware;
45
46 /**
47  * RepositoryContentConsumerUtil
48  * 
49  * @version $Id$
50  */
51 public class RepositoryContentConsumers
52     implements ApplicationContextAware
53 {
54     private ApplicationContext applicationContext;
55
56     private ArchivaConfiguration archivaConfiguration;
57
58     private List<KnownRepositoryContentConsumer> selectedKnownConsumers;
59
60     private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers;
61     
62     public RepositoryContentConsumers( ArchivaConfiguration archivaConfiguration )
63     {
64         this.archivaConfiguration = archivaConfiguration;      
65     }
66
67     public void setApplicationContext( ApplicationContext applicationContext )
68         throws BeansException
69     {
70         this.applicationContext = applicationContext;
71     }
72
73     /**
74      * <p>
75      * Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have been selected in the
76      * configuration to execute.
77      * </p>
78      * <p>
79      * NOTE: This list can be larger and contain entries that might not exist or be available in the classpath, or as a
80      * component.
81      * </p>
82      * 
83      * @return the list of consumer ids that have been selected by the configuration.
84      */
85     public List<String> getSelectedKnownConsumerIds()
86     {
87         RepositoryScanningConfiguration scanning = archivaConfiguration.getConfiguration().getRepositoryScanning();
88         return scanning.getKnownContentConsumers();
89     }
90
91     /**
92      * <p>
93      * Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have been selected in the
94      * configuration to execute.
95      * </p>
96      * <p>
97      * NOTE: This list can be larger and contain entries that might not exist or be available in the classpath, or as a
98      * component.
99      * </p>
100      * 
101      * @return the list of consumer ids that have been selected by the configuration.
102      */
103     public List<String> getSelectedInvalidConsumerIds()
104     {
105         RepositoryScanningConfiguration scanning = archivaConfiguration.getConfiguration().getRepositoryScanning();
106         return scanning.getInvalidContentConsumers();
107     }
108
109     /**
110      * Get the map of {@link String} ids to {@link KnownRepositoryContentConsumer} implementations, for those consumers
111      * that have been selected according to the active configuration.
112      * 
113      * @return the map of String ids to {@link KnownRepositoryContentConsumer} objects.
114      */
115     public Map<String, KnownRepositoryContentConsumer> getSelectedKnownConsumersMap()
116     {
117         Map<String, KnownRepositoryContentConsumer> consumerMap = new HashMap<String, KnownRepositoryContentConsumer>();
118
119         for ( KnownRepositoryContentConsumer consumer : getSelectedKnownConsumers() )
120         {
121             consumerMap.put( consumer.getId(), consumer );
122         }
123
124         return consumerMap;
125     }
126
127     /**
128      * Get the map of {@link String} ids to {@link InvalidRepositoryContentConsumer} implementations, for those
129      * consumers that have been selected according to the active configuration.
130      * 
131      * @return the map of String ids to {@link InvalidRepositoryContentConsumer} objects.
132      */
133     public Map<String, InvalidRepositoryContentConsumer> getSelectedInvalidConsumersMap()
134     {
135         Map<String, InvalidRepositoryContentConsumer> consumerMap =
136             new HashMap<String, InvalidRepositoryContentConsumer>();
137
138         for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() )
139         {
140             consumerMap.put( consumer.getId(), consumer );
141         }
142
143         return consumerMap;
144     }
145
146     /**
147      * Get the list of {@link KnownRepositoryContentConsumer} objects that are selected according to the active
148      * configuration.
149      * 
150      * @return the list of {@link KnownRepositoryContentConsumer} that have been selected by the active configuration.
151      */
152     public synchronized List<KnownRepositoryContentConsumer> getSelectedKnownConsumers()
153     {
154         if ( selectedKnownConsumers == null )
155         {
156             List<KnownRepositoryContentConsumer> ret = new ArrayList<KnownRepositoryContentConsumer>();
157
158             List<String> knownSelected = getSelectedKnownConsumerIds();
159
160             for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() )
161             {
162                 if ( knownSelected.contains( consumer.getId() ) || consumer.isPermanent() )
163                 {
164                     ret.add( consumer );
165                 }
166             }
167             this.selectedKnownConsumers = ret;
168         }
169         return selectedKnownConsumers;
170     }
171
172     /**
173      * Get the list of {@link InvalidRepositoryContentConsumer} objects that are selected according to the active
174      * configuration.
175      * 
176      * @return the list of {@link InvalidRepositoryContentConsumer} that have been selected by the active configuration.
177      */
178     public synchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers()
179     {
180         if ( selectedInvalidConsumers == null )
181         {
182             List<InvalidRepositoryContentConsumer> ret = new ArrayList<InvalidRepositoryContentConsumer>();
183
184             List<String> invalidSelected = getSelectedInvalidConsumerIds();
185
186             for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() )
187             {
188                 if ( invalidSelected.contains( consumer.getId() ) || consumer.isPermanent() )
189                 {
190                     ret.add( consumer );
191                 }
192             }
193             selectedInvalidConsumers = ret;
194         }
195         return selectedInvalidConsumers;
196     }
197
198     /**
199      * Get the list of {@link KnownRepositoryContentConsumer} objects that are available and present in the classpath
200      * and as components in the IoC.
201      * 
202      * @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath and as a
203      *         component in the IoC.
204      */
205     @SuppressWarnings("unchecked")
206     public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers()
207     {
208         return new ArrayList<KnownRepositoryContentConsumer>( applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() );
209     }
210
211     /**
212      * Get the list of {@link InvalidRepositoryContentConsumer} objects that are available and present in the classpath
213      * and as components in the IoC.
214      * 
215      * @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath and as a
216      *         component in the IoC.
217      */
218     @SuppressWarnings("unchecked")
219     public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers()
220     {
221         return new ArrayList<InvalidRepositoryContentConsumer>( applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() );
222     }
223
224     /**
225      * A convenience method to execute all of the active selected consumers for a particular arbitrary file.
226      * NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent
227      * the index writer/reader of the current index-content consumer executing from getting closed. For an example,
228      * see ArchivaDavResource#executeConsumers( File ). 
229      * 
230      * @param repository the repository configuration to use.
231      * @param localFile the local file to execute the consumers against.
232      * @param updateRelatedArtifacts TODO
233      */
234     public void executeConsumers( ManagedRepositoryConfiguration repository, File localFile, boolean updateRelatedArtifacts )
235     {
236         // Run the repository consumers
237         try
238         {
239             Closure triggerBeginScan = new TriggerBeginScanClosure( repository, getStartTime() );
240
241             List<KnownRepositoryContentConsumer> selectedKnownConsumers = getSelectedKnownConsumers();
242             
243             // MRM-1212/MRM-1197 
244             // - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven          
245             if( updateRelatedArtifacts == false )
246             {  
247                 List<KnownRepositoryContentConsumer> clone = new ArrayList<KnownRepositoryContentConsumer>();
248                 clone.addAll( selectedKnownConsumers );
249                 
250                 for( KnownRepositoryContentConsumer consumer : clone )
251                 {
252                     if( consumer.getId().equals( "create-missing-checksums" ) || 
253                                     consumer.getId().equals( "metadata-updater" ) )
254                     {
255                         selectedKnownConsumers.remove( consumer );
256                     }
257                 }               
258             }
259             
260             List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers();
261             CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan );
262             CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan );
263
264             // yuck. In case you can't read this, it says
265             // "process the file if the consumer has it in the includes list, and not in the excludes list"
266             BaseFile baseFile = new BaseFile( repository.getLocation(), localFile );
267             ConsumerWantsFilePredicate predicate = new ConsumerWantsFilePredicate();
268             predicate.setBasefile( baseFile );
269             ConsumerProcessFileClosure closure = new ConsumerProcessFileClosure();
270             closure.setBasefile( baseFile );
271             predicate.setCaseSensitive( false );
272             Closure processIfWanted = IfClosure.getInstance( predicate, closure );
273
274             CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted );
275
276             if ( predicate.getWantedFileCount() <= 0 )
277             {
278                 // Nothing known processed this file. It is invalid!
279                 CollectionUtils.forAllDo( selectedInvalidConsumers, closure );
280             }
281
282             TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository );
283
284             CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure );
285         }
286         finally
287         {
288             /*
289              * TODO: This is never called by the repository scanner instance, so not calling here either - but it
290              * probably should be? CollectionUtils.forAllDo( availableKnownConsumers, triggerCompleteScan );
291              * CollectionUtils.forAllDo( availableInvalidConsumers, triggerCompleteScan );
292              */
293         }
294     }
295
296     public void setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers )
297     {
298         this.selectedKnownConsumers = selectedKnownConsumers;
299     }
300
301     public void setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers )
302     {
303         this.selectedInvalidConsumers = selectedInvalidConsumers;
304     }
305
306     protected Date getStartTime()
307     {
308         return new Date( System.currentTimeMillis() );
309     }
310
311     public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
312     {
313         this.archivaConfiguration = archivaConfiguration;
314     }
315 }