Return-Path: Delivered-To: apmail-jakarta-ant-dev-archive@jakarta.apache.org Received: (qmail 40545 invoked by uid 500); 23 May 2001 13:42:52 -0000 Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk Reply-To: ant-dev@jakarta.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 40345 invoked by uid 500); 23 May 2001 13:42:42 -0000 Delivered-To: apmail-jakarta-ant-cvs@apache.org Date: 23 May 2001 13:42:38 -0000 Message-ID: <20010523134238.40252.qmail@apache.org> From: conor@apache.org To: jakarta-ant-cvs@apache.org Subject: cvs commit: jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types AbstractScanner.java DirectoryScanner.java FileSet.java FileSetScanner.java DataType.java PatternSet.java conor 01/05/23 06:42:37 Modified: proposal/mutant build.xml proposal/mutant/src/main/org/apache/ant/component/core FileConverter.java Property.java URLConverter.java antlib.xml proposal/mutant/src/main/org/apache/ant/core/execution AbstractAspectHandler.java AspectHandler.java ExecutionFrame.java proposal/mutant/src/main/org/apache/ant/core/types DataType.java PatternSet.java Added: proposal/mutant/src/main/org/apache/ant/core/types AbstractScanner.java DirectoryScanner.java FileSet.java FileSetScanner.java Log: Lots of mutant changes Revision Changes Path 1.3 +2 -1 jakarta-ant/proposal/mutant/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/build.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- build.xml 2001/05/18 13:37:03 1.2 +++ build.xml 2001/05/23 13:42:10 1.3 @@ -12,7 +12,8 @@ + destdir="${build.classes}" closure="yes" + cache="${build.dir}/depcache"/> + 1.2 +3 -0 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/AbstractAspectHandler.java Index: AbstractAspectHandler.java =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/AbstractAspectHandler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AbstractAspectHandler.java 2001/05/18 13:37:27 1.1 +++ AbstractAspectHandler.java 2001/05/23 13:42:24 1.2 @@ -74,6 +74,9 @@ return aspectContext; } + public void beforeConfigElement(Object element) throws ExecutionException { +} + public void afterConfigElement(Object element) throws ExecutionException { } } 1.2 +1 -0 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/AspectHandler.java Index: AspectHandler.java =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/AspectHandler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AspectHandler.java 2001/05/18 13:37:29 1.1 +++ AspectHandler.java 2001/05/23 13:42:25 1.2 @@ -69,6 +69,7 @@ void setAspectContext(ExecutionContext context); + void beforeConfigElement(Object element) throws ExecutionException ; void afterConfigElement(Object element) throws ExecutionException ; } 1.3 +12 -4 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionFrame.java Index: ExecutionFrame.java =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionFrame.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ExecutionFrame.java 2001/05/18 13:37:33 1.2 +++ ExecutionFrame.java 2001/05/23 13:42:26 1.3 @@ -543,8 +543,6 @@ task = new TaskAdapter(taskType, element); } - ExecutionContext context = new ExecutionContext(this, eventSupport, model); - task.setTaskContext(context); configureElement(element, model); return task; @@ -611,10 +609,21 @@ */ private void configureElement(Object element, TaskElement model) throws ExecutionException, ConfigException { - + + if (element instanceof Task) { + Task task = (Task)element; + ExecutionContext context = new ExecutionContext(this, eventSupport, model); + task.setTaskContext(context); + } try { ClassIntrospector introspector = getIntrospector(element.getClass()); + List aspects = getActiveAspects(model); + for (Iterator i = aspects.iterator(); i.hasNext(); ) { + AspectHandler aspectHandler = (AspectHandler)i.next(); + aspectHandler.beforeConfigElement(element); + } + // start by setting the attributes of this element for (Iterator i = model.getAttributeNames(); i.hasNext();) { String attributeName = (String)i.next(); @@ -644,7 +653,6 @@ configureElement(nestedElement, nestedElementModel); } } - List aspects = getActiveAspects(model); for (Iterator i = aspects.iterator(); i.hasNext(); ) { AspectHandler aspectHandler = (AspectHandler)i.next(); aspectHandler.afterConfigElement(element); 1.3 +4 -0 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/DataType.java Index: DataType.java =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/DataType.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DataType.java 2001/05/19 08:00:24 1.2 +++ DataType.java 2001/05/23 13:42:31 1.3 @@ -67,6 +67,10 @@ private Object referencedObject = null; public void execute() throws ExecutionException { + validate(); + } + + protected void validate() throws ExecutionException { } /** 1.3 +19 -22 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/PatternSet.java Index: PatternSet.java =================================================================== RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/PatternSet.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PatternSet.java 2001/05/19 08:00:25 1.2 +++ PatternSet.java 2001/05/23 13:42:32 1.3 @@ -69,6 +69,7 @@ * @author Stefan Bodewig */ public class PatternSet extends DataType { + private boolean filesRead = false; private List includeList = new ArrayList(); private List excludeList = new ArrayList(); @@ -115,10 +116,6 @@ // } } - - public PatternSet() { - } - /** * Makes this instance in effect a reference to another PatternSet * instance. @@ -203,7 +200,7 @@ * * @param incl The file to fetch the include patterns from. */ - public void setIncludesfile(URL includeFile) throws ExecutionException { + public void setIncludesFile(URL includeFile) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } @@ -220,7 +217,7 @@ * * @param excludeFile The file to fetch the exclude patterns from. */ - public void setExcludesfile(URL excludeFile) throws ExecutionException { + public void setExcludesFile(URL excludeFile) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } @@ -316,15 +313,15 @@ } } -// /** -// * helper for FileSet. -// */ -// boolean hasPatterns() { -// return incl != null || excl != null -// || includeList.size() > 0 || excludeList.size() > 0; -// } -// /** + * helper for FileSet. + */ + boolean hasPatterns() { + return includeFile != null || excludeFile != null + || includeList.size() > 0 || excludeList.size() > 0; + } + + /** * Performs the check for circular references and returns the * referenced PatternSet. */ @@ -363,14 +360,14 @@ * Read includefile ot excludefile if not already done so. */ private void readFiles() throws ExecutionException { - if (includeFile != null) { - readPatterns(includeFile, includeList); - includeFile = null; - } - if (excludeFile != null) { - readPatterns(excludeFile, excludeList); - excludeFile = null; + if (!filesRead) { + filesRead = true; + if (includeFile != null) { + readPatterns(includeFile, includeList); + } + if (excludeFile != null) { + readPatterns(excludeFile, excludeList); + } } } - } 1.1 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/AbstractScanner.java Index: AbstractScanner.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.ant.core.types; import java.io.*; import java.util.*; import org.apache.ant.core.execution.*; /** * The abstract FileSetInfo performs all of the name matching and mapping operations * common to FileSetInfo classes. */ public abstract class AbstractScanner implements FileSetScanner { /** The list of patternSets to process on this directory */ List patternSets; /** Indicator for whether default excludes should be applied. */ boolean useDefaultExcludes; /* * The patterns for the files that should be included. */ private String[] includes; /** * The patterns for the files that should be excluded. */ private String[] excludes; /** * Patterns that should be excluded by default. * * @see #addDefaultExcludes() */ protected final static String[] DEFAULTEXCLUDES = { "**/*~", "**/#*#", "**/.#*", "**/%*%", "**/CVS", "**/CVS/**", "**/.cvsignore", "**/SCCS", "**/SCCS/**" }; public AbstractScanner(List patternSets, boolean useDefaultExcludes) throws ExecutionException { this.patternSets = patternSets; this.useDefaultExcludes = useDefaultExcludes; //convert patternsets into excludes PatternSet combinedSet = new PatternSet(); for (Iterator i = patternSets.iterator(); i.hasNext(); ) { PatternSet set = (PatternSet)i.next(); combinedSet.append(set); } String[] includes = combinedSet.getIncludePatterns(); if (includes == null) { // No includes supplied, so set it to 'matches all' includes = new String[1]; includes[0] = "**"; } String[] excludes = combinedSet.getExcludePatterns(); if (excludes == null) { excludes = new String[0]; } setIncludes(includes); setExcludes(excludes); if (useDefaultExcludes) { addDefaultExcludes(); } } /** * Sets the set 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 list of include patterns */ protected 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('/',File.separatorChar).replace('\\',File.separatorChar); if (pattern.endsWith(File.separator)) { pattern += "**"; } this.includes[i] = pattern; } } } /** * Sets the set 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 list of exclude patterns */ protected 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('/',File.separatorChar).replace('\\',File.separatorChar); if (pattern.endsWith(File.separator)) { pattern += "**"; } this.excludes[i] = pattern; } } } /** * Does the path match the start of this pattern up to the first "**". + *

This is not a general purpose test and should only be used if you * can live with false positives.

* *

pattern=**\\a and str=b will yield true. * * @param pattern the (non-null) pattern to match against * @param str the (non-null) string (path) to match */ protected static boolean matchPatternStart(String pattern, String str) { // When str starts with a File.separator, pattern has to start with a // File.separator. // When pattern starts with a File.separator, str has to start with a // File.separator. if (str.startsWith(File.separator) != pattern.startsWith(File.separator)) { return false; } Vector patDirs = new Vector(); StringTokenizer st = new StringTokenizer(pattern,File.separator); while (st.hasMoreTokens()) { patDirs.addElement(st.nextToken()); } Vector strDirs = new Vector(); st = new StringTokenizer(str,File.separator); while (st.hasMoreTokens()) { strDirs.addElement(st.nextToken()); } int patIdxStart = 0; int patIdxEnd = patDirs.size()-1; int strIdxStart = 0; int strIdxEnd = strDirs.size()-1; // up to first '**' while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { String patDir = (String)patDirs.elementAt(patIdxStart); if (patDir.equals("**")) { break; } if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { return false; } patIdxStart++; strIdxStart++; } if (strIdxStart > strIdxEnd) { // String is exhausted return true; } else if (patIdxStart > patIdxEnd) { // String not exhausted, but pattern is. Failure. return false; } else { // pattern now holds ** while string is not exhausted // this will generate false positives but we can live with that. return true; } } /** * Matches a path against a pattern. * * @param pattern the (non-null) pattern to match against * @param str the (non-null) string (path) to match * * @return true when the pattern matches against the string. * false otherwise. */ protected static boolean matchPath(String pattern, String str) { // When str starts with a File.separator, pattern has to start with a // File.separator. // When pattern starts with a File.separator, str has to start with a // File.separator. if (str.startsWith(File.separator) != pattern.startsWith(File.separator)) { return false; } Vector patDirs = new Vector(); StringTokenizer st = new StringTokenizer(pattern,File.separator); while (st.hasMoreTokens()) { patDirs.addElement(st.nextToken()); } Vector strDirs = new Vector(); st = new StringTokenizer(str,File.separator); while (st.hasMoreTokens()) { strDirs.addElement(st.nextToken()); } int patIdxStart = 0; int patIdxEnd = patDirs.size()-1; int strIdxStart = 0; int strIdxEnd = strDirs.size()-1; // up to first '**' while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { String patDir = (String)patDirs.elementAt(patIdxStart); if (patDir.equals("**")) { break; } if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { return false; } patIdxStart++; strIdxStart++; } if (strIdxStart > strIdxEnd) { // String is exhausted for (int i = patIdxStart; i <= patIdxEnd; i++) { if (!patDirs.elementAt(i).equals("**")) { return false; } } return true; } else { if (patIdxStart > patIdxEnd) { // String not exhausted, but pattern is. Failure. return false; } } // up to last '**' while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { String patDir = (String)patDirs.elementAt(patIdxEnd); if (patDir.equals("**")) { break; } if (!match(patDir,(String)strDirs.elementAt(strIdxEnd))) { return false; } patIdxEnd--; strIdxEnd--; } if (strIdxStart > strIdxEnd) { // String is exhausted for (int i = patIdxStart; i <= patIdxEnd; i++) { if (!patDirs.elementAt(i).equals("**")) { return false; } } return true; } while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { int patIdxTmp = -1; for (int i = patIdxStart+1; i <= patIdxEnd; i++) { if (patDirs.elementAt(i).equals("**")) { patIdxTmp = i; break; } } if (patIdxTmp == patIdxStart+1) { // '**/**' situation, so skip one patIdxStart++; continue; } // Find the pattern between padIdxStart & padIdxTmp in str between // strIdxStart & strIdxEnd int patLength = (patIdxTmp-patIdxStart-1); int strLength = (strIdxEnd-strIdxStart+1); int foundIdx = -1; strLoop: for (int i = 0; i <= strLength - patLength; i++) { for (int j = 0; j < patLength; j++) { String subPat = (String)patDirs.elementAt(patIdxStart+j+1); String subStr = (String)strDirs.elementAt(strIdxStart+i+j); if (!match(subPat,subStr)) { continue strLoop; } } foundIdx = strIdxStart+i; break; } if (foundIdx == -1) { return false; } patIdxStart = patIdxTmp; strIdxStart = foundIdx+patLength; } for (int i = patIdxStart; i <= patIdxEnd; i++) { if (!patDirs.elementAt(i).equals("**")) { return false; } } return true; } /** * Matches a string against a pattern. The pattern contains two special * characters: * '*' which means zero or more characters, * '?' which means one and only one character. * * @param pattern the (non-null) pattern to match against * @param str the (non-null) string that must be matched against the * pattern * * @return true when the string matches against the pattern, * false otherwise. */ protected static boolean match(String pattern, String str) { char[] patArr = pattern.toCharArray(); char[] strArr = str.toCharArray(); int patIdxStart = 0; int patIdxEnd = patArr.length-1; int strIdxStart = 0; int strIdxEnd = strArr.length-1; char ch; boolean containsStar = false; for (int i = 0; i < patArr.length; i++) { if (patArr[i] == '*') { containsStar = true; break; } } if (!containsStar) { // No '*'s, so we make a shortcut if (patIdxEnd != strIdxEnd) { return false; // Pattern and string do not have the same size } for (int i = 0; i <= patIdxEnd; i++) { ch = patArr[i]; if (ch != '?' && ch != strArr[i]) { return false; // Character mismatch } } return true; // String matches against pattern } if (patIdxEnd == 0) { return true; // Pattern contains only '*', which matches anything } // Process characters before first star while((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { if (ch != '?' && ch != strArr[strIdxStart]) { return false; } patIdxStart++; strIdxStart++; } if (strIdxStart > strIdxEnd) { // All characters in the string are used. Check if only '*'s are // left in the pattern. If so, we succeeded. Otherwise failure. for (int i = patIdxStart; i <= patIdxEnd; i++) { if (patArr[i] != '*') { return false; } } return true; } // Process characters after last star while((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { if (ch != '?' && ch != strArr[strIdxEnd]) { return false; } patIdxEnd--; strIdxEnd--; } if (strIdxStart > strIdxEnd) { // All characters in the string are used. Check if only '*'s are // left in the pattern. If so, we succeeded. Otherwise failure. for (int i = patIdxStart; i <= patIdxEnd; i++) { if (patArr[i] != '*') { return false; } } return true; } // process pattern between stars. padIdxStart and patIdxEnd point // always to a '*'. while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { int patIdxTmp = -1; for (int i = patIdxStart+1; i <= patIdxEnd; i++) { if (patArr[i] == '*') { patIdxTmp = i; break; } } if (patIdxTmp == patIdxStart+1) { // Two stars next to each other, skip the first one. patIdxStart++; continue; } // Find the pattern between padIdxStart & padIdxTmp in str between // strIdxStart & strIdxEnd int patLength = (patIdxTmp-patIdxStart-1); int strLength = (strIdxEnd-strIdxStart+1); int foundIdx = -1; strLoop: for (int i = 0; i <= strLength - patLength; i++) { for (int j = 0; j < patLength; j++) { ch = patArr[patIdxStart+j+1]; if (ch != '?' && ch != strArr[strIdxStart+i+j]) { continue strLoop; } } foundIdx = strIdxStart+i; break; } if (foundIdx == -1) { return false; } patIdxStart = patIdxTmp; strIdxStart = foundIdx+patLength; } // All characters in the string are used. Check if only '*'s are left // in the pattern. If so, we succeeded. Otherwise failure. for (int i = patIdxStart; i <= patIdxEnd; i++) { if (patArr[i] != '*') { return false; } } return true; } /** * Tests whether a name matches against at least one include pattern. * * @param name the name to match * @return true when the name matches against at least one * include pattern, false otherwise. */ protected boolean isIncluded(String name) { for (int i = 0; i < includes.length; i++) { if (matchPath(includes[i],name)) { return true; } } return false; } /** * Tests whether a name matches the start of at least one include pattern. * * @param name the name to match * @return true when the name matches against at least one * include pattern, false otherwise. */ protected boolean couldHoldIncluded(String name) { for (int i = 0; i < includes.length; i++) { if (matchPatternStart(includes[i],name)) { return true; } } return false; } /** * Tests whether a name matches against at least one exclude pattern. * * @param name the name to match * @return true when the name matches against at least one * exclude pattern, false otherwise. */ protected boolean isExcluded(String name) { for (int i = 0; i < excludes.length; i++) { if (matchPath(excludes[i],name)) { return true; } } return false; } /** * Adds the array with default exclusions to the current exclusions set. * */ public void addDefaultExcludes() { int excludesLength = excludes == null ? 0 : excludes.length; String[] newExcludes; newExcludes = new String[excludesLength + DEFAULTEXCLUDES.length]; if (excludesLength > 0) { System.arraycopy(excludes,0,newExcludes,0,excludesLength); } for (int i = 0; i < DEFAULTEXCLUDES.length; i++) { newExcludes[i+excludesLength] = DEFAULTEXCLUDES[i].replace('/',File.separatorChar).replace('\\',File.separatorChar); } excludes = newExcludes; } } 1.1 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/DirectoryScanner.java Index: DirectoryScanner.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.ant.core.types; import java.io.*; import java.util.*; import org.apache.ant.core.execution.*; /** * A DirectoryFileset is a fileset where the files come from a directory and * its subdirectories. */ public class DirectoryScanner extends AbstractScanner { /** The directory which is the root of the search space. */ File basedir; /** * The files that where found and matched at least one includes, and matched * no excludes. */ protected List filesIncluded; /** * The files that where found and did not match any includes. */ protected List filesNotIncluded; /** * The files that where found and matched at least one includes, and also * matched at least one excludes. */ protected List filesExcluded; /** * The directories that where found and matched at least one includes, and * matched no excludes. */ protected List dirsIncluded; /** * The directories that where found and did not match any includes. */ protected List dirsNotIncluded; /** * The files that where found and matched at least one includes, and also * matched at least one excludes. */ protected List dirsExcluded; /** Map to map filenames to actual File objects */ private Map filenameMap = null; public DirectoryScanner(File basedir, List patternSets, boolean useDefaultExcludes) throws ExecutionException { super(patternSets, useDefaultExcludes); this.basedir = basedir; } public String[] getIncludedFiles() throws ExecutionException { if (filesIncluded == null) { scan(); } return (String[])filesIncluded.toArray(new String[0]); } /** * Scans the base directory for files that match at least one include * pattern, and don't match any exclude patterns. * * @throws ExecutionException when basedir was set incorrecly */ public void scan() throws ExecutionException { if (basedir == null) { throw new ExecutionException("The directory to scan has not been set"); } if (!basedir.exists()) { throw new ExecutionException("basedir \"" + basedir + "\" does not exist"); } if (!basedir.isDirectory()) { throw new ExecutionException("basedir \"" + basedir + "\" is not a directory"); } filesIncluded = new ArrayList(); filesNotIncluded = new ArrayList(); filesExcluded = new ArrayList(); dirsIncluded = new ArrayList(); dirsNotIncluded = new ArrayList(); dirsExcluded = new ArrayList(); filenameMap = new HashMap(); String root = ""; String mappedRoot = mapName(root); filenameMap.put(mappedRoot, root); if (isIncluded(root)) { if (!isExcluded(root)) { dirsIncluded.add(mappedRoot); } else { dirsExcluded.add(mappedRoot); } } else { dirsNotIncluded.add(mappedRoot); } scandir(basedir, root, true); } /** * Scans the passed dir for files and directories. Found files and * directories are placed in their respective collections, based on the * matching of includes and excludes. When a directory is found, it is * scanned recursively. * * @param dir the directory to scan * @param vpath the path relative to the basedir (needed to prevent * problems with an absolute path when using dir) * * @see #filesIncluded * @see #filesNotIncluded * @see #filesExcluded * @see #dirsIncluded * @see #dirsNotIncluded * @see #dirsExcluded */ protected void scandir(File dir, String vpath, boolean fast) throws ExecutionException { String[] newfiles = dir.list(); if (newfiles == null) { /* * two reasons are mentioned in the API docs for File.list * (1) dir is not a directory. This is impossible as * we wouldn't get here in this case. * (2) an IO error occurred (why doesn't it throw an exception * then???) */ throw new ExecutionException ("IO error scanning directory " + dir.getAbsolutePath()); } for (int i = 0; i < newfiles.length; i++) { String name = vpath+newfiles[i]; String mappedName = mapName(name); filenameMap.put(mappedName, name); File file = new File(dir,newfiles[i]); if (file.isDirectory()) { if (isIncluded(name)) { if (!isExcluded(name)) { dirsIncluded.add(mappedName); if (fast) { scandir(file, name+File.separator, fast); } } else { dirsExcluded.add(mappedName); } } else { dirsNotIncluded.add(mappedName); if (fast && couldHoldIncluded(name)) { scandir(file, name+File.separator, fast); } } if (!fast) { scandir(file, name+File.separator, fast); } } else if (file.isFile()) { if (isIncluded(name)) { if (!isExcluded(name)) { filesIncluded.add(mappedName); } else { filesExcluded.add(mappedName); } } else { filesNotIncluded.add(mappedName); } } } } private String mapName(String rawName) { return "bozo/" + rawName; } public File getLocalFile(String mappedName) throws ExecutionException { if (filesIncluded == null) { scan(); } String realName = (String)filenameMap.get(mappedName); if (realName == null) { throw new ExecutionException("\"" + mappedName + "\" was not included in the scan."); } return new File(basedir, realName); } public String toString() { try { String[] files = getIncludedFiles(); StringBuffer sb = new StringBuffer(); String lsep = System.getProperty("line.separator"); for (int i = 0; i < files.length; ++i) { sb.append(files[i]); sb.append(lsep); } return sb.toString(); } catch (ExecutionException e) { return "Fileset from \"" + basedir + "\""; } } } 1.1 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/FileSet.java Index: FileSet.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.ant.core.types; import java.util.*; import java.io.*; import java.net.URL; import org.apache.ant.core.execution.*; /** * Moved out of MatchingTask to make it a standalone object that could * be referenced (by scripts for example). * * @author Arnout J. Kuiper ajkuiper@wxs.nl * @author Stefano Mazzocchi stefano@apache.org * @author Sam Ruby rubys@us.ibm.com * @author Jon S. Stevens jon@clearink.com * @author Stefan Bodewig */ public class FileSet extends DataType { private FileSetScanner scanner = null; private PatternSet defaultPatterns = new PatternSet(); private List patternSets = new ArrayList(); /** * The dir attribute is set when you are generating the list of files * from a directory. */ private File dir = null; /** The zipfile attribute is used when the source of files is a zip file */ private URL zipFile = null; /** * The filelist attribute is a file which contains a list of file names. It must be used * with the base attribute which indicates where the files are stored. */ private URL fileList = null; /** * When using the filelist this attribute indicates the base location of the files in * the list. */ private URL fileListBase = null; private boolean useDefaultExcludes = true; public FileSet() { patternSets.add(defaultPatterns); } /** * Makes this instance in effect a reference to another FileSet * instance. * *

You must not set another attribute or nest elements inside * this element if you make it a reference.

*/ public void setRefid(String reference) throws ExecutionException { if (dir != null || defaultPatterns.hasPatterns()) { throw tooManyAttributes(); } if (!(patternSets.size() == 1)) { throw noChildrenAllowed(); } super.setRefid(reference); } public void setDir(File dir) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } this.dir = dir; } public void setZipFile(URL zipFile) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } this.zipFile = zipFile; } public void setFileList(URL fileList) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } this.fileList = fileList; } public void setFileListBase(URL fileListBase) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } this.fileListBase = fileListBase; } public PatternSet createPatternSet() throws ExecutionException { if (isReference()) { throw noChildrenAllowed(); } PatternSet patternSet = new PatternSet(); patternSets.add(patternSet); return patternSet; } /** * add a name entry on the include list */ public PatternSet.NameEntry createInclude() throws ExecutionException { if (isReference()) { throw noChildrenAllowed(); } return defaultPatterns.createInclude(); } /** * add a name entry on the exclude list */ public PatternSet.NameEntry createExclude() throws ExecutionException { if (isReference()) { throw noChildrenAllowed(); } return defaultPatterns.createExclude(); } /** * Sets the set of include patterns. Patterns may be separated by a comma * or a space. * * @param includes the string containing the include patterns */ public void setIncludes(String includes) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } defaultPatterns.setIncludes(includes); } /** * Sets the set of exclude patterns. Patterns may be separated by a comma * or a space. * * @param excludes the string containing the exclude patterns */ public void setExcludes(String excludes) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } defaultPatterns.setExcludes(excludes); } /** * Sets the name of the file containing the includes patterns. * * @param incl The file to fetch the include patterns from. */ public void setIncludesFile(URL incl) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } defaultPatterns.setIncludesFile(incl); } /** * Sets the name of the file containing the includes patterns. * * @param excl The file to fetch the exclude patterns from. */ public void setExcludesFile(URL excl) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } defaultPatterns.setExcludesFile(excl); } /** * Sets whether default exclusions should be used or not. * * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions * should be used, "false"|"off"|"no" when they * shouldn't be used. */ public void setDefaultExcludes(boolean useDefaultExcludes) throws ExecutionException { if (isReference()) { throw tooManyAttributes(); } this.useDefaultExcludes = useDefaultExcludes; } protected FileSet getReferencedFileSet() throws ExecutionException { Object o = getReferencedObject(); if (!(o instanceof FileSet)) { throw new ExecutionException(getReference() + " doesn\'t denote a fileset");; } else { return (FileSet) o; } } public void validate() throws ExecutionException { if (dir != null) { // firstly validate that the other attributes are not set if (zipFile != null || fileList != null || fileListBase != null) { throw new ExecutionException("The 'dir' attribute may not be combined with any " + "of the 'zipfile', 'filelist' and 'base' attributes"); } } else if (zipFile != null) { if (fileList != null || fileListBase != null) { throw new ExecutionException("The 'zipfile' attribute may not be combined with any " + "of the 'dir', 'filelist' and 'base' attributes"); } } else if (fileList != null) { if (fileListBase == null) { throw new ExecutionException("A 'base' attribute is required when using the 'filelist' " + "attribute"); } } else { throw new ExecutionException("You must specify one of the 'dir', 'zipfile', or 'filelist' " + "attributes"); } } public FileSetScanner getScanner() throws ExecutionException { if (isReference()) { return getReferencedFileSet().getScanner(); } if (scanner != null) { return scanner; } // need to create the fileset info. For that we are going to need // to determine which type of FileSetInfo implementation we should use. if (dir != null) { scanner = new DirectoryScanner(dir, patternSets, useDefaultExcludes); } else if (zipFile != null) { } else if (fileList != null) { } else { } return scanner; } public String toString() { try { return getScanner().toString(); } catch (ExecutionException e) { return "FileSet"; } } } 1.1 jakarta-ant/proposal/mutant/src/main/org/apache/ant/core/types/FileSetScanner.java Index: FileSetScanner.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.ant.core.types; import java.io.*; import java.net.URL; import org.apache.ant.core.execution.*; /** * The FileSetInfo interface defines the result of applying filtering to * some base collection of files. Filtering involves both file exclusion * and file name mapping. * * FileSetInfo should be lazily evaluated to allow them to be defined before the * required files have been created. They should be evaluated at first use. */ public interface FileSetScanner { /** * Get the included files after their file names have been mapped * * @return an array of strings, each one is the mapped name of a file. */ String[] getIncludedFiles() throws ExecutionException ; // // /** // * Get directories included after their file names have been mapped // * // * @return an array of strings, each one is the mapped name of a file. // */ // String[] getIncludedDirectories(); // // /** // * Get a file for the content of the named included file. If the content // * is not stored in the local filesystem, a temporary file is created with the content. // * Callers should not rely on this file representing the actual location of the underlying // * data. // */ // File getContentFile(String mappedName); // // /** // * Get a URL for the content. The content may be cached on the local system and thus // * callers should not rely on the location // * // */ // URL getContentURL(String mappedName); // // /** // * Get an input stream to the content of the named entry of the fileset. // */ // InputStream getInputStream(String mappedName); // /** * Get a local file. * * This method returns a file pointing to the actual local filesystem file from * which the file content comes. If the file does not exist locally, a null is * returned. Note that due to name mapping, the actual file name may be different * from the mapped name. * * @return a file representing the mapped file in the local filesystem. */ File getLocalFile(String mappedName) throws ExecutionException ; }