git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@808009 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -73,6 +73,7 @@ David Gärtner | |||||
| David S. Johnson | David S. Johnson | ||||
| David Kavanagh | David Kavanagh | ||||
| David LeRoy | David LeRoy | ||||
| David Leal | |||||
| David M. Lloyd | David M. Lloyd | ||||
| David Maclean | David Maclean | ||||
| David Rees | David Rees | ||||
| @@ -923,6 +923,10 @@ Other changes: | |||||
| parent directory of the destination archive if it doesn't exist. | parent directory of the destination archive if it doesn't exist. | ||||
| Bugzilla Report 45377. | Bugzilla Report 45377. | ||||
| * A new filterreader <sortfilter> that sorts input lines has been | |||||
| added. | |||||
| Bugzilla Report 40504. | |||||
| Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
| ============================================= | ============================================= | ||||
| @@ -316,6 +316,10 @@ | |||||
| <first>David</first> | <first>David</first> | ||||
| <last>LeRoy</last> | <last>LeRoy</last> | ||||
| </name> | </name> | ||||
| <name> | |||||
| <first>David</first> | |||||
| <last>Leal</last> | |||||
| </name> | |||||
| <name> | <name> | ||||
| <first>David</first> | <first>David</first> | ||||
| <middle>M.</middle> | <middle>M.</middle> | ||||
| @@ -124,6 +124,7 @@ nested elements.<br> | |||||
| <a href="#concatfilter">ConcatFilter</a><br> | <a href="#concatfilter">ConcatFilter</a><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> | |||||
| <h3><a name="filterreader">FilterReader</a></h3> | <h3><a name="filterreader">FilterReader</a></h3> | ||||
| @@ -1481,7 +1482,7 @@ public class Capitalize | |||||
| This may be used as follows: | This may be used as follows: | ||||
| <blockquote><pre> | <blockquote><pre> | ||||
| <typedef type="capitalize" classname="my.customant.Capitalize" | |||||
| <typedef name="capitalize" classname="my.customant.Capitalize" | |||||
| classpath="my.customant.path"/> | classpath="my.customant.path"/> | ||||
| <copy file="input" tofile="output"> | <copy file="input" tofile="output"> | ||||
| <filterchain> | <filterchain> | ||||
| @@ -1493,4 +1494,97 @@ This may be used as follows: | |||||
| </copy> | </copy> | ||||
| </pre></blockquote> | </pre></blockquote> | ||||
| <h3><a name="sortfilter">SortFilter</a></h3> | |||||
| <p>This filter sorts lines lexicographically but you can specifiy a | |||||
| custom comparator as well.</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. | |||||
| <blockquote><pre> | |||||
| <filterreader classname="org.apache.tools.ant.filters.SortFilter"> | |||||
| <param name="reverse" value="true"/> | |||||
| </filterreader> | |||||
| </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> | |||||
| </pre></blockquote> | |||||
| </body></html> | </body></html> | ||||
| @@ -51,6 +51,8 @@ | |||||
| classname="org.apache.tools.ant.taskdefs.condition.IsFailure"/> | classname="org.apache.tools.ant.taskdefs.condition.IsFailure"/> | ||||
| <componentdef name="isfalse" onerror="ignore" | <componentdef name="isfalse" onerror="ignore" | ||||
| classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/> | classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/> | ||||
| <componentdef name="islastmodified" onerror="ignore" | |||||
| classname="org.apache.tools.ant.taskdefs.condition.IsLastModified"/> | |||||
| <componentdef name="isreachable" onerror="ignore" | <componentdef name="isreachable" onerror="ignore" | ||||
| classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/> | classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/> | ||||
| <componentdef name="isreference" onerror="ignore" | <componentdef name="isreference" onerror="ignore" | ||||
| @@ -73,6 +75,8 @@ | |||||
| classname="org.apache.tools.ant.taskdefs.condition.ParserSupports"/> | classname="org.apache.tools.ant.taskdefs.condition.ParserSupports"/> | ||||
| <componentdef name="resourcecontains" onerror="ignore" | <componentdef name="resourcecontains" onerror="ignore" | ||||
| classname="org.apache.tools.ant.taskdefs.condition.ResourceContains"/> | classname="org.apache.tools.ant.taskdefs.condition.ResourceContains"/> | ||||
| <componentdef name="resourceexists" onerror="ignore" | |||||
| classname="org.apache.tools.ant.taskdefs.condition.ResourceExists"/> | |||||
| <componentdef name="resourcesmatch" onerror="ignore" | <componentdef name="resourcesmatch" onerror="ignore" | ||||
| classname="org.apache.tools.ant.taskdefs.condition.ResourcesMatch"/> | classname="org.apache.tools.ant.taskdefs.condition.ResourcesMatch"/> | ||||
| <componentdef name="socket" onerror="ignore" | <componentdef name="socket" onerror="ignore" | ||||
| @@ -131,5 +135,8 @@ | |||||
| <componentdef name="reverse" onerror="ignore" | <componentdef name="reverse" onerror="ignore" | ||||
| classname="org.apache.tools.ant.types.resources.comparators.Reverse" /> | classname="org.apache.tools.ant.types.resources.comparators.Reverse" /> | ||||
| <!-- filters --> | |||||
| <componentdef name="sortfilter" onerror="ignore" | |||||
| classname="org.apache.tools.ant.filters.SortFilter"/> | |||||
| </antlib> | </antlib> | ||||
| @@ -0,0 +1,362 @@ | |||||
| /* | |||||
| * 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; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Collections; | |||||
| import java.util.Comparator; | |||||
| import java.util.Iterator; | |||||
| import java.util.List; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.types.Parameter; | |||||
| /** | |||||
| * <p> | |||||
| * Sort a file before and/or after the file. | |||||
| * </p> | |||||
| * | |||||
| * <p> | |||||
| * Examples: | |||||
| * </p> | |||||
| * | |||||
| * <pre> | |||||
| * <copy todir="build"> | |||||
| * <fileset dir="input" includes="*.txt"/> | |||||
| * <filterchain> | |||||
| * <sortfilter/> | |||||
| * </filterchain> | |||||
| * </copy> | |||||
| * </pre> | |||||
| * | |||||
| * <p> | |||||
| * Sort all files <code>*.txt</code> from <i>src</i> location in descendant | |||||
| * order and copy them into <i>build</i> location. The lines of each file are | |||||
| * sorted in ascendant order comparing the lines vía | |||||
| * <code>String.compareTo(Object o)</code> method. | |||||
| * </p> | |||||
| * | |||||
| * <pre> | |||||
| * <copy todir="build"> | |||||
| * <fileset dir="input" includes="*.txt"/> | |||||
| * <filterchain> | |||||
| * <sortfilter/> | |||||
| * <param name="reverse" value="true"/> | |||||
| * </sortfilter/> | |||||
| * </filterchain> | |||||
| * </copy> | |||||
| * </pre> | |||||
| * | |||||
| * <p> | |||||
| * Sort all files <code>*.txt</code> from <i>src</i> location into reverse | |||||
| * order and copy them into <i>build</i> location. If reverse parameter has | |||||
| * value <code>true</code> (default value), then the output line of the files | |||||
| * will be in ascendant order. | |||||
| * </p> | |||||
| * | |||||
| * <pre> | |||||
| * <copy todir="build"> | |||||
| * <fileset dir="input" includes="*.txt"/> | |||||
| * <filterchain> | |||||
| * <sortfilter/> | |||||
| * <param name="comparator" value="org.apache.tools.ant.filters.EvenFirstCmp"/> | |||||
| * </sortfilter/> | |||||
| * </filterchain> | |||||
| * </copy> | |||||
| * </pre> | |||||
| * | |||||
| * <p> | |||||
| * Sort all files <code>*.txt</code> from <i>src</i> location using as | |||||
| * sorting criterium <code>EvenFirstCmp</code> class, that sorts the file | |||||
| * lines putting even lines first then odd lines for example. The modified files | |||||
| * are copied into <i>build</i> location. The <code>EventFirstCmp</code>, | |||||
| * has to an instanciable class via <code>Class.newInstance()</code>, | |||||
| * therefore in case of inner class has to be <em>static</em>. It also has to | |||||
| * implement <code>java.util.Comparator</code> interface, for example: | |||||
| * </p> | |||||
| * | |||||
| * <pre> | |||||
| * package org.apache.tools.ant.filters; | |||||
| * ...(omitted) | |||||
| * public final class EvenFirstCmp implements <b>Comparator</b> { | |||||
| * public int compare(Object o1, Object o2) { | |||||
| * ...(omitted) | |||||
| * } | |||||
| * } | |||||
| * </pre> | |||||
| * | |||||
| * <p> If parameter <code>comparator</code> is present, then | |||||
| * <code>reverse</code> parameter will not taken into account. </p> | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public final class SortFilter extends BaseParamFilterReader | |||||
| implements ChainableReader { | |||||
| /** Parameter name for reverse order. */ | |||||
| private static final String REVERSE_KEY = "reverse"; | |||||
| /** | |||||
| * Parameter name for specifying the comparator criteria via class that | |||||
| * implement <code>java.util.Comparator</code> interface. | |||||
| */ | |||||
| private static final String COMPARATOR_KEY = "comparator"; | |||||
| /** | |||||
| * Instance of comparator class to be used for sorting. | |||||
| */ | |||||
| private Comparator comparator = null; | |||||
| /** | |||||
| * Controls if the sorting process will be in ascendant/descendant order. If | |||||
| * If has value <code>true</code>, then the line of the file will be | |||||
| * sorted on descendant order. Default value: <code>false</code>. It will | |||||
| * be considered only if <code>comparator</code> is <code>null</code>. | |||||
| */ | |||||
| private boolean reverse; | |||||
| /** | |||||
| * Stores the lines to be sorted. | |||||
| */ | |||||
| private List lines; | |||||
| /** | |||||
| * Remaining line to be read from this filter, or <code>null</code> if the | |||||
| * next call to <code>read()</code> should read the original stream to | |||||
| * find the next matching line. | |||||
| */ | |||||
| private String line = null; | |||||
| private Iterator iterator = null; | |||||
| /** | |||||
| * Constructor for "dummy" instances. | |||||
| * | |||||
| * @see BaseFilterReader#BaseFilterReader() | |||||
| */ | |||||
| public SortFilter() { | |||||
| super(); | |||||
| } | |||||
| /** | |||||
| * Creates a new filtered reader. | |||||
| * | |||||
| * @param in | |||||
| * A Reader object providing the underlying stream. Must not be | |||||
| * <code>null</code>. | |||||
| */ | |||||
| public SortFilter(final Reader in) { | |||||
| super(in); | |||||
| } | |||||
| /** | |||||
| * Returns the next character in the filtered stream. If the desired number | |||||
| * of lines have already been read, the resulting stream is effectively at | |||||
| * an end. Otherwise, the next character from the underlying stream is read | |||||
| * and returned. | |||||
| * | |||||
| * @return the next character in the resulting stream, or -1 if the end of | |||||
| * the resulting stream has been reached | |||||
| * | |||||
| * @exception IOException | |||||
| * if the underlying stream throws an IOException during | |||||
| * reading | |||||
| */ | |||||
| public int read() throws IOException { | |||||
| if (!getInitialized()) { | |||||
| initialize(); | |||||
| setInitialized(true); | |||||
| } | |||||
| int ch = -1; | |||||
| if (line != null) { | |||||
| /* | |||||
| * We are on the state: "reading the current line", lines are | |||||
| * already sorted | |||||
| */ | |||||
| ch = line.charAt(0); | |||||
| if (line.length() == 1) { | |||||
| line = null; | |||||
| } else { | |||||
| line = line.substring(1); | |||||
| } | |||||
| } else { | |||||
| if (lines == null) { | |||||
| // We read all lines and sort them | |||||
| lines = new ArrayList(); | |||||
| for (line = readLine(); line != null; line = readLine()) { | |||||
| lines.add(line); | |||||
| } | |||||
| sort(); | |||||
| iterator = lines.iterator(); | |||||
| } | |||||
| if (iterator.hasNext()) { | |||||
| line = (String) iterator.next(); | |||||
| } else { | |||||
| line = null; | |||||
| lines = null; | |||||
| iterator = null; | |||||
| } | |||||
| if (line != null) { | |||||
| return read(); | |||||
| } | |||||
| } | |||||
| return ch; | |||||
| } | |||||
| /** | |||||
| * Creates a new SortReader using the passed in Reader for instantiation. | |||||
| * | |||||
| * @param rdr | |||||
| * A Reader object providing the underlying stream. Must not be | |||||
| * <code>null</code>. | |||||
| * | |||||
| * @return a new filter based on this configuration, but filtering the | |||||
| * specified reader | |||||
| */ | |||||
| public Reader chain(final Reader rdr) { | |||||
| SortFilter newFilter = new SortFilter(rdr); | |||||
| newFilter.setReverse(isReverse()); | |||||
| newFilter.setComparator(getComparator()); | |||||
| newFilter.setInitialized(true); | |||||
| return newFilter; | |||||
| } | |||||
| /** | |||||
| * Returns <code>true</code> if the sorting process will be in reverse | |||||
| * order, otherwise the sorting process will be in ascendant order. | |||||
| * | |||||
| * @return <code>true</code> if the sorting process will be in reverse | |||||
| * order, otherwise the sorting process will be in ascendant order. | |||||
| */ | |||||
| public boolean isReverse() { | |||||
| return reverse; | |||||
| } | |||||
| /** | |||||
| * Sets the sorting process will be in ascendant (<code>reverse=false</code>) | |||||
| * or to descendant (<code>reverse=true</code>). | |||||
| * | |||||
| * @param reverse | |||||
| * Boolean representing reverse ordering process. | |||||
| */ | |||||
| public void setReverse(boolean reverse) { | |||||
| this.reverse = reverse; | |||||
| } | |||||
| /** | |||||
| * Returns the comparator to be used for sorting. | |||||
| * | |||||
| * @return the comparator | |||||
| */ | |||||
| public Comparator getComparator() { | |||||
| return comparator; | |||||
| } | |||||
| /** | |||||
| * Set the comparator to be used as sorting criterium. | |||||
| * | |||||
| * @param comparator | |||||
| * the comparator to set | |||||
| */ | |||||
| public void setComparator(Comparator comparator) { | |||||
| this.comparator = comparator; | |||||
| } | |||||
| /** | |||||
| * Set the comparator to be used as sorting criterium as nested element. | |||||
| * | |||||
| * @param comparator | |||||
| * the comparator to set | |||||
| */ | |||||
| public void add(Comparator comparator) { | |||||
| if (this.comparator != null && comparator != null) { | |||||
| throw new BuildException("can't have more than one comparator"); | |||||
| } | |||||
| setComparator(comparator); | |||||
| } | |||||
| /** | |||||
| * Scans the parameters list | |||||
| */ | |||||
| private void initialize() throws IOException { | |||||
| // get parameters | |||||
| Parameter[] params = getParameters(); | |||||
| if (params != null) { | |||||
| for (int i = 0; i < params.length; i++) { | |||||
| final String paramName = params[i].getName(); | |||||
| if (REVERSE_KEY.equals(paramName)) { | |||||
| setReverse(Boolean.valueOf(params[i].getValue()) | |||||
| .booleanValue()); | |||||
| continue; | |||||
| } | |||||
| if (COMPARATOR_KEY.equals(paramName)) { | |||||
| try { | |||||
| String className = (String) params[i].getValue(); | |||||
| setComparator((Comparator) (Class.forName(className) | |||||
| .newInstance())); | |||||
| continue; | |||||
| } catch (InstantiationException e) { | |||||
| throw new BuildException(e); | |||||
| } catch (IllegalAccessException e) { | |||||
| /* | |||||
| * Probably a inner non-static class, this this case is | |||||
| * not considered | |||||
| */ | |||||
| throw new BuildException(e); | |||||
| } catch (ClassNotFoundException e) { | |||||
| throw new BuildException(e); | |||||
| } catch (ClassCastException e) { | |||||
| throw new BuildException("Value of comparator attribute" | |||||
| + " should implement" | |||||
| + " java.util.Comparator" | |||||
| + " interface"); | |||||
| } catch (Exception e) { | |||||
| throw new BuildException(e); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Sorts the read lines (<code>lines</code>)acording to the sorting | |||||
| * criteria defined by the user. | |||||
| * | |||||
| */ | |||||
| private void sort() { | |||||
| if (comparator == null) { | |||||
| if (reverse) { | |||||
| Collections.sort(lines, new Comparator() { | |||||
| public int compare(Object o1, Object o2) { | |||||
| String s1 = (String) o1; | |||||
| String s2 = (String) o2; | |||||
| return (-s1.compareTo(s2)); | |||||
| } | |||||
| }); | |||||
| } else { | |||||
| Collections.sort(lines); | |||||
| } | |||||
| } else { | |||||
| Collections.sort(lines, comparator); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,10 @@ | |||||
| Line 2 | |||||
| Line 4 | |||||
| Line 6 | |||||
| Line 8 | |||||
| Line 10 | |||||
| Line 1 | |||||
| Line 3 | |||||
| Line 5 | |||||
| Line 7 | |||||
| Line 9 | |||||
| @@ -0,0 +1,10 @@ | |||||
| Line 1 | |||||
| Line 2 | |||||
| Line 3 | |||||
| Line 4 | |||||
| Line 5 | |||||
| Line 6 | |||||
| Line 7 | |||||
| Line 8 | |||||
| Line 9 | |||||
| Line 10 | |||||
| @@ -0,0 +1,10 @@ | |||||
| Line 10 | |||||
| Line 9 | |||||
| Line 8 | |||||
| Line 7 | |||||
| Line 6 | |||||
| Line 5 | |||||
| Line 4 | |||||
| Line 3 | |||||
| Line 2 | |||||
| Line 1 | |||||
| @@ -0,0 +1,10 @@ | |||||
| Line 10 | |||||
| Line 1 | |||||
| Line 9 | |||||
| Line 6 | |||||
| Line 3 | |||||
| Line 2 | |||||
| Line 4 | |||||
| Line 5 | |||||
| Line 7 | |||||
| Line 8 | |||||
| @@ -0,0 +1,126 @@ | |||||
| <?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="testSortFilterNoArgs" depends="setUp"> | |||||
| <copy file="input/sort.sortDefault.test" | |||||
| tofile="${output}/sort.sortDefault.test"> | |||||
| <filterchain> | |||||
| <sortfilter/> | |||||
| </filterchain> | |||||
| </copy> | |||||
| <au:assertFilesMatch | |||||
| expected="expected/sort.sortDefault.test" | |||||
| actual="${output}/sort.sortDefault.test"/> | |||||
| </target> | |||||
| <target name="testSortFilterNoArgsLong" depends="setUp"> | |||||
| <copy file="input/sort.sortDefault.test" | |||||
| tofile="${output}/sort.sortDefault.test"> | |||||
| <filterchain> | |||||
| <filterreader classname="org.apache.tools.ant.filters.SortFilter"/> | |||||
| </filterchain> | |||||
| </copy> | |||||
| <au:assertFilesMatch | |||||
| expected="expected/sort.sortDefault.test" | |||||
| actual="${output}/sort.sortDefault.test"/> | |||||
| </target> | |||||
| <target name="testSortFilterReverse" depends="setUp"> | |||||
| <copy file="input/sort.sortDefault.test" | |||||
| tofile="${output}/sort.sortReverse.test"> | |||||
| <filterchain> | |||||
| <sortfilter reverse="true"/> | |||||
| </filterchain> | |||||
| </copy> | |||||
| <au:assertFilesMatch | |||||
| expected="expected/sort.sortReverse.test" | |||||
| actual="${output}/sort.sortReverse.test"/> | |||||
| </target> | |||||
| <target name="testSortFilterReverseLong" depends="setUp"> | |||||
| <copy file="input/sort.sortDefault.test" | |||||
| tofile="${output}/sort.sortReverse.test"> | |||||
| <filterchain> | |||||
| <filterreader classname="org.apache.tools.ant.filters.SortFilter"> | |||||
| <param name="reverse" value="true"/> | |||||
| </filterreader> | |||||
| </filterchain> | |||||
| </copy> | |||||
| <au:assertFilesMatch | |||||
| expected="expected/sort.sortReverse.test" | |||||
| actual="${output}/sort.sortReverse.test"/> | |||||
| </target> | |||||
| <target name="-setUpEvenFirst" depends="setUp"> | |||||
| <mkdir dir="${input}/src/org/apache/tools/ant/filters"/> | |||||
| <echo file="${input}/src/org/apache/tools/ant/filters/EvenFirstCmp.java"><![CDATA[ | |||||
| package org.apache.tools.ant.filters; | |||||
| import java.util.Comparator; | |||||
| 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; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ]]></echo> | |||||
| <mkdir dir="${input}/build"/> | |||||
| <javac srcdir="${input}/src" destdir="${input}/build"/> | |||||
| <typedef classname="org.apache.tools.ant.filters.EvenFirstCmp" | |||||
| name="evenfirst"> | |||||
| <classpath location="${input}/build"/> | |||||
| </typedef> | |||||
| </target> | |||||
| <target name="testSortFilterComparator" depends="-setUpEvenFirst"> | |||||
| <copy file="input/sort.sortDefault.test" | |||||
| tofile="${output}/sort.sortComparator.test"> | |||||
| <filterchain> | |||||
| <sortfilter> | |||||
| <evenfirst/> | |||||
| </sortfilter> | |||||
| </filterchain> | |||||
| </copy> | |||||
| <au:assertFilesMatch | |||||
| expected="expected/sort.sortComparator.test" | |||||
| actual="${output}/sort.sortComparator.test"/> | |||||
| </target> | |||||
| </project> | |||||