This project has retired. For details please refer to its
Attic page.
RepositoryScannerInstance xref
1 package org.apache.archiva.repository.scanner;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.common.utils.BaseFile;
23 import org.apache.archiva.common.utils.PathUtil;
24 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
25 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
26 import org.apache.archiva.consumers.RepositoryContentConsumer;
27 import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
28 import org.apache.archiva.repository.ManagedRepository;
29 import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
30 import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure;
31 import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
32 import org.apache.commons.collections4.Closure;
33 import org.apache.commons.collections4.CollectionUtils;
34 import org.apache.commons.collections4.IterableUtils;
35 import org.apache.commons.collections4.functors.IfClosure;
36 import org.apache.commons.lang3.SystemUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import java.io.IOException;
41 import java.nio.file.FileSystem;
42 import java.nio.file.FileSystems;
43 import java.nio.file.FileVisitResult;
44 import java.nio.file.FileVisitor;
45 import java.nio.file.Files;
46 import java.nio.file.Path;
47 import java.nio.file.PathMatcher;
48 import java.nio.file.attribute.BasicFileAttributes;
49 import java.util.ArrayList;
50 import java.util.Date;
51 import java.util.HashMap;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.stream.Collectors;
55
56
57
58
59 public class RepositoryScannerInstance
60 implements FileVisitor<Path>
61 {
62 private Logger log = LoggerFactory.getLogger( RepositoryScannerInstance.class );
63
64
65
66
67 private List<KnownRepositoryContentConsumer> knownConsumers;
68
69
70
71
72 private List<InvalidRepositoryContentConsumer> invalidConsumers;
73
74 private ManagedRepository repository;
75
76 private RepositoryScanStatistics stats;
77
78 private long changesSince = 0;
79
80 private ConsumerProcessFileClosure consumerProcessFile;
81
82 private ConsumerWantsFilePredicate consumerWantsFile;
83
84 private Map<String, Long> consumerTimings;
85
86 private Map<String, Long> consumerCounts;
87
88
89 private List<String> fileNameIncludePattern = new ArrayList<>();
90 private List<String> fileNameExcludePattern = new ArrayList<>();
91
92 private List<PathMatcher> includeMatcher = new ArrayList<>();
93 private List<PathMatcher> excludeMatcher = new ArrayList<>();
94
95 private boolean isRunning = false;
96
97 Path basePath = null;
98
99 public RepositoryScannerInstance( ManagedRepository repository,
100 List<KnownRepositoryContentConsumer> knownConsumerList,
101 List<InvalidRepositoryContentConsumer> invalidConsumerList )
102 {
103 this.repository = repository;
104 this.knownConsumers = knownConsumerList;
105 this.invalidConsumers = invalidConsumerList;
106
107 addFileNameIncludePattern("**/*");
108
109 consumerTimings = new HashMap<>();
110 consumerCounts = new HashMap<>();
111
112 this.consumerProcessFile = new ConsumerProcessFileClosure();
113 consumerProcessFile.setExecuteOnEntireRepo( true );
114 consumerProcessFile.setConsumerTimings( consumerTimings );
115 consumerProcessFile.setConsumerCounts( consumerCounts );
116
117 this.consumerWantsFile = new ConsumerWantsFilePredicate( repository );
118
119 stats = new RepositoryScanStatistics();
120 stats.setRepositoryId( repository.getId() );
121
122 Closure<RepositoryContentConsumer> triggerBeginScan =
123 new TriggerBeginScanClosure( repository, new Date( System.currentTimeMillis() ), true );
124
125 IterableUtils.forEach( knownConsumerList, triggerBeginScan );
126 IterableUtils.forEach( invalidConsumerList, triggerBeginScan );
127
128 if ( SystemUtils.IS_OS_WINDOWS )
129 {
130 consumerWantsFile.setCaseSensitive( false );
131 }
132 }
133
134 public RepositoryScannerInstance( ManagedRepository repository,
135 List<KnownRepositoryContentConsumer> knownContentConsumers,
136 List<InvalidRepositoryContentConsumer> invalidContentConsumers,
137 long changesSince )
138 {
139 this( repository, knownContentConsumers, invalidContentConsumers );
140
141 consumerWantsFile.setChangesSince( changesSince );
142
143 this.changesSince = changesSince;
144 }
145
146 public RepositoryScanStatistics getStatistics()
147 {
148 return stats;
149 }
150
151 public Map<String, Long> getConsumerTimings()
152 {
153 return consumerTimings;
154 }
155
156 public Map<String, Long> getConsumerCounts()
157 {
158 return consumerCounts;
159 }
160
161 public ManagedRepository getRepository()
162 {
163 return repository;
164 }
165
166 public RepositoryScanStatistics getStats()
167 {
168 return stats;
169 }
170
171 public long getChangesSince()
172 {
173 return changesSince;
174 }
175
176 public List<String> getFileNameIncludePattern() {
177 return fileNameIncludePattern;
178 }
179
180 public void setFileNameIncludePattern(List<String> fileNamePattern) {
181 this.fileNameIncludePattern = fileNamePattern;
182 FileSystem sys = FileSystems.getDefault();
183 this.includeMatcher = fileNamePattern.stream().map(ts ->sys
184 .getPathMatcher("glob:" + ts)).collect(Collectors.toList());
185 }
186
187 public void addFileNameIncludePattern(String fileNamePattern) {
188 if (! this.fileNameIncludePattern.contains(fileNamePattern)) {
189 this.fileNameIncludePattern.add(fileNamePattern);
190 this.includeMatcher.add(FileSystems.getDefault().getPathMatcher("glob:" + fileNamePattern));
191 }
192 }
193
194 public List<String> getFileNameExcludePattern() {
195 return fileNameExcludePattern;
196 }
197
198 public void setFileNameExcludePattern(List<String> fileNamePattern) {
199 this.fileNameExcludePattern = fileNamePattern;
200 FileSystem sys = FileSystems.getDefault();
201 this.excludeMatcher = fileNamePattern.stream().map(ts ->sys
202 .getPathMatcher("glob:" + ts)).collect(Collectors.toList());
203 }
204
205 public void addFileNameExcludePattern(String fileNamePattern) {
206 if (! this.fileNameExcludePattern.contains(fileNamePattern)) {
207 this.fileNameExcludePattern.add(fileNamePattern);
208 this.excludeMatcher.add(FileSystems.getDefault().getPathMatcher("glob:" + fileNamePattern));
209 }
210 }
211
212
213 @Override
214 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
215 if (!isRunning) {
216 isRunning = true;
217 this.basePath = dir;
218 log.info( "Walk Started: [{}] {}", this.repository.getId(), this.repository.getLocation() );
219 stats.triggerStart();
220 }
221 return FileVisitResult.CONTINUE;
222 }
223
224 @Override
225 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
226 final Path relativeFile = basePath.relativize( file );
227 if (excludeMatcher.stream().noneMatch(m -> m.matches(relativeFile)) && includeMatcher.stream().allMatch(m -> m.matches(relativeFile))) {
228 log.debug( "Walk Step: {}, {}", file );
229
230 stats.increaseFileCount();
231
232
233 Path repoPath = PathUtil.getPathFromUri( repository.getLocation() );
234 BaseFilels/BaseFile.html#BaseFile">BaseFile basefile = new BaseFile( repoPath.toString(), file.toFile() );
235
236
237 if ( Files.getLastModifiedTime(file).toMillis() >= changesSince )
238 {
239 stats.increaseNewFileCount();
240 }
241
242 consumerProcessFile.setBasefile( basefile );
243 consumerWantsFile.setBasefile( basefile );
244
245 Closure<RepositoryContentConsumer> processIfWanted = IfClosure.ifClosure( consumerWantsFile, consumerProcessFile );
246 IterableUtils.forEach( this.knownConsumers, processIfWanted );
247
248 if ( consumerWantsFile.getWantedFileCount() <= 0 )
249 {
250
251 IterableUtils.forEach( this.invalidConsumers, consumerProcessFile );
252 }
253
254 }
255 return FileVisitResult.CONTINUE;
256 }
257
258 @Override
259 public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
260 log.error("Error occured at {}: {}", file, exc.getMessage(), exc);
261 try
262 {
263 if ( basePath != null && Files.isSameFile( file, basePath ) )
264 {
265 log.debug( "Finishing walk from visitFileFailed" );
266 finishWalk( );
267 }
268 } catch (Throwable e) {
269 log.error( "Error during visitFileFailed handling: {}", e.getMessage( ), e );
270 }
271 return FileVisitResult.CONTINUE;
272 }
273
274 @Override
275 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
276 if (Files.isSameFile(dir, basePath)) {
277 finishWalk();
278 }
279 return FileVisitResult.CONTINUE;
280 }
281
282 private void finishWalk() {
283 this.isRunning = false;
284 TriggerScanCompletedClosurempletedClosure.html#TriggerScanCompletedClosure">TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository, true );
285 IterableUtils.forEach( knownConsumers, scanCompletedClosure );
286 IterableUtils.forEach( invalidConsumers, scanCompletedClosure );
287
288 stats.setConsumerTimings( consumerTimings );
289 stats.setConsumerCounts( consumerCounts );
290
291 log.info( "Walk Finished: [{}] {}", this.repository.getId(), this.repository.getLocation() );
292 stats.triggerFinished();
293 this.basePath = null;
294 }
295 }