📄 directoryscanner.java
字号:
/* * 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;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.Vector;import org.apache.tools.ant.taskdefs.condition.Os;import org.apache.tools.ant.types.Resource;import org.apache.tools.ant.types.ResourceFactory;import org.apache.tools.ant.types.resources.FileResource;import org.apache.tools.ant.types.selectors.FileSelector;import org.apache.tools.ant.types.selectors.SelectorScanner;import org.apache.tools.ant.types.selectors.SelectorUtils;import org.apache.tools.ant.util.FileUtils;/** * Class for scanning a directory for files/directories which match certain * criteria. * <p> * These criteria consist of selectors and patterns which have been specified. * With the selectors you can select which files you want to have included. * Files which are not selected are excluded. With patterns you can include * or exclude files based on their filename. * <p> * The idea is simple. A given directory is recursively scanned for all files * and directories. Each file/directory is matched against a set of selectors, * including special support for matching against filenames with include and * and exclude patterns. Only files/directories which match at least one * pattern of the include pattern list or other file selector, and don't match * any pattern of the exclude pattern list or fail to match against a required * selector will be placed in the list of files/directories found. * <p> * When no list of include patterns is supplied, "**" will be used, which * means that everything will be matched. When no list of exclude patterns is * supplied, an empty list is used, such that nothing will be excluded. When * no selectors are supplied, none are applied. * <p> * The filename pattern matching is done as follows: * The name to be matched is split up in path segments. A path segment is the * name of a directory or file, which is bounded by * <code>File.separator</code> ('/' under UNIX, '\' under Windows). * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc", * "def","ghi" and "xyz.java". * The same is done for the pattern against which should be matched. * <p> * The segments of the name and the pattern are then matched against each * other. When '**' is used for a path segment in the pattern, it matches * zero or more path segments of the name. * <p> * There is a special case regarding the use of <code>File.separator</code>s * at the beginning of the pattern and the string to match:<br> * When a pattern starts with a <code>File.separator</code>, the string * to match must also start with a <code>File.separator</code>. * When a pattern does not start with a <code>File.separator</code>, the * string to match may not start with a <code>File.separator</code>. * When one of these rules is not obeyed, the string will not * match. * <p> * When a name path segment is matched against a pattern path segment, the * following special characters can be used:<br> * '*' matches zero or more characters<br> * '?' matches one character. * <p> * Examples: * <p> * "**\*.class" matches all .class files/dirs in a directory tree. * <p> * "test\a??.java" matches all files/dirs which start with an 'a', then two * more characters and then ".java", in a directory called test. * <p> * "**" matches everything in a directory tree. * <p> * "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123"). * <p> * Case sensitivity may be turned off if necessary. By default, it is * turned on. * <p> * Example of usage: * <pre> * String[] includes = {"**\\*.class"}; * String[] excludes = {"modules\\*\\**"}; * ds.setIncludes(includes); * ds.setExcludes(excludes); * ds.setBasedir(new File("test")); * ds.setCaseSensitive(true); * ds.scan(); * * System.out.println("FILES:"); * String[] files = ds.getIncludedFiles(); * for (int i = 0; i < files.length; i++) { * System.out.println(files[i]); * } * </pre> * This will scan a directory called test for .class files, but excludes all * files in all proper subdirectories of a directory called "modules" * */public class DirectoryScanner implements FileScanner, SelectorScanner, ResourceFactory { /** Is OpenVMS the operating system we're running on? */ private static final boolean ON_VMS = Os.isFamily("openvms"); /** * Patterns which should be excluded by default. * * <p>Note that you can now add patterns to the list of default * excludes. Added patterns will not become part of this array * that has only been kept around for backwards compatibility * reasons.</p> * * @deprecated since 1.6.x. * Use the {@link #getDefaultExcludes getDefaultExcludes} * method instead. */ protected static final String[] DEFAULTEXCLUDES = { // Miscellaneous typical temporary files "**/*~", "**/#*#", "**/.#*", "**/%*%", "**/._*", // CVS "**/CVS", "**/CVS/**", "**/.cvsignore", // SCCS "**/SCCS", "**/SCCS/**", // Visual SourceSafe "**/vssver.scc", // Subversion "**/.svn", "**/.svn/**", // Mac "**/.DS_Store" }; /** Helper. */ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** iterations for case-sensitive scanning. */ private static final boolean[] CS_SCAN_ONLY = new boolean[] {true}; /** iterations for non-case-sensitive scanning. */ private static final boolean[] CS_THEN_NON_CS = new boolean[] {true, false}; /** * Patterns which should be excluded by default. * * @see #addDefaultExcludes() */ private static Vector defaultExcludes = new Vector(); static { resetDefaultExcludes(); } // CheckStyle:VisibilityModifier OFF - bc /** The base directory to be scanned. */ protected File basedir; /** The patterns for the files to be included. */ protected String[] includes; /** The patterns for the files to be excluded. */ protected String[] excludes; /** Selectors that will filter which files are in our candidate list. */ protected FileSelector[] selectors = null; /** * The files which matched at least one include and no excludes * and were selected. */ protected Vector filesIncluded; /** The files which did not match any includes or selectors. */ protected Vector filesNotIncluded; /** * The files which matched at least one include and at least * one exclude. */ protected Vector filesExcluded; /** * The directories which matched at least one include and no excludes * and were selected. */ protected Vector dirsIncluded; /** The directories which were found and did not match any includes. */ protected Vector dirsNotIncluded; /** * The directories which matched at least one include and at least one * exclude. */ protected Vector dirsExcluded; /** * The files which matched at least one include and no excludes and * which a selector discarded. */ protected Vector filesDeselected; /** * The directories which matched at least one include and no excludes * but which a selector discarded. */ protected Vector dirsDeselected; /** Whether or not our results were built by a slow scan. */ protected boolean haveSlowResults = false; /** * Whether or not the file system should be treated as a case sensitive * one. */ protected boolean isCaseSensitive = true; /** * Whether a missing base directory is an error. * @since Ant 1.7.1 */ protected boolean errorOnMissingDir = true; /** * Whether or not symbolic links should be followed. * * @since Ant 1.5 */ private boolean followSymlinks = true; /** Whether or not everything tested so far has been included. */ protected boolean everythingIncluded = true; // CheckStyle:VisibilityModifier ON /** * Temporary table to speed up the various scanning methods. * * @since Ant 1.6 */ private Map fileListMap = new HashMap(); /** * List of all scanned directories. * * @since Ant 1.6 */ private Set scannedDirs = new HashSet(); /** * Set of all include patterns that are full file names and don't * contain any wildcards. * * <p>If this instance is not case sensitive, the file names get * turned to lower case.</p> * * <p>Gets lazily initialized on the first invocation of * isIncluded or isExcluded and cleared at the end of the scan * method (cleared in clearCaches, actually).</p> * * @since Ant 1.6.3 */ private Set includeNonPatterns = new HashSet(); /** * Set of all include patterns that are full file names and don't * contain any wildcards. * * <p>If this instance is not case sensitive, the file names get * turned to lower case.</p> * * <p>Gets lazily initialized on the first invocation of * isIncluded or isExcluded and cleared at the end of the scan * method (cleared in clearCaches, actually).</p> * * @since Ant 1.6.3 */ private Set excludeNonPatterns = new HashSet(); /** * Array of all include patterns that contain wildcards. * * <p>Gets lazily initialized on the first invocation of * isIncluded or isExcluded and cleared at the end of the scan * method (cleared in clearCaches, actually).</p> * * @since Ant 1.6.3 */ private String[] includePatterns; /** * Array of all exclude patterns that contain wildcards. * * <p>Gets lazily initialized on the first invocation of * isIncluded or isExcluded and cleared at the end of the scan * method (cleared in clearCaches, actually).</p> * * @since Ant 1.6.3 */ private String[] excludePatterns; /** * Have the non-pattern sets and pattern arrays for in- and * excludes been initialized? * * @since Ant 1.6.3 */ private boolean areNonPatternSetsReady = false; /** * Scanning flag. * * @since Ant 1.6.3 */ private boolean scanning = false; /** * Scanning lock. * * @since Ant 1.6.3 */ private Object scanLock = new Object(); /** * Slow scanning flag. * * @since Ant 1.6.3 */ private boolean slowScanning = false; /** * Slow scanning lock. * * @since Ant 1.6.3 */ private Object slowScanLock = new Object(); /** * Exception thrown during scan. * * @since Ant 1.6.3 */ private IllegalStateException illegal = null; /** * Sole constructor. */ public DirectoryScanner() { } /** * Test whether or not a given path matches the start of a given * pattern up to the first "**". * <p> * This is not a general purpose test and should only be used if you * can live with false positives. For example, <code>pattern=**\a</code> * and <code>str=b</code> will yield <code>true</code>. * * @param pattern The pattern to match against. Must not be * <code>null</code>. * @param str The path to match, as a String. Must not be * <code>null</code>. * * @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 SelectorUtils.matchPatternStart(pattern, str); } /** * Test whether or not a given path matches the start of a given * pattern up to the first "**". * <p> * This is not a general purpose test and should only be used if you * can live with false positives. For example, <code>pattern=**\a</code> * and <code>str=b</code> will yield <code>true</code>. * * @param pattern The pattern to match against. Must not be * <code>null</code>. * @param str The path to match, as a String. Must not be * <code>null</code>. * @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 SelectorUtils.matchPatternStart(pattern, str, isCaseSensitive); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -