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