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. | |||
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 | |||
============================================= | |||
@@ -503,8 +503,14 @@ platforms. | |||
</tr> | |||
<tr> | |||
<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> | |||
<td valign="top">casesensitive</td> | |||
@@ -435,7 +435,12 @@ | |||
<td valign="top">The name of files to select. The name parameter | |||
can contain the standard Ant wildcard characters. | |||
</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> | |||
<td valign="top">casesensitive</td> | |||
@@ -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); | |||
} | |||
} | |||
} |
@@ -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 <code>FilenameSelector</code> 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; | |||
} | |||
} | |||
} | |||
@@ -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]); | |||
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(); | |||