- /*
- * Copyright 2001-2004 The Apache Software Foundation
- *
- * Licensed 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.io.IOException;
- import java.util.Arrays;
- import java.util.Vector;
- import java.util.Hashtable;
- import java.util.Enumeration;
- import java.util.zip.ZipException;
-
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.DirectoryScanner;
- import org.apache.tools.zip.ZipEntry;
- import org.apache.tools.zip.ZipFile;
-
- /**
- * ZipScanner 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 Zip entries.
- *
- */
- public class ZipScanner extends DirectoryScanner {
-
- /**
- * The zip file which should be scanned.
- */
- protected File srcFile;
- /**
- * to record the last scanned zip file with its modification date
- */
- private Resource lastScannedResource;
- /**
- * record list of all zip entries
- */
- private Hashtable myentries;
-
- /**
- * encoding of file names.
- *
- * @since Ant 1.6
- */
- private String encoding;
-
- /**
- * Sets the srcFile for scanning. This is the jar or zip file that
- * is scanned for matching entries.
- *
- * @param srcFile the (non-null) zip file name for scanning
- */
- public void setSrc(File srcFile) {
- this.srcFile = srcFile;
- }
-
- /**
- * Sets encoding of file names.
- *
- * @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 (srcFile != null) {
- Vector myvector = new Vector();
- // first check if the archive needs to be scanned again
- scanme();
- for (Enumeration e = myentries.elements(); e.hasMoreElements();) {
- Resource myresource = (Resource) e.nextElement();
- if (!myresource.isDirectory() && match(myresource.getName())) {
- myvector.addElement(myresource.getName());
- }
- }
- String[] files = new String[myvector.size()];
- myvector.copyInto(files);
- Arrays.sort(files);
- return files;
- } else {
- return super.getIncludedFiles();
- }
- }
-
- /**
- * 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 (srcFile != null) {
- Vector myvector = new Vector();
- // first check if the archive needs to be scanned again
- scanme();
- for (Enumeration e = myentries.elements(); e.hasMoreElements();) {
- Resource myresource = (Resource) e.nextElement();
- if (myresource.isDirectory() && match(myresource.getName())) {
- myvector.addElement(myresource.getName());
- }
- }
- String[] files = new String[myvector.size()];
- myvector.copyInto(files);
- Arrays.sort(files);
- return files;
- } else {
- return super.getIncludedDirectories();
- }
- }
-
- /**
- * 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.replace('/', File.separatorChar).
- replace('\\', File.separatorChar);
- return isIncluded(vpath) && !isExcluded(vpath);
- }
-
- /**
- * @param name path name of the file sought in the archive
- *
- * @since Ant 1.5.2
- */
- public Resource getResource(String name) {
- if (srcFile == null) {
- return super.getResource(name);
- } else 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 (myentries.containsKey(name)) {
- return (Resource) myentries.get(name);
- } else if (myentries.containsKey(name + "/")) {
- return (Resource) myentries.get(name + "/");
- } else {
- return new Resource(name);
- }
- }
-
- /**
- * 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 vector myentries as a vector of the resource
- * type
- */
- private void scanme() {
- Resource thisresource = new Resource(srcFile.getAbsolutePath(),
- srcFile.exists(),
- srcFile.lastModified());
-
- // spare scanning again and again
- if (lastScannedResource != null
- && lastScannedResource.getName().equals(thisresource.getName())
- && lastScannedResource.getLastModified()
- == thisresource.getLastModified()) {
- return;
- }
-
- ZipEntry entry = null;
- ZipFile zf = null;
- myentries = new Hashtable();
- try {
- try {
- zf = new ZipFile(srcFile, encoding);
- } catch (ZipException ex) {
- throw new BuildException("problem reading " + srcFile, ex);
- } catch (IOException ex) {
- throw new BuildException("problem opening " + srcFile, ex);
- }
-
- Enumeration e = zf.getEntries();
- while (e.hasMoreElements()) {
- entry = (ZipEntry) e.nextElement();
- myentries.put(new String(entry.getName()),
- new Resource(entry.getName(), true,
- entry.getTime(),
- entry.isDirectory()));
- }
- } finally {
- if (zf != null) {
- try {
- zf.close();
- } catch (IOException ex) {
- // swallow
- }
- }
- }
- // record data about the last scanned resource
- lastScannedResource = thisresource;
- }
- }