git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@808304 13f79535-47bb-0310-9956-ffa450edef68master
@@ -927,8 +927,8 @@ Other changes: | |||||
added. | added. | ||||
Bugzilla Report 40504. | Bugzilla Report 40504. | ||||
* A new filterreader <uniqfilter> that suppresses lines that match | |||||
their ancestor line has been added. | |||||
* A new token filter <uniqfilter> that suppresses tokens that match | |||||
their ancestor token has been added. | |||||
Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
============================================= | ============================================= | ||||
@@ -125,7 +125,6 @@ nested elements.<br> | |||||
<a href="#tokenfilter">TokenFilter</a><br> | <a href="#tokenfilter">TokenFilter</a><br> | ||||
<a href="../CoreTasks/fixcrlf.html">FixCRLF</a><br> | <a href="../CoreTasks/fixcrlf.html">FixCRLF</a><br> | ||||
<a href="#sortfilter">SortFilter</a><br> | <a href="#sortfilter">SortFilter</a><br> | ||||
<a href="#uniqfilter">UniqFilter</a><br> | |||||
<h3><a name="filterreader">FilterReader</a></h3> | <h3><a name="filterreader">FilterReader</a></h3> | ||||
@@ -1032,6 +1031,7 @@ and \\. | |||||
<a href="#trim">Trim</a><br> | <a href="#trim">Trim</a><br> | ||||
<a href="#ignoreblank">IgnoreBlank</a><br> | <a href="#ignoreblank">IgnoreBlank</a><br> | ||||
<a href="#filterdeletecharacters">DeleteCharacters</a><br> | <a href="#filterdeletecharacters">DeleteCharacters</a><br> | ||||
<a href="#uniqfilter">UniqFilter</a><br> | |||||
</p> | </p> | ||||
The following string filters are provided by the optional distribution. | The following string filters are provided by the optional distribution. | ||||
@@ -1360,6 +1360,20 @@ Delete tabs from lines, trim the lines and removes empty lines. | |||||
</pre></blockquote> | </pre></blockquote> | ||||
<p><b><em><a name="uniqfilter">UniqFilter</a></em></b></p> | |||||
<p>Suppresses all tokens that match their ancestor token. It is most | |||||
useful if combined with a sort filter.</p> | |||||
<h4>Example:</h4> | |||||
This suppresses duplicate lines. | |||||
<blockquote><pre> | |||||
<tokenfilter> | |||||
<uniqfilter/> | |||||
</tokenfilter> | |||||
</pre></blockquote> | |||||
<p><b><em><a name="scriptfilter">ScriptFilter</a></em></b></p> | <p><b><em><a name="scriptfilter">ScriptFilter</a></em></b></p> | ||||
This is an optional filter that executes a script in a | This is an optional filter that executes a script in a | ||||
<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> | <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> | ||||
@@ -1495,21 +1509,4 @@ This may be used as follows: | |||||
</copy> | </copy> | ||||
</pre></blockquote> | </pre></blockquote> | ||||
<h3><a name="uniqfilter">UniqFilter</a></h3> | |||||
<p>Suppresses all lines that match their ancestor line. It is most | |||||
useful if combined with a sort filter.</p> | |||||
<h4>Example:</h4> | |||||
This suppresses duplicate lines. | |||||
<blockquote><pre> | |||||
<filterreader classname="org.apache.tools.ant.filters.UniqFilter"/> | |||||
</pre></blockquote> | |||||
Convenience method: | |||||
<blockquote><pre> | |||||
<uniqfilter/> | |||||
</pre></blockquote> | |||||
</body></html> | </body></html> |
@@ -17,53 +17,23 @@ | |||||
*/ | */ | ||||
package org.apache.tools.ant.filters; | 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. | |||||
* Like the Unix uniq(1) command, only returns tokens that are | |||||
* different from their ancestor token. | |||||
* | * | ||||
* <p>This filter is probably most useful if used together with a sortfilter.</p> | |||||
* <p>This filter is probably most useful if used together with a | |||||
* sortfilter.</p> | |||||
* | * | ||||
* @since Ant 1.8.0 | * @since Ant 1.8.0 | ||||
*/ | */ | ||||
public class UniqFilter extends BaseFilterReader implements ChainableReader { | |||||
public class UniqFilter implements TokenFilter.Filter { | |||||
private String lastLine = null; | private String lastLine = null; | ||||
private String currentLine = null; | |||||
public UniqFilter() { } | 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; | |||||
public String filter(String string) { | |||||
return lastLine == null || !lastLine.equals(string) | |||||
? (lastLine = string) : null; | |||||
} | } | ||||
} | } |
@@ -0,0 +1 @@ | |||||
A B C B |
@@ -0,0 +1 @@ | |||||
A A B C B |
@@ -26,7 +26,9 @@ | |||||
<copy file="input/uniq.txt" | <copy file="input/uniq.txt" | ||||
tofile="${output}/uniq.txt"> | tofile="${output}/uniq.txt"> | ||||
<filterchain> | <filterchain> | ||||
<uniqfilter/> | |||||
<tokenfilter> | |||||
<uniqfilter/> | |||||
</tokenfilter> | |||||
</filterchain> | </filterchain> | ||||
</copy> | </copy> | ||||
<au:assertFilesMatch | <au:assertFilesMatch | ||||
@@ -39,11 +41,29 @@ | |||||
tofile="${output}/uniq.txt"> | tofile="${output}/uniq.txt"> | ||||
<filterchain> | <filterchain> | ||||
<sortfilter/> | <sortfilter/> | ||||
<uniqfilter/> | |||||
<tokenfilter> | |||||
<uniqfilter/> | |||||
</tokenfilter> | |||||
</filterchain> | </filterchain> | ||||
</copy> | </copy> | ||||
<au:assertFilesMatch | <au:assertFilesMatch | ||||
expected="expected/sortuniq.txt" | expected="expected/sortuniq.txt" | ||||
actual="${output}/uniq.txt"/> | actual="${output}/uniq.txt"/> | ||||
</target> | </target> | ||||
<target name="testUniqueColumns" depends="setUp"> | |||||
<copy file="input/unique-columns.txt" | |||||
tofile="${output}/unique-columns.txt"> | |||||
<filterchain> | |||||
<tokenfilter> | |||||
<stringtokenizer/> | |||||
<uniqfilter/> | |||||
</tokenfilter> | |||||
</filterchain> | |||||
</copy> | |||||
<au:assertFilesMatch | |||||
expected="expected/unique-columns.txt" | |||||
actual="${output}/unique-columns.txt"/> | |||||
</target> | |||||
</project> | </project> |