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