001 package org.apache.archiva.repository.scanner; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import org.apache.archiva.admin.model.RepositoryAdminException; 023 import org.apache.archiva.admin.model.admin.ArchivaAdministration; 024 import org.apache.archiva.admin.model.beans.ManagedRepository; 025 import org.apache.archiva.common.utils.BaseFile; 026 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer; 027 import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 028 import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate; 029 import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure; 030 import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure; 031 import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure; 032 import org.apache.commons.collections.Closure; 033 import org.apache.commons.collections.CollectionUtils; 034 import org.apache.commons.collections.functors.IfClosure; 035 import org.springframework.beans.BeansException; 036 import org.springframework.context.ApplicationContext; 037 import org.springframework.context.ApplicationContextAware; 038 import org.springframework.stereotype.Service; 039 040 import javax.inject.Inject; 041 import java.io.File; 042 import java.util.ArrayList; 043 import java.util.Date; 044 import java.util.HashMap; 045 import java.util.List; 046 import java.util.Map; 047 048 /** 049 * RepositoryContentConsumerUtil 050 */ 051 @Service ("repositoryContentConsumers") 052 public class RepositoryContentConsumers 053 implements ApplicationContextAware 054 { 055 056 @Inject 057 private ApplicationContext applicationContext; 058 059 private ArchivaAdministration archivaAdministration; 060 061 private List<KnownRepositoryContentConsumer> selectedKnownConsumers; 062 063 private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers; 064 065 @Inject 066 public RepositoryContentConsumers( ArchivaAdministration archivaAdministration ) 067 { 068 this.archivaAdministration = archivaAdministration; 069 } 070 071 public void setApplicationContext( ApplicationContext applicationContext ) 072 throws BeansException 073 { 074 this.applicationContext = applicationContext; 075 } 076 077 /** 078 * <p> 079 * Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have 080 * been selected in the configuration to execute. 081 * </p> 082 * <p/> 083 * <p> 084 * NOTE: This list can be larger and contain entries that might not exist or be available 085 * in the classpath, or as a component. 086 * </p> 087 * 088 * @return the list of consumer ids that have been selected by the configuration. 089 */ 090 public List<String> getSelectedKnownConsumerIds() 091 throws RepositoryAdminException 092 { 093 return archivaAdministration.getKnownContentConsumers(); 094 } 095 096 /** 097 * <p> 098 * Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have 099 * been selected in the configuration to execute. 100 * </p> 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<String, KnownRepositoryContentConsumer>(); 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 = 144 new HashMap<String, InvalidRepositoryContentConsumer>(); 145 146 for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() ) 147 { 148 consumerMap.put( consumer.getId(), consumer ); 149 } 150 151 return consumerMap; 152 } 153 154 /** 155 * Get the list of {@link KnownRepositoryContentConsumer} objects that are 156 * selected according to the active configuration. 157 * 158 * @return the list of {@link KnownRepositoryContentConsumer} that have been selected 159 * by the active configuration. 160 */ 161 public synchronized List<KnownRepositoryContentConsumer> getSelectedKnownConsumers() 162 throws RepositoryAdminException 163 { 164 // FIXME only for testing 165 if ( selectedKnownConsumers != null ) 166 { 167 return selectedKnownConsumers; 168 } 169 List<KnownRepositoryContentConsumer> ret = new ArrayList<KnownRepositoryContentConsumer>(); 170 171 List<String> knownSelected = getSelectedKnownConsumerIds(); 172 173 for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() ) 174 { 175 if ( knownSelected.contains( consumer.getId() ) || consumer.isPermanent() ) 176 { 177 ret.add( consumer ); 178 } 179 } 180 return ret; 181 } 182 183 /** 184 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are 185 * selected according to the active configuration. 186 * 187 * @return the list of {@link InvalidRepositoryContentConsumer} that have been selected 188 * by the active configuration. 189 */ 190 public synchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers() 191 throws RepositoryAdminException 192 { 193 194 // FIXME only for testing 195 if ( selectedInvalidConsumers != null ) 196 { 197 return selectedInvalidConsumers; 198 } 199 200 List<InvalidRepositoryContentConsumer> ret = new ArrayList<InvalidRepositoryContentConsumer>(); 201 202 List<String> invalidSelected = getSelectedInvalidConsumerIds(); 203 204 for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() ) 205 { 206 if ( invalidSelected.contains( consumer.getId() ) || consumer.isPermanent() ) 207 { 208 ret.add( consumer ); 209 } 210 } 211 return ret; 212 } 213 214 215 /** 216 * Get the list of {@link KnownRepositoryContentConsumer} objects that are 217 * available and present in the classpath and as components in the IoC. 218 * 219 * @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath 220 * and as a component in the IoC. 221 */ 222 public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers() 223 { 224 return new ArrayList<KnownRepositoryContentConsumer>( 225 applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() ); 226 } 227 228 /** 229 * Get the list of {@link InvalidRepositoryContentConsumer} objects that are 230 * available and present in the classpath and as components in the IoC. 231 * 232 * @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath 233 * and as a component in the IoC. 234 */ 235 public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers() 236 { 237 return new ArrayList<InvalidRepositoryContentConsumer>( 238 applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() ); 239 } 240 241 /** 242 * A convienence method to execute all of the active selected consumers for a 243 * particular arbitrary file. 244 * NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent 245 * the index writer/reader of the current index-content consumer executing from getting closed. For an example, 246 * see ArchivaDavResource#executeConsumers( File ). 247 * 248 * @param repository the repository configuration to use. 249 * @param localFile the local file to execute the consumers against. 250 * @param updateRelatedArtifacts TODO 251 */ 252 public void executeConsumers( ManagedRepository repository, File localFile, boolean updateRelatedArtifacts ) 253 throws RepositoryAdminException 254 { 255 // Run the repository consumers 256 try 257 { 258 Closure triggerBeginScan = new TriggerBeginScanClosure( repository, getStartTime(), false ); 259 260 List<KnownRepositoryContentConsumer> selectedKnownConsumers = getSelectedKnownConsumers(); 261 262 // MRM-1212/MRM-1197 263 // - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven 264 if ( !updateRelatedArtifacts ) 265 { 266 List<KnownRepositoryContentConsumer> clone = new ArrayList<KnownRepositoryContentConsumer>(); 267 clone.addAll( selectedKnownConsumers ); 268 269 for ( KnownRepositoryContentConsumer consumer : clone ) 270 { 271 if ( consumer.getId().equals( "create-missing-checksums" ) || consumer.getId().equals( 272 "metadata-updater" ) ) 273 { 274 selectedKnownConsumers.remove( consumer ); 275 } 276 } 277 } 278 279 List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers(); 280 CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan ); 281 CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan ); 282 283 // yuck. In case you can't read this, it says 284 // "process the file if the consumer has it in the includes list, and not in the excludes list" 285 BaseFile baseFile = new BaseFile( repository.getLocation(), localFile ); 286 ConsumerWantsFilePredicate predicate = new ConsumerWantsFilePredicate(); 287 predicate.setBasefile( baseFile ); 288 predicate.setCaseSensitive( false ); 289 290 ConsumerProcessFileClosure closure = new ConsumerProcessFileClosure(); 291 closure.setBasefile( baseFile ); 292 closure.setExecuteOnEntireRepo( false ); 293 294 Closure processIfWanted = IfClosure.getInstance( predicate, closure ); 295 296 CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted ); 297 298 if ( predicate.getWantedFileCount() <= 0 ) 299 { 300 // Nothing known processed this file. It is invalid! 301 CollectionUtils.forAllDo( selectedInvalidConsumers, closure ); 302 } 303 304 TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository, false ); 305 306 CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure ); 307 } 308 finally 309 { 310 /* TODO: This is never called by the repository scanner instance, so not calling here either - but it probably should be? 311 CollectionUtils.forAllDo( availableKnownConsumers, triggerCompleteScan ); 312 CollectionUtils.forAllDo( availableInvalidConsumers, triggerCompleteScan ); 313 */ 314 } 315 } 316 317 public void setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers ) 318 { 319 this.selectedKnownConsumers = selectedKnownConsumers; 320 } 321 322 public void setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers ) 323 { 324 this.selectedInvalidConsumers = selectedInvalidConsumers; 325 } 326 327 protected Date getStartTime() 328 { 329 return new Date( System.currentTimeMillis() ); 330 } 331 332 public void setArchivaAdministration( ArchivaAdministration archivaAdministration ) 333 { 334 this.archivaAdministration = archivaAdministration; 335 } 336 }