All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.antx.util.ZipScanner Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2002-2012 Alibaba Group Holding Limited.
 * All rights reserved.
 *
 * 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 com.alibaba.antx.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipScanner {
    /** The base directory to be scanned. */
    protected URL zipURL;

    /** The patterns for the files to be included. */
    protected String[] includes;

    /** The patterns for the files to be excluded. */
    protected String[] excludes;

    /**
     * The files which matched at least one include and no excludes and were
     * selected.
     */
    protected List filesIncluded;

    /** The files which did not match any includes or selectors. */
    protected List filesNotIncluded;

    /** The files which matched at least one include and at least one exclude. */
    protected List filesExcluded;

    /**
     * The directories which matched at least one include and no excludes and
     * were selected.
     */
    protected List dirsIncluded;

    /** The directories which were found and did not match any includes. */
    protected List dirsNotIncluded;

    /**
     * The directories which matched at least one include and at least one
     * exclude.
     */
    protected List dirsExcluded;

    /** Whether or not the file system should be treated as a case sensitive one. */
    protected boolean isCaseSensitive = true;

    /** Whether or not everything tested so far has been included. */
    protected boolean everythingIncluded = true;

    /** Sole constructor. */
    public ZipScanner() {
    }

    /**
     * Tests whether or not a given path matches the start of a given pattern up
     * to the first "".
     * 

* This is not a general purpose test and should only be used if you can * live with false positives. For example, pattern=\a and * str=b will yield true. *

* * @param pattern The pattern to match against. Must not be * null. * @param str The path to match, as a String. Must not be null. * @return whether or not a given path matches the start of a given pattern * up to the first "". */ protected static boolean matchPatternStart(String pattern, String str) { return SelectorUtil.matchPatternStart(pattern, str); } /** * Tests whether or not a given path matches the start of a given pattern up * to the first "". *

* This is not a general purpose test and should only be used if you can * live with false positives. For example, pattern=\a and * str=b will yield true. *

* * @param pattern The pattern to match against. Must not be * null. * @param str The path to match, as a String. Must not be null. * @param isCaseSensitive Whether or not matching should be performed case * sensitively. * @return whether or not a given path matches the start of a given pattern * up to the first "". */ protected static boolean matchPatternStart(String pattern, String str, boolean isCaseSensitive) { return SelectorUtil.matchPatternStart(pattern, str, isCaseSensitive); } /** * Tests whether or not a given path matches a given pattern. * * @param pattern The pattern to match against. Must not be * null. * @param str The path to match, as a String. Must not be null. * @return true if the pattern matches against the string, or * false otherwise. */ protected static boolean matchPath(String pattern, String str) { return SelectorUtil.matchPath(pattern, str); } /** * Tests whether or not a given path matches a given pattern. * * @param pattern The pattern to match against. Must not be * null. * @param str The path to match, as a String. Must not be null. * @param isCaseSensitive Whether or not matching should be performed case * sensitively. * @return true if the pattern matches against the string, or * false otherwise. */ protected static boolean matchPath(String pattern, String str, boolean isCaseSensitive) { return SelectorUtil.matchPath(pattern, str, isCaseSensitive); } /** * Tests whether or not a string matches against a pattern. The pattern may * contain two special characters:
* '' means zero or more characters
* '?' means one and only one character * * @param pattern The pattern to match against. Must not be * null. * @param str The string which must be matched against the pattern. Must not * be null. * @return true if the string matches against the pattern, or * false otherwise. */ public static boolean match(String pattern, String str) { return SelectorUtil.match(pattern, str); } /** * Tests whether or not a string matches against a pattern. The pattern may * contain two special characters:
* '' means zero or more characters
* '?' means one and only one character * * @param pattern The pattern to match against. Must not be * null. * @param str The string which must be matched against the pattern. Must not * be null. * @param isCaseSensitive Whether or not matching should be performed case * sensitively. * @return true if the string matches against the pattern, or * false otherwise. */ protected static boolean match(String pattern, String str, boolean isCaseSensitive) { return SelectorUtil.match(pattern, str, isCaseSensitive); } /** * Sets the base directory to be scanned. This is the directory which is * scanned recursively. All '/' and '\' characters are replaced by * File.separatorChar, so the separator used need not match * File.separatorChar. * * @param basedir The base directory to scan. Must not be null. */ public void setZipURL(String zipURL) throws MalformedURLException { setSrc(new URL(zipURL)); } /** * Sets the base directory to be scanned. This is the directory which is * scanned recursively. * * @param basedir The base directory for scanning. Should not be * null. */ public void setSrc(URL zipURL) { this.zipURL = zipURL; } /** * Returns the base directory to be scanned. This is the directory which is * scanned recursively. * * @return the base directory to be scanned */ public URL getZipURL() { return zipURL; } /** * Sets whether or not the file system should be regarded as case sensitive. * * @param isCaseSensitive whether or not the file system should be regarded * as a case sensitive one */ public void setCaseSensitive(boolean isCaseSensitive) { this.isCaseSensitive = isCaseSensitive; } /** * Sets the list of include patterns to use. All '/' and '\' characters are * replaced by File.separatorChar, so the separator used need * not match File.separatorChar. *

* When a pattern ends with a '/' or '\', "" is appended. *

* * @param includes A list of include patterns. May be null, * indicating that all files should be included. If a non- * null list is given, all elements must be non- * null. */ public void setIncludes(String[] includes) { if (includes == null) { this.includes = null; } else { this.includes = new String[includes.length]; for (int i = 0; i < includes.length; i++) { String pattern; pattern = includes[i].replace('\\', '/'); if (pattern.endsWith(File.separator)) { pattern += "**"; } this.includes[i] = pattern; } } } /** * Sets the list of exclude patterns to use. All '/' and '\' characters are * replaced by File.separatorChar, so the separator used need * not match File.separatorChar. *

* When a pattern ends with a '/' or '\', "" is appended. *

* * @param excludes A list of exclude patterns. May be null, * indicating that no files should be excluded. If a non- * null list is given, all elements must be non- * null. */ public void setExcludes(String[] excludes) { if (excludes == null) { this.excludes = null; } else { this.excludes = new String[excludes.length]; for (int i = 0; i < excludes.length; i++) { String pattern; pattern = excludes[i].replace('\\', '/'); if (pattern.endsWith(File.separator)) { pattern += "**"; } this.excludes[i] = pattern; } } } /** * Returns whether or not the scanner has included all the files or * directories it has come across so far. * * @return true if all files and directories which have been * found so far have been included. */ public boolean isEverythingIncluded() { return everythingIncluded; } /** * Scans the base directory for files which match at least one include * pattern and don't match any exclude patterns. If there are selectors then * the files must pass muster there, as well. * * @throws IllegalStateException if the base directory was set * incorrectly (i.e. if it is null, doesn't * exist, or isn't a directory). */ public void scan() throws IllegalStateException, IOException { if (zipURL == null) { throw new IllegalStateException("No zipURL set"); } 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]; } filesIncluded = new ArrayList(); filesNotIncluded = new ArrayList(); filesExcluded = new ArrayList(); dirsIncluded = new ArrayList(); dirsNotIncluded = new ArrayList(); dirsExcluded = new ArrayList(); if (isIncluded("")) { if (!isExcluded("")) { dirsIncluded.add(""); } else { dirsExcluded.add(""); } } else { dirsNotIncluded.add(""); } scanZipFile(zipURL); } /** * Scans the given directory for files and directories. Found files and * directories are placed in their respective collections, based on the * matching of includes, excludes, and the selectors. When a directory is * found, it is scanned recursively. * * @param dir The directory to scan. Must not be null. * @param vpath The path relative to the base directory (needed to prevent * problems with an absolute path when using dir). Must not be * null. * @param fast Whether or not this call is part of a fast scan. * @see #filesIncluded * @see #filesNotIncluded * @see #filesExcluded * @see #dirsIncluded * @see #dirsNotIncluded * @see #dirsExcluded * @see #slowScan */ protected void scanZipFile(URL zipURL) throws IOException { InputStream istream = null; ZipInputStream zipStream = null; try { istream = zipURL.openStream(); if (!(istream instanceof BufferedInputStream)) { istream = new BufferedInputStream(istream, 8192); } zipStream = new ZipInputStream(istream); ZipEntry entry; while ((entry = zipStream.getNextEntry()) != null) { String name = entry.getName().replace('\\', '/'); if (name.endsWith(File.separator)) { name = name.substring(0, name.length() - 1); } if (entry.isDirectory()) { if (isIncluded(name)) { if (!isExcluded(name)) { dirsIncluded.add(name); } else { everythingIncluded = false; dirsExcluded.add(name); } } else { everythingIncluded = false; dirsNotIncluded.add(name); } } else { if (isIncluded(name)) { if (!isExcluded(name)) { filesIncluded.add(name); } else { everythingIncluded = false; filesExcluded.add(name); } } else { everythingIncluded = false; filesNotIncluded.add(name); } } } } finally { if (zipStream != null) { try { zipStream.close(); } catch (IOException e) { } } if (istream != null) { try { istream.close(); } catch (IOException e) { } } } } /** * Tests whether or not a name matches against at least one include pattern. * * @param name The name to match. Must not be null. * @return true when the name matches against at least one * include pattern, or false otherwise. */ protected boolean isIncluded(String name) { for (String include : includes) { if (matchPath(include, name, isCaseSensitive)) { return true; } } return false; } /** * Tests whether or not a name matches against at least one exclude pattern. * * @param name The name to match. Must not be null. * @return true when the name matches against at least one * exclude pattern, or false otherwise. */ protected boolean isExcluded(String name) { for (String exclude : excludes) { if (matchPath(exclude, name, isCaseSensitive)) { return true; } } return false; } /** * 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() { return (String[]) filesIncluded.toArray(new String[filesIncluded.size()]); } /** * Returns the names of the files which matched none of the include * patterns. The names are relative to the base directory. This involves * performing a slow scan if one has not already been completed. * * @return the names of the files which matched none of the include * patterns. * @see #slowScan */ public String[] getNotIncludedFiles() { return (String[]) filesNotIncluded.toArray(new String[filesNotIncluded.size()]); } /** * Returns the names of the files which matched at least one of the include * patterns and at least one of the exclude patterns. The names are relative * to the base directory. This involves performing a slow scan if one has * not already been completed. * * @return the names of the files which matched at least one of the include * patterns and at at least one of the exclude patterns. * @see #slowScan */ public String[] getExcludedFiles() { return (String[]) filesExcluded.toArray(new String[filesExcluded.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() { return (String[]) dirsIncluded.toArray(new String[dirsIncluded.size()]); } /** * Returns the names of the directories which matched none of the include * patterns. The names are relative to the base directory. This involves * performing a slow scan if one has not already been completed. * * @return the names of the directories which matched none of the include * patterns. * @see #slowScan */ public String[] getNotIncludedDirectories() { return (String[]) dirsNotIncluded.toArray(new String[dirsNotIncluded.size()]); } /** * Returns the names of the directories which matched at least one of the * include patterns and at least one of the exclude patterns. The names are * relative to the base directory. This involves performing a slow scan if * one has not already been completed. * * @return the names of the directories which matched at least one of the * include patterns and at least one of the exclude patterns. * @see #slowScan */ public String[] getExcludedDirectories() { return (String[]) dirsExcluded.toArray(new String[dirsExcluded.size()]); } /** Adds default exclusions to the current exclusions set. */ public void addDefaultExcludes() { int excludesLength = excludes == null ? 0 : excludes.length; String[] newExcludes; newExcludes = new String[excludesLength + FileUtil.DEFAULT_EXCLUDES.length]; if (excludesLength > 0) { System.arraycopy(excludes, 0, newExcludes, 0, excludesLength); } for (int i = 0; i < FileUtil.DEFAULT_EXCLUDES.length; i++) { newExcludes[i + excludesLength] = FileUtil.DEFAULT_EXCLUDES[i].replace('\\', '/'); } excludes = newExcludes; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy