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.beans.ManagedRepository; 023 import org.apache.archiva.common.utils.BaseFile; 024 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer; 025 import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 026 import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate; 027 import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure; 028 import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure; 029 import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure; 030 import org.apache.commons.collections.Closure; 031 import org.apache.commons.collections.CollectionUtils; 032 import org.apache.commons.collections.functors.IfClosure; 033 import org.apache.commons.lang.SystemUtils; 034 import org.codehaus.plexus.util.DirectoryWalkListener; 035 import org.slf4j.Logger; 036 import org.slf4j.LoggerFactory; 037 038 import java.io.File; 039 import java.util.Date; 040 import java.util.HashMap; 041 import java.util.List; 042 import java.util.Map; 043 044 /** 045 * RepositoryScannerInstance 046 * 047 * 048 */ 049 public class RepositoryScannerInstance 050 implements DirectoryWalkListener 051 { 052 private Logger log = LoggerFactory.getLogger( RepositoryScannerInstance.class ); 053 054 /** 055 * Consumers that process known content. 056 */ 057 private List<KnownRepositoryContentConsumer> knownConsumers; 058 059 /** 060 * Consumers that process unknown/invalid content. 061 */ 062 private List<InvalidRepositoryContentConsumer> invalidConsumers; 063 064 private ManagedRepository repository; 065 066 private RepositoryScanStatistics stats; 067 068 private long changesSince = 0; 069 070 private ConsumerProcessFileClosure consumerProcessFile; 071 072 private ConsumerWantsFilePredicate consumerWantsFile; 073 074 private Map<String, Long> consumerTimings; 075 076 private Map<String, Long> consumerCounts; 077 078 public RepositoryScannerInstance( ManagedRepository repository, 079 List<KnownRepositoryContentConsumer> knownConsumerList, 080 List<InvalidRepositoryContentConsumer> invalidConsumerList ) 081 { 082 this.repository = repository; 083 this.knownConsumers = knownConsumerList; 084 this.invalidConsumers = invalidConsumerList; 085 086 consumerTimings = new HashMap<String, Long>(); 087 consumerCounts = new HashMap<String, Long>(); 088 089 this.consumerProcessFile = new ConsumerProcessFileClosure(); 090 consumerProcessFile.setExecuteOnEntireRepo( true ); 091 consumerProcessFile.setConsumerTimings( consumerTimings ); 092 consumerProcessFile.setConsumerCounts( consumerCounts ); 093 094 this.consumerWantsFile = new ConsumerWantsFilePredicate(); 095 096 stats = new RepositoryScanStatistics(); 097 stats.setRepositoryId( repository.getId() ); 098 099 Closure triggerBeginScan = 100 new TriggerBeginScanClosure( repository, new Date( System.currentTimeMillis() ), true ); 101 102 CollectionUtils.forAllDo( knownConsumerList, triggerBeginScan ); 103 CollectionUtils.forAllDo( invalidConsumerList, triggerBeginScan ); 104 105 if ( SystemUtils.IS_OS_WINDOWS ) 106 { 107 consumerWantsFile.setCaseSensitive( false ); 108 } 109 } 110 111 public RepositoryScannerInstance( ManagedRepository repository, 112 List<KnownRepositoryContentConsumer> knownContentConsumers, 113 List<InvalidRepositoryContentConsumer> invalidContentConsumers, 114 long changesSince ) 115 { 116 this( repository, knownContentConsumers, invalidContentConsumers ); 117 118 consumerWantsFile.setChangesSince( changesSince ); 119 120 this.changesSince = changesSince; 121 } 122 123 public RepositoryScanStatistics getStatistics() 124 { 125 return stats; 126 } 127 128 public Map<String, Long> getConsumerTimings() 129 { 130 return consumerTimings; 131 } 132 133 public Map<String, Long> getConsumerCounts() 134 { 135 return consumerCounts; 136 } 137 138 public void directoryWalkStarting( File basedir ) 139 { 140 log.info( "Walk Started: [{}] {}", this.repository.getId(), this.repository.getLocation() ); 141 stats.triggerStart(); 142 } 143 144 public void directoryWalkStep( int percentage, File file ) 145 { 146 log.debug( "Walk Step: {}, {}", percentage, file ); 147 148 stats.increaseFileCount(); 149 150 // consume files regardless - the predicate will check the timestamp 151 BaseFile basefile = new BaseFile( repository.getLocation(), file ); 152 153 // Timestamp finished points to the last successful scan, not this current one. 154 if ( file.lastModified() >= changesSince ) 155 { 156 stats.increaseNewFileCount(); 157 } 158 159 consumerProcessFile.setBasefile( basefile ); 160 consumerWantsFile.setBasefile( basefile ); 161 162 Closure processIfWanted = IfClosure.getInstance( consumerWantsFile, consumerProcessFile ); 163 CollectionUtils.forAllDo( this.knownConsumers, processIfWanted ); 164 165 if ( consumerWantsFile.getWantedFileCount() <= 0 ) 166 { 167 // Nothing known processed this file. It is invalid! 168 CollectionUtils.forAllDo( this.invalidConsumers, consumerProcessFile ); 169 } 170 } 171 172 public void directoryWalkFinished() 173 { 174 TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository, true ); 175 CollectionUtils.forAllDo( knownConsumers, scanCompletedClosure ); 176 CollectionUtils.forAllDo( invalidConsumers, scanCompletedClosure ); 177 178 stats.setConsumerTimings( consumerTimings ); 179 stats.setConsumerCounts( consumerCounts ); 180 181 log.info( "Walk Finished: [{}] {}", this.repository.getId(), this.repository.getLocation() ); 182 stats.triggerFinished(); 183 } 184 185 /** 186 * Debug method from DirectoryWalker. 187 */ 188 public void debug( String message ) 189 { 190 log.debug( "Repository Scanner: {}", message ); 191 } 192 193 public ManagedRepository getRepository() 194 { 195 return repository; 196 } 197 198 public RepositoryScanStatistics getStats() 199 { 200 return stats; 201 } 202 203 public long getChangesSince() 204 { 205 return changesSince; 206 } 207 }