From 8b00ce3f42610084921921e60a77473199eb0d2e Mon Sep 17 00:00:00 2001 From: Magesh Umasankar Date: Fri, 15 Feb 2002 21:50:55 +0000 Subject: [PATCH] Initial version of FilterReaderSet implementation with as example. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271370 13f79535-47bb-0310-9956-ffa450edef68 --- proposal/sandbox/filterreaders/README | 59 ++++ .../tools/ant/filters/StripLineBreaks.java | 101 ++++++ .../apache/tools/ant/taskdefs/LoadFile.java | 291 ++++++++++++++++++ .../tools/ant/types/AntFilterReader.java | 131 ++++++++ .../tools/ant/types/FilterReaderSet.java | 74 +++++ .../tools/ant/types/Parameterizable.java | 65 ++++ 6 files changed, 721 insertions(+) create mode 100644 proposal/sandbox/filterreaders/README create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/StripLineBreaks.java create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/taskdefs/LoadFile.java create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/AntFilterReader.java create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/Parameterizable.java diff --git a/proposal/sandbox/filterreaders/README b/proposal/sandbox/filterreaders/README new file mode 100644 index 000000000..b1311d0a9 --- /dev/null +++ b/proposal/sandbox/filterreaders/README @@ -0,0 +1,59 @@ +Ant Filter Readers +================== + +Usecase: +======== +* Usage of filtering has become a common pattern in + Ant's tasks. Filtering is being performed one way or + another in tasks like , , , + , etc. + +* There is no generic way to add custom filters + currently to these tasks. User has to either extend + the task to add custom filter processing or add + more attributes as needed to the task itself. + +* If user is provided with a pluggable filtering + mechanism, changes to built-in tasks can be mininized, + while at the same time providing increased flexibility + to the user. + +Design: +====== +* FilterReaderSet is a collection of 'AntFilterReader's + +* Each AntFilterReader encloses the custom class representing + the actual java.io.FilterReader and contains configuration + parameters that may be used by the custom class if it + implements the org.apache.tools.ant.types.Configurable + interface. + +* Custom filter readers can be created easily even + without using any of Ant's API - all one needs to + do to create a custom filter is to extend + java.io.FilterReader. + +* If the extended class also implements Configurable, + operation parameters can be made available to the + custom filter. + +* Each FilterReader is piped through the other, if any, in + the chain, in the order of declaration. + +Example: +======= + + + + + + + + + + +The above example loads the contents of the file foo, +filters out the lines that begin with //, REM and --, +removes line breaks and then stores the result in +the property named bar. + diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/StripLineBreaks.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/StripLineBreaks.java new file mode 100644 index 000000000..58081e54d --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/StripLineBreaks.java @@ -0,0 +1,101 @@ +package org.apache.tools.ant.filters; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Hashtable; + +import org.apache.tools.ant.types.Parameterizable; + +/** + * Filter to flatten the stream to a single line. + * + * @author Steve Loughran + * @author Magesh Umasankar + */ +public final class StripLineBreaks + extends FilterReader + implements Parameterizable +{ + /** + * Linebreaks. What do to on funny IBM mainframes with odd line endings? + */ + private static final String DEFAULT_LINE_BREAKS = "\r\n"; + + /** + * Linebreaks key that can be set via param element of + * AntFilterReader + */ + private static final String LINE_BREAKS_KEY = "linebreaks"; + + private Hashtable parameters; + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public StripLineBreaks(final Reader in) { + super(in); + } + + /** + * Strip line break characters from an array. + * + * @exception IOException If an I/O error occurs + */ + public final int read(final char[] cbuf) throws IOException { + int length = -1; + if (cbuf != null) { + length = cbuf.length; + if (in != null) { + length = in.read(cbuf); + } + if (length != -1) { + String str = new String(cbuf, 0, length); + str = stripLineBreaks(str); + final char[] newcbuf = str.toCharArray(); + System.arraycopy(newcbuf, 0, cbuf, 0, newcbuf.length); + for (int j = newcbuf.length; j < cbuf.length; j++) { + cbuf[j] = 0; + } + length = newcbuf.length; + } + } + return length; + } + + /** + * strip out all line breaks from a string. + * @param source source + * This implementation always duplicates the string; it is nominally possible to probe + * the string first looking for any line breaks before bothering to do a copy. But we assume if + * the option is requested, then line breaks are probably in the source string. + */ + private final String stripLineBreaks(final String source) { + final int len=source.length(); + final String userDefinedLineBreaks = + (String) parameters.get(LINE_BREAKS_KEY); + + String lineBreaks = DEFAULT_LINE_BREAKS; + if (userDefinedLineBreaks != null) { + lineBreaks = userDefinedLineBreaks; + } + final StringBuffer dest=new StringBuffer(len); + for(int i=0;i. + */ +package org.apache.tools.ant.taskdefs; + +import org.apache.tools.ant.Task; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.AntFilterReader; +import org.apache.tools.ant.types.FilterReaderSet; +import org.apache.tools.ant.types.Parameterizable; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.io.*; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Load a file into a property + * + * @author Steve Loughran + * @author Magesh Umasankar + * @created 10 December 2001 + */ +public class LoadFile extends Task { + + /** + * source file, usually null + */ + private File srcFile = null; + + /** + * what to do when it goes pear-shaped + */ + private boolean failOnError = true; + + /** + * Encoding to use for filenames, defaults to the platform's default + * encoding. + */ + private String encoding = null; + + /** + * name of property + */ + private String property = null; + + /** + * flag to control whether props get evaluated or not + */ + private boolean evaluateProperties=false; + + /** + * Holds filterReaderSets + */ + private Vector filterReaderSets=new Vector(); + + /** + * Encoding to use for filenames, defaults to the platform's default + * encoding.

+ * + * For a list of possible values see + * http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html + * .

+ * + * @param encoding The new Encoding value + */ + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + + /** + * Sets the Property attribute of the LoadFile object + * + * @param property The new Property value + */ + public void setProperty(String property) { + this.property = property; + } + + + /** + * Sets the srcfile attribute. + * + * @param srcFile The new SrcFile value + */ + public void setSrcFile(File srcFile) { + this.srcFile = srcFile; + } + + + /** + * Sets the Failonerror attribute of the LoadFile object + * + * @param fail The new Failonerror value + */ + public void setFailonerror(boolean fail) { + failOnError = fail; + } + + + /** + * setter to eval properties. + * @since 1.6 + */ + public void setEvaluateProperties(boolean evaluateProperties) { + this.evaluateProperties=evaluateProperties; + } + + + /** + * read in a source file to a property + * + * @exception BuildException if something goes wrong with the build + */ + public void execute() + throws BuildException { + //validation + if (srcFile == null) { + throw new BuildException("source file not defined"); + } + if (property == null) { + throw new BuildException("output property not defined"); + } + FileInputStream fis = null; + BufferedInputStream bis = null; + Reader instream = null; + log("loading "+srcFile+" into property "+property,Project.MSG_VERBOSE); + try { + long len = srcFile.length(); + log("file size = "+len,Project.MSG_DEBUG); + //discard most of really big files + if (len > Integer.MAX_VALUE) { + log("this file is far to big to load completely"); + } + int size=(int) len; + //open up the file + fis = new FileInputStream(srcFile); + bis = new BufferedInputStream(fis); + if (encoding == null) { + instream = new InputStreamReader(bis); + } + else { + instream = new InputStreamReader(bis, encoding); + } + + String text = processStream(instream, size); + + if(evaluateProperties) { + text = project.replaceProperties(text); + } + project.setNewProperty(property, text); + log("loaded " + text.length() + " characters",Project.MSG_VERBOSE); + log(property+" := "+text,Project.MSG_DEBUG); + + } catch (IOException ioe) { + String message = "Unable to load file: " + ioe.toString(); + if (failOnError) { + throw new BuildException(message, ioe, location); + } + else { + log(message, Project.MSG_ERR); + } + } finally { + try { + if (fis != null) { + fis.close(); + } + } catch (IOException ioex) { + } + } + } + + /** + * Process the input by passing it through the reader chain. + */ + private final String processStream(Reader instream, final int size) + throws IOException { + + final char[] buffer = new char[size]; + final int filterReadersCount = filterReaderSets.size(); + final Vector finalFilters = new Vector(); + + for (int i = 0; i < filterReadersCount; i++) { + final FilterReaderSet filterset = (FilterReaderSet) filterReaderSets.elementAt(i); + final Vector filterReaders = filterset.getFilterReaders(); + final int readerCount = filterReaders.size(); + for (int j = 0; j < readerCount; j++) { + final AntFilterReader fr = (AntFilterReader) filterReaders.elementAt(j); + finalFilters.addElement(fr); + } + } + + final int filtersCount = finalFilters.size(); + + if (filtersCount > 0) { + for (int i = 0; i < filtersCount; i++) { + final AntFilterReader filter = (AntFilterReader) finalFilters.elementAt(i); + final String clazz = filter.getClassName(); + if (clazz != null) { + try { + final Class c = Class.forName(clazz); + if (c != null) { + final Constructor[] constructors = c.getConstructors(); + final Reader[] rdr = {instream}; + instream = (Reader) constructors[0].newInstance(rdr); + if (Parameterizable.class.isAssignableFrom(c)) { + final Hashtable 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); + } + } + } + } + + final int bufferLength = instream.read(buffer); + final String text = new String(buffer, 0, bufferLength); + return text; + } + + /** + * Add the FilterReaderSet element. + */ + public final void addFilterReaderSet(FilterReaderSet filter) { + filterReaderSets.addElement(filter); + } + +//end class +} diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/AntFilterReader.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/AntFilterReader.java new file mode 100644 index 000000000..2d9277556 --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/AntFilterReader.java @@ -0,0 +1,131 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.types; + +import java.io.FilterReader; +import java.util.Hashtable; +import java.util.Vector; + +import org.apache.tools.ant.types.Parameterizable; +import org.apache.tools.ant.BuildException; + +/** + * An AntFileReader is a wrapper class that encloses the classname + * and configuration of a Configurable FilterReader. + * + * @author Magesh Umasankar + */ +public final class AntFilterReader { + + private String className; + + private final Vector parameters = new Vector(); + + public final void setClassName(final String className) { + try { + final Class c = Class.forName(className); + if (FilterReader.class.isAssignableFrom(c)) { + this.className = className; + } else { + throw new BuildException(className + + " does not extend java.io.FilterReader"); + } + } catch (final ClassNotFoundException cnfe) { + throw new BuildException(cnfe); + } + } + + public final String getClassName() { + return className; + } + + public final void addParam(final Parameter param) { + parameters.addElement(param); + } + + public final Hashtable getParams() { + final int size = parameters.size(); + final Hashtable params = new Hashtable(); + for (int i = 0; i < size; i++) { + final Parameter param = (Parameter) parameters.elementAt(i); + final String name = param.getName(); + final String value = param.getValue(); + if (name != null && value != null) { + params.put(name, value); + } + } + return params; + } + + public static final class Parameter { + private String name = null; + private String value = null; + + public final void setName(final String name) { + this.name = name; + } + + public final void setValue(final String value) { + this.value = value; + } + + public final String getName() { + return name; + } + + public final String getValue() { + return value; + } + } +} 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 new file mode 100644 index 000000000..01890e5d2 --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/FilterReaderSet.java @@ -0,0 +1,74 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.types; + +import java.util.Vector; + +/** + * Set of FilterReaders + * + * @author Magesh Umasankar + */ +public final class FilterReaderSet { + + private final Vector filterReaders = new Vector(); + + public final void addFilterReader(final AntFilterReader filterReader) { + filterReaders.addElement(filterReader); + } + + public final Vector getFilterReaders() { + return filterReaders; + } +} diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/Parameterizable.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/Parameterizable.java new file mode 100644 index 000000000..f66f0fae4 --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/types/Parameterizable.java @@ -0,0 +1,65 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.types; + +import java.util.Hashtable; + +/** + * Parameterizable objects take genric key value pairs. + * + * @author Magesh Umasankar + */ +public interface Parameterizable { + void setParameters(Hashtable parameters); +}