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"}; | |||||
} | |||||
} | |||||
} | |||||