git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@808018 13f79535-47bb-0310-9956-ffa450edef68master
@@ -927,6 +927,9 @@ Other changes: | |||
added. | |||
Bugzilla Report 40504. | |||
* A new filterreader <uniqfilter> that suppresses lines that match | |||
their ancestor line has been added. | |||
Changes from Ant 1.7.0 TO Ant 1.7.1 | |||
============================================= | |||
@@ -125,6 +125,7 @@ nested elements.<br> | |||
<a href="#tokenfilter">TokenFilter</a><br> | |||
<a href="../CoreTasks/fixcrlf.html">FixCRLF</a><br> | |||
<a href="#sortfilter">SortFilter</a><br> | |||
<a href="#sortfilter">UniqFilter</a><br> | |||
<h3><a name="filterreader">FilterReader</a></h3> | |||
@@ -1494,97 +1495,21 @@ This may be used as follows: | |||
</copy> | |||
</pre></blockquote> | |||
<h3><a name="sortfilter">SortFilter</a></h3> | |||
<h3><a name="uniqfilter">UniqFilter</a></h3> | |||
<p>This filter sorts lines lexicographically but you can specifiy a | |||
custom comparator as well.</p> | |||
<p>Suppresses all lines that match their ancestor line. It is most | |||
useful if combined with a sort filter.</p> | |||
<table cellSpacing=0 cellPadding=2 border=1> | |||
<tr> | |||
<td vAlign=top><b>Parameter Type</b></td> | |||
<td vAlign=top><b>Parameter Value</b></td> | |||
<td vAlign=top align="center"><b>Required</b></td> | |||
</tr> | |||
<tr> | |||
<td vAlign=top>reverse</td> | |||
<td vAlign=top align="center">Whether to reverse the sort order | |||
(boolean). Will be ignored if a custom comparator has been | |||
specified.</td> | |||
<td vAlign=top align="center">No</td> | |||
</tr> | |||
<tr> | |||
<td vAlign=top>comparator</td> | |||
<td vAlign=top align="center">Classname of a class | |||
implementing <code>java.util.Comparator</code> an instance of | |||
which will be used when comparing lines.</td> | |||
<td vAlign=top align="center">No</td> | |||
</tr> | |||
</table> | |||
<p> | |||
<h4>Example:</h4> | |||
This will sort the lines. | |||
<blockquote><pre> | |||
<filterreader classname="org.apache.tools.ant.filters.SortFilter"/> | |||
</pre></blockquote> | |||
Convenience method: | |||
<blockquote><pre> | |||
<sortfilter/> | |||
</pre></blockquote> | |||
This will reverse the sort order. | |||
This suppresses duplicate lines. | |||
<blockquote><pre> | |||
<filterreader classname="org.apache.tools.ant.filters.SortFilter"> | |||
<param name="reverse" value="true"/> | |||
</filterreader> | |||
<filterreader classname="org.apache.tools.ant.filters.UniqFilter"/> | |||
</pre></blockquote> | |||
Convenience method: | |||
<blockquote><pre> | |||
<sortfilter reverse="true"/> | |||
</pre></blockquote> | |||
You can use your own comparator, the easiest way is by using typedef | |||
and the convenience method which allows to specify the comparator as a | |||
nested element: | |||
<blockquote><pre> | |||
public final class EvenFirstCmp implements Comparator { | |||
public int compare(Object o1, Object o2) { | |||
String s1 = ((String) o1).substring(5).trim(); | |||
String s2 = ((String) o2).substring(5).trim(); | |||
int n1 = Integer.parseInt(s1); | |||
int n2 = Integer.parseInt(s2); | |||
if (n1 % 2 == 0) { | |||
if (n2 % 2 == 0) { | |||
return n1 - n2; | |||
} else { | |||
return -1; | |||
} | |||
} else { | |||
if (n2 % 2 == 0) { | |||
return 1; | |||
} else { | |||
return n1 - n2; | |||
} | |||
} | |||
} | |||
} | |||
</pre></blockquote> | |||
and used as | |||
<blockquote><pre> | |||
<typedef classname="org.apache.tools.ant.filters.EvenFirstCmp" | |||
name="evenfirst"/> | |||
... | |||
<filterchain> | |||
<sortfilter> | |||
<evenfirst/> | |||
</sortfilter> | |||
</filterchain> | |||
<uniqfilter/> | |||
</pre></blockquote> | |||
</body></html> |
@@ -138,5 +138,7 @@ | |||
<!-- filters --> | |||
<componentdef name="sortfilter" onerror="ignore" | |||
classname="org.apache.tools.ant.filters.SortFilter"/> | |||
<componentdef name="uniqfilter" onerror="ignore" | |||
classname="org.apache.tools.ant.filters.UniqFilter"/> | |||
</antlib> | |||
@@ -0,0 +1,69 @@ | |||
/* | |||
* 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. | |||
* | |||
*/ | |||
package org.apache.tools.ant.filters; | |||
import java.io.IOException; | |||
import java.io.Reader; | |||
/** | |||
* Like the Unix uniq(1) command, only returns lines that are | |||
* different from their ancestor line. | |||
* | |||
* <p>This filter is probably most useful if used together with a sortfilter.</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public class UniqFilter extends BaseFilterReader implements ChainableReader { | |||
private String lastLine = null; | |||
private String currentLine = null; | |||
public UniqFilter() { } | |||
public UniqFilter(Reader rdr) { | |||
super(rdr); | |||
} | |||
public int read() throws IOException { | |||
int ch = -1; | |||
if (currentLine != null) { | |||
ch = currentLine.charAt(0); | |||
if (currentLine.length() == 1) { | |||
currentLine = null; | |||
} else { | |||
currentLine = currentLine.substring(1); | |||
} | |||
} else { | |||
do { | |||
currentLine = readLine(); | |||
} while (lastLine != null && currentLine != null | |||
&& lastLine.equals(currentLine)); | |||
lastLine = currentLine; | |||
if (currentLine != null) { | |||
return read(); | |||
} | |||
} | |||
return ch; | |||
} | |||
public Reader chain(final Reader rdr) { | |||
UniqFilter newFilter = new UniqFilter(rdr); | |||
newFilter.setInitialized(true); | |||
return newFilter; | |||
} | |||
} |
@@ -0,0 +1,4 @@ | |||
A | |||
AA | |||
B | |||
C |
@@ -0,0 +1,5 @@ | |||
A | |||
AA | |||
B | |||
C | |||
B |
@@ -0,0 +1,6 @@ | |||
A | |||
AA | |||
AA | |||
B | |||
C | |||
B |
@@ -0,0 +1,49 @@ | |||
<?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 default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||
<import file="../antunit-base.xml" /> | |||
<target name="setUp"> | |||
<mkdir dir="${output}"/> | |||
</target> | |||
<target name="testUniqFilter" depends="setUp"> | |||
<copy file="input/uniq.txt" | |||
tofile="${output}/uniq.txt"> | |||
<filterchain> | |||
<uniqfilter/> | |||
</filterchain> | |||
</copy> | |||
<au:assertFilesMatch | |||
expected="expected/uniq.txt" | |||
actual="${output}/uniq.txt"/> | |||
</target> | |||
<target name="testSortUniq" depends="setUp"> | |||
<copy file="input/uniq.txt" | |||
tofile="${output}/uniq.txt"> | |||
<filterchain> | |||
<sortfilter/> | |||
<uniqfilter/> | |||
</filterchain> | |||
</copy> | |||
<au:assertFilesMatch | |||
expected="expected/sortuniq.txt" | |||
actual="${output}/uniq.txt"/> | |||
</target> | |||
</project> |