git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@685887 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -257,6 +257,16 @@ Other changes: | |||||
| write. | write. | ||||
| Bugzilla Report 45081. | 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 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
| ============================================= | ============================================= | ||||
| @@ -503,8 +503,14 @@ platforms. | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td valign="top">name</td> | <td valign="top">name</td> | ||||
| <td valign="top">The name pattern to test</td> | |||||
| <td align="center" valign="top">Yes</td> | |||||
| <td valign="top">The name pattern to test using standard Ant | |||||
| patterns.</td> | |||||
| <td valign="top" align="center" rowspan="2">Exactly one of | |||||
| the two</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">regex</td> | |||||
| <td valign="top">The regular expression matching files to select.</td> | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td valign="top">casesensitive</td> | <td valign="top">casesensitive</td> | ||||
| @@ -435,7 +435,12 @@ | |||||
| <td valign="top">The name of files to select. The name parameter | <td valign="top">The name of files to select. The name parameter | ||||
| can contain the standard Ant wildcard characters. | can contain the standard Ant wildcard characters. | ||||
| </td> | </td> | ||||
| <td valign="top" align="center">Yes</td> | |||||
| <td valign="top" align="center" rowspan="2">Exactly one of | |||||
| the two</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">regex</td> | |||||
| <td valign="top">The regular expression matching files to select.</td> | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td valign="top">casesensitive</td> | <td valign="top">casesensitive</td> | ||||
| @@ -17,17 +17,31 @@ | |||||
| */ | */ | ||||
| package org.apache.tools.ant.types.resources.selectors; | 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.Resource; | ||||
| import org.apache.tools.ant.types.selectors.SelectorUtils; | import org.apache.tools.ant.types.selectors.SelectorUtils; | ||||
| import org.apache.tools.ant.util.regexp.Regexp; | |||||
| /** | /** | ||||
| * Name ResourceSelector. | * Name ResourceSelector. | ||||
| * @since Ant 1.7 | * @since Ant 1.7 | ||||
| */ | */ | ||||
| public class Name implements ResourceSelector { | public class Name implements ResourceSelector { | ||||
| private String regex = null; | |||||
| private String pattern; | private String pattern; | ||||
| private boolean cs = true; | 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. | * Set the pattern to compare names against. | ||||
| * @param n the pattern String to set. | * @param n the pattern String to set. | ||||
| @@ -44,6 +58,23 @@ public class Name implements ResourceSelector { | |||||
| return pattern; | 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. | * Set whether the name comparisons are case-sensitive. | ||||
| * @param b boolean case-sensitivity flag. | * @param b boolean case-sensitivity flag. | ||||
| @@ -67,11 +98,27 @@ public class Name implements ResourceSelector { | |||||
| */ | */ | ||||
| public boolean isSelected(Resource r) { | public boolean isSelected(Resource r) { | ||||
| String n = r.getName(); | String n = r.getName(); | ||||
| if (SelectorUtils.match(pattern, n, cs)) { | |||||
| if (matches(n)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| String s = r.toString(); | 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); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -22,6 +22,8 @@ import java.io.File; | |||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.types.Parameter; | 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. | * Selector that filters files based on the filename. | ||||
| @@ -31,6 +33,7 @@ import org.apache.tools.ant.types.Parameter; | |||||
| public class FilenameSelector extends BaseExtendSelector { | public class FilenameSelector extends BaseExtendSelector { | ||||
| private String pattern = null; | private String pattern = null; | ||||
| private String regex = null; | |||||
| private boolean casesensitive = true; | private boolean casesensitive = true; | ||||
| private boolean negated = false; | private boolean negated = false; | ||||
| @@ -40,6 +43,12 @@ public class FilenameSelector extends BaseExtendSelector { | |||||
| public static final String CASE_KEY = "casesensitive"; | public static final String CASE_KEY = "casesensitive"; | ||||
| /** Used for parameterized custom selector */ | /** Used for parameterized custom selector */ | ||||
| public static final String NEGATE_KEY = "negate"; | 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 <code>FilenameSelector</code> instance. | * Creates a new <code>FilenameSelector</code> instance. | ||||
| @@ -53,19 +62,14 @@ public class FilenameSelector extends BaseExtendSelector { | |||||
| */ | */ | ||||
| public String toString() { | public String toString() { | ||||
| StringBuffer buf = new StringBuffer("{filenameselector name: "); | StringBuffer buf = new StringBuffer("{filenameselector name: "); | ||||
| if (pattern != null) { | |||||
| buf.append(pattern); | 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("}"); | buf.append("}"); | ||||
| return buf.toString(); | return buf.toString(); | ||||
| } | } | ||||
| @@ -86,6 +90,17 @@ public class FilenameSelector extends BaseExtendSelector { | |||||
| this.pattern = pattern; | 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. | * Whether to ignore case when checking filenames. | ||||
| * | * | ||||
| @@ -125,6 +140,8 @@ public class FilenameSelector extends BaseExtendSelector { | |||||
| parameters[i].getValue())); | parameters[i].getValue())); | ||||
| } else if (NEGATE_KEY.equalsIgnoreCase(paramname)) { | } else if (NEGATE_KEY.equalsIgnoreCase(paramname)) { | ||||
| setNegate(Project.toBoolean(parameters[i].getValue())); | setNegate(Project.toBoolean(parameters[i].getValue())); | ||||
| } else if (REGEX_KEY.equalsIgnoreCase(paramname)) { | |||||
| setRegex(parameters[i].getValue()); | |||||
| } else { | } else { | ||||
| setError("Invalid parameter " + paramname); | setError("Invalid parameter " + paramname); | ||||
| } | } | ||||
| @@ -138,8 +155,10 @@ public class FilenameSelector extends BaseExtendSelector { | |||||
| * | * | ||||
| */ | */ | ||||
| public void verifySettings() { | 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) { | public boolean isSelected(File basedir, String filename, File file) { | ||||
| validate(); | validate(); | ||||
| if (pattern != null) { | |||||
| return (SelectorUtils.matchPath(pattern, filename, | return (SelectorUtils.matchPath(pattern, filename, | ||||
| casesensitive) == !(negated)); | 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; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,64 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project xmlns:au="antlib:org.apache.ant.antunit" default="antunit" | |||||
| xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors"> | |||||
| <import file="../../../antunit-base.xml" /> | |||||
| <property name="dir" location="testdir"/> | |||||
| <property name="file" value="testfile"/> | |||||
| <target name="createTestdir"> | |||||
| <mkdir dir="${dir}"/> | |||||
| <touch file="${dir}/${file}"/> | |||||
| </target> | |||||
| <target name="tearDown"> | |||||
| <delete dir="${dir}"/> | |||||
| </target> | |||||
| <target name="testPattern" depends="createTestdir"> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="1"> | |||||
| <restrict> | |||||
| <fileset dir="${dir}"/> | |||||
| <rsel:name name="*"/> | |||||
| </restrict> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="0"> | |||||
| <restrict> | |||||
| <fileset dir="${dir}"/> | |||||
| <rsel:name name=".*"/> | |||||
| </restrict> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| </target> | |||||
| <target name="testRegex" depends="createTestdir"> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="1"> | |||||
| <restrict> | |||||
| <fileset dir="${dir}"/> | |||||
| <rsel:name regex=".*"/> | |||||
| </restrict> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,74 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"> | |||||
| <import file="../../antunit-base.xml" /> | |||||
| <property name="dir" location="testdir"/> | |||||
| <property name="file" value="testfile"/> | |||||
| <target name="createTestdir"> | |||||
| <mkdir dir="${dir}"/> | |||||
| <touch file="${dir}/${file}"/> | |||||
| </target> | |||||
| <target name="tearDown"> | |||||
| <delete dir="${dir}"/> | |||||
| </target> | |||||
| <target name="testPattern" depends="createTestdir"> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="1"> | |||||
| <fileset dir="${dir}"> | |||||
| <filename name="*"/> | |||||
| </fileset> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="0"> | |||||
| <fileset dir="${dir}"> | |||||
| <filename name="*" negate="true"/> | |||||
| </fileset> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="0"> | |||||
| <fileset dir="${dir}"> | |||||
| <filename name=".*"/> | |||||
| </fileset> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| </target> | |||||
| <target name="testRegex" depends="createTestdir"> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="1"> | |||||
| <fileset dir="${dir}"> | |||||
| <filename regex=".*"/> | |||||
| </fileset> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| <au:assertTrue> | |||||
| <resourcecount when="equal" count="0"> | |||||
| <fileset dir="${dir}"> | |||||
| <filename regex=".*" negate="true"/> | |||||
| </fileset> | |||||
| </resourcecount> | |||||
| </au:assertTrue> | |||||
| </target> | |||||
| </project> | |||||
| @@ -51,7 +51,7 @@ public class FilenameSelectorTest extends BaseSelectorTest { | |||||
| s.isSelected(basedir,filenames[0],files[0]); | s.isSelected(basedir,filenames[0],files[0]); | ||||
| fail("FilenameSelector did not check for required fields"); | fail("FilenameSelector did not check for required fields"); | ||||
| } catch (BuildException be1) { | } catch (BuildException be1) { | ||||
| assertEquals("The name attribute is required", be1.getMessage()); | |||||
| assertEquals("The name or regex attribute is required", be1.getMessage()); | |||||
| } | } | ||||
| s = (FilenameSelector)getInstance(); | s = (FilenameSelector)getInstance(); | ||||