From 3094f588408bd4c0805d305db7b68aecb4a60e1c Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Tue, 1 May 2018 10:30:21 +0530 Subject: [PATCH] bz-62313 Enhance "linecontains" filter to allow any of the "contains" to match instead of all --- WHATSNEW | 5 ++ manual/Types/filterchain.html | 10 +++ src/etc/testcases/filters/build.xml | 27 ++++++++ .../linecontains-matchany-negate.test | 2 + .../expected/linecontains-matchany.test | 5 ++ .../tools/ant/filters/LineContains.java | 62 ++++++++++++++++++- .../tools/ant/filters/LineContainsTest.java | 26 ++++++++ 7 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/etc/testcases/filters/expected/linecontains-matchany-negate.test create mode 100644 src/etc/testcases/filters/expected/linecontains-matchany.test diff --git a/WHATSNEW b/WHATSNEW index a2d325e51..09303281f 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -46,6 +46,11 @@ Other changes: properties with values taken as snapshots from the availableProcessors, freeMemory, maxMemory and totalMemory methods of the Java Runtime class. + + * linecontains filter now has a new "matchAny" attribute which when + set to "true" allows any (instead of all) of the user-specified + strings to be present in the line. + Bugzilla Report 62313 Changes from Ant 1.10.2 TO Ant 1.10.3 ===================================== diff --git a/manual/Types/filterchain.html b/manual/Types/filterchain.html index f5266e5d5..d0db8ee48 100644 --- a/manual/Types/filterchain.html +++ b/manual/Types/filterchain.html @@ -318,6 +318,16 @@ the source distribution).

Whether to select non-matching lines only. Since Ant 1.7 No + + matchAny + If false, then all the strings are expected to be present in the line. If + true, then the presence of any of the strings in the line, is considered + a successful match. Defaults to false. +
+ Since Ant 1.10.4 + + No +

Example

diff --git a/src/etc/testcases/filters/build.xml b/src/etc/testcases/filters/build.xml index dc32ad05b..eb4dcdbf0 100644 --- a/src/etc/testcases/filters/build.xml +++ b/src/etc/testcases/filters/build.xml @@ -145,4 +145,31 @@ File was modified + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/etc/testcases/filters/expected/linecontains-matchany-negate.test b/src/etc/testcases/filters/expected/linecontains-matchany-negate.test new file mode 100644 index 000000000..9dacab951 --- /dev/null +++ b/src/etc/testcases/filters/expected/linecontains-matchany-negate.test @@ -0,0 +1,2 @@ +This is line 4 with gamma. +This is line 6 with delta. diff --git a/src/etc/testcases/filters/expected/linecontains-matchany.test b/src/etc/testcases/filters/expected/linecontains-matchany.test new file mode 100644 index 000000000..0a472b2b7 --- /dev/null +++ b/src/etc/testcases/filters/expected/linecontains-matchany.test @@ -0,0 +1,5 @@ +This is line 1 with alpha. +This is line 2 with beta. +This is line 3 with beta. +This is line 5 with beta. +This is line 7 with beta. diff --git a/src/main/org/apache/tools/ant/filters/LineContains.java b/src/main/org/apache/tools/ant/filters/LineContains.java index 5c3609cb6..b55b8dd1c 100644 --- a/src/main/org/apache/tools/ant/filters/LineContains.java +++ b/src/main/org/apache/tools/ant/filters/LineContains.java @@ -25,7 +25,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Parameter; /** - * Filter which includes only those lines that contain all the user-specified + * Filter which includes only those lines that contain the user-specified * strings. * * Example: @@ -45,6 +45,19 @@ import org.apache.tools.ant.types.Parameter; * This will include only those lines that contain foo and * bar. * + * Starting Ant 1.10.4, the {@code matchAny} attribute can be used to control whether any one + * of the user-specified strings is expected to be contained in the line or all + * of them are expected to be contained. + * + * For example: + * + *
<linecontains matchAny="true">
+ *  *   <contains value="foo">
+ *  *   <contains value="bar">
+ *  * </linecontains>
+ * + * This will include only those lines that contain either foo or bar. + * */ public final class LineContains extends BaseParamFilterReader @@ -67,6 +80,8 @@ public final class LineContains private boolean negate = false; + private boolean matchAny = false; + /** * Constructor for "dummy" instances. * @@ -116,9 +131,24 @@ public final class LineContains for (line = readLine(); line != null; line = readLine()) { boolean matches = true; - for (int i = 0; matches && i < containsSize; i++) { - String containsStr = contains.elementAt(i); + for (int i = 0; i < containsSize; i++) { + final String containsStr = contains.elementAt(i); matches = line.contains(containsStr); + if (!matches) { + if (this.matchAny) { + // this one didn't match, but we are expected to have + // any one of them match. so try next + continue; + } else { + // all were expected to match, but this one didn't. + // so no point checking the rest + break; + } + } else if (this.matchAny) { + // we were expected to match any of the contains + // and this one did. so no more checks needed + break; + } } if (matches ^ isNegated()) { break; @@ -157,6 +187,31 @@ public final class LineContains return negate; } + /** + * + * @param matchAny True if this {@link LineContains} is considered a match, + * if {@code any} of the {@code contains} value match. False + * if {@code all} of the {@code contains} value are expected + * to match + * @since Ant 1.10.4 + * + */ + public void setMatchAny(final boolean matchAny) { + this.matchAny = matchAny; + } + + /** + * @return Returns true if this {@link LineContains} is considered a match, + * if {@code any} of the {@code contains} value match. False + * if {@code all} of the {@code contains} value are expected + * to match + * + * @since Ant 1.10.4 + */ + public boolean isMatchAny() { + return this.matchAny; + } + /** * Sets the vector of words which must be contained within a line read * from the original stream in order for it to match this filter. @@ -195,6 +250,7 @@ public final class LineContains LineContains newFilter = new LineContains(rdr); newFilter.setContains(getContains()); newFilter.setNegate(isNegated()); + newFilter.setMatchAny(isMatchAny()); return newFilter; } diff --git a/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java b/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java index 5127c8639..e28c316ea 100644 --- a/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java +++ b/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java @@ -53,4 +53,30 @@ public class LineContainsTest { buildRule.executeTarget("testNegateLineContains"); } + /** + * Tests that the {@code matchAny} attribute of {@link LineContains} works as expected + * + * @throws IOException + */ + @Test + public void testLineContainsMatchAny() throws IOException { + buildRule.executeTarget("testMatchAny"); + File expected = buildRule.getProject().resolveFile("expected/linecontains-matchany.test"); + File result = new File(buildRule.getProject().getProperty("output"), "linecontains.test"); + assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result)); + } + + /** + * Tests that the {@code matchAny} attribute when used with the {@code negate} attribute + * of {@link LineContains} works as expected + * + * @throws IOException + */ + @Test + public void testLineContainsMatchAnyNegate() throws IOException { + buildRule.executeTarget("testMatchAnyNegate"); + File expected = buildRule.getProject().resolveFile("expected/linecontains-matchany-negate.test"); + File result = new File(buildRule.getProject().getProperty("output"), "linecontains.test"); + assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result)); + } }