1 package org.apache.maven.archiva.repository.scanner;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import org.apache.commons.lang.SystemUtils;
23 import org.apache.maven.archiva.common.consumers.Consumer;
24 import org.apache.maven.archiva.common.utils.BaseFile;
25 import org.apache.maven.artifact.repository.ArtifactRepository;
26 import org.codehaus.plexus.util.DirectoryWalkListener;
27 import org.codehaus.plexus.util.SelectorUtils;
28 import org.codehaus.plexus.util.StringUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 import java.util.Iterator;
34 import java.util.List;
37 * RepositoryScannerInstance
39 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
42 public class RepositoryScannerInstance implements DirectoryWalkListener
44 private static Logger log = LoggerFactory.getLogger( RepositoryScannerInstance.class );
46 private List consumers;
48 private ArtifactRepository repository;
50 private boolean isCaseSensitive = true;
52 private ScanStatistics stats;
54 private long onlyModifiedAfterTimestamp = 0;
56 public RepositoryScannerInstance( ArtifactRepository repository, List consumerList )
58 this.repository = repository;
59 this.consumers = consumerList;
60 stats = new ScanStatistics( repository );
62 Iterator it = this.consumers.iterator();
63 while ( it.hasNext() )
65 Consumer consumer = (Consumer) it.next();
67 if ( !consumer.init( this.repository ) )
69 throw new IllegalStateException( "Consumer [" + consumer.getName() +
70 "] is reporting that it is incompatible with the [" + repository.getId() + "] repository." );
74 if ( SystemUtils.IS_OS_WINDOWS )
76 isCaseSensitive = false;
80 public ScanStatistics getStatistics()
85 public void directoryWalkStarting( File basedir )
87 log.info( "Walk Started: [" + this.repository.getId() + "] " + this.repository.getBasedir() );
89 stats.timestampStarted = System.currentTimeMillis();
92 public void directoryWalkStep( int percentage, File file )
94 log.debug( "Walk Step: " + percentage + ", " + file );
96 // Timestamp finished points to the last successful scan, not this current one.
97 if ( file.lastModified() < onlyModifiedAfterTimestamp )
99 // Skip file as no change has occured.
100 log.debug( "Skipping, No Change: " + file.getAbsolutePath() );
101 stats.filesSkipped++;
105 synchronized ( consumers )
107 stats.filesIncluded++;
109 BaseFile basefile = new BaseFile( repository.getBasedir(), file );
111 Iterator itConsumers = this.consumers.iterator();
112 while ( itConsumers.hasNext() )
114 Consumer consumer = (Consumer) itConsumers.next();
116 if ( wantsFile( consumer, StringUtils.replace( basefile.getRelativePath(), "\\", "/" ) ) )
120 log.debug( "Sending to consumer: " + consumer.getName() );
121 stats.filesConsumed++;
122 consumer.processFile( basefile );
124 catch ( Exception e )
126 /* Intentionally Catch all exceptions.
127 * So that the discoverer processing can continue.
129 log.error( "Consumer [" + consumer.getName() + "] had an error when processing file [" +
130 basefile.getAbsolutePath() + "]: " + e.getMessage(), e );
136 "Skipping consumer " + consumer.getName() + " for file " + basefile.getRelativePath() );
142 public void directoryWalkFinished()
144 log.info( "Walk Finished: [" + this.repository.getId() + "] " + this.repository.getBasedir() );
145 stats.timestampFinished = System.currentTimeMillis();
148 private boolean wantsFile( Consumer consumer, String relativePath )
152 // Test excludes first.
153 it = consumer.getExcludePatterns().iterator();
154 while ( it.hasNext() )
156 String pattern = (String) it.next();
157 if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) )
159 // Definately does NOT WANT FILE.
164 // Now test includes.
165 it = consumer.getIncludePatterns().iterator();
166 while ( it.hasNext() )
168 String pattern = (String) it.next();
169 if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) )
171 // Specifically WANTS FILE.
176 // Not included, and Not excluded? Default to EXCLUDE.
180 public long getOnlyModifiedAfterTimestamp()
182 return onlyModifiedAfterTimestamp;
185 public void setOnlyModifiedAfterTimestamp( long onlyModifiedAfterTimestamp )
187 this.onlyModifiedAfterTimestamp = onlyModifiedAfterTimestamp;
191 * Debug method from DirectoryWalker.
193 public void debug( String message )
195 log.debug( "Repository Scanner: " + message );