]> source.dussan.org Git - archiva.git/blob
8eef2b7665bed0e03152c8949a113aa83144a910
[archiva.git] /
1 package org.apache.maven.archiva.discoverer;
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.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.logging.Logger;
27 import org.codehaus.plexus.util.DirectoryWalkListener;
28 import org.codehaus.plexus.util.SelectorUtils;
29 import org.codehaus.plexus.util.StringUtils;
30
31 import java.io.File;
32 import java.util.Iterator;
33 import java.util.List;
34
35 /**
36  * RepositoryScanner - this is an instance of a scan against a repository.
37  *
38  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
39  * @version $Id$
40  */
41 public class RepositoryScanner
42     implements DirectoryWalkListener
43 {
44     public static final String ROLE = RepositoryScanner.class.getName();
45
46     private List consumers;
47
48     private ArtifactRepository repository;
49
50     private Logger logger;
51
52     private boolean isCaseSensitive = true;
53
54     private DiscovererStatistics stats;
55
56     private long onlyModifiedAfterTimestamp = 0;
57
58     public RepositoryScanner( ArtifactRepository repository, List consumerList )
59     {
60         this.repository = repository;
61         this.consumers = consumerList;
62         stats = new DiscovererStatistics( repository );
63
64         Iterator it = this.consumers.iterator();
65         while ( it.hasNext() )
66         {
67             Consumer consumer = (Consumer) it.next();
68
69             if ( !consumer.init( this.repository ) )
70             {
71                 throw new IllegalStateException( "Consumer [" + consumer.getName() +
72                     "] is reporting that it is incompatible with the [" + repository.getId() + "] repository." );
73             }
74         }
75
76         if ( SystemUtils.IS_OS_WINDOWS )
77         {
78             isCaseSensitive = false;
79         }
80     }
81
82     public DiscovererStatistics getStatistics()
83     {
84         return stats;
85     }
86
87     public void directoryWalkStarting( File basedir )
88     {
89         getLogger().info( "Walk Started: [" + this.repository.getId() + "] " + this.repository.getBasedir() );
90         stats.reset();
91         stats.timestampStarted = System.currentTimeMillis();
92     }
93
94     public void directoryWalkStep( int percentage, File file )
95     {
96         getLogger().debug( "Walk Step: " + percentage + ", " + file );
97
98         // Timestamp finished points to the last successful scan, not this current one.
99         if ( file.lastModified() < onlyModifiedAfterTimestamp )
100         {
101             // Skip file as no change has occured.
102             getLogger().debug( "Skipping, No Change: " + file.getAbsolutePath() );
103             stats.filesSkipped++;
104             return;
105         }
106
107         synchronized ( consumers )
108         {
109             stats.filesIncluded++;
110
111             BaseFile basefile = new BaseFile( repository.getBasedir(), file );
112
113             Iterator itConsumers = this.consumers.iterator();
114             while ( itConsumers.hasNext() )
115             {
116                 Consumer consumer = (Consumer) itConsumers.next();
117
118                 if ( wantsFile( consumer, StringUtils.replace( basefile.getRelativePath(), "\\", "/" ) ) )
119                 {
120                     try
121                     {
122                         getLogger().debug( "Sending to consumer: " + consumer.getName() );
123                         stats.filesConsumed++;
124                         consumer.processFile( basefile );
125                     }
126                     catch ( Exception e )
127                     {
128                         /* Intentionally Catch all exceptions.
129                          * So that the discoverer processing can continue.
130                          */
131                         getLogger().error( "Consumer [" + consumer.getName() + "] had an error when processing file [" +
132                             basefile.getAbsolutePath() + "]: " + e.getMessage(), e );
133                     }
134                 }
135                 else
136                 {
137                     getLogger().debug(
138                         "Skipping consumer " + consumer.getName() + " for file " + basefile.getRelativePath() );
139                 }
140             }
141         }
142     }
143
144     public void directoryWalkFinished()
145     {
146         getLogger().info( "Walk Finished: [" + this.repository.getId() + "] " + this.repository.getBasedir() );
147         stats.timestampFinished = System.currentTimeMillis();
148     }
149
150     private boolean wantsFile( Consumer consumer, String relativePath )
151     {
152         Iterator it;
153
154         // Test excludes first.
155         it = consumer.getExcludePatterns().iterator();
156         while ( it.hasNext() )
157         {
158             String pattern = (String) it.next();
159             if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) )
160             {
161                 // Definately does NOT WANT FILE.
162                 return false;
163             }
164         }
165
166         // Now test includes.
167         it = consumer.getIncludePatterns().iterator();
168         while ( it.hasNext() )
169         {
170             String pattern = (String) it.next();
171             if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) )
172             {
173                 // Specifically WANTS FILE.
174                 return true;
175             }
176         }
177
178         // Not included, and Not excluded?  Default to EXCLUDE.
179         return false;
180     }
181
182     public long getOnlyModifiedAfterTimestamp()
183     {
184         return onlyModifiedAfterTimestamp;
185     }
186
187     public void setOnlyModifiedAfterTimestamp( long onlyModifiedAfterTimestamp )
188     {
189         this.onlyModifiedAfterTimestamp = onlyModifiedAfterTimestamp;
190     }
191
192     /**
193      * Debug method from DirectoryWalker.
194      */
195     public void debug( String message )
196     {
197         getLogger().debug( "Repository Scanner: " + message );
198     }
199
200     public Logger getLogger()
201     {
202         return logger;
203     }
204
205     public void setLogger( Logger logger )
206     {
207         this.logger = logger;
208     }
209 }