]> source.dussan.org Git - archiva.git/blob
bc8a62aecda66e65818a9478b8069c95449d907a
[archiva.git] /
1 package org.apache.maven.archiva.repository.scanner;
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.maven.archiva.common.consumers.Consumer;
23 import org.apache.maven.archiva.repository.RepositoryException;
24 import org.apache.maven.artifact.repository.ArtifactRepository;
25 import org.codehaus.plexus.util.DirectoryWalker;
26 import org.codehaus.plexus.util.FileUtils;
27
28 import java.io.File;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Iterator;
32 import java.util.List;
33
34 /**
35  * RepositoryScanner 
36  *
37  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
38  * @version $Id$
39  */
40 public class RepositoryScanner
41 {
42     /**
43      * Standard patterns to exclude from discovery as they are usually noise.
44      */
45     private static final String[] STANDARD_SCANNER_EXCLUDES = {
46         "bin/**",
47         "reports/**",
48         ".index",
49         ".reports/**",
50         ".maven/**",
51         "**/*snapshot-version",
52         "*/website/**",
53         "*/licences/**",
54         "**/.htaccess",
55         "**/*.html",
56         "**/*.txt",
57         "**/README*",
58         "**/CHANGELOG*",
59         "**/KEYS*" };
60
61     /**
62      * Walk the repository, and report to the consumers the files found.
63      * 
64      * Report changes to the appropriate Consumer.
65      * 
66      * This is just a convenience method to {@link #scan(ArtifactRepository, List, boolean, long, List, List)}
67      * equivalent to calling <code>scan( repository, consumers, includeSnapshots, 0, null, null );</code>
68      * 
69      * @param repository the repository to change.
70      * @param consumers use the provided list of consumers.
71      * @param includeSnapshots true to include snapshots in the walking of this repository.
72      * @return the statistics for this scan.
73      * @throws RepositoryException if there was a fundamental problem with getting the discoverer started.
74      */
75     public ScanStatistics scan( ArtifactRepository repository, List consumers, boolean includeSnapshots )
76         throws RepositoryException
77     {
78         return scan( repository, consumers, includeSnapshots, 0, null, null );
79     }
80
81     /**
82      * Walk the repository, and report to the consumers the files found.
83      * 
84      * Report changes to the appropriate Consumer.
85      * 
86      * @param repository the repository to change.
87      * @param consumers use the provided list of consumers.
88      * @param includeSnapshots true to include snapshots in the scanning of this repository.
89      * @param onlyModifiedAfterTimestamp Only report to the consumers, files that have a {@link File#lastModified()}) 
90      *          after the provided timestamp.
91      * @param extraFileExclusions an optional list of file exclusions on the walk.
92      * @param extraFileInclusions an optional list of file inclusions on the walk.
93      * @return the statistics for this scan.
94      * @throws RepositoryException if there was a fundamental problem with getting the discoverer started. 
95      */
96     public ScanStatistics scan( ArtifactRepository repository, List consumers, boolean includeSnapshots,
97                                 long onlyModifiedAfterTimestamp, List extraFileExclusions, List extraFileInclusions )
98         throws RepositoryException
99     {
100         if ( repository == null )
101         {
102             throw new IllegalArgumentException( "Unable to operate on a null repository." );
103         }
104
105         if ( !"file".equals( repository.getProtocol() ) )
106         {
107             throw new UnsupportedOperationException( "Only filesystem repositories are supported." );
108         }
109
110         File repositoryBase = new File( repository.getBasedir() );
111
112         if ( !repositoryBase.exists() )
113         {
114             throw new UnsupportedOperationException( "Unable to scan a repository, directory "
115                 + repositoryBase.getAbsolutePath() + " does not exist." );
116         }
117
118         if ( !repositoryBase.isDirectory() )
119         {
120             throw new UnsupportedOperationException( "Unable to scan a repository, path "
121                 + repositoryBase.getAbsolutePath() + " is not a directory." );
122         }
123
124         // Setup Includes / Excludes.
125
126         List allExcludes = new ArrayList();
127         List allIncludes = new ArrayList();
128
129         // Exclude all of the SCM patterns.
130         allExcludes.addAll( FileUtils.getDefaultExcludesAsList() );
131
132         // Exclude all of the archiva noise patterns.
133         allExcludes.addAll( Arrays.asList( STANDARD_SCANNER_EXCLUDES ) );
134
135         if ( !includeSnapshots )
136         {
137             allExcludes.add( "**/*-SNAPSHOT*" );
138         }
139
140         if ( extraFileExclusions != null )
141         {
142             allExcludes.addAll( extraFileExclusions );
143         }
144
145         Iterator it = consumers.iterator();
146         while ( it.hasNext() )
147         {
148             Consumer consumer = (Consumer) it.next();
149
150             /* NOTE: Do not insert the consumer exclusion patterns here.
151              * Exclusion patterns are handled by RepositoryScanner.wantsFile(Consumer, String)
152              * 
153              * addUniqueElements( consumer.getExcludePatterns(), allExcludes );
154              */
155             addUniqueElements( consumer.getIncludePatterns(), allIncludes );
156         }
157
158         if ( extraFileInclusions != null )
159         {
160             allIncludes.addAll( extraFileInclusions );
161         }
162
163         // Setup Directory Walker
164
165         DirectoryWalker dirWalker = new DirectoryWalker();
166
167         dirWalker.setBaseDir( repositoryBase );
168
169         dirWalker.setIncludes( allIncludes );
170         dirWalker.setExcludes( allExcludes );
171
172         // Setup the Scan Instance
173         RepositoryScannerInstance scannerInstance = new RepositoryScannerInstance( repository, consumers );
174         scannerInstance.setOnlyModifiedAfterTimestamp( onlyModifiedAfterTimestamp );
175
176         dirWalker.addDirectoryWalkListener( scannerInstance );
177
178         // Execute scan.
179         dirWalker.scan();
180
181         return scannerInstance.getStatistics();
182     }
183     
184     private void addUniqueElements( List fromList, List toList )
185     {
186         Iterator itFrom = fromList.iterator();
187         while ( itFrom.hasNext() )
188         {
189             Object o = itFrom.next();
190             if ( !toList.contains( o ) )
191             {
192                 toList.add( o );
193             }
194         }
195     }
196 }