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