diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java new file mode 100644 index 00000000..db5a8d46 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.types; + +import java.io.File; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.resources.FileProvider; +import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.FileResourceIterator; + +/** + * ArchiveScanner accesses the pattern matching algorithm in DirectoryScanner, + * which are protected methods that can only be accessed by subclassing. + * + * This implementation of FileScanner defines getIncludedFiles to return + * the matching archive entries. + * + * @since Ant 1.7 + */ +public abstract class ArchiveScanner extends DirectoryScanner { + // CheckStyle:VisibilityModifier OFF - bc + + /** + * The archive file which should be scanned. + */ + protected File srcFile; + + // CheckStyle:VisibilityModifier ON + + /** + * The archive resource which should be scanned. + */ + private Resource src; + + /** + * to record the last scanned zip file with its modification date + */ + private Resource lastScannedResource; + + /** + * record list of all file zip entries + */ + private Map<String, Resource> fileEntries = new TreeMap<String, Resource>(); + + /** + * record list of all directory zip entries + */ + private Map<String, Resource> dirEntries = new TreeMap<String, Resource>(); + + /** + * record list of matching file zip entries + */ + private Map<String, Resource> matchFileEntries = new TreeMap<String, Resource>(); + + /** + * record list of matching directory zip entries + */ + private Map<String, Resource> matchDirEntries = new TreeMap<String, Resource>(); + + /** + * encoding of file names. + * + * @since Ant 1.6 + */ + private String encoding; + + /** + * @since Ant 1.8.0 + */ + private boolean errorOnMissingArchive = true; + + /** + * Sets whether an error is thrown if an archive does not exist. + * + * @param errorOnMissingArchive true if missing archives cause errors, + * false if not. + * @since Ant 1.8.0 + */ + public void setErrorOnMissingArchive(boolean errorOnMissingArchive) { + this.errorOnMissingArchive = errorOnMissingArchive; + } + + /** + * Don't scan when we have no zipfile. + * @since Ant 1.7 + */ + public void scan() { + if (src == null || (!src.isExists() && !errorOnMissingArchive)) { + return; + } + super.scan(); + } + + /** + * Sets the srcFile for scanning. This is the jar or zip file that + * is scanned for matching entries. + * + * @param srcFile the (non-null) archive file name for scanning + */ + public void setSrc(File srcFile) { + setSrc(new FileResource(srcFile)); + } + + /** + * Sets the src for scanning. This is the jar or zip file that + * is scanned for matching entries. + * + * @param src the (non-null) archive resource + */ + public void setSrc(Resource src) { + this.src = src; + FileProvider fp = src.as(FileProvider.class); + if (fp != null) { + srcFile = fp.getFile(); + } + } + + /** + * Sets encoding of file names. + * @param encoding the encoding format + * @since Ant 1.6 + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * Returns the names of the files which matched at least one of the + * include patterns and none of the exclude patterns. + * The names are relative to the base directory. + * + * @return the names of the files which matched at least one of the + * include patterns and none of the exclude patterns. + */ + public String[] getIncludedFiles() { + if (src == null) { + return super.getIncludedFiles(); + } + scanme(); + return matchFileEntries.keySet().toArray(new String[matchFileEntries.size()]); + } + + /** + * Override parent implementation. + * @return count of included files. + * @since Ant 1.7 + */ + public int getIncludedFilesCount() { + if (src == null) { + return super.getIncludedFilesCount(); + } + scanme(); + return matchFileEntries.size(); + } + + /** + * Returns the names of the directories which matched at least one of the + * include patterns and none of the exclude patterns. + * The names are relative to the base directory. + * + * @return the names of the directories which matched at least one of the + * include patterns and none of the exclude patterns. + */ + public String[] getIncludedDirectories() { + if (src == null) { + return super.getIncludedDirectories(); + } + scanme(); + return matchDirEntries.keySet().toArray(new String[matchDirEntries.size()]); + } + + /** + * Override parent implementation. + * @return count of included directories. + * @since Ant 1.7 + */ + public int getIncludedDirsCount() { + if (src == null) { + return super.getIncludedDirsCount(); + } + scanme(); + return matchDirEntries.size(); + } + + /** + * Get the set of Resources that represent files. + * @param project since Ant 1.8 + * @return an Iterator of Resources. + * @since Ant 1.7 + */ + /* package-private for now */ Iterator<Resource> getResourceFiles(Project project) { + if (src == null) { + return new FileResourceIterator(project, getBasedir(), getIncludedFiles()); + } + scanme(); + return matchFileEntries.values().iterator(); + } + + /** + * Get the set of Resources that represent directories. + * @param project since Ant 1.8 + * @return an Iterator of Resources. + * @since Ant 1.7 + */ + /* package-private for now */ Iterator<Resource> getResourceDirectories(Project project) { + if (src == null) { + return new FileResourceIterator(project, getBasedir(), getIncludedDirectories()); + } + scanme(); + return matchDirEntries.values().iterator(); + } + + /** + * Initialize DirectoryScanner data structures. + */ + public void init() { + if (includes == null) { + // No includes supplied, so set it to 'matches all' + includes = new String[1]; + includes[0] = "**"; + } + if (excludes == null) { + excludes = new String[0]; + } + } + + /** + * Matches a jar entry against the includes/excludes list, + * normalizing the path separator. + * + * @param path the (non-null) path name to test for inclusion + * + * @return <code>true</code> if the path should be included + * <code>false</code> otherwise. + */ + public boolean match(String path) { + String vpath = path; + if (path.length() > 0) { + vpath = path.replace('/', File.separatorChar). + replace('\\', File.separatorChar); + if (vpath.charAt(0) == File.separatorChar) { + vpath = vpath.substring(1); + } + } + return isIncluded(vpath) && !isExcluded(vpath); + } + + /** + * Get the named Resource. + * @param name path name of the file sought in the archive + * @return the resource + * @since Ant 1.5.2 + */ + public Resource getResource(String name) { + if (src == null) { + return super.getResource(name); + } + if (name.equals("")) { + // special case in ZIPs, we do not want this thing included + return new Resource("", true, Long.MAX_VALUE, true); + } + // first check if the archive needs to be scanned again + scanme(); + if (fileEntries.containsKey(name)) { + return fileEntries.get(name); + } + name = trimSeparator(name); + + if (dirEntries.containsKey(name)) { + return dirEntries.get(name); + } + return new Resource(name); + } + + /** + * Fills the file and directory maps with resources read from the archive. + * + * @param archive the archive to scan. + * @param encoding encoding used to encode file names inside the archive. + * @param fileEntries Map (name to resource) of non-directory + * resources found inside the archive. + * @param matchFileEntries Map (name to resource) of non-directory + * resources found inside the archive that matched all include + * patterns and didn't match any exclude patterns. + * @param dirEntries Map (name to resource) of directory + * resources found inside the archive. + * @param matchDirEntries Map (name to resource) of directory + * resources found inside the archive that matched all include + * patterns and didn't match any exclude patterns. + */ + protected abstract void fillMapsFromArchive(Resource archive, + String encoding, + Map<String, Resource> fileEntries, + Map<String, Resource> matchFileEntries, + Map<String, Resource> dirEntries, + Map<String, Resource> matchDirEntries); + + /** + * if the datetime of the archive did not change since + * lastScannedResource was initialized returns immediately else if + * the archive has not been scanned yet, then all the zip entries + * are put into the appropriate tables. + */ + private void scanme() { + if (!src.isExists() && !errorOnMissingArchive) { + return; + } + + //do not use a FileResource b/c it pulls File info from the filesystem: + Resource thisresource = new Resource(src.getName(), + src.isExists(), + src.getLastModified()); + // spare scanning again and again + if (lastScannedResource != null + && lastScannedResource.getName().equals(thisresource.getName()) + && lastScannedResource.getLastModified() + == thisresource.getLastModified()) { + return; + } + init(); + + fileEntries.clear(); + dirEntries.clear(); + matchFileEntries.clear(); + matchDirEntries.clear(); + fillMapsFromArchive(src, encoding, fileEntries, matchFileEntries, + dirEntries, matchDirEntries); + + // record data about the last scanned resource + lastScannedResource = thisresource; + } + + /** + * Remove trailing slash if present. + * @param s the file name to trim. + * @return the trimmed file name. + */ + protected static final String trimSeparator(String s) { + return s.endsWith("/") ? s.substring(0, s.length() - 1) : s; + } + +} |