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