git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269043 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -12,7 +12,8 @@ | |||||
| <target name="compile"> | <target name="compile"> | ||||
| <mkdir dir="${build.classes}"/> | <mkdir dir="${build.classes}"/> | ||||
| <depend srcdir="${src.dir}" | <depend srcdir="${src.dir}" | ||||
| destdir="${build.classes}"/> | |||||
| destdir="${build.classes}" closure="yes" | |||||
| cache="${build.dir}/depcache"/> | |||||
| <javac srcdir="${src.dir}" | <javac srcdir="${src.dir}" | ||||
| destdir="${build.classes}" | destdir="${build.classes}" | ||||
| deprecation="true" | deprecation="true" | ||||
| @@ -78,11 +78,10 @@ public class FileConverter implements AntConverter { | |||||
| if (url.getProtocol().equals("file")) { | if (url.getProtocol().equals("file")) { | ||||
| return new File(url.getFile()); | return new File(url.getFile()); | ||||
| } | } | ||||
| return new File(value); | |||||
| } | } | ||||
| catch (MalformedURLException e) { | catch (MalformedURLException e) { | ||||
| throw new ConversionException("Unable to convert " + value | |||||
| + " into a File relative to the project's base"); | |||||
| // ignore and return as a file. | |||||
| } | } | ||||
| return new File(value); | |||||
| } | } | ||||
| } | } | ||||
| @@ -175,9 +175,6 @@ public class Property extends AbstractTask { | |||||
| if (file.exists()) { | if (file.exists()) { | ||||
| stream = new FileInputStream(file); | stream = new FileInputStream(file); | ||||
| } | } | ||||
| else { | |||||
| throw new ExecutionException("Unable to find " + file.getAbsolutePath()); | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| stream = url.openStream(); | stream = url.openStream(); | ||||
| @@ -192,8 +189,8 @@ public class Property extends AbstractTask { | |||||
| stream.close(); | stream.close(); | ||||
| } | } | ||||
| } | } | ||||
| } catch (Exception ex) { | |||||
| throw new ExecutionException("Unable to load property file: " + url, ex); | |||||
| } catch (IOException e) { | |||||
| throw new ExecutionException("Unable to load property file: " + url, e); | |||||
| } | } | ||||
| } | } | ||||
| @@ -79,8 +79,15 @@ public class URLConverter implements AntConverter { | |||||
| return url; | return url; | ||||
| } | } | ||||
| catch (MalformedURLException e) { | catch (MalformedURLException e) { | ||||
| throw new ConversionException("Unable to convert " + value | |||||
| + " into a URL relative to the project's base"); | |||||
| //try a local file | |||||
| try { | |||||
| File file = new File(value); | |||||
| return file.toURL(); | |||||
| } | |||||
| catch (MalformedURLException e2) { | |||||
| throw new ConversionException("Unable to convert " + value | |||||
| + " into a URL relative to the project's base"); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -5,6 +5,7 @@ | |||||
| <!-- Data Types --> | <!-- Data Types --> | ||||
| <taskdef name="patternset" classname="org.apache.ant.core.types.PatternSet"/> | <taskdef name="patternset" classname="org.apache.ant.core.types.PatternSet"/> | ||||
| <taskdef name="fileset" classname="org.apache.ant.core.types.FileSet"/> | |||||
| <!-- Converters --> | <!-- Converters --> | ||||
| <converter target="java.io.File" classname="org.apache.ant.component.core.FileConverter"/> | <converter target="java.io.File" classname="org.apache.ant.component.core.FileConverter"/> | ||||
| @@ -74,6 +74,9 @@ public abstract class AbstractAspectHandler implements AspectHandler { | |||||
| return aspectContext; | return aspectContext; | ||||
| } | } | ||||
| public void beforeConfigElement(Object element) throws ExecutionException { | |||||
| } | |||||
| public void afterConfigElement(Object element) throws ExecutionException { | public void afterConfigElement(Object element) throws ExecutionException { | ||||
| } | } | ||||
| } | } | ||||
| @@ -69,6 +69,7 @@ public interface AspectHandler { | |||||
| void setAspectContext(ExecutionContext context); | void setAspectContext(ExecutionContext context); | ||||
| void beforeConfigElement(Object element) throws ExecutionException ; | |||||
| void afterConfigElement(Object element) throws ExecutionException ; | void afterConfigElement(Object element) throws ExecutionException ; | ||||
| } | } | ||||
| @@ -543,8 +543,6 @@ public class ExecutionFrame { | |||||
| task = new TaskAdapter(taskType, element); | task = new TaskAdapter(taskType, element); | ||||
| } | } | ||||
| ExecutionContext context = new ExecutionContext(this, eventSupport, model); | |||||
| task.setTaskContext(context); | |||||
| configureElement(element, model); | configureElement(element, model); | ||||
| return task; | return task; | ||||
| @@ -611,10 +609,21 @@ public class ExecutionFrame { | |||||
| */ | */ | ||||
| private void configureElement(Object element, TaskElement model) | private void configureElement(Object element, TaskElement model) | ||||
| throws ExecutionException, ConfigException { | throws ExecutionException, ConfigException { | ||||
| if (element instanceof Task) { | |||||
| Task task = (Task)element; | |||||
| ExecutionContext context = new ExecutionContext(this, eventSupport, model); | |||||
| task.setTaskContext(context); | |||||
| } | |||||
| try { | try { | ||||
| ClassIntrospector introspector = getIntrospector(element.getClass()); | 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 | // start by setting the attributes of this element | ||||
| for (Iterator i = model.getAttributeNames(); i.hasNext();) { | for (Iterator i = model.getAttributeNames(); i.hasNext();) { | ||||
| String attributeName = (String)i.next(); | String attributeName = (String)i.next(); | ||||
| @@ -644,7 +653,6 @@ public class ExecutionFrame { | |||||
| configureElement(nestedElement, nestedElementModel); | configureElement(nestedElement, nestedElementModel); | ||||
| } | } | ||||
| } | } | ||||
| List aspects = getActiveAspects(model); | |||||
| for (Iterator i = aspects.iterator(); i.hasNext(); ) { | for (Iterator i = aspects.iterator(); i.hasNext(); ) { | ||||
| AspectHandler aspectHandler = (AspectHandler)i.next(); | AspectHandler aspectHandler = (AspectHandler)i.next(); | ||||
| aspectHandler.afterConfigElement(element); | aspectHandler.afterConfigElement(element); | ||||
| @@ -0,0 +1,580 @@ | |||||
| /* | |||||
| * 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 | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| 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 <code>File.separatorChar</code>. So the separator used need | |||||
| * not match <code>File.separatorChar</code>. | |||||
| * <p> | |||||
| * 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 <code>File.separatorChar</code>. So the separator used need | |||||
| * not match <code>File.separatorChar</code>. | |||||
| * <p> | |||||
| * 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 "**". | |||||
| + | |||||
| * <p>This is not a general purpose test and should only be used if you | |||||
| * can live with false positives.</p> | |||||
| * | |||||
| * <p><code>pattern=**\\a</code> and <code>str=b</code> 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 <code>true</code> when the pattern matches against the string. | |||||
| * <code>false</code> 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 <code>true</code> when the string matches against the pattern, | |||||
| * <code>false</code> 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 <code>true</code> when the name matches against at least one | |||||
| * include pattern, <code>false</code> 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 <code>true</code> when the name matches against at least one | |||||
| * include pattern, <code>false</code> 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 <code>true</code> when the name matches against at least one | |||||
| * exclude pattern, <code>false</code> 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; | |||||
| } | |||||
| } | |||||
| @@ -67,6 +67,10 @@ public abstract class DataType extends AbstractTask { | |||||
| private Object referencedObject = null; | private Object referencedObject = null; | ||||
| public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
| validate(); | |||||
| } | |||||
| protected void validate() throws ExecutionException { | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -0,0 +1,266 @@ | |||||
| /* | |||||
| * 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 | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| 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 + "\""; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,319 @@ | |||||
| /* | |||||
| * 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 | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| 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 <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a> | |||||
| * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a> | |||||
| * @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a> | |||||
| * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a> | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| 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. | |||||
| * | |||||
| * <p>You must not set another attribute or nest elements inside | |||||
| * this element if you make it a reference.</p> | |||||
| */ | |||||
| 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"; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,115 @@ | |||||
| /* | |||||
| * 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 | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| 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 ; | |||||
| } | |||||
| @@ -69,6 +69,7 @@ import java.net.URL; | |||||
| * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a> | ||||
| */ | */ | ||||
| public class PatternSet extends DataType { | public class PatternSet extends DataType { | ||||
| private boolean filesRead = false; | |||||
| private List includeList = new ArrayList(); | private List includeList = new ArrayList(); | ||||
| private List excludeList = new ArrayList(); | private List excludeList = new ArrayList(); | ||||
| @@ -115,10 +116,6 @@ public class PatternSet extends DataType { | |||||
| // } | // } | ||||
| } | } | ||||
| public PatternSet() { | |||||
| } | |||||
| /** | /** | ||||
| * Makes this instance in effect a reference to another PatternSet | * Makes this instance in effect a reference to another PatternSet | ||||
| * instance. | * instance. | ||||
| @@ -203,7 +200,7 @@ public class PatternSet extends DataType { | |||||
| * | * | ||||
| * @param incl The file to fetch the include patterns from. | * @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()) { | if (isReference()) { | ||||
| throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
| } | } | ||||
| @@ -220,7 +217,7 @@ public class PatternSet extends DataType { | |||||
| * | * | ||||
| * @param excludeFile The file to fetch the exclude patterns from. | * @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()) { | if (isReference()) { | ||||
| throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
| } | } | ||||
| @@ -316,14 +313,14 @@ public class PatternSet extends DataType { | |||||
| } | } | ||||
| } | } | ||||
| // /** | |||||
| // * 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 | * Performs the check for circular references and returns the | ||||
| * referenced PatternSet. | * referenced PatternSet. | ||||
| @@ -363,14 +360,14 @@ public class PatternSet extends DataType { | |||||
| * Read includefile ot excludefile if not already done so. | * Read includefile ot excludefile if not already done so. | ||||
| */ | */ | ||||
| private void readFiles() throws ExecutionException { | 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); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||