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: | 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 | * 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 | 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 | 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.FileScanner; | ||||
| import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.types.selectors.*; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Stack; | import java.util.Stack; | ||||
| @@ -70,23 +71,26 @@ import java.util.Enumeration; | |||||
| * | * | ||||
| * <p>Common base class for DirSet and FileSet.</p> | * <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:stefano@apache.org">Stefano Mazzocchi</a> | ||||
| * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</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:jon@clearink.com">Jon S. Stevens</a> | ||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</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: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 PatternSet defaultPatterns = new PatternSet(); | ||||
| private Vector additionalPatterns = new Vector(); | private Vector additionalPatterns = new Vector(); | ||||
| private Vector selectors = new Vector(); | |||||
| private File dir; | private File dir; | ||||
| private boolean useDefaultExcludes = true; | private boolean useDefaultExcludes = true; | ||||
| private boolean isCaseSensitive = true; | private boolean isCaseSensitive = true; | ||||
| public AbstractFileSet() { | public AbstractFileSet() { | ||||
| super(); | super(); | ||||
| } | } | ||||
| @@ -104,7 +108,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| * Makes this instance in effect a reference to another instance. | * Makes this instance in effect a reference to another instance. | ||||
| * | * | ||||
| * <p>You must not set another attribute or nest elements inside | * <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 { | public void setRefid(Reference r) throws BuildException { | ||||
| if (dir != null || defaultPatterns.hasPatterns()) { | if (dir != null || defaultPatterns.hasPatterns()) { | ||||
| @@ -158,7 +162,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| } | } | ||||
| return defaultPatterns.createInclude(); | return defaultPatterns.createInclude(); | ||||
| } | } | ||||
| /** | /** | ||||
| * add a name entry on the include files list | * add a name entry on the include files list | ||||
| */ | */ | ||||
| @@ -168,7 +172,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| } | } | ||||
| return defaultPatterns.createIncludesFile(); | return defaultPatterns.createIncludesFile(); | ||||
| } | } | ||||
| /** | /** | ||||
| * add a name entry on the exclude list | * add a name entry on the exclude list | ||||
| */ | */ | ||||
| @@ -188,7 +192,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| } | } | ||||
| return defaultPatterns.createExcludesFile(); | return defaultPatterns.createExcludesFile(); | ||||
| } | } | ||||
| /** | /** | ||||
| * Appends <code>includes</code> to the current list of include | * Appends <code>includes</code> to the current list of include | ||||
| * patterns. | * patterns. | ||||
| @@ -224,7 +228,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| /** | /** | ||||
| * Sets the name of the file containing the includes patterns. | * 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 { | public void setIncludesfile(File incl) throws BuildException { | ||||
| if (isReference()) { | if (isReference()) { | ||||
| @@ -237,7 +241,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| /** | /** | ||||
| * Sets the name of the file containing the includes patterns. | * 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 { | public void setExcludesfile(File excl) throws BuildException { | ||||
| if (isReference()) { | if (isReference()) { | ||||
| @@ -250,7 +254,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| /** | /** | ||||
| * Sets whether default exclusions should be used or not. | * 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 | * should be used, "false"|"off"|"no" when they | ||||
| * shouldn't be used. | * shouldn't be used. | ||||
| */ | */ | ||||
| @@ -272,8 +276,8 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| this.isCaseSensitive = isCaseSensitive; | this.isCaseSensitive = isCaseSensitive; | ||||
| } | } | ||||
| /** | /** | ||||
| * sets the name used for this datatype instance. | * sets the name used for this datatype instance. | ||||
| */ | */ | ||||
| @@ -290,14 +294,14 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| String classname = getClass().getName(); | String classname = getClass().getName(); | ||||
| int dotIndex = classname.lastIndexOf("."); | int dotIndex = classname.lastIndexOf("."); | ||||
| if (dotIndex == -1) { | if (dotIndex == -1) { | ||||
| return classname; | 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(); | ds.scan(); | ||||
| return ds; | return ds; | ||||
| } | } | ||||
| public void setupDirectoryScanner(FileScanner ds, Project p) { | public void setupDirectoryScanner(FileScanner ds, Project p) { | ||||
| if (ds == null) { | if (ds == null) { | ||||
| throw new IllegalArgumentException("ds cannot be null"); | throw new IllegalArgumentException("ds cannot be null"); | ||||
| } | } | ||||
| ds.setBasedir(dir); | ds.setBasedir(dir); | ||||
| final int count = additionalPatterns.size(); | final int count = additionalPatterns.size(); | ||||
| @@ -340,11 +344,16 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| defaultPatterns.append((PatternSet) o, p); | 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); | " with " + defaultPatterns, Project.MSG_DEBUG); | ||||
| ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | ||||
| ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | ||||
| if (ds instanceof SelectorScanner) { | |||||
| SelectorScanner ss = (SelectorScanner)ds; | |||||
| ss.setSelectors(getSelectors(p)); | |||||
| } | |||||
| if (useDefaultExcludes) { | if (useDefaultExcludes) { | ||||
| ds.addDefaultExcludes(); | ds.addDefaultExcludes(); | ||||
| } | } | ||||
| @@ -353,7 +362,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| /** | /** | ||||
| * Performs the check for circular references and returns the | * Performs the check for circular references and returns the | ||||
| * referenced FileSet. | |||||
| * referenced FileSet. | |||||
| */ | */ | ||||
| protected AbstractFileSet getRef(Project p) { | protected AbstractFileSet getRef(Project p) { | ||||
| if (!checked) { | if (!checked) { | ||||
| @@ -361,10 +370,10 @@ public abstract class AbstractFileSet extends DataType implements Cloneable { | |||||
| stk.push(this); | stk.push(this); | ||||
| dieOnCircularReference(stk, p); | dieOnCircularReference(stk, p); | ||||
| } | } | ||||
| Object o = ref.getReferencedObject(p); | Object o = ref.getReferencedObject(p); | ||||
| if (!getClass().isAssignableFrom(o.getClass())) { | if (!getClass().isAssignableFrom(o.getClass())) { | ||||
| String msg = ref.getRefId() + " doesn\'t denote a " | |||||
| String msg = ref.getRefId() + " doesn\'t denote a " | |||||
| + getDataTypeName(); | + getDataTypeName(); | ||||
| throw new BuildException(msg); | throw new BuildException(msg); | ||||
| } else { | } 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"}; | |||||
| } | |||||
| } | |||||
| } | |||||