diff --git a/WHATSNEW b/WHATSNEW index 2ecbcd468..f0aaec5bb 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -257,6 +257,16 @@ Other changes: write. Bugzilla Report 45081. + * The filename file selector has a new attribute regex that allows + files to be selected by matching their names against a regular + expression. + Bugzilla Report 45284 + + * The name resource selector has a new attribute regex that allows + resources to be selected by matching their names against a regular + expression. + Bugzilla Report 45284 + Changes from Ant 1.7.0 TO Ant 1.7.1 ============================================= diff --git a/docs/manual/CoreTypes/resources.html b/docs/manual/CoreTypes/resources.html index 06ea92df3..d0a8281b5 100644 --- a/docs/manual/CoreTypes/resources.html +++ b/docs/manual/CoreTypes/resources.html @@ -503,8 +503,14 @@ platforms. name - The name pattern to test - Yes + The name pattern to test using standard Ant + patterns. + Exactly one of + the two + + + regex + The regular expression matching files to select. casesensitive diff --git a/docs/manual/CoreTypes/selectors.html b/docs/manual/CoreTypes/selectors.html index edbe3871f..eae12ae63 100644 --- a/docs/manual/CoreTypes/selectors.html +++ b/docs/manual/CoreTypes/selectors.html @@ -435,7 +435,12 @@ The name of files to select. The name parameter can contain the standard Ant wildcard characters. - Yes + Exactly one of + the two + + + regex + The regular expression matching files to select. casesensitive diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Name.java b/src/main/org/apache/tools/ant/types/resources/selectors/Name.java index 30717cb27..12e87ebf2 100755 --- a/src/main/org/apache/tools/ant/types/resources/selectors/Name.java +++ b/src/main/org/apache/tools/ant/types/resources/selectors/Name.java @@ -17,17 +17,31 @@ */ package org.apache.tools.ant.types.resources.selectors; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.RegularExpression; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.selectors.SelectorUtils; +import org.apache.tools.ant.util.regexp.Regexp; /** * Name ResourceSelector. * @since Ant 1.7 */ public class Name implements ResourceSelector { + private String regex = null; private String pattern; private boolean cs = true; + // caches for performance reasons + private RegularExpression reg; + private Regexp expression; + + private Project project; + + public void setProject(Project p) { + project = p; + } + /** * Set the pattern to compare names against. * @param n the pattern String to set. @@ -44,6 +58,23 @@ public class Name implements ResourceSelector { return pattern; } + /** + * Set the regular expression to compare names against. + * @param r the regex to set. + */ + public void setRegex(String r) { + regex = r; + reg = null; + } + + /** + * Get the regular expression used by this Name ResourceSelector. + * @return the String selection pattern. + */ + public String getRegex() { + return regex; + } + /** * Set whether the name comparisons are case-sensitive. * @param b boolean case-sensitivity flag. @@ -67,11 +98,27 @@ public class Name implements ResourceSelector { */ public boolean isSelected(Resource r) { String n = r.getName(); - if (SelectorUtils.match(pattern, n, cs)) { + if (matches(n)) { return true; } String s = r.toString(); - return s.equals(n) ? false : SelectorUtils.match(pattern, s, cs); + return s.equals(n) ? false : matches(s); } + private boolean matches(String name) { + if (pattern != null) { + return SelectorUtils.match(pattern, name, cs); + } else { + if (reg == null) { + reg = new RegularExpression(); + reg.setPattern(regex); + expression = reg.getRegexp(project); + } + int options = Regexp.MATCH_DEFAULT; + if (!cs) { + options |= Regexp.MATCH_CASE_INSENSITIVE; + } + return expression.matches(name, options); + } + } } diff --git a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java index dc5d4ecbd..83f51dd13 100644 --- a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java @@ -22,6 +22,8 @@ import java.io.File; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.RegularExpression; +import org.apache.tools.ant.util.regexp.Regexp; /** * Selector that filters files based on the filename. @@ -31,6 +33,7 @@ import org.apache.tools.ant.types.Parameter; public class FilenameSelector extends BaseExtendSelector { private String pattern = null; + private String regex = null; private boolean casesensitive = true; private boolean negated = false; @@ -40,6 +43,12 @@ public class FilenameSelector extends BaseExtendSelector { public static final String CASE_KEY = "casesensitive"; /** Used for parameterized custom selector */ public static final String NEGATE_KEY = "negate"; + /** Used for parameterized custom selector */ + public static final String REGEX_KEY = "regex"; + + // caches for performance reasons + private RegularExpression reg; + private Regexp expression; /** * Creates a new FilenameSelector instance. @@ -53,19 +62,14 @@ public class FilenameSelector extends BaseExtendSelector { */ public String toString() { StringBuffer buf = new StringBuffer("{filenameselector name: "); + if (pattern != null) { 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"); + if (regex != null) { + buf.append(regex).append(" [as regular expression]"); } + buf.append(" negate: ").append(negated); + buf.append(" casesensitive: ").append(casesensitive); buf.append("}"); return buf.toString(); } @@ -86,6 +90,17 @@ public class FilenameSelector extends BaseExtendSelector { this.pattern = pattern; } + /** + * The regular expression the file name will be matched against. + * + * @param pattern the regular expression that any filename must match + * against in order to be selected. + */ + public void setRegex(String pattern) { + this.regex = pattern; + this.reg = null; + } + /** * Whether to ignore case when checking filenames. * @@ -125,6 +140,8 @@ public class FilenameSelector extends BaseExtendSelector { parameters[i].getValue())); } else if (NEGATE_KEY.equalsIgnoreCase(paramname)) { setNegate(Project.toBoolean(parameters[i].getValue())); + } else if (REGEX_KEY.equalsIgnoreCase(paramname)) { + setRegex(parameters[i].getValue()); } else { setError("Invalid parameter " + paramname); } @@ -138,8 +155,10 @@ public class FilenameSelector extends BaseExtendSelector { * */ public void verifySettings() { - if (pattern == null) { - setError("The name attribute is required"); + if (pattern == null && regex == null) { + setError("The name or regex attribute is required"); + } else if (pattern != null && regex != null) { + setError("Only one of name and regex attribute is allowed"); } } @@ -157,9 +176,21 @@ public class FilenameSelector extends BaseExtendSelector { */ public boolean isSelected(File basedir, String filename, File file) { validate(); - + if (pattern != null) { return (SelectorUtils.matchPath(pattern, filename, casesensitive) == !(negated)); + } else { + if (reg == null) { + reg = new RegularExpression(); + reg.setPattern(regex); + expression = reg.getRegexp(getProject()); + } + int options = Regexp.MATCH_DEFAULT; + if (!casesensitive) { + options |= Regexp.MATCH_CASE_INSENSITIVE; + } + return expression.matches(filename, options) == !negated; + } } } diff --git a/src/tests/antunit/types/resources/selectors/name-test.xml b/src/tests/antunit/types/resources/selectors/name-test.xml new file mode 100644 index 000000000..ea208bf46 --- /dev/null +++ b/src/tests/antunit/types/resources/selectors/name-test.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/antunit/types/selectors/filename-test.xml b/src/tests/antunit/types/selectors/filename-test.xml new file mode 100644 index 000000000..06e180fbb --- /dev/null +++ b/src/tests/antunit/types/selectors/filename-test.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java index 2083d6341..11836a22e 100644 --- a/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java +++ b/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java @@ -51,7 +51,7 @@ public class FilenameSelectorTest extends BaseSelectorTest { s.isSelected(basedir,filenames[0],files[0]); fail("FilenameSelector did not check for required fields"); } catch (BuildException be1) { - assertEquals("The name attribute is required", be1.getMessage()); + assertEquals("The name or regex attribute is required", be1.getMessage()); } s = (FilenameSelector)getInstance();