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