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