diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java new file mode 100644 index 00000000..471660c3 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java @@ -0,0 +1,375 @@ +/* + * 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 and copy + * them into <i>build</i> location. The lines of each file are sorted + * in ascendant order comparing the lines via the + * <code>String.compareTo(Object o)</code> method. + * </p> + * + * <pre> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <sortfilter reverse="true"/> + * </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> + * <filterreader classname="org.apache.tools.ant.filters.SortFilter"> + * <param name="comparator" value="org.apache.tools.ant.filters.EvenFirstCmp"/> + * </filterreader> + * </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>EvenFirstCmp</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>The example above is equivalent to:</p> + * + * <blockquote><pre> + * <componentdef name="evenfirst" + * classname="org.apache.tools.ant.filters.EvenFirstCmp"/> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <sortfilter> + * <evenfirst/> + * </sortfilter> + * </filterchain> + * </copy> + * </pre></blockquote> + * + * <p> If parameter <code>comparator</code> is present, then + * <code>reverse</code> parameter will not be 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<? super String> 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<String> 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<String> 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<String>(); + 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<? super String> getComparator() { + return comparator; + } + + /** + * Set the comparator to be used as sorting criterium. + * + * @param comparator + * the comparator to set + */ + public void setComparator(Comparator<? super String> comparator) { + this.comparator = comparator; + } + + /** + * Set the comparator to be used as sorting criterion as nested element. + * + * @param comparator + * the comparator to set + */ + public void add(Comparator<? super String> 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(); + @SuppressWarnings("unchecked") + final Comparator<? super String> comparatorInstance = (Comparator<? super String>) (Class + .forName(className).newInstance()); + setComparator(comparatorInstance); + 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>) according to the sorting + * criteria defined by the user. + * + */ + private void sort() { + if (comparator == null) { + if (reverse) { + Collections.sort(lines, new Comparator<String>() { + public int compare(String s1, String s2) { + return (-s1.compareTo(s2)); + } + }); + } else { + Collections.sort(lines); + } + } else { + Collections.sort(lines, comparator); + } + } +} |