@@ -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 | |||
===================================== | |||
@@ -318,6 +318,16 @@ the source distribution).</p> | |||
<td>Whether to select <em>non-</em>matching lines only. <em>Since Ant 1.7</em></td> | |||
<td>No</td> | |||
</tr> | |||
<tr> | |||
<td>matchAny</td> | |||
<td>If <em>false</em>, then all the strings are expected to be present in the line. If | |||
<em>true</em>, then the presence of any of the strings in the line, is considered | |||
a successful match. Defaults to <em>false</em>. | |||
<br/> | |||
<em>Since Ant 1.10.4</em> | |||
</td> | |||
<td>No</td> | |||
</tr> | |||
</table> | |||
<p> | |||
<h4>Example</h4> | |||
@@ -145,4 +145,31 @@ | |||
<fail unless="filterchain.files.are.same">File was modified</fail> | |||
</target> | |||
<target name="testMatchAny" depends="setUp"> | |||
<copy todir="${output}"> | |||
<fileset dir="input"> | |||
<include name="linecontains.test"/> | |||
</fileset> | |||
<filterchain> | |||
<linecontains matchAny="true"> | |||
<contains value="beta"/> | |||
<contains value="alpha"/> | |||
</linecontains> | |||
</filterchain> | |||
</copy> | |||
</target> | |||
<target name="testMatchAnyNegate" depends="setUp"> | |||
<copy todir="${output}"> | |||
<fileset dir="input"> | |||
<include name="linecontains.test"/> | |||
</fileset> | |||
<filterchain> | |||
<linecontains matchAny="true" negate="true"> | |||
<contains value="beta"/> | |||
<contains value="alpha"/> | |||
</linecontains> | |||
</filterchain> | |||
</copy> | |||
</target> | |||
</project> |
@@ -0,0 +1,2 @@ | |||
This is line 4 with gamma. | |||
This is line 6 with delta. |
@@ -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. |
@@ -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 <code>foo</code> and | |||
* <code>bar</code>. | |||
* | |||
* 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: | |||
* | |||
* <pre><linecontains matchAny="true"> | |||
* * <contains value="foo"> | |||
* * <contains value="bar"> | |||
* * </linecontains></pre> | |||
* | |||
* This will include only those lines that contain either <code>foo</code> or <code>bar</code>. | |||
* | |||
*/ | |||
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; | |||
} | |||
@@ -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)); | |||
} | |||
} |