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