Got it in in the 11(and a half)th hour ;-) Submitted by: Bruce Atherton <bruce@callenish.com> Docs and testcases to follow in the next few days. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272630 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -109,6 +109,9 @@ Fixed bugs: | |||
| Other changes: | |||
| -------------- | |||
| * Selector Elements now provide a way to create filesets based on | |||
| sophisticated selection criteria. | |||
| * Gzip and Bzip2 files can now be constructed in the fly when using | |||
| the tar task without having to create the intermediate tar file on | |||
| disk. The Untar task can also untar GZip and BZip2 files on the fly | |||
| @@ -57,6 +57,7 @@ import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.FileScanner; | |||
| import org.apache.tools.ant.DirectoryScanner; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.selectors.*; | |||
| import java.io.File; | |||
| import java.util.Stack; | |||
| @@ -70,23 +71,26 @@ import java.util.Enumeration; | |||
| * | |||
| * <p>Common base class for DirSet and FileSet.</p> | |||
| * | |||
| * @author <a href="mailto:ajkuiper@wxs.nl">Arnout J. Kuiper</a> | |||
| * @author <a href="mailto:ajkuiper@wxs.nl">Arnout J. Kuiper</a> | |||
| * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> | |||
| * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a> | |||
| * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a> | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| */ | |||
| public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| public abstract class AbstractFileSet extends DataType implements Cloneable, | |||
| SelectorContainer { | |||
| private PatternSet defaultPatterns = new PatternSet(); | |||
| private Vector additionalPatterns = new Vector(); | |||
| private Vector selectors = new Vector(); | |||
| private File dir; | |||
| private boolean useDefaultExcludes = true; | |||
| private boolean isCaseSensitive = true; | |||
| public AbstractFileSet() { | |||
| super(); | |||
| } | |||
| @@ -104,7 +108,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| * Makes this instance in effect a reference to another instance. | |||
| * | |||
| * <p>You must not set another attribute or nest elements inside | |||
| * this element if you make it a reference.</p> | |||
| * this element if you make it a reference.</p> | |||
| */ | |||
| public void setRefid(Reference r) throws BuildException { | |||
| if (dir != null || defaultPatterns.hasPatterns()) { | |||
| @@ -158,7 +162,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| } | |||
| return defaultPatterns.createInclude(); | |||
| } | |||
| /** | |||
| * add a name entry on the include files list | |||
| */ | |||
| @@ -168,7 +172,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| } | |||
| return defaultPatterns.createIncludesFile(); | |||
| } | |||
| /** | |||
| * add a name entry on the exclude list | |||
| */ | |||
| @@ -188,7 +192,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| } | |||
| return defaultPatterns.createExcludesFile(); | |||
| } | |||
| /** | |||
| * Appends <code>includes</code> to the current list of include | |||
| * patterns. | |||
| @@ -224,7 +228,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| /** | |||
| * Sets the name of the file containing the includes patterns. | |||
| * | |||
| * @param incl The file to fetch the include patterns from. | |||
| * @param incl The file to fetch the include patterns from. | |||
| */ | |||
| public void setIncludesfile(File incl) throws BuildException { | |||
| if (isReference()) { | |||
| @@ -237,7 +241,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| /** | |||
| * Sets the name of the file containing the includes patterns. | |||
| * | |||
| * @param excl The file to fetch the exclude patterns from. | |||
| * @param excl The file to fetch the exclude patterns from. | |||
| */ | |||
| public void setExcludesfile(File excl) throws BuildException { | |||
| if (isReference()) { | |||
| @@ -250,7 +254,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| /** | |||
| * Sets whether default exclusions should be used or not. | |||
| * | |||
| * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions | |||
| * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions | |||
| * should be used, "false"|"off"|"no" when they | |||
| * shouldn't be used. | |||
| */ | |||
| @@ -272,8 +276,8 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| this.isCaseSensitive = isCaseSensitive; | |||
| } | |||
| /** | |||
| * sets the name used for this datatype instance. | |||
| */ | |||
| @@ -290,14 +294,14 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| } | |||
| } | |||
| } | |||
| String classname = getClass().getName(); | |||
| int dotIndex = classname.lastIndexOf("."); | |||
| if (dotIndex == -1) { | |||
| return classname; | |||
| } | |||
| return classname.substring(dotIndex + 1); | |||
| return classname.substring(dotIndex + 1); | |||
| } | |||
| /** | |||
| @@ -326,12 +330,12 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| ds.scan(); | |||
| return ds; | |||
| } | |||
| public void setupDirectoryScanner(FileScanner ds, Project p) { | |||
| if (ds == null) { | |||
| throw new IllegalArgumentException("ds cannot be null"); | |||
| } | |||
| ds.setBasedir(dir); | |||
| final int count = additionalPatterns.size(); | |||
| @@ -340,11 +344,16 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| defaultPatterns.append((PatternSet) o, p); | |||
| } | |||
| p.log(getDataTypeName() + ": Setup scanner in dir " + dir + | |||
| p.log(getDataTypeName() + ": Setup scanner in dir " + dir + | |||
| " with " + defaultPatterns, Project.MSG_DEBUG); | |||
| ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | |||
| ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | |||
| if (ds instanceof SelectorScanner) { | |||
| SelectorScanner ss = (SelectorScanner)ds; | |||
| ss.setSelectors(getSelectors(p)); | |||
| } | |||
| if (useDefaultExcludes) { | |||
| ds.addDefaultExcludes(); | |||
| } | |||
| @@ -353,7 +362,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| /** | |||
| * Performs the check for circular references and returns the | |||
| * referenced FileSet. | |||
| * referenced FileSet. | |||
| */ | |||
| protected AbstractFileSet getRef(Project p) { | |||
| if (!checked) { | |||
| @@ -361,10 +370,10 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| stk.push(this); | |||
| dieOnCircularReference(stk, p); | |||
| } | |||
| Object o = ref.getReferencedObject(p); | |||
| if (!getClass().isAssignableFrom(o.getClass())) { | |||
| String msg = ref.getRefId() + " doesn\'t denote a " | |||
| String msg = ref.getRefId() + " doesn\'t denote a " | |||
| + getDataTypeName(); | |||
| throw new BuildException(msg); | |||
| } else { | |||
| @@ -372,4 +381,153 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||
| } | |||
| } | |||
| // SelectorContainer methods | |||
| /** | |||
| * Indicates whether there are any selectors here. | |||
| * | |||
| * @return whether any selectors are in this container | |||
| */ | |||
| public boolean hasSelectors() { | |||
| return !(selectors.isEmpty()); | |||
| } | |||
| /** | |||
| * Gives the count of the number of selectors in this container | |||
| * | |||
| * @return the number of selectors in this container | |||
| */ | |||
| public int selectorCount() { | |||
| return selectors.size(); | |||
| } | |||
| /** | |||
| * Returns the set of selectors as an array. | |||
| * | |||
| * @return an array of selectors in this container | |||
| */ | |||
| public FileSelector[] getSelectors(Project p) { | |||
| if (isReference()) { | |||
| return getRef(p).getSelectors(p); | |||
| } else { | |||
| FileSelector[] result = new FileSelector[selectors.size()]; | |||
| selectors.copyInto(result); | |||
| return result; | |||
| } | |||
| } | |||
| /** | |||
| * Returns an enumerator for accessing the set of selectors. | |||
| * | |||
| * @return an enumerator that goes through each of the selectors | |||
| */ | |||
| public Enumeration selectorElements() { | |||
| return selectors.elements(); | |||
| } | |||
| /** | |||
| * Add a new selector into this container. | |||
| * | |||
| * @param selector the new selector to add | |||
| */ | |||
| public void appendSelector(FileSelector selector) { | |||
| if (isReference()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| selectors.addElement(selector); | |||
| } | |||
| /* Methods below all implement the static selectors */ | |||
| /** | |||
| * add an "And" selector entry on the selector list | |||
| */ | |||
| public void addAnd(AndSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add an "Or" selector entry on the selector list | |||
| */ | |||
| public void addOr(OrSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a "Not" selector entry on the selector list | |||
| */ | |||
| public void addNot(NotSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a "None" selector entry on the selector list | |||
| */ | |||
| public void addNone(NoneSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a majority selector entry on the selector list | |||
| */ | |||
| public void addMajority(MajoritySelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector date entry on the selector list | |||
| */ | |||
| public void addDateselect(DateSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector size entry on the selector list | |||
| */ | |||
| public void addSizeselect(SizeSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector filename entry on the selector list | |||
| */ | |||
| public void addFilenameselect(FilenameSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add an extended selector entry on the selector list | |||
| */ | |||
| public void addExtendSelect(ExtendSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a contains selector entry on the selector list | |||
| */ | |||
| public void addContainsSelect(ContainsSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a present selector entry on the selector list | |||
| */ | |||
| public void addPresentSelect(PresentSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a depth selector entry on the selector list | |||
| */ | |||
| public void addDepthSelect(DepthSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a depends selector entry on the selector list | |||
| */ | |||
| public void addDependSelect(DependSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| } | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| /** | |||
| * This selector has a collection of other selectors, all of which have to | |||
| * select a file in order for this selector to select it. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class AndSelector extends BaseSelectorContainer { | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public AndSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| if (hasSelectors()) { | |||
| buf.append("{andselect: "); | |||
| buf.append(super.toString()); | |||
| buf.append("}"); | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * Returns true (the file is selected) only if all other selectors | |||
| * agree that the file should be selected. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename the name of the file to check | |||
| * @param file a java.io.File object for the filename that the selector | |||
| * can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| Enumeration e = selectorElements(); | |||
| boolean result; | |||
| while(e.hasMoreElements()) { | |||
| result = ((FileSelector)e.nextElement()).isSelected(basedir, | |||
| filename,file); | |||
| if (!result) { | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,121 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.DataType; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| /** | |||
| * Convenience base class for all selectors accessed through ExtendSelector. | |||
| * It provides support for gathering the parameters together as well as for | |||
| * assigning an error message and throwing a build exception if an error is | |||
| * detected. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public abstract class BaseExtendSelector extends BaseSelector implements | |||
| ExtendFileSelector { | |||
| /** The passed in parameter array. */ | |||
| protected Parameter[] parameters = null; | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public BaseExtendSelector() { | |||
| } | |||
| /** | |||
| * Set all the Parameters for this dynamic selector, collected by | |||
| * the ExtendSelector class. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| this.parameters = parameters; | |||
| } | |||
| /** | |||
| * Allows access to the parameters gathered and set within the | |||
| * <extendselect> tag. | |||
| * | |||
| * @return the set of parameters defined for this selector | |||
| */ | |||
| protected Parameter[] getParameters() { | |||
| return parameters; | |||
| } | |||
| /** | |||
| * Method that each selector will implement to create their | |||
| * selection behaviour. If there is a problem with the setup | |||
| * of a selector, it can throw a BuildException to indicate | |||
| * the problem. | |||
| * | |||
| * @param basedir A java.io.File object for the base directory | |||
| * @param filename The name of the file to check | |||
| * @param file A File object for this filename | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public abstract boolean isSelected(File basedir, String filename, | |||
| File file) | |||
| throws BuildException; | |||
| } | |||
| @@ -0,0 +1,143 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.DataType; | |||
| /** | |||
| * A convenience base class that you can subclass Selectors from. It | |||
| * provides some helpful common behaviour. Note that there is no need | |||
| * for Selectors to inherit from this class, it is only necessary that | |||
| * they implement FileSelector. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public abstract class BaseSelector extends DataType implements FileSelector { | |||
| private String errmsg = null; | |||
| /** | |||
| * Do nothing constructor. | |||
| */ | |||
| public BaseSelector() { | |||
| } | |||
| /** | |||
| * Allows all selectors to indicate a setup error. Note that only | |||
| * the first error message is recorded. | |||
| * | |||
| * @param msg The error message any BuildException should throw. | |||
| */ | |||
| public void setError(String msg) { | |||
| if (errmsg == null) { | |||
| errmsg = msg; | |||
| } | |||
| } | |||
| /** | |||
| * Returns any error messages that have been set. | |||
| * | |||
| * @return the error condition | |||
| */ | |||
| public String getError() { | |||
| return errmsg; | |||
| } | |||
| /** | |||
| * <p>Subclasses can override this method to provide checking of their | |||
| * state. So long as they call validate() from isSelected(), this will | |||
| * be called automatically (unless they override validate()).</p> | |||
| * <p>Implementations should check for incorrect settings and call | |||
| * setError() as necessary.</p> | |||
| */ | |||
| public void verifySettings() { | |||
| } | |||
| /** | |||
| * Subclasses can use this to throw the requisite exception | |||
| * in isSelected() in the case of an error condition. | |||
| */ | |||
| public void validate() { | |||
| verifySettings(); | |||
| if (getError() != null) { | |||
| throw new BuildException(errmsg); | |||
| } | |||
| } | |||
| /** | |||
| * Method that each selector will implement to create their | |||
| * selection behaviour. If there is a problem with the setup | |||
| * of a selector, it can throw a BuildException to indicate | |||
| * the problem. | |||
| * | |||
| * @param basedir A java.io.File object for the base directory | |||
| * @param filename The name of the file to check | |||
| * @param file A File object for this filename | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public abstract boolean isSelected(File basedir, String filename, | |||
| File file); | |||
| } | |||
| @@ -0,0 +1,312 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.Reference; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| import java.util.Stack; | |||
| import java.util.Vector; | |||
| /** | |||
| * This is the base class for selectors that can contain other selectors. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public abstract class BaseSelectorContainer extends BaseSelector | |||
| implements SelectorContainer { | |||
| private Vector selectorsList = new Vector(); | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public BaseSelectorContainer() { | |||
| } | |||
| /** | |||
| * Indicates whether there are any selectors here. | |||
| */ | |||
| public boolean hasSelectors() { | |||
| return !(selectorsList.isEmpty()); | |||
| } | |||
| /** | |||
| * Gives the count of the number of selectors in this container | |||
| */ | |||
| public int selectorCount() { | |||
| return selectorsList.size(); | |||
| } | |||
| /** | |||
| * Returns the set of selectors as an array. | |||
| */ | |||
| public FileSelector[] getSelectors(Project p) { | |||
| if (isReference()) { | |||
| return getRef(p).getSelectors(p); | |||
| } else { | |||
| FileSelector[] result = new FileSelector[selectorsList.size()]; | |||
| selectorsList.copyInto(result); | |||
| return result; | |||
| } | |||
| } | |||
| /** | |||
| * Returns an enumerator for accessing the set of selectors. | |||
| */ | |||
| public Enumeration selectorElements() { | |||
| return selectorsList.elements(); | |||
| } | |||
| /** | |||
| * Performs the check for circular references and returns the | |||
| * referenced SelectorContainer. | |||
| */ | |||
| private SelectorContainer getRef(Project p) { | |||
| if (!checked) { | |||
| Stack stk = new Stack(); | |||
| stk.push(this); | |||
| dieOnCircularReference(stk, p); | |||
| } | |||
| Object o = ref.getReferencedObject(p); | |||
| if (!(o instanceof SelectorContainer)) { | |||
| throw new BuildException(ref.getRefId() + | |||
| " doesn\'t denote a selector type"); | |||
| } else { | |||
| return (SelectorContainer) o; | |||
| } | |||
| } | |||
| /** | |||
| * Convert the Selectors within this container to a string. This will | |||
| * just be a helper class for the subclasses that put their own name | |||
| * around the contents listed here. | |||
| * | |||
| * @return comma separated list of Selectors contained in this one | |||
| */ | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| Enumeration e = selectorElements(); | |||
| if (e.hasMoreElements()) { | |||
| while(e.hasMoreElements()) { | |||
| buf.append(e.nextElement().toString()); | |||
| if (e.hasMoreElements()) { | |||
| buf.append(", "); | |||
| } | |||
| } | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * Add a new selector into this container. | |||
| * | |||
| * @param selector the new selector to add | |||
| * @return the selector that was added | |||
| */ | |||
| public void appendSelector(FileSelector selector) { | |||
| if (isReference()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| selectorsList.addElement(selector); | |||
| } | |||
| /** | |||
| * <p>This implementation validates the container by calling | |||
| * verifySettings() and then validates each contained selector | |||
| * provided that the selector implements the validate interface. | |||
| * </p> | |||
| * <p>Ordinarily, this will validate all the elements of a selector | |||
| * container even if the isSelected() method of some elements is | |||
| * never called. This has two effects:</p> | |||
| * <ul> | |||
| * <li>Validation will often occur twice. | |||
| * <li>Since it is not required that selectors derive from | |||
| * BaseSelector, there could be selectors in the container whose | |||
| * error conditions are not detected if their isSelected() call | |||
| * is never made. | |||
| * </ul> | |||
| */ | |||
| public void validate() { | |||
| verifySettings(); | |||
| String errmsg = getError(); | |||
| if (errmsg != null) { | |||
| throw new BuildException(errmsg); | |||
| } | |||
| Enumeration e = selectorElements(); | |||
| while(e.hasMoreElements()) { | |||
| Object o = e.nextElement(); | |||
| if (o instanceof BaseSelector) { | |||
| ((BaseSelector)o).validate(); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Method that each selector will implement to create their selection | |||
| * behaviour. This is what makes SelectorContainer abstract. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename the name of the file to check | |||
| * @param file a java.io.File object for the filename that the selector | |||
| * can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public abstract boolean isSelected(File basedir, String filename, | |||
| File file); | |||
| /* Methods below all implement the static selectors */ | |||
| /** | |||
| * add an "And" selector entry on the selector list | |||
| */ | |||
| public void addAnd(AndSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add an "Or" selector entry on the selector list | |||
| */ | |||
| public void addOr(OrSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a "Not" selector entry on the selector list | |||
| */ | |||
| public void addNot(NotSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a "None" selector entry on the selector list | |||
| */ | |||
| public void addNone(NoneSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a majority selector entry on the selector list | |||
| */ | |||
| public void addMajority(MajoritySelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector date entry on the selector list | |||
| */ | |||
| public void addDateselect(DateSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector size entry on the selector list | |||
| */ | |||
| public void addSizeselect(SizeSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a selector filename entry on the selector list | |||
| */ | |||
| public void addFilenameselect(FilenameSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add an extended selector entry on the selector list | |||
| */ | |||
| public void addExtendSelect(ExtendSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a contains selector entry on the selector list | |||
| */ | |||
| public void addContainsSelect(ContainsSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a present selector entry on the selector list | |||
| */ | |||
| public void addPresentSelect(PresentSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a depth selector entry on the selector list | |||
| */ | |||
| public void addDepthSelect(DepthSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| /** | |||
| * add a depends selector entry on the selector list | |||
| */ | |||
| public void addDependSelect(DependSelector selector) { | |||
| appendSelector(selector); | |||
| } | |||
| } | |||
| @@ -0,0 +1,197 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.io.BufferedReader; | |||
| import java.io.InputStreamReader; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Selector that filters files based on whether they contain a | |||
| * particular string. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class ContainsSelector extends BaseExtendSelector { | |||
| private String contains = null; | |||
| private boolean casesensitive = true; | |||
| public final static String CONTAINS_KEY = "contains"; | |||
| public final static String CASE_KEY = "casesensitive"; | |||
| public ContainsSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{containsselector contains: "); | |||
| buf.append(contains); | |||
| buf.append(" casesensitive: "); | |||
| if (casesensitive) { | |||
| buf.append("true"); | |||
| } else { | |||
| buf.append("false"); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * The string to search for within a file. | |||
| * | |||
| * @param contains the string that a file must contain to be selected. | |||
| */ | |||
| public void setContains(String contains) { | |||
| this.contains = contains; | |||
| } | |||
| /** | |||
| * Whether to ignore case in the string being searched. | |||
| * | |||
| * @param casesensitive whether to pay attention to case sensitivity | |||
| */ | |||
| public void setCasesensitive(boolean casesensitive) { | |||
| this.casesensitive = casesensitive; | |||
| } | |||
| /** | |||
| * When using this as a dynamic selector, this method will be called. | |||
| * It translates each parameter into the appropriate setXXX() call. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| super.setParameters(parameters); | |||
| if (parameters != null) { | |||
| for (int i = 0; i < parameters.length; i++) { | |||
| String paramname = parameters[i].getName(); | |||
| if (CONTAINS_KEY.equalsIgnoreCase(paramname)) { | |||
| setContains(parameters[i].getValue()); | |||
| } | |||
| else if (CASE_KEY.equalsIgnoreCase(paramname)) { | |||
| setCasesensitive(Project.toBoolean( | |||
| parameters[i].getValue())); | |||
| } | |||
| else { | |||
| setError("Invalid parameter " + paramname); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Checks to make sure all settings are kosher. In this case, it | |||
| * means that the pattern attribute has been set. | |||
| * | |||
| */ | |||
| public void verifySettings() { | |||
| if (contains == null) { | |||
| setError("The contains attribute is required"); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| // throw BuildException on error | |||
| validate(); | |||
| if (file.isDirectory()) { | |||
| return true; | |||
| } | |||
| BufferedReader in = null; | |||
| try { | |||
| in = new BufferedReader(new InputStreamReader( | |||
| new FileInputStream(file))); | |||
| String teststr = in.readLine(); | |||
| while (teststr != null) { | |||
| if (teststr.indexOf(contains) > -1) { | |||
| return true; | |||
| } | |||
| teststr = in.readLine(); | |||
| } | |||
| return false; | |||
| } | |||
| catch (IOException ioe) { | |||
| throw new BuildException("Could not read file " + filename); | |||
| } | |||
| finally { | |||
| try { | |||
| in.close(); | |||
| } | |||
| catch (Exception e) { | |||
| throw new BuildException("Could not close file " + filename); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,250 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.text.DateFormat; | |||
| import java.text.ParseException; | |||
| import java.util.Locale; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| /** | |||
| * Selector that chooses files based on their last modified date. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class DateSelector extends BaseExtendSelector { | |||
| private long millis = -1; | |||
| private String dateTime = null; | |||
| private boolean includeDirs = false; | |||
| private int cmp = 0; | |||
| public final static String MILLIS_KEY = "millis"; | |||
| public final static String DATETIME_KEY = "datetime"; | |||
| public final static String CHECKDIRS_KEY = "checkdirs"; | |||
| public final static String WHEN_KEY = "when"; | |||
| public DateSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{dateselector date: "); | |||
| buf.append(dateTime); | |||
| buf.append("compare: "); | |||
| if (cmp == 0) { | |||
| buf.append("before"); | |||
| } | |||
| else if (cmp == 1) { | |||
| buf.append("after"); | |||
| } else { | |||
| buf.append("equal"); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * For users that prefer to express time in milliseconds since 1970 | |||
| * | |||
| * @param millis the time to compare file's last modified date to, | |||
| * expressed in milliseconds | |||
| */ | |||
| public void setMillis(long millis) { | |||
| this.millis = millis; | |||
| } | |||
| /** | |||
| * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM | |||
| * format | |||
| * | |||
| * @param dateTime a string in MM/DD/YYYY HH:MM AM_PM format | |||
| */ | |||
| public void setDatetime(String dateTime) { | |||
| this.dateTime = dateTime; | |||
| if (dateTime != null) { | |||
| DateFormat df = DateFormat.getDateTimeInstance( | |||
| DateFormat.SHORT, | |||
| DateFormat.SHORT, | |||
| Locale.US); | |||
| try { | |||
| setMillis(df.parse(dateTime).getTime()); | |||
| if (millis < 0) { | |||
| setError("Date of " + dateTime | |||
| + " results in negative milliseconds value relative" | |||
| + " to epoch (January 1, 1970, 00:00:00 GMT)."); | |||
| } | |||
| } catch (ParseException pe) { | |||
| setError("Date of " + dateTime | |||
| + " Cannot be parsed correctly. It should be in" | |||
| + " MM/DD/YYYY HH:MM AM_PM format."); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Should we be checking dates on directories? | |||
| * | |||
| * @param includeDirs whether to check the timestamp on directories | |||
| */ | |||
| public void setCheckdirs(boolean includeDirs) { | |||
| this.includeDirs = includeDirs; | |||
| } | |||
| /** | |||
| * Sets the type of comparison to be done on the file's last modified | |||
| * date. | |||
| * | |||
| * @param cmp The comparison to perform, an EnumeratedAttribute | |||
| */ | |||
| public void setWhen(TimeComparisons cmp) { | |||
| this.cmp = cmp.getIndex(); | |||
| } | |||
| /** | |||
| * When using this as a dynamic selector, this method will be called. | |||
| * It translates each parameter into the appropriate setXXX() call. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| super.setParameters(parameters); | |||
| if (parameters != null) { | |||
| for (int i = 0; i < parameters.length; i++) { | |||
| String paramname = parameters[i].getName(); | |||
| if (MILLIS_KEY.equalsIgnoreCase(paramname)) { | |||
| try { | |||
| setMillis(new Long(parameters[i].getValue() | |||
| ).longValue()); | |||
| } catch (NumberFormatException nfe) { | |||
| setError("Invalid millisecond setting " + | |||
| parameters[i].getValue()); | |||
| } | |||
| } | |||
| else if (DATETIME_KEY.equalsIgnoreCase(paramname)) { | |||
| setDatetime(parameters[i].getValue()); | |||
| } | |||
| else if (CHECKDIRS_KEY.equalsIgnoreCase(paramname)) { | |||
| setCheckdirs(Project.toBoolean(parameters[i].getValue())); | |||
| } | |||
| else if (WHEN_KEY.equalsIgnoreCase(paramname)) { | |||
| TimeComparisons cmp = new TimeComparisons(); | |||
| cmp.setValue(parameters[i].getValue()); | |||
| setWhen(cmp); | |||
| } | |||
| else { | |||
| setError("Invalid parameter " + paramname); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * This is a consistency check to ensure the selector's required | |||
| * values have been set. | |||
| */ | |||
| public void verifySettings() { | |||
| if (dateTime == null && millis < 0) { | |||
| setError("You must provide a datetime or the number of " | |||
| + "milliseconds."); | |||
| } | |||
| else if (millis < 0) { | |||
| setError("Date of " + dateTime | |||
| + " results in negative milliseconds" | |||
| + " value relative to epoch (January 1, 1970, 00:00:00 GMT)."); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| if (file.isDirectory() && (includeDirs == false)) { | |||
| return true; | |||
| } | |||
| if (cmp == 0) { | |||
| return (file.lastModified() < millis); | |||
| } | |||
| else if (cmp == 1) { | |||
| return (file.lastModified() > millis); | |||
| } | |||
| else { | |||
| return (file.lastModified() == millis); | |||
| } | |||
| } | |||
| /** | |||
| * Enumerated attribute with the values for time comparison. | |||
| * <p> | |||
| */ | |||
| public static class TimeComparisons extends EnumeratedAttribute { | |||
| public String[] getValues() { | |||
| return new String[] {"before", "after", "equal"}; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,186 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Mapper; | |||
| import org.apache.tools.ant.util.IdentityMapper; | |||
| import org.apache.tools.ant.util.FileNameMapper; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Selector that filters files based on whether they are newer than | |||
| * a matching file in another directory tree. It can contain a mapper | |||
| * element, so isn't available as an ExtendSelector (since those | |||
| * parameters can't hold other elements). | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class DependSelector extends BaseSelector { | |||
| private String targetdir = null; | |||
| private File targetbase = null; | |||
| private Mapper mapperElement = null; | |||
| private FileNameMapper map = null; | |||
| private int granularity = 0; | |||
| public DependSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{dependselector targetdir: "); | |||
| buf.append(targetdir); | |||
| buf.append(" granularity: "); | |||
| buf.append(granularity); | |||
| if (map != null) { | |||
| buf.append(" mapper: "); | |||
| buf.append(map.toString()); | |||
| } | |||
| else if (mapperElement != null) { | |||
| buf.append(" mapper: "); | |||
| buf.append(mapperElement.toString()); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * The name of the file or directory which is checked for out-of-date | |||
| * files. | |||
| * | |||
| * @param targetdir the directory to scan looking for files. | |||
| */ | |||
| public void setTargetdir(String targetdir) { | |||
| this.targetdir = SelectorUtils.fixPath(targetdir); | |||
| targetbase = new File(this.targetdir); | |||
| } | |||
| /** | |||
| * Sets the number of milliseconds leeway we will give before we consider | |||
| * a file out of date. | |||
| */ | |||
| public void setGranularity(int granularity) { | |||
| this.granularity = granularity; | |||
| } | |||
| /** | |||
| * Defines the FileNameMapper to use (nested mapper element). | |||
| */ | |||
| public Mapper createMapper() throws BuildException { | |||
| if (mapperElement != null) { | |||
| throw new BuildException("Cannot define more than one mapper"); | |||
| } | |||
| mapperElement = new Mapper(project); | |||
| return mapperElement; | |||
| } | |||
| /** | |||
| * Checks to make sure all settings are kosher. In this case, it | |||
| * means that the dest attribute has been set and we have a mapper. | |||
| */ | |||
| public void verifySettings() { | |||
| if (targetdir == null) { | |||
| setError("The targetdir attribute is required."); | |||
| } | |||
| if (mapperElement == null) { | |||
| map = new IdentityMapper(); | |||
| } | |||
| else { | |||
| map = mapperElement.getImplementation(); | |||
| } | |||
| if (map == null) { | |||
| setError("Could not set <mapper> element."); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| // throw BuildException on error | |||
| validate(); | |||
| // Get File object for the target directory | |||
| File target = targetbase; | |||
| if (target == null) { | |||
| target = new File(basedir,targetdir); | |||
| } | |||
| // Determine file whose out-of-dateness is to be checked | |||
| String[] destfiles = map.mapFileName(filename); | |||
| // Sanity check | |||
| if (destfiles.length != 1 || destfiles[0] == null) { | |||
| throw new BuildException("Invalid destination file results for " | |||
| + targetdir + " with filename " + filename); | |||
| } | |||
| String destname = destfiles[0]; | |||
| File destfile = new File(target,destname); | |||
| return SelectorUtils.isOutOfDate(file, destfile, granularity); | |||
| } | |||
| } | |||
| @@ -0,0 +1,209 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.StringTokenizer; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Selector that filters files based on the how deep in the directory | |||
| * tree they are. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class DepthSelector extends BaseExtendSelector { | |||
| public int min = -1; | |||
| public int max = -1; | |||
| public final static String MIN_KEY = "min"; | |||
| public final static String MAX_KEY = "max"; | |||
| public DepthSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{depthselector min: "); | |||
| buf.append(min); | |||
| buf.append(" max: "); | |||
| buf.append(max); | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * The minimum depth below the basedir before a file is selected. | |||
| * | |||
| * @param min minimum directory levels below basedir to go | |||
| */ | |||
| public void setMin(int min) { | |||
| this.min = min; | |||
| } | |||
| /** | |||
| * The minimum depth below the basedir before a file is selected. | |||
| * | |||
| * @param min maximum directory levels below basedir to go | |||
| */ | |||
| public void setMax(int max) { | |||
| this.max = max; | |||
| } | |||
| /** | |||
| * When using this as a dynamic selector, this method will be called. | |||
| * It translates each parameter into the appropriate setXXX() call. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| super.setParameters(parameters); | |||
| if (parameters != null) { | |||
| for (int i = 0; i < parameters.length; i++) { | |||
| String paramname = parameters[i].getName(); | |||
| if (MIN_KEY.equalsIgnoreCase(paramname)) { | |||
| try { | |||
| setMin(Integer.parseInt(parameters[i].getValue())); | |||
| } | |||
| catch (NumberFormatException nfe1) { | |||
| setError("Invalid minimum value " | |||
| + parameters[i].getValue()); | |||
| } | |||
| } | |||
| else if (MAX_KEY.equalsIgnoreCase(paramname)) { | |||
| try { | |||
| setMax(Integer.parseInt(parameters[i].getValue())); | |||
| } | |||
| catch (NumberFormatException nfe1) { | |||
| setError("Invalid maximum value " | |||
| + parameters[i].getValue()); | |||
| } | |||
| } | |||
| else { | |||
| setError("Invalid parameter " + paramname); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Checks to make sure all settings are kosher. In this case, it | |||
| * means that the max depth is not lower than the min depth. | |||
| */ | |||
| public void verifySettings() { | |||
| if (min < 0 && max < 0) { | |||
| setError("You must set at least one of the min or the " + | |||
| "max levels."); | |||
| } | |||
| if (max < min) { | |||
| setError("The maximum depth is lower than the minimum."); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. Most of the work | |||
| * for this selector is offloaded into SelectorUtils, a static class | |||
| * that provides the same services for both FilenameSelector and | |||
| * DirectoryScanner. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| // throw BuildException on error | |||
| validate(); | |||
| int depth = -1; | |||
| // If you felt daring, you could cache the basedir absolute path | |||
| String abs_base = basedir.getAbsolutePath(); | |||
| String abs_file = file.getAbsolutePath(); | |||
| StringTokenizer tok_base = new StringTokenizer(abs_base, File.separator); | |||
| StringTokenizer tok_file = new StringTokenizer(abs_file, File.separator); | |||
| while (tok_file.hasMoreTokens()) { | |||
| String filetoken = tok_file.nextToken(); | |||
| if (tok_base.hasMoreTokens()) { | |||
| String basetoken = tok_base.nextToken(); | |||
| // Sanity check. Ditch it if you want faster performance | |||
| if (!basetoken.equals(filetoken)) { | |||
| throw new BuildException("File " + filename + | |||
| " does not appear within " + abs_base + "directory"); | |||
| } | |||
| } | |||
| else { | |||
| depth += 1; | |||
| if (max > -1 && depth > max) { | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| if (tok_base.hasMoreTokens()) { | |||
| throw new BuildException("File " + filename + | |||
| " is outside of " + abs_base + "directory tree"); | |||
| } | |||
| if (min > -1 && depth < min) { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,78 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.types.Parameterizable; | |||
| /** | |||
| * This is the interface to be used by all dynamic selectors, those that are | |||
| * called through the <extendselect> tag. It is the amalgamation of two | |||
| * interfaces, the FileSelector and the Paramterizable interface. Note that | |||
| * you will almost certainly want the default behaviour for handling | |||
| * Parameters, so you probably want to use the BaseExtendSelector class | |||
| * as the base class for your dynamic selector rather than implementing | |||
| * this interface from scratch. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public interface ExtendFileSelector extends FileSelector, Parameterizable { | |||
| // No further methods necessary. This is just an amalgamation of two other | |||
| // interfaces. | |||
| } | |||
| @@ -0,0 +1,213 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.DataType; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| import org.apache.tools.ant.types.Reference; | |||
| /** | |||
| * Selector that selects files by forwarding the request on to other classes. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class ExtendSelector extends BaseSelector { | |||
| private String classname = null; | |||
| private ExtendFileSelector dynselector = null; | |||
| private Vector paramVec = new Vector(); | |||
| private Path classpath = null; | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public ExtendSelector() { | |||
| } | |||
| /** | |||
| * Sets the classname of the dynamic selector. | |||
| * | |||
| * @param classname is the class which implements this selector | |||
| */ | |||
| public void setClassname(String classname) { | |||
| this.classname = classname; | |||
| } | |||
| /** | |||
| * Instantiates the identified dynamic selector class. | |||
| */ | |||
| public void selectorCreate() { | |||
| if (classname != null && classname.length() > 0) { | |||
| try { | |||
| dynselector = (ExtendFileSelector) | |||
| Class.forName(classname).newInstance(); | |||
| } | |||
| catch (ClassNotFoundException cnfexcept) { | |||
| setError("Selector " + classname + | |||
| " not initialized, no such class"); | |||
| } | |||
| catch (InstantiationException iexcept) { | |||
| setError("Selector " + classname + | |||
| " not initialized, could not create class"); | |||
| } | |||
| catch (IllegalAccessException iaexcept) { | |||
| setError("Selector " + classname + | |||
| " not initialized, class not accessible"); | |||
| } | |||
| } else { | |||
| setError("There is no classname specified"); | |||
| } | |||
| } | |||
| /** | |||
| * Create new parameters to pass to dynamic selector. | |||
| * | |||
| * @param p The new Parameter object | |||
| */ | |||
| public void addParam(Parameter p) { | |||
| paramVec.addElement(p); | |||
| } | |||
| /** | |||
| * Set the classpath to load the classname specified using an attribute. | |||
| */ | |||
| public final void setClasspath(Path classpath) { | |||
| if (isReference()) { | |||
| throw tooManyAttributes(); | |||
| } | |||
| if (this.classpath == null) { | |||
| this.classpath = classpath; | |||
| } else { | |||
| this.classpath.append(classpath); | |||
| } | |||
| } | |||
| /** | |||
| * Specify the classpath to use to load the Selector (nested element). | |||
| */ | |||
| public final Path createClasspath() { | |||
| if (isReference()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| if (this.classpath == null) { | |||
| this.classpath = new Path(getProject()); | |||
| } | |||
| return this.classpath.createPath(); | |||
| } | |||
| /** | |||
| * Get the classpath | |||
| */ | |||
| public final Path getClasspath() { | |||
| return classpath; | |||
| } | |||
| /** | |||
| * Set the classpath to use for loading a dynamic selector by using | |||
| * a reference. | |||
| */ | |||
| public void setClasspathref(Reference r) { | |||
| if (isReference()) { | |||
| throw tooManyAttributes(); | |||
| } | |||
| createClasspath().setRefid(r); | |||
| } | |||
| /** | |||
| * These are errors specific to ExtendSelector only. If there are | |||
| * errors in the dynamic selector, it should throw a BuildException | |||
| * when isSelected() is called. | |||
| */ | |||
| public void verifySettings() { | |||
| if (classname == null || classname.length() < 1) { | |||
| setError("The classname attribute is required"); | |||
| } | |||
| else if (dynselector == null) { | |||
| setError("Internal Error: The dynamic selector is not set"); | |||
| } | |||
| } | |||
| /** | |||
| * Allows the dynamic selector to choose whether to select a file. This | |||
| * is also where the Parameters are passed to the dynamic selector, | |||
| * since we know we must have them all by now. And since we must know | |||
| * both classpath and classname, creating the class is deferred to here | |||
| * as well. | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) | |||
| throws BuildException { | |||
| if (dynselector == null) { | |||
| selectorCreate(); | |||
| } | |||
| validate(); | |||
| if (paramVec.size() > 0) { | |||
| Parameter[] paramArray = new Parameter[paramVec.size()]; | |||
| paramVec.copyInto(paramArray); | |||
| // We know that dynselector must be non-null if no error message | |||
| dynselector.setParameters(paramArray); | |||
| } | |||
| return dynselector.isSelected(basedir,filename,file); | |||
| } | |||
| } | |||
| @@ -0,0 +1,85 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * This is the interface to be used by all selectors. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public interface FileSelector { | |||
| /** | |||
| * Method that each selector will implement to create their | |||
| * selection behaviour. If there is a problem with the setup | |||
| * of a selector, it can throw a BuildException to indicate | |||
| * the problem. | |||
| * | |||
| * @param basedir A java.io.File object for the base directory | |||
| * @param filename The name of the file to check | |||
| * @param file A File object for this filename | |||
| * @return whether the file should be selected or not | |||
| * @exception BuildException if the selector was not configured correctly | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) | |||
| throws BuildException; | |||
| } | |||
| @@ -0,0 +1,195 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| /** | |||
| * Selector that filters files based on the filename. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class FilenameSelector extends BaseExtendSelector { | |||
| private String pattern = null; | |||
| private boolean casesensitive = true; | |||
| private boolean negated = false; | |||
| public final static String NAME_KEY = "name"; | |||
| public final static String CASE_KEY = "casesensitive"; | |||
| public final static String NEGATE_KEY = "negate"; | |||
| public FilenameSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{filenameselector name: "); | |||
| buf.append(pattern); | |||
| buf.append(" negate: "); | |||
| if (negated) { | |||
| buf.append("true"); | |||
| } else { | |||
| buf.append("false"); | |||
| } | |||
| buf.append(" casesensitive: "); | |||
| if (casesensitive) { | |||
| buf.append("true"); | |||
| } else { | |||
| buf.append("false"); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * The name of the file, or the pattern for the name, that | |||
| * should be used for selection. | |||
| * | |||
| * @param pattern the file pattern that any filename must match | |||
| * against in order to be selected. | |||
| */ | |||
| public void setName(String pattern) { | |||
| pattern = pattern.replace('/',File.separatorChar).replace('\\', | |||
| File.separatorChar); | |||
| if (pattern.endsWith(File.separator)) { | |||
| pattern += "**"; | |||
| } | |||
| this.pattern = pattern; | |||
| } | |||
| /** | |||
| * Whether to ignore case when checking filenames. | |||
| * | |||
| * @param casesensitive whether to pay attention to case sensitivity | |||
| */ | |||
| public void setCasesensitive(boolean casesensitive) { | |||
| this.casesensitive = casesensitive; | |||
| } | |||
| /** | |||
| * You can optionally reverse the selection of this selector, | |||
| * thereby emulating an <exclude> tag, by setting the attribute | |||
| * negate to true. This is identical to surrounding the selector | |||
| * with <not></not>. | |||
| * | |||
| * @param negated whether to negate this selection | |||
| */ | |||
| public void setNegate(boolean negated) { | |||
| this.negated = negated; | |||
| } | |||
| /** | |||
| * When using this as a dynamic selector, this method will be called. | |||
| * It translates each parameter into the appropriate setXXX() call. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| super.setParameters(parameters); | |||
| if (parameters != null) { | |||
| for (int i = 0; i < parameters.length; i++) { | |||
| String paramname = parameters[i].getName(); | |||
| if (NAME_KEY.equalsIgnoreCase(paramname)) { | |||
| setName(parameters[i].getValue()); | |||
| } | |||
| else if (CASE_KEY.equalsIgnoreCase(paramname)) { | |||
| setCasesensitive(Project.toBoolean( | |||
| parameters[i].getValue())); | |||
| } | |||
| else if (NEGATE_KEY.equalsIgnoreCase(paramname)) { | |||
| setNegate(Project.toBoolean(parameters[i].getValue())); | |||
| } | |||
| else { | |||
| setError("Invalid parameter " + paramname); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Checks to make sure all settings are kosher. In this case, it | |||
| * means that the name attribute has been set. | |||
| * | |||
| */ | |||
| public void verifySettings() { | |||
| if (pattern == null) { | |||
| setError("The name attribute is required"); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. Most of the work | |||
| * for this selector is offloaded into SelectorUtils, a static class | |||
| * that provides the same services for both FilenameSelector and | |||
| * DirectoryScanner. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| return SelectorUtils.matchPath(pattern,filename, | |||
| casesensitive); | |||
| } | |||
| } | |||
| @@ -0,0 +1,135 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| /** | |||
| * This selector is here just to shake up your thinking a bit. Don't get | |||
| * too caught up in boolean, there are other ways you can evaluate a | |||
| * collection of selectors. This one takes a vote of the selectors it | |||
| * contains, and majority wins. You could also have an "all-but-one" | |||
| * selector, a "weighted-average" selector, and so on. These are left | |||
| * as exercises for the reader (as are the usecases where this would | |||
| * be necessary). | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class MajoritySelector extends BaseSelectorContainer { | |||
| private boolean allowtie = true; | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public MajoritySelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| if (hasSelectors()) { | |||
| buf.append("{majorityselect: "); | |||
| buf.append(super.toString()); | |||
| buf.append("}"); | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| public void setAllowtie(boolean tiebreaker) { | |||
| allowtie = tiebreaker; | |||
| } | |||
| /** | |||
| * Returns true (the file is selected) if most of the other selectors | |||
| * agree. In case of a tie, go by the allowtie setting. That defaults | |||
| * to true, meaning in case of a tie, the file is selected. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object for the filename that the selector | |||
| * can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| int yesvotes = 0; | |||
| int novotes = 0; | |||
| Enumeration e = selectorElements(); | |||
| boolean result; | |||
| while(e.hasMoreElements()) { | |||
| result = ((FileSelector)e.nextElement()).isSelected(basedir, | |||
| filename,file); | |||
| if (result) { | |||
| yesvotes = yesvotes + 1; | |||
| } | |||
| else { | |||
| novotes = novotes + 1; | |||
| } | |||
| } | |||
| if (yesvotes > novotes) | |||
| { | |||
| return true; | |||
| } | |||
| else if (novotes > yesvotes) { | |||
| return false; | |||
| } | |||
| // At this point, we know we have a tie. | |||
| return allowtie; | |||
| } | |||
| } | |||
| @@ -0,0 +1,112 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| /** | |||
| * This selector has a collection of other selectors. All of those selectors | |||
| * must refuse to select a file before the file is considered selected by | |||
| * this selector. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class NoneSelector extends BaseSelectorContainer { | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public NoneSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| if (hasSelectors()) { | |||
| buf.append("{noneselect: "); | |||
| buf.append(super.toString()); | |||
| buf.append("}"); | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * Returns true (the file is selected) only if all other selectors | |||
| * agree that the file should not be selected. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object for the filename that the selector | |||
| * can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| Enumeration e = selectorElements(); | |||
| boolean result; | |||
| while(e.hasMoreElements()) { | |||
| result = ((FileSelector)e.nextElement()).isSelected(basedir, | |||
| filename,file); | |||
| if (result) { | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,99 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| /** | |||
| * This selector has one other selectors whose meaning it inverts. It | |||
| * actually relies on NoneSelector for its implementation of the | |||
| * isSelected() method, but it adds a check to ensure there is only one | |||
| * other selector contained within. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class NotSelector extends NoneSelector { | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public NotSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| if (hasSelectors()) { | |||
| buf.append("{notselect: "); | |||
| buf.append(super.toString()); | |||
| buf.append("}"); | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * Makes sure that there is only one entry, sets an error message if | |||
| * not. | |||
| */ | |||
| public void verifySettings() { | |||
| if (selectorCount() != 1) { | |||
| setError("One and only one selector is allowed within the " + | |||
| "<not> tag"); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,112 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| /** | |||
| * This selector has a collection of other selectors, any of which have to | |||
| * select a file in order for this selector to select it. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class OrSelector extends BaseSelectorContainer { | |||
| /** | |||
| * Default constructor. | |||
| */ | |||
| public OrSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer(); | |||
| if (hasSelectors()) { | |||
| buf.append("{orselect: "); | |||
| buf.append(super.toString()); | |||
| buf.append("}"); | |||
| } | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * Returns true (the file is selected) if any of the other selectors | |||
| * agree that the file should be selected. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename the name of the file to check | |||
| * @param file a java.io.File object for the filename that the selector | |||
| * can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| validate(); | |||
| Enumeration e = selectorElements(); | |||
| boolean result; | |||
| // First, check that all elements are correctly configured | |||
| while(e.hasMoreElements()) { | |||
| result = ((FileSelector)e.nextElement()).isSelected(basedir, | |||
| filename,file); | |||
| if (result) { | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -0,0 +1,208 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Mapper; | |||
| import org.apache.tools.ant.util.IdentityMapper; | |||
| import org.apache.tools.ant.util.FileNameMapper; | |||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Selector that filters files based on whether they appear in another | |||
| * directory tree. It can contain a mapper element, so isn't available | |||
| * as an ExtendSelector (since those parameters can't hold other | |||
| * elements). | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class PresentSelector extends BaseSelector { | |||
| private String targetdir = null; | |||
| private File targetbase = null; | |||
| private Mapper mapperElement = null; | |||
| private FileNameMapper map = null; | |||
| private boolean destmustexist = true; | |||
| public PresentSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{presentselector targetdir: "); | |||
| buf.append(targetdir); | |||
| buf.append(" present: "); | |||
| if (destmustexist) { | |||
| buf.append("both"); | |||
| } else { | |||
| buf.append("srconly"); | |||
| } | |||
| if (map != null) { | |||
| buf.append(map.toString()); | |||
| } | |||
| else if (mapperElement != null) { | |||
| buf.append(mapperElement.toString()); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * The name of the file or directory which is checked for matching | |||
| * files. | |||
| * | |||
| * @param targetdir the directory to scan looking for matching files. | |||
| */ | |||
| public void setTargetdir(String targetdir) { | |||
| this.targetdir = SelectorUtils.fixPath(targetdir); | |||
| targetbase = new File(this.targetdir); | |||
| } | |||
| /** | |||
| * Defines the FileNameMapper to use (nested mapper element). | |||
| */ | |||
| public Mapper createMapper() throws BuildException { | |||
| if (mapperElement != null) { | |||
| throw new BuildException("Cannot define more than one mapper"); | |||
| } | |||
| mapperElement = new Mapper(project); | |||
| return mapperElement; | |||
| } | |||
| /** | |||
| * This sets whether to select a file if its dest file is present. | |||
| * It could be a <code>negate</code> boolean, but by doing things | |||
| * this way, we get some documentation on how the system works. | |||
| * A user looking at the documentation should clearly understand | |||
| * that the ONLY files whose presence is being tested are those | |||
| * that already exist in the source directory, hence the lack of | |||
| * a <code>destonly</code> option. | |||
| * | |||
| * @param fp An attribute set to either <code>srconly</code or | |||
| * <code>both</code>. | |||
| */ | |||
| public void setPresent(FilePresence fp) { | |||
| if (fp.getIndex() == 0) { | |||
| destmustexist = false; | |||
| } | |||
| } | |||
| /** | |||
| * Checks to make sure all settings are kosher. In this case, it | |||
| * means that the targetdir attribute has been set and we have a mapper. | |||
| */ | |||
| public void verifySettings() { | |||
| if (targetdir == null) { | |||
| setError("The targetdir attribute is required."); | |||
| } | |||
| if (mapperElement == null) { | |||
| map = new IdentityMapper(); | |||
| } | |||
| else { | |||
| map = mapperElement.getImplementation(); | |||
| } | |||
| if (map == null) { | |||
| setError("Could not set <mapper> element."); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. | |||
| * | |||
| * @param basedir the base directory the scan is being done from | |||
| * @param filename is the name of the file to check | |||
| * @param file is a java.io.File object the selector can use | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| // throw BuildException on error | |||
| validate(); | |||
| // Get File object for the target directory | |||
| File target = targetbase; | |||
| if (target == null) { | |||
| target = new File(basedir,targetdir); | |||
| } | |||
| // Determine file whose existence is to be checked | |||
| String[] destfiles = map.mapFileName(filename); | |||
| // Sanity check | |||
| if (destfiles.length != 1 || destfiles[0] == null) { | |||
| throw new BuildException("Invalid destination file results for " | |||
| + targetdir + " with filename " + filename); | |||
| } | |||
| String destname = destfiles[0]; | |||
| File destfile = new File(target,destname); | |||
| return destfile.exists() == destmustexist; | |||
| } | |||
| /** | |||
| * Enumerated attribute with the values for indicating where a file's | |||
| * presence is allowed and required. | |||
| */ | |||
| public static class FilePresence extends EnumeratedAttribute { | |||
| public String[] getValues() { | |||
| return new String[] {"srconly", "both"}; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,178 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.Reference; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| import java.util.Stack; | |||
| import java.util.Vector; | |||
| /** | |||
| * This is the base class for selectors that can contain other selectors. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public interface SelectorContainer { | |||
| /** | |||
| * Indicates whether there are any selectors here. | |||
| * | |||
| * @return whether any selectors are in this container | |||
| */ | |||
| public boolean hasSelectors(); | |||
| /** | |||
| * Gives the count of the number of selectors in this container | |||
| * | |||
| * @return the number of selectors in this container | |||
| */ | |||
| public int selectorCount(); | |||
| /** | |||
| * Returns the set of selectors as an array. | |||
| * | |||
| * @return an array of selectors in this container | |||
| */ | |||
| public FileSelector[] getSelectors(Project p); | |||
| /** | |||
| * Returns an enumerator for accessing the set of selectors. | |||
| * | |||
| * @return an enumerator that goes through each of the selectors | |||
| */ | |||
| public Enumeration selectorElements(); | |||
| /** | |||
| * Add a new selector into this container. | |||
| * | |||
| * @param selector the new selector to add | |||
| * @return the selector that was added | |||
| */ | |||
| public void appendSelector(FileSelector selector); | |||
| /* Methods below all implement the static selectors */ | |||
| /** | |||
| * add an "And" selector entry on the selector list | |||
| */ | |||
| public void addAnd(AndSelector selector); | |||
| /** | |||
| * add an "Or" selector entry on the selector list | |||
| */ | |||
| public void addOr(OrSelector selector); | |||
| /** | |||
| * add a "Not" selector entry on the selector list | |||
| */ | |||
| public void addNot(NotSelector selector); | |||
| /** | |||
| * add a "None" selector entry on the selector list | |||
| */ | |||
| public void addNone(NoneSelector selector); | |||
| /** | |||
| * add a majority selector entry on the selector list | |||
| */ | |||
| public void addMajority(MajoritySelector selector); | |||
| /** | |||
| * add a selector date entry on the selector list | |||
| */ | |||
| public void addDateselect(DateSelector selector); | |||
| /** | |||
| * add a selector size entry on the selector list | |||
| */ | |||
| public void addSizeselect(SizeSelector selector); | |||
| /** | |||
| * add a selector filename entry on the selector list | |||
| */ | |||
| public void addFilenameselect(FilenameSelector selector); | |||
| /** | |||
| * add an extended selector entry on the selector list | |||
| */ | |||
| public void addExtendSelect(ExtendSelector selector); | |||
| /** | |||
| * add a contains selector entry on the selector list | |||
| */ | |||
| public void addContainsSelect(ContainsSelector selector); | |||
| /** | |||
| * add a present selector entry on the selector list | |||
| */ | |||
| public void addPresentSelect(PresentSelector selector); | |||
| /** | |||
| * add a depth selector entry on the selector list | |||
| */ | |||
| public void addDepthSelect(DepthSelector selector); | |||
| /** | |||
| * add a depends selector entry on the selector list | |||
| */ | |||
| public void addDependSelect(DependSelector selector); | |||
| } | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| /** | |||
| * An interface used to describe the actions required by any type of | |||
| * directory scanner that supports Selecters. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public interface SelectorScanner { | |||
| /** | |||
| * Sets the selectors the scanner should use. | |||
| * | |||
| * @param selectors the list of selectors | |||
| */ | |||
| void setSelectors(FileSelector[] selectors); | |||
| /** | |||
| * Directories which were selected out of a scan. | |||
| * | |||
| * @param selectors list selector objects | |||
| */ | |||
| public String[] getDeselectedDirectories(); | |||
| /** | |||
| * Files which were selected out of a scan. | |||
| * | |||
| * @param selectors list selector objects | |||
| */ | |||
| public String[] getDeselectedFiles(); | |||
| } | |||
| @@ -0,0 +1,564 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.StringTokenizer; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * <p>This is a utility class used by selectors and DirectoryScanner. The | |||
| * functionality more properly belongs just to selectors, but unfortunately | |||
| * DirectoryScanner exposed these as protected methods. Thus we have to | |||
| * support any subclasses of DirectoryScanner that may access these methods. | |||
| * </p> | |||
| * <p>This is a Singleton.</p> | |||
| * | |||
| * @author Arnout J. Kuiper | |||
| * <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a> | |||
| * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public final class SelectorUtils { | |||
| private static SelectorUtils instance = new SelectorUtils(); | |||
| /** | |||
| * Private Constructor | |||
| */ | |||
| private SelectorUtils() { | |||
| } | |||
| /** | |||
| * Retrieves the instance of the Singleton. | |||
| */ | |||
| public static SelectorUtils getInstance() { | |||
| return instance; | |||
| } | |||
| /** | |||
| * Tests whether or not a given path matches the start of a given | |||
| * pattern up to the first "**". | |||
| * <p> | |||
| * This is not a general purpose test and should only be used if you | |||
| * can live with false positives. For example, <code>pattern=**\a</code> | |||
| * and <code>str=b</code> will yield <code>true</code>. | |||
| * | |||
| * @param pattern The pattern to match against. Must not be | |||
| * <code>null</code>. | |||
| * @param str The path to match, as a String. Must not be | |||
| * <code>null</code>. | |||
| * | |||
| * @return whether or not a given path matches the start of a given | |||
| * pattern up to the first "**". | |||
| */ | |||
| public static boolean matchPatternStart(String pattern, String str) { | |||
| return matchPatternStart(pattern, str, true); | |||
| } | |||
| /** | |||
| * Tests whether or not a given path matches the start of a given | |||
| * pattern up to the first "**". | |||
| * <p> | |||
| * This is not a general purpose test and should only be used if you | |||
| * can live with false positives. For example, <code>pattern=**\a</code> | |||
| * and <code>str=b</code> will yield <code>true</code>. | |||
| * | |||
| * @param pattern The pattern to match against. Must not be | |||
| * <code>null</code>. | |||
| * @param str The path to match, as a String. Must not be | |||
| * <code>null</code>. | |||
| * @param isCaseSensitive Whether or not matching should be performed | |||
| * case sensitively. | |||
| * | |||
| * @return whether or not a given path matches the start of a given | |||
| * pattern up to the first "**". | |||
| */ | |||
| public static boolean matchPatternStart(String pattern, String str, | |||
| boolean isCaseSensitive) { | |||
| // 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 = tokenizePath (pattern); | |||
| Vector strDirs = tokenizePath (str); | |||
| 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), | |||
| isCaseSensitive)) { | |||
| 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; | |||
| } | |||
| } | |||
| /** | |||
| * Tests whether or not a given path matches a given pattern. | |||
| * | |||
| * @param pattern The pattern to match against. Must not be | |||
| * <code>null</code>. | |||
| * @param str The path to match, as a String. Must not be | |||
| * <code>null</code>. | |||
| * | |||
| * @return <code>true</code> if the pattern matches against the string, | |||
| * or <code>false</code> otherwise. | |||
| */ | |||
| public static boolean matchPath(String pattern, String str) { | |||
| return matchPath(pattern, str, true); | |||
| } | |||
| /** | |||
| * Tests whether or not a given path matches a given pattern. | |||
| * | |||
| * @param pattern The pattern to match against. Must not be | |||
| * <code>null</code>. | |||
| * @param str The path to match, as a String. Must not be | |||
| * <code>null</code>. | |||
| * @param isCaseSensitive Whether or not matching should be performed | |||
| * case sensitively. | |||
| * | |||
| * @return <code>true</code> if the pattern matches against the string, | |||
| * or <code>false</code> otherwise. | |||
| */ | |||
| public static boolean matchPath(String pattern, String str, | |||
| boolean isCaseSensitive) { | |||
| // 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 = tokenizePath (pattern); | |||
| Vector strDirs = tokenizePath (str); | |||
| 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), | |||
| isCaseSensitive)) { | |||
| 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), | |||
| isCaseSensitive)) { | |||
| 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, isCaseSensitive)) { | |||
| 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; | |||
| } | |||
| /** | |||
| * Tests whether or not a string matches against a pattern. | |||
| * The pattern may contain two special characters:<br> | |||
| * '*' means zero or more characters<br> | |||
| * '?' means one and only one character | |||
| * | |||
| * @param pattern The pattern to match against. | |||
| * Must not be <code>null</code>. | |||
| * @param str The string which must be matched against the pattern. | |||
| * Must not be <code>null</code>. | |||
| * | |||
| * @return <code>true</code> if the string matches against the pattern, | |||
| * or <code>false</code> otherwise. | |||
| */ | |||
| public static boolean match(String pattern, String str) { | |||
| return match(pattern, str, true); | |||
| } | |||
| /** | |||
| * Tests whether or not a string matches against a pattern. | |||
| * The pattern may contain two special characters:<br> | |||
| * '*' means zero or more characters<br> | |||
| * '?' means one and only one character | |||
| * | |||
| * @param pattern The pattern to match against. | |||
| * Must not be <code>null</code>. | |||
| * @param str The string which must be matched against the pattern. | |||
| * Must not be <code>null</code>. | |||
| * @param isCaseSensitive Whether or not matching should be performed | |||
| * case sensitively. | |||
| * | |||
| * | |||
| * @return <code>true</code> if the string matches against the pattern, | |||
| * or <code>false</code> otherwise. | |||
| */ | |||
| public static boolean match(String pattern, String str, | |||
| boolean isCaseSensitive) { | |||
| 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 != '?') { | |||
| if (isCaseSensitive && ch != strArr[i]) { | |||
| return false;// Character mismatch | |||
| } | |||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||
| Character.toUpperCase(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 != '?') { | |||
| if (isCaseSensitive && ch != strArr[strIdxStart]) { | |||
| return false;// Character mismatch | |||
| } | |||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||
| Character.toUpperCase(strArr[strIdxStart])) { | |||
| return false;// Character mismatch | |||
| } | |||
| } | |||
| 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 != '?') { | |||
| if (isCaseSensitive && ch != strArr[strIdxEnd]) { | |||
| return false;// Character mismatch | |||
| } | |||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||
| Character.toUpperCase(strArr[strIdxEnd])) { | |||
| return false;// Character mismatch | |||
| } | |||
| } | |||
| 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 != '?') { | |||
| if (isCaseSensitive && ch != strArr[strIdxStart+i+j]) { | |||
| continue strLoop; | |||
| } | |||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||
| Character.toUpperCase(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; | |||
| } | |||
| /** | |||
| * Breaks a path up into a Vector of path elements, tokenizing on | |||
| * <code>File.separator</code>. | |||
| * | |||
| * @param path Path to tokenize. Must not be <code>null</code>. | |||
| * | |||
| * @return a Vector of path elements from the tokenized path | |||
| */ | |||
| public static Vector tokenizePath (String path) { | |||
| Vector ret = new Vector(); | |||
| StringTokenizer st = new StringTokenizer(path,File.separator); | |||
| while (st.hasMoreTokens()) { | |||
| ret.addElement(st.nextToken()); | |||
| } | |||
| return ret; | |||
| } | |||
| /** | |||
| * Helper method which corrects paths to use forward slashes. | |||
| * | |||
| * @param pattern the path pattern which needs correcting | |||
| * @return corrected pattern | |||
| */ | |||
| public static String fixPath(String pattern) { | |||
| return pattern.replace('/',File.separatorChar).replace('\\', | |||
| File.separatorChar); | |||
| } | |||
| /** | |||
| * Returns dependency information on these two files. If src has been | |||
| * modified later than target, it returns true. If target doesn't exist, | |||
| * it likewise returns true. Otherwise, target is newer than src and | |||
| * is not out of date, thus the method returns false. It also returns | |||
| * false if the src file doesn't even exist, since how could the | |||
| * target then be out of date. | |||
| * | |||
| * @param src the original file | |||
| * @param target the file being compared against | |||
| * @param granularity the amount in seconds of slack we will give in | |||
| * determining out of dateness | |||
| * @return whether the target is out of date | |||
| */ | |||
| public static boolean isOutOfDate(File src, File target, int granularity) { | |||
| if (!src.exists()) { | |||
| return false; | |||
| } | |||
| if (!target.exists()) { | |||
| return true; | |||
| } | |||
| if ((src.lastModified() - granularity) > target.lastModified()) { | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -0,0 +1,313 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 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.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||
| import org.apache.tools.ant.types.Parameter; | |||
| import org.apache.tools.ant.BuildException; | |||
| /** | |||
| * Selector that filters files based on their size. | |||
| * | |||
| * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> | |||
| * @since 1.5 | |||
| */ | |||
| public class SizeSelector extends BaseExtendSelector { | |||
| private long size = -1; | |||
| private long multiplier = 1; | |||
| private long sizelimit = -1; | |||
| private int cmp = 0; | |||
| public final static String SIZE_KEY = "millis"; | |||
| public final static String UNITS_KEY = "datetime"; | |||
| public final static String WHEN_KEY = "when"; | |||
| public SizeSelector() { | |||
| } | |||
| public String toString() { | |||
| StringBuffer buf = new StringBuffer("{sizeselector size: "); | |||
| buf.append(sizelimit); | |||
| buf.append("compare: "); | |||
| if (cmp == 0) { | |||
| buf.append("less"); | |||
| } | |||
| else if (cmp == 1) { | |||
| buf.append("more"); | |||
| } else { | |||
| buf.append("equal"); | |||
| } | |||
| buf.append("}"); | |||
| return buf.toString(); | |||
| } | |||
| /** | |||
| * A size selector needs to know what size to base its selecting on. | |||
| * This will be further modified by the multiplier to get an | |||
| * actual size limit. | |||
| * | |||
| * @param size the size to select against expressed in units | |||
| */ | |||
| public void setSize(long size) { | |||
| this.size = size; | |||
| if ((multiplier != 0) && (size > -1)) { | |||
| sizelimit = size * multiplier; | |||
| } | |||
| } | |||
| /** | |||
| * Sets the units to use for the comparison. This is a little | |||
| * complicated because common usage has created standards that | |||
| * play havoc with capitalization rules. Thus, some people will | |||
| * use "K" for indicating 1000's, when the SI standard calls for | |||
| * "k". Others have tried to introduce "K" as a multiple of 1024, | |||
| * but that falls down when you reach "M", since "m" is already | |||
| * defined as 0.001. | |||
| * <p> | |||
| * To get around this complexity, a number of standards bodies | |||
| * have proposed the 2^10 standard, and at least one has adopted | |||
| * it. But we are still left with a populace that isn't clear on | |||
| * how capitalization should work. | |||
| * <p> | |||
| * We therefore ignore capitalization as much as possible. | |||
| * Completely mixed case is not possible, but all upper and lower | |||
| * forms are accepted for all long and short forms. Since we have | |||
| * no need to work with the 0.001 case, this practice works here. | |||
| * <p> | |||
| * This function translates all the long and short forms that a | |||
| * unit prefix can occur in and translates them into a single | |||
| * multiplier. | |||
| * | |||
| * @param units The units to compare the size to, using an | |||
| * EnumeratedAttribute | |||
| */ | |||
| public void setUnits(ByteUnits units) { | |||
| int i = units.getIndex(); | |||
| multiplier = 0; | |||
| if ((i > -1) && (i < 4)) { | |||
| multiplier = 1000; | |||
| } | |||
| else if ((i > 3) && (i < 9)) { | |||
| multiplier = 1024; | |||
| } | |||
| else if ((i > 8) && (i < 13)) { | |||
| multiplier = 1000000; | |||
| } | |||
| else if ((i > 12) && (i < 18)) { | |||
| multiplier = 1048576; | |||
| } | |||
| else if ((i > 17) && (i < 22)) { | |||
| multiplier = 1000000000L; | |||
| } | |||
| else if ((i > 21) && (i < 27)) { | |||
| multiplier = 1073741824L; | |||
| } | |||
| else if ((i > 26) && (i < 31)) { | |||
| multiplier = 1000000000000L; | |||
| } | |||
| else if ((i > 30) && (i < 36)) { | |||
| multiplier = 1099511627776L; | |||
| } | |||
| if ((multiplier > 0) && (size > -1)) { | |||
| sizelimit = size * multiplier; | |||
| } | |||
| } | |||
| /** | |||
| * This specifies when the file should be selected, whether it be | |||
| * when the file matches a particular size, when it is smaller, | |||
| * or whether it is larger. | |||
| * | |||
| * @param cmp The comparison to perform, an EnumeratedAttribute | |||
| */ | |||
| public void setWhen(SizeComparisons cmp) { | |||
| this.cmp = cmp.getIndex(); | |||
| } | |||
| /** | |||
| * When using this as a dynamic selector, this method will be called. | |||
| * It translates each parameter into the appropriate setXXX() call. | |||
| * | |||
| * @param parameters the complete set of parameters for this selector | |||
| */ | |||
| public void setParameters(Parameter[] parameters) { | |||
| super.setParameters(parameters); | |||
| if (parameters != null) { | |||
| for (int i = 0; i < parameters.length; i++) { | |||
| String paramname = parameters[i].getName(); | |||
| if (SIZE_KEY.equalsIgnoreCase(paramname)) { | |||
| try { | |||
| setSize(new Long(parameters[i].getValue() | |||
| ).longValue()); | |||
| } catch (NumberFormatException nfe) { | |||
| setError("Invalid size setting " | |||
| + parameters[i].getValue()); | |||
| } | |||
| } | |||
| else if (UNITS_KEY.equalsIgnoreCase(paramname)) { | |||
| ByteUnits units = new ByteUnits(); | |||
| units.setValue(parameters[i].getValue()); | |||
| setUnits(units); | |||
| } | |||
| else if (WHEN_KEY.equalsIgnoreCase(paramname)) { | |||
| SizeComparisons cmp = new SizeComparisons(); | |||
| cmp.setValue(parameters[i].getValue()); | |||
| setWhen(cmp); | |||
| } | |||
| else { | |||
| setError("Invalid parameter " + paramname); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * <p>Checks to make sure all settings are kosher. In this case, it | |||
| * means that the size attribute has been set (to a positive value), | |||
| * that the multiplier has a valid setting, and that the size limit | |||
| * is valid. Since the latter is a calculated value, this can only | |||
| * fail due to a programming error. | |||
| * </p> | |||
| * <p>If a problem is detected, the setError() method is called. | |||
| * </p> | |||
| */ | |||
| public void verifySettings() { | |||
| if (size < 0) { | |||
| setError("The size attribute is required, and must be positive"); | |||
| } | |||
| else if (multiplier < 1) { | |||
| setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti"); | |||
| } | |||
| else if (sizelimit < 0) { | |||
| setError("Internal error: Code is not setting sizelimit correctly"); | |||
| } | |||
| } | |||
| /** | |||
| * The heart of the matter. This is where the selector gets to decide | |||
| * on the inclusion of a file in a particular fileset. | |||
| * | |||
| * @param basedir A java.io.File object for the base directory | |||
| * @param filename The name of the file to check | |||
| * @param file A File object for this filename | |||
| * @return whether the file should be selected or not | |||
| */ | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| // throw BuildException on error | |||
| validate(); | |||
| // Directory size never selected for | |||
| if (file.isDirectory()) { | |||
| return true; | |||
| } | |||
| if (cmp == 0) { | |||
| return (file.length() < sizelimit); | |||
| } | |||
| else if (cmp == 1) { | |||
| return (file.length() > sizelimit); | |||
| } | |||
| else { | |||
| return (file.length() == sizelimit); | |||
| } | |||
| } | |||
| /** | |||
| * Enumerated attribute with the values for units. | |||
| * <p> | |||
| * This treats the standard SI units as representing powers of ten, | |||
| * as they should. If you want the powers of 2 that approximate | |||
| * the SI units, use the first two characters followed by a | |||
| * <code>bi</code>. So 1024 (2^10) becomes <code>kibi</code>, | |||
| * 1048576 (2^20) becomes <code>mebi</code>, 1073741824 (2^30) | |||
| * becomes <code>gibi</code>, and so on. The symbols are also | |||
| * accepted, and these are the first letter capitalized followed | |||
| * by an <code>i</code>. <code>Ki</code>, <code>Mi</code>, | |||
| * <code>Gi</code>, and so on. Capitalization variations on these | |||
| * are also accepted. | |||
| * <p> | |||
| * This binary prefix system is approved by the IEC and appears on | |||
| * its way for approval by other agencies, but it is not an SI | |||
| * standard. It disambiguates things for us, though. | |||
| */ | |||
| public static class ByteUnits extends EnumeratedAttribute { | |||
| public String[] getValues() { | |||
| return new String[] {"K", "k", "kilo", "KILO", | |||
| "Ki", "KI", "ki", "kibi", "KIBI", | |||
| "M", "m", "mega", "MEGA", | |||
| "Mi", "MI", "mi", "mebi", "MEBI", | |||
| "G", "g", "giga", "GIGA", | |||
| "Gi", "GI", "gi", "gibi", "GIBI", | |||
| "T", "t", "tera", "TERA", | |||
| /* You wish! */ "Ti", "TI", "ti", "tebi", "TEBI" | |||
| }; | |||
| } | |||
| } | |||
| /** | |||
| * Enumerated attribute with the values for size comparison. | |||
| */ | |||
| public static class SizeComparisons extends EnumeratedAttribute { | |||
| public String[] getValues() { | |||
| return new String[] {"less", "more", "equal"}; | |||
| } | |||
| } | |||
| } | |||