diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/CloneableReader.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/CloneableReader.java new file mode 100644 index 000000000..21db350fb --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/CloneableReader.java @@ -0,0 +1,7 @@ +package org.apache.tools.ant.filters; + +import java.io.Reader; + +public interface CloneableReader { + public Reader clone(Reader rdr); +} diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/HeadFilter.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/HeadFilter.java index 5867dee80..e87c216bc 100644 --- a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/HeadFilter.java +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/HeadFilter.java @@ -56,6 +56,7 @@ package org.apache.tools.ant.filters; import java.io.FilterReader; import java.io.IOException; import java.io.Reader; +import java.io.StringReader; import org.apache.tools.ant.types.Parameter; import org.apache.tools.ant.types.Parameterizable; @@ -66,6 +67,10 @@ import org.apache.tools.ant.types.Parameterizable; * Example: * ======= * + * <headfilter lines="3"/> + * + * Or: + * * <filterreader classname="org.apache.tools.ant.filters.HeadFilter"> * <param name="lines" value="3"/> * </filterreader> @@ -74,7 +79,7 @@ import org.apache.tools.ant.types.Parameterizable; */ public final class HeadFilter extends FilterReader - implements Parameterizable + implements Parameterizable, CloneableReader { private static final String LINES_KEY = "lines"; @@ -88,6 +93,22 @@ public final class HeadFilter private boolean ignoreLineFeed = false; + /** + * This constructor is a dummy constructor and is + * not meant to be used by any class other than Ant's + * introspection mechanism. This will close the filter + * that is created making it useless for further operations. + */ + public HeadFilter() { + // Dummy constructor to be invoked by Ant's Introspector + super(new StringReader(new String())); + try { + close(); + } catch (IOException ioe) { + // Ignore + } + } + /** * Create a new filtered reader. * @@ -98,9 +119,9 @@ public final class HeadFilter } public final int read() throws IOException { - if (!initialized) { + if (!getInitialized()) { initialize(); - initialized = true; + setInitialized(true); } int ch = -1; @@ -155,12 +176,35 @@ public final class HeadFilter return n; } + public final void setLines(final long lines) { + this.lines = lines; + } + + public final long getLines() { + return lines; + } + + public final void setInitialized(final boolean initialized) { + this.initialized = initialized; + } + + public final boolean getInitialized() { + return initialized; + } + + public final Reader clone(final Reader rdr) { + HeadFilter newFilter = new HeadFilter(rdr); + newFilter.setLines(getLines()); + newFilter.setInitialized(true); + return newFilter; + } + /** * Set Parameters */ public final void setParameters(final Parameter[] parameters) { this.parameters = parameters; - initialized = false; + setInitialized(false); } private final void initialize() { diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java index 01890e5d2..5c11d0350 100644 --- a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java @@ -55,6 +55,8 @@ package org.apache.tools.ant.types; import java.util.Vector; +import org.apache.tools.ant.filters.HeadFilter; + /** * Set of FilterReaders * @@ -71,4 +73,8 @@ public final class FilterReaderSet { public final Vector getFilterReaders() { return filterReaders; } + + public final void addHeadFilter(final HeadFilter headFilter) { + filterReaders.addElement(headFilter); + } } diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/util/ChainReaderHelper.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/util/ChainReaderHelper.java index d5619bbdc..d78ef6ede 100644 --- a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/util/ChainReaderHelper.java +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/util/ChainReaderHelper.java @@ -56,6 +56,7 @@ package org.apache.tools.ant.util; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; +import org.apache.tools.ant.filters.CloneableReader; import org.apache.tools.ant.types.AntFilterReader; import org.apache.tools.ant.types.FilterReaderSet; import org.apache.tools.ant.types.Path; @@ -133,9 +134,7 @@ public final class ChainReaderHelper { final Vector filterReaders = filterset.getFilterReaders(); final int readerCount = filterReaders.size(); for (int j = 0; j < readerCount; j++) { - final AntFilterReader afr = - (AntFilterReader) filterReaders.elementAt(j); - finalFilters.addElement(afr); + finalFilters.addElement(filterReaders.elementAt(j)); } } @@ -143,47 +142,62 @@ public final class ChainReaderHelper { if (filtersCount > 0) { for (int i = 0; i < filtersCount; i++) { - final AntFilterReader filter = - (AntFilterReader) finalFilters.elementAt(i); - final String className = filter.getClassName(); - final Path classpath = filter.getClasspath(); - final Project project = filter.getProject(); - if (className != null) { - try { - Class clazz = null; - if (classpath == null) { - clazz = Class.forName(className); - } else { - AntClassLoader al = new AntClassLoader(project, - classpath); - clazz = al.loadClass(className); - AntClassLoader.initializeClass(clazz); - } - if (clazz != null) { - if (!FilterReader.class.isAssignableFrom(clazz)) { - throw new BuildException(className + - " does not extend java.io.FilterReader"); + Object o = finalFilters.elementAt(i); + + if (o instanceof AntFilterReader) { + final AntFilterReader filter = (AntFilterReader) finalFilters.elementAt(i); + final String className = filter.getClassName(); + final Path classpath = filter.getClasspath(); + final Project project = filter.getProject(); + if (className != null) { + try { + Class clazz = null; + if (classpath == null) { + clazz = Class.forName(className); + } else { + AntClassLoader al = new AntClassLoader(project, + classpath); + clazz = al.loadClass(className); + AntClassLoader.initializeClass(clazz); } - final Constructor[] constructors = - clazz.getConstructors(); - final Reader[] rdr = {instream}; - instream = - (Reader) constructors[0].newInstance(rdr); - if (Parameterizable.class.isAssignableFrom(clazz)) { - final Parameter[] params = filter.getParams(); - ((Parameterizable) - instream).setParameters(params); + if (clazz != null) { + if (!FilterReader.class.isAssignableFrom(clazz)) { + throw new BuildException(className + + " does not extend java.io.FilterReader"); + } + final Constructor[] constructors = + clazz.getConstructors(); + int j = 0; + for (; j < constructors.length; j++) { + Class[] types = constructors[j] + .getParameterTypes(); + if (types.length == 1 && + types[0].isAssignableFrom(Reader.class)) { + break; + } + } + final Reader[] rdr = {instream}; + instream = + (Reader) constructors[j].newInstance(rdr); + if (Parameterizable.class.isAssignableFrom(clazz)) { + final Parameter[] params = filter.getParams(); + ((Parameterizable) + instream).setParameters(params); + } } + } catch (final ClassNotFoundException cnfe) { + throw new BuildException(cnfe); + } catch (final InstantiationException ie) { + throw new BuildException(ie); + } catch (final IllegalAccessException iae) { + throw new BuildException(iae); + } catch (final InvocationTargetException ite) { + throw new BuildException(ite); } - } catch (final ClassNotFoundException cnfe) { - throw new BuildException(cnfe); - } catch (final InstantiationException ie) { - throw new BuildException(ie); - } catch (final IllegalAccessException iae) { - throw new BuildException(iae); - } catch (final InvocationTargetException ite) { - throw new BuildException(ite); } + } else if (o instanceof CloneableReader && + o instanceof Reader) { + instream = ((CloneableReader) o).clone(instream); } } }