Browse Source

Selectors feature to specify sophisticated selection criteria to create filesets.

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-ffa450edef68
master
Magesh Umasankar 23 years ago
parent
commit
f61c1bcd3a
24 changed files with 4327 additions and 443 deletions
  1. +3
    -0
      WHATSNEW
  2. +236
    -420
      src/main/org/apache/tools/ant/DirectoryScanner.java
  3. +181
    -23
      src/main/org/apache/tools/ant/types/AbstractFileSet.java
  4. +111
    -0
      src/main/org/apache/tools/ant/types/selectors/AndSelector.java
  5. +121
    -0
      src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
  6. +143
    -0
      src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
  7. +312
    -0
      src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
  8. +197
    -0
      src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
  9. +250
    -0
      src/main/org/apache/tools/ant/types/selectors/DateSelector.java
  10. +186
    -0
      src/main/org/apache/tools/ant/types/selectors/DependSelector.java
  11. +209
    -0
      src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
  12. +78
    -0
      src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java
  13. +213
    -0
      src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
  14. +85
    -0
      src/main/org/apache/tools/ant/types/selectors/FileSelector.java
  15. +195
    -0
      src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
  16. +135
    -0
      src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
  17. +112
    -0
      src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
  18. +99
    -0
      src/main/org/apache/tools/ant/types/selectors/NotSelector.java
  19. +112
    -0
      src/main/org/apache/tools/ant/types/selectors/OrSelector.java
  20. +208
    -0
      src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
  21. +178
    -0
      src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java
  22. +86
    -0
      src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java
  23. +564
    -0
      src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
  24. +313
    -0
      src/main/org/apache/tools/ant/types/selectors/SizeSelector.java

+ 3
- 0
WHATSNEW View File

@@ -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


+ 236
- 420
src/main/org/apache/tools/ant/DirectoryScanner.java
File diff suppressed because it is too large
View File


+ 181
- 23
src/main/org/apache/tools/ant/types/AbstractFileSet.java View File

@@ -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);
}

}

+ 111
- 0
src/main/org/apache/tools/ant/types/selectors/AndSelector.java View File

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

}


+ 121
- 0
src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java View File

@@ -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;

}


+ 143
- 0
src/main/org/apache/tools/ant/types/selectors/BaseSelector.java View File

@@ -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);

}



+ 312
- 0
src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java View 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);
}

}


+ 197
- 0
src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java View File

@@ -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);
}
}
}

}


+ 250
- 0
src/main/org/apache/tools/ant/types/selectors/DateSelector.java View File

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

}



+ 186
- 0
src/main/org/apache/tools/ant/types/selectors/DependSelector.java View File

@@ -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);
}

}


+ 209
- 0
src/main/org/apache/tools/ant/types/selectors/DepthSelector.java View File

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

}


+ 78
- 0
src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java View File

@@ -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.
}


+ 213
- 0
src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java View File

@@ -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);
}

}


+ 85
- 0
src/main/org/apache/tools/ant/types/selectors/FileSelector.java View 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;

}


+ 195
- 0
src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java View File

@@ -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);
}

}


+ 135
- 0
src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java View File

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


+ 112
- 0
src/main/org/apache/tools/ant/types/selectors/NoneSelector.java View File

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

}


+ 99
- 0
src/main/org/apache/tools/ant/types/selectors/NotSelector.java View File

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

}


+ 112
- 0
src/main/org/apache/tools/ant/types/selectors/OrSelector.java View File

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

}


+ 208
- 0
src/main/org/apache/tools/ant/types/selectors/PresentSelector.java View File

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

}


+ 178
- 0
src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java View File

@@ -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);

}


+ 86
- 0
src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java View File

@@ -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();


}

+ 564
- 0
src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java View File

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

}


+ 313
- 0
src/main/org/apache/tools/ant/types/selectors/SizeSelector.java View File

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

}


Loading…
Cancel
Save