KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > types > ArchiveScanner


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.types;
20
21 import java.io.File JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.TreeMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 import org.apache.tools.ant.DirectoryScanner;
28 import org.apache.tools.ant.types.resources.FileResource;
29 import org.apache.tools.ant.types.resources.FileResourceIterator;
30
31 /**
32  * ArchiveScanner accesses the pattern matching algorithm in DirectoryScanner,
33  * which are protected methods that can only be accessed by subclassing.
34  *
35  * This implementation of FileScanner defines getIncludedFiles to return
36  * the matching archive entries.
37  *
38  * @since Ant 1.7
39  */

40 public abstract class ArchiveScanner extends DirectoryScanner {
41     // CheckStyle:VisibilityModifier OFF - bc
42

43     /**
44      * The archive file which should be scanned.
45      */

46     protected File JavaDoc srcFile;
47
48     // CheckStyle:VisibilityModifier ON
49

50     /**
51      * The archive resource which should be scanned.
52      */

53     private Resource src;
54
55     /**
56      * to record the last scanned zip file with its modification date
57      */

58     private Resource lastScannedResource;
59
60     /**
61      * record list of all file zip entries
62      */

63     private TreeMap JavaDoc fileEntries = new TreeMap JavaDoc();
64
65     /**
66      * record list of all directory zip entries
67      */

68     private TreeMap JavaDoc dirEntries = new TreeMap JavaDoc();
69
70     /**
71      * record list of matching file zip entries
72      */

73     private TreeMap JavaDoc matchFileEntries = new TreeMap JavaDoc();
74
75     /**
76      * record list of matching directory zip entries
77      */

78     private TreeMap JavaDoc matchDirEntries = new TreeMap JavaDoc();
79
80     /**
81      * encoding of file names.
82      *
83      * @since Ant 1.6
84      */

85     private String JavaDoc encoding;
86
87     /**
88      * Don't scan when we have no zipfile.
89      * @since Ant 1.7
90      */

91     public void scan() {
92         if (src == null) {
93             return;
94         }
95         super.scan();
96     }
97
98     /**
99      * Sets the srcFile for scanning. This is the jar or zip file that
100      * is scanned for matching entries.
101      *
102      * @param srcFile the (non-null) archive file name for scanning
103      */

104     public void setSrc(File JavaDoc srcFile) {
105         setSrc(new FileResource(srcFile));
106     }
107
108     /**
109      * Sets the src for scanning. This is the jar or zip file that
110      * is scanned for matching entries.
111      *
112      * @param src the (non-null) archive resource
113      */

114     public void setSrc(Resource src) {
115         this.src = src;
116         if (src instanceof FileResource) {
117             srcFile = ((FileResource) src).getFile();
118         }
119     }
120
121     /**
122      * Sets encoding of file names.
123      * @param encoding the encoding format
124      * @since Ant 1.6
125      */

126     public void setEncoding(String JavaDoc encoding) {
127         this.encoding = encoding;
128     }
129
130     /**
131      * Returns the names of the files which matched at least one of the
132      * include patterns and none of the exclude patterns.
133      * The names are relative to the base directory.
134      *
135      * @return the names of the files which matched at least one of the
136      * include patterns and none of the exclude patterns.
137      */

138     public String JavaDoc[] getIncludedFiles() {
139         if (src == null) {
140             return super.getIncludedFiles();
141         }
142         scanme();
143         Set JavaDoc s = matchFileEntries.keySet();
144         return (String JavaDoc[]) (s.toArray(new String JavaDoc[s.size()]));
145     }
146
147     /**
148      * Override parent implementation.
149      * @return count of included files.
150      * @since Ant 1.7
151      */

152     public int getIncludedFilesCount() {
153         if (src == null) {
154             return super.getIncludedFilesCount();
155         }
156         scanme();
157         return matchFileEntries.size();
158     }
159
160     /**
161      * Returns the names of the directories which matched at least one of the
162      * include patterns and none of the exclude patterns.
163      * The names are relative to the base directory.
164      *
165      * @return the names of the directories which matched at least one of the
166      * include patterns and none of the exclude patterns.
167      */

168     public String JavaDoc[] getIncludedDirectories() {
169         if (src == null) {
170             return super.getIncludedDirectories();
171         }
172         scanme();
173         Set JavaDoc s = matchDirEntries.keySet();
174         return (String JavaDoc[]) (s.toArray(new String JavaDoc[s.size()]));
175     }
176
177     /**
178      * Override parent implementation.
179      * @return count of included directories.
180      * @since Ant 1.7
181      */

182     public int getIncludedDirsCount() {
183         if (src == null) {
184             return super.getIncludedDirsCount();
185         }
186         scanme();
187         return matchDirEntries.size();
188     }
189
190     /**
191      * Get the set of Resources that represent files.
192      * @return an Iterator of Resources.
193      * @since Ant 1.7
194      */

195     /* package-private for now */ Iterator JavaDoc getResourceFiles() {
196         if (src == null) {
197             return new FileResourceIterator(getBasedir(), getIncludedFiles());
198         }
199         scanme();
200         return matchFileEntries.values().iterator();
201     }
202
203     /**
204      * Get the set of Resources that represent directories.
205      * @return an Iterator of Resources.
206      * @since Ant 1.7
207      */

208     /* package-private for now */ Iterator JavaDoc getResourceDirectories() {
209         if (src == null) {
210             return new FileResourceIterator(getBasedir(), getIncludedDirectories());
211         }
212         scanme();
213         return matchDirEntries.values().iterator();
214     }
215
216     /**
217      * Initialize DirectoryScanner data structures.
218      */

219     public void init() {
220         if (includes == null) {
221             // No includes supplied, so set it to 'matches all'
222
includes = new String JavaDoc[1];
223             includes[0] = "**";
224         }
225         if (excludes == null) {
226             excludes = new String JavaDoc[0];
227         }
228     }
229
230     /**
231      * Matches a jar entry against the includes/excludes list,
232      * normalizing the path separator.
233      *
234      * @param path the (non-null) path name to test for inclusion
235      *
236      * @return <code>true</code> if the path should be included
237      * <code>false</code> otherwise.
238      */

239     public boolean match(String JavaDoc path) {
240         String JavaDoc vpath = path.replace('/', File.separatorChar).
241             replace('\\', File.separatorChar);
242         return isIncluded(vpath) && !isExcluded(vpath);
243     }
244
245     /**
246      * Get the named Resource.
247      * @param name path name of the file sought in the archive
248      * @return the resource
249      * @since Ant 1.5.2
250      */

251     public Resource getResource(String JavaDoc name) {
252         if (src == null) {
253             return super.getResource(name);
254         }
255         if (name.equals("")) {
256             // special case in ZIPs, we do not want this thing included
257
return new Resource("", true, Long.MAX_VALUE, true);
258         }
259         // first check if the archive needs to be scanned again
260
scanme();
261         if (fileEntries.containsKey(name)) {
262             return (Resource) fileEntries.get(name);
263         }
264         name = trimSeparator(name);
265
266         if (dirEntries.containsKey(name)) {
267             return (Resource) dirEntries.get(name);
268         }
269         return new Resource(name);
270     }
271
272     /**
273      * Fills the file and directory maps with resources read from the archive.
274      *
275      * @param archive the archive to scan.
276      * @param encoding encoding used to encode file names inside the archive.
277      * @param fileEntries Map (name to resource) of non-directory
278      * resources found inside the archive.
279      * @param matchFileEntries Map (name to resource) of non-directory
280      * resources found inside the archive that matched all include
281      * patterns and didn't match any exclude patterns.
282      * @param dirEntries Map (name to resource) of directory
283      * resources found inside the archive.
284      * @param matchDirEntries Map (name to resource) of directory
285      * resources found inside the archive that matched all include
286      * patterns and didn't match any exclude patterns.
287      */

288     protected abstract void fillMapsFromArchive(Resource archive,
289                                                 String JavaDoc encoding,
290                                                 Map JavaDoc fileEntries,
291                                                 Map JavaDoc matchFileEntries,
292                                                 Map JavaDoc dirEntries,
293                                                 Map JavaDoc matchDirEntries);
294
295     /**
296      * if the datetime of the archive did not change since
297      * lastScannedResource was initialized returns immediately else if
298      * the archive has not been scanned yet, then all the zip entries
299      * are put into the appropriate tables.
300      */

301     private void scanme() {
302         //do not use a FileResource b/c it pulls File info from the filesystem:
303
Resource thisresource = new Resource(src.getName(),
304                                              src.isExists(),
305                                              src.getLastModified());
306         // spare scanning again and again
307
if (lastScannedResource != null
308             && lastScannedResource.getName().equals(thisresource.getName())
309             && lastScannedResource.getLastModified()
310             == thisresource.getLastModified()) {
311             return;
312         }
313         init();
314
315         fileEntries.clear();
316         dirEntries.clear();
317         matchFileEntries.clear();
318         matchDirEntries.clear();
319         fillMapsFromArchive(src, encoding, fileEntries, matchFileEntries,
320                             dirEntries, matchDirEntries);
321
322         // record data about the last scanned resource
323
lastScannedResource = thisresource;
324     }
325
326     /**
327      * Remove trailing slash if present.
328      * @param s the file name to trim.
329      * @return the trimed file name.
330      */

331     protected static final String JavaDoc trimSeparator(String JavaDoc s) {
332         return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
333     }
334
335 }
336
Popular Tags