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