diff --git a/WHATSNEW b/WHATSNEW index 6f59b8f74..69d357c2b 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -77,6 +77,16 @@ Fixed bugs: Other changes: -------------- +* New filter readers: ClassConstants, ExpandProperties, HeadFilter, + LineContains, LineContainsRegExp, PrefixLines, ReplaceTokens, + StripJavaComments, StripLineBreaks, StripLineComments, TabsToSpaces, + TailFilter. + +* , , , support FilterChains + of FilterReaders. + +* New task to load contents of file as Ant properties. + * Users can control what and must do when duplicate files are found. A new element allows for multiple zip files to be merged into the archive. In addition, also has diff --git a/build.xml b/build.xml index 9d95e66c7..727f61912 100644 --- a/build.xml +++ b/build.xml @@ -208,6 +208,8 @@ unless="jakarta.oro.present"/> + Description

Load a text file into a single property. Unless an encoding is specified, - the encoding of the current locale is used. There is no explicit limit - upon the size of the file which can be loaded, but loading very large - files is not something anyone has yet explored. Because the file is - converted to text + the encoding of the current locale is used.

@@ -44,40 +41,21 @@ Whether to halt the build on failure No, default "true" - - evaluateProperties - flag to enable property evalation in the file - No, default "false" - - - makeOneLine - flag to strip out newlines (but not spaces or - tabs) from the file - No, default "false" -

-The makeOneLine parameter enables you to use a file as an -input to task parameters which expect single line input. It flattens -the file by removing all carriage return and line feed characters, -so that the file -

a
-b
-c
-
would become "abc": you need spaces or -commas at the end/start of line to stop alphanumeric characters -being merged together. +The LoadFile task supports nested +FilterChains.

Examples

    <loadfile property="message"
-      srcFile="message.txt" / >
+      srcFile="message.txt" />
 
Load file message.txt into property "message"; an <echo> can print this.
    <loadfile property="encoded-file"
       srcFile="loadfile.xml"
-      encoding="ISO-8859-1" / >
+      encoding="ISO-8859-1" />
 
Load a file using the latin-1 encoding @@ -90,20 +68,22 @@ Load a file, don't fail if it is missing (a message is printed, though)
    <loadfile
       property="mail.recipients"
-      srcFile="recipientlist.txt"
-      makeOneLine="true" />
+      srcFile="recipientlist.txt">
+      <filterchain>
+        <striplinebreaks/>
+      </filterchaint>
+    </loadfile>
 
- -load a property which can be used as a parameter for another task (in this case mail), +Load a property which can be used as a parameter for another task (in this case mail), merging lines to ensure this happens.
    <loadfile
       property="system.configuration.xml"
-      srcFile="configuration.xml"
-      evaluateProperties="true" />
+      srcFile="configuration.xml">
+        <expandproperties/>
+    </loadfile>
 
- -load an XML file into a property, expanding all properties declared +Load an XML file into a property, expanding all properties declared in the file in the process. diff --git a/docs/manual/CoreTasks/loadproperties.html b/docs/manual/CoreTasks/loadproperties.html new file mode 100644 index 000000000..91d94ad26 --- /dev/null +++ b/docs/manual/CoreTasks/loadproperties.html @@ -0,0 +1,59 @@ + + +LoadProperties Task + + + + + +

LoadProperties

+

Description

+

+Load a file's contents as Ant properties. This is equivalent +to <property file="..."/> except that it +supports nested <filterchain> elements and it cannot be +specified outside a target. + +

+ +

Parameters

+ + + + + + + + + + + +
AttributeDescriptionRequired
srcFilesource fileYes
+

+The LoadProperties task supports nested +FilterChains. + +

Examples

+
    <loadproperties srcFile="file.properties" />
+
+Load contents of file.properties as Ant properties. + +
    <loadproperties srcFile="file.properties">
+      <filterchain>
+        <linecontains>
+          <contains value="import."/>
+        <linecontains/>
+      </filterchaint>
+    </loadproperties>
+
+Read the lines that contain the string "import." +from the file "file.properties" and load them as +Ant properties. +
+ +

Copyright © 2002 Apache Software Foundation. All rights +Reserved.

+ + + + diff --git a/docs/manual/conceptstypeslist.html b/docs/manual/conceptstypeslist.html index 2e2997b38..a2cbc22b8 100644 --- a/docs/manual/conceptstypeslist.html +++ b/docs/manual/conceptstypeslist.html @@ -18,6 +18,7 @@ FileList
FileSet
File Mappers
+FilterChains and FilterReaders
Filterset
Patternset
diff --git a/docs/manual/coretasklist.html b/docs/manual/coretasklist.html index 17cbc6a95..aa93b5966 100644 --- a/docs/manual/coretasklist.html +++ b/docs/manual/coretasklist.html @@ -48,6 +48,7 @@ Javac
Javadoc/Javadoc2
LoadFile
+LoadProperties
Mail
Manifest
Mkdir
diff --git a/src/etc/testcases/taskdefs/copy.xml b/src/etc/testcases/taskdefs/copy.xml index 712970e81..73014a75a 100644 --- a/src/etc/testcases/taskdefs/copy.xml +++ b/src/etc/testcases/taskdefs/copy.xml @@ -52,6 +52,16 @@
+ + + + + + + + + + @@ -60,6 +70,7 @@ + diff --git a/src/etc/testcases/taskdefs/loadfile.xml b/src/etc/testcases/taskdefs/loadfile.xml index e57c02d07..b90fad278 100644 --- a/src/etc/testcases/taskdefs/loadfile.xml +++ b/src/etc/testcases/taskdefs/loadfile.xml @@ -53,12 +53,39 @@ file="loadfile1.tmp" /> - ${testLoadAFile} + srcFile="loadfile1.tmp"> + + + + + ${testEvalProps} + + #Line 1 +REM Line 2 +--Line 3 +Line 4 +Hello World! + + + + + + + + + + + + + + + + + @@ -67,10 +94,12 @@ file="loadfile1.tmp" /> - ${testLoadAFile} + srcFile="loadfile1.tmp"> + + + + + ${testOneLine} diff --git a/src/etc/testcases/taskdefs/move.xml b/src/etc/testcases/taskdefs/move.xml index 6d584c3e5..e40e78516 100644 --- a/src/etc/testcases/taskdefs/move.xml +++ b/src/etc/testcases/taskdefs/move.xml @@ -11,8 +11,20 @@ + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/filters/BaseFilterReader.java b/src/main/org/apache/tools/ant/filters/BaseFilterReader.java new file mode 100644 index 000000000..5ce041edb --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/BaseFilterReader.java @@ -0,0 +1,207 @@ +/* + * 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.filters; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.FileUtils; + +/** + * Base class for core filter readers. + * + * @author Magesh Umasankar + */ +public abstract class BaseFilterReader + extends FilterReader +{ + /** Have the parameters passed been interpreted? */ + private boolean initialized = false; + + /** The Ant project */ + private Project project = null; + + /** + * 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 BaseFilterReader() { + // 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. + * + * @param in a Reader object providing the underlying stream. + */ + public BaseFilterReader(final Reader in) { + super(in); + } + + /** + * Read characters into a portion of an array. This method will block + * until some input is available, an I/O error occurs, or the end of the + * stream is reached. + * + * @param cbuf Destination buffer + * @param off Offset at which to start storing characters + * @param len Maximum number of characters to read + * + * @return The number of characters read, or -1 if the end of the + * stream has been reached + * + * @exception IOException If an I/O error occurs + */ + public final int read(final char cbuf[], final int off, + final int len) throws IOException { + for (int i = 0; i < len; i++) { + final int ch = read(); + if (ch == -1) { + if (i == 0) { + return -1; + } else { + return i; + } + } + cbuf[off + i] = (char) ch; + } + return len; + } + + /** + * Skip characters. This method will block until some characters are + * available, an I/O error occurs, or the end of the stream is reached. + * + * @param n The number of characters to skip + * + * @return The number of characters actually skipped + * + * @exception IllegalArgumentException If n is negative. + * @exception IOException If an I/O error occurs + */ + public final long skip(final long n) throws IOException { + if (n < 0L) { + throw new IllegalArgumentException("skip value is negative"); + } + + for (long i = 0; i < n; i++) { + if (read() == -1) { + return i; + } + } + return n; + } + + /** + * Set the initialized status. + */ + protected final void setInitialized(final boolean initialized) { + this.initialized = initialized; + } + + /** + * Get the initialized status. + */ + protected final boolean getInitialized() { + return initialized; + } + + /** + * Set the project to work with + */ + public final void setProject(final Project project) { + this.project = project; + } + + /** + * Get the project + */ + protected final Project getProject() { + return project; + } + + /** + * Read till EOL + */ + protected final String readLine() throws IOException { + int ch = in.read(); + String line = (ch == -1) ? null : ""; + while (ch != -1) { + line += (char) ch; + if (ch == '\n') { + break; + } + ch = in.read(); + } + return line; + } + + /** + * Read till EOF + */ + protected final String readFully() throws IOException { + return FileUtils.readFully(in, 8192); + } +} diff --git a/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java b/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java new file mode 100644 index 000000000..ff9109c48 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java @@ -0,0 +1,106 @@ +/* + * 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.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; + +/** + * Parameterized Base class for core filter readers. + * + * @author Magesh Umasankar + */ +public abstract class BaseParamFilterReader + extends BaseFilterReader + implements Parameterizable +{ + /** The passed in parameter array. */ + private Parameter[] parameters; + + /** + * 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 BaseParamFilterReader() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public BaseParamFilterReader(final Reader in) { + super(in); + } + + /** + * Set Parameters + */ + public final void setParameters(final Parameter[] parameters) { + this.parameters = parameters; + setInitialized(false); + } + + protected final Parameter[] getParameters() { + return parameters; + } +} diff --git a/src/main/org/apache/tools/ant/filters/ChainableReader.java b/src/main/org/apache/tools/ant/filters/ChainableReader.java new file mode 100644 index 000000000..548d0aaeb --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/ChainableReader.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.filters; + +import java.io.Reader; + +/** + * Chains readers. + * + * @author Magesh Umasankar + */ +public interface ChainableReader { + public Reader chain(Reader rdr); +} diff --git a/src/main/org/apache/tools/ant/filters/ClassConstants.java b/src/main/org/apache/tools/ant/filters/ClassConstants.java new file mode 100644 index 000000000..f59c88130 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/ClassConstants.java @@ -0,0 +1,187 @@ +/* + * 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.filters; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.Reader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tools.ant.Project; + +/** + * Assemble the constants declared in a Java class in + * key1=value1(line separator)key2=value2 + * format + * + * Notes: + * ===== + * 1. This filter uses the BCEL external toolkit. + * 2. This assembles only those constants that are not created + * using the syntax new whatever(). + * 3. This assembles constants declared using the basic datatypes + * and String only. + * 4. The access modifiers of the declared constants do not matter. + * + * Example: + * ======= + * + * <classconstants/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.ClassConstants"/> + * + * @author Magesh Umasankar + */ +public final class ClassConstants + extends BaseFilterReader + implements ChainableReader +{ + /** Data that must be read from, if not null. */ + private String queuedData = null; + + /** Helper Class to be invoked via reflection. */ + private String JAVA_CLASS_HELPER = + "org.apache.tools.ant.filters.util.JavaClassHelper"; + + /** + * 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 ClassConstants() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public ClassConstants(final Reader in) { + super(in); + } + + /** + * Read and assemble the constants declared in a class file. + */ + public final int read() throws IOException { + + int ch = -1; + + if (queuedData != null && queuedData.length() == 0) { + queuedData = null; + } + + if (queuedData != null) { + ch = queuedData.charAt(0); + queuedData = queuedData.substring(1); + if (queuedData.length() == 0) { + queuedData = null; + } + } else { + final String clazz = readFully(); + if (clazz == null) { + ch = -1; + } else { + final byte[] bytes = clazz.getBytes(); + try { + final Class javaClassHelper = + Class.forName(JAVA_CLASS_HELPER); + if (javaClassHelper != null) { + final Class params[] = { + byte[].class + }; + final Method getConstants = + javaClassHelper.getMethod("getConstants", params); + final Object[] args = { + bytes + }; + // getConstants is a staic method, no need to + // pass in the object + final StringBuffer sb = (StringBuffer) + getConstants.invoke(null, args); + if (sb.length() > 0) { + queuedData = sb.toString(); + return read(); + } + } + } catch (ClassNotFoundException cnfe) { + throw new IOException(cnfe.getMessage()); + } catch (NoSuchMethodException nsme) { + throw new IOException(nsme.getMessage()); + } catch (IllegalAccessException iae) { + throw new IOException(iae.getMessage()); + } catch (IllegalArgumentException iarge) { + throw new IOException(iarge.getMessage()); + } catch (InvocationTargetException ite) { + throw new IOException(ite.getMessage()); + } + } + } + return ch; + } + + /** + * Create a new ClassConstants using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + ClassConstants newFilter = new ClassConstants(rdr); + return newFilter; + } +} diff --git a/src/main/org/apache/tools/ant/filters/ExpandProperties.java b/src/main/org/apache/tools/ant/filters/ExpandProperties.java new file mode 100644 index 000000000..3cf146031 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/ExpandProperties.java @@ -0,0 +1,140 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.Project; + +/** + * Expand Ant properties, if any, in the data. + * + * Example: + * ======= + * + * <expandproperties/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.ExpandProperties"/> + * + * @author Magesh Umasankar + */ +public final class ExpandProperties + extends BaseFilterReader + implements ChainableReader +{ + /** Data that must be read from, if not null. */ + private String queuedData = null; + + /** + * 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 ExpandProperties() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public ExpandProperties(final Reader in) { + super(in); + } + + /** + * Prefix lines with user defined prefix. + */ + public final int read() throws IOException { + + int ch = -1; + + if (queuedData != null && queuedData.length() == 0) { + queuedData = null; + } + + if (queuedData != null) { + ch = queuedData.charAt(0); + queuedData = queuedData.substring(1); + if (queuedData.length() == 0) { + queuedData = null; + } + } else { + queuedData = readFully(); + if (queuedData == null) { + ch = -1; + } else { + Project project = getProject(); + queuedData = project.replaceProperties(queuedData); + return read(); + } + } + return ch; + } + + /** + * Create a new PrefixLines using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + ExpandProperties newFilter = new ExpandProperties(rdr); + newFilter.setProject(getProject()); + return newFilter; + } +} diff --git a/src/main/org/apache/tools/ant/filters/HeadFilter.java b/src/main/org/apache/tools/ant/filters/HeadFilter.java new file mode 100644 index 000000000..f0eb99847 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/HeadFilter.java @@ -0,0 +1,171 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; + +/** + * Read the first n lines (Default is first 10 lines) + * + * Example: + * ======= + * + * <headfilter lines="3"/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.HeadFilter"> + * <param name="lines" value="3"/> + * </filterreader> + * + * @author Magesh Umasankar + */ +public final class HeadFilter + extends BaseParamFilterReader + implements ChainableReader +{ + /** Lines key to represent the number of lines to be returned. */ + private static final String LINES_KEY = "lines"; + + /** Number of lines currently read in. */ + private long linesRead = 0; + + /** Default number of lines returned. */ + private long lines = 10; + + /** + * 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() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public HeadFilter(final Reader in) { + super(in); + } + + /** + * Read the first n lines. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (linesRead < lines) { + + ch = in.read(); + + if (ch == '\n') { + linesRead++; + } + } + + return ch; + } + + /** + * Set number of lines to be returned. + */ + public final void setLines(final long lines) { + this.lines = lines; + } + + /** + * Get number of lines to be returned. + */ + private final long getLines() { + return lines; + } + + /** + * Create a new HeadFilter using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + HeadFilter newFilter = new HeadFilter(rdr); + newFilter.setLines(getLines()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Scan for the lines parameter. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (LINES_KEY.equals(params[i].getName())) { + lines = new Long(params[i].getValue()).longValue(); + break; + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/LineContains.java b/src/main/org/apache/tools/ant/filters/LineContains.java new file mode 100644 index 000000000..8e9fd6b0d --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/LineContains.java @@ -0,0 +1,225 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; + +import org.apache.tools.ant.types.Parameter; + +/** + * Filter Reader to fetch only those lines that contain user specified + * strings. + * + * Example: + * ======= + * + * <linecontains> + * <contains value="foo"> + * <contains value="bar"> + * </linecontains> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.LineContains"> + * <param type="contains" value="foo"/> + * <param type="contains" value="bar"/> + * </filterreader> + * + * This will fetch all those lines that contain foo and bar + * + * @author Magesh Umasankar + */ +public final class LineContains + extends BaseParamFilterReader + implements ChainableReader +{ + /** contains key */ + private static final String CONTAINS_KEY = "contains"; + + /** Vector that holds the strings that input lines must contain. */ + private Vector contains = new Vector(); + + /** Currently read in line. */ + private String line = null; + + /** + * 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 LineContains() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public LineContains(final Reader in) { + super(in); + } + + /** + * Choose only those lines that contains + * user defined values. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (line != null) { + ch = line.charAt(0); + if (line.length() == 1) { + line = null; + } else { + line = line.substring(1); + } + } else { + line = readLine(); + if (line == null) { + ch = -1; + } else { + int containsSize = contains.size(); + for (int i = 0; i < containsSize; i++) { + String containsStr = (String) contains.elementAt(i); + if (line.indexOf(containsStr) == -1) { + line = null; + break; + } + } + + return read(); + } + } + + return ch; + } + + /** + * Add a contains element. + */ + public final void addConfiguredContains(final Contains contains) { + this.contains.addElement(contains.getValue()); + } + + /** + * Set contains vector. + */ + private void setContains(final Vector contains) { + this.contains = contains; + } + + /** + * Get contains vector. + */ + private final Vector getContains() { + return contains; + } + + /** + * Create a new LineContains using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + LineContains newFilter = new LineContains(rdr); + newFilter.setContains(getContains()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Parse params to add user defined contains strings. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (CONTAINS_KEY.equals(params[i].getType())) { + contains.addElement(params[i].getValue()); + } + } + } + } + + /** + * Holds a contains element + */ + public static class Contains { + + /** User defined contains string */ + private String value; + + /** + * Set the contains string + */ + public final void setValue(String contains) { + value = contains; + } + + /** + * Get the contains string + */ + public final String getValue() { + return value; + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java b/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java new file mode 100644 index 000000000..8e2e2e999 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java @@ -0,0 +1,208 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; + +import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.RegularExpression; +import org.apache.tools.ant.util.regexp.Regexp; + +/** + * Filter Reader to fetch only those lines that contain user specified + * regular expression matching strings. + * + * Example: + * ======= + * + * <linecontainsregexp> + * <regexp pattern="foo*"> + * </linecontainsregexp> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.LineContainsRegExp"> + * <param type="regexp" value="foo*"/> + * </filterreader> + * + * This will fetch all those lines that contain the pattern foo + * + * @author Magesh Umasankar + */ +public final class LineContainsRegExp + extends BaseParamFilterReader + implements ChainableReader +{ + /** contains key */ + private static final String REGEXP_KEY = "regexp"; + + /** Vector that holds the strings that input lines must contain. */ + private Vector regexps = new Vector(); + + /** Currently read in line. */ + private String line = null; + + /** + * 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 LineContainsRegExp() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public LineContainsRegExp(final Reader in) { + super(in); + } + + /** + * Choose only those lines that contains + * user defined values. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (line != null) { + ch = line.charAt(0); + if (line.length() == 1) { + line = null; + } else { + line = line.substring(1); + } + } else { + line = readLine(); + if (line == null) { + ch = -1; + } else { + final int regexpsSize = regexps.size(); + for (int i = 0; i < regexpsSize; i++) { + RegularExpression regexp = (RegularExpression) + regexps.elementAt(i); + Regexp re = regexp.getRegexp(getProject()); + boolean matches = re.matches(line); + if (!matches) { + line = null; + break; + } + } + + return read(); + } + } + + return ch; + } + + /** + * Add a contains element. + */ + public final void addConfiguredRegexp(final RegularExpression regExp) { + this.regexps.addElement(regExp); + } + + /** + * Set regexps vector. + */ + private void setRegexps(final Vector regexps) { + this.regexps = regexps; + } + + /** + * Get regexps vector. + */ + private final Vector getRegexps() { + return regexps; + } + + /** + * Create a new LineContainsRegExp using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + LineContainsRegExp newFilter = new LineContainsRegExp(rdr); + newFilter.setRegexps(getRegexps()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Parse params to add user defined contains strings. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (REGEXP_KEY.equals(params[i].getType())) { + String pattern = params[i].getValue(); + RegularExpression regexp = new RegularExpression(); + regexp.setPattern(pattern); + regexps.addElement(regexp); + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/PrefixLines.java b/src/main/org/apache/tools/ant/filters/PrefixLines.java new file mode 100644 index 000000000..6ba85a936 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/PrefixLines.java @@ -0,0 +1,183 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; + +/** + * Attach a prefix to every line + * + * Example: + * ======= + * + * <prefixlines prefix="Foo"/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.PrefixLines"> + * <param name="prefix" value="Foo"/> + * </filterreader> + * + * @author Magesh Umasankar + */ +public final class PrefixLines + extends BaseParamFilterReader + implements ChainableReader +{ + /** prefix key */ + private static final String PREFIX_KEY = "prefix"; + + /** The prefix to be used. */ + private String prefix = null; + + /** Data that must be read from, if not null. */ + private String queuedData = null; + + /** + * 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 PrefixLines() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public PrefixLines(final Reader in) { + super(in); + } + + /** + * Prefix lines with user defined prefix. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (queuedData != null && queuedData.length() == 0) { + queuedData = null; + } + + if (queuedData != null) { + ch = queuedData.charAt(0); + queuedData = queuedData.substring(1); + if (queuedData.length() == 0) { + queuedData = null; + } + } else { + queuedData = readLine(); + if (queuedData == null) { + ch = -1; + } else { + if (prefix != null) { + queuedData = prefix + queuedData; + } + return read(); + } + } + return ch; + } + + /** + * Set the prefix + */ + public final void setPrefix(final String prefix) { + this.prefix = prefix; + } + + /** + * Get the prefix + */ + private final String getPrefix() { + return prefix; + } + + /** + * Create a new PrefixLines using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + PrefixLines newFilter = new PrefixLines(rdr); + newFilter.setPrefix(getPrefix()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Initialize prefix if available from the param element. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (PREFIX_KEY.equals(params[i].getName())) { + prefix = params[i].getValue(); + break; + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/ReplaceTokens.java b/src/main/org/apache/tools/ant/filters/ReplaceTokens.java new file mode 100644 index 000000000..fd7ab0a50 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/ReplaceTokens.java @@ -0,0 +1,299 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; +import java.util.Hashtable; + +import org.apache.tools.ant.types.Parameter; + +/** + * Replace tokens with user supplied values + * + * Example Usage: + * ============= + * + * <replacetokens begintoken="#" endtoken="#"> + * <token key="DATE" value="${TODAY}"/> + * </replacetokens> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"> + * <param type="tokenchar" name="begintoken" value="#"/> + * <param type="tokenchar" name="endtoken" value="#"/> + * <param type="token" name="DATE" value="${TODAY}"/> + * </filterreader> + * + * @author Magesh Umasankar + */ +public final class ReplaceTokens + extends BaseParamFilterReader + implements ChainableReader +{ + /** Default begin token character. */ + private static final char DEFAULT_BEGIN_TOKEN = '@'; + + /** Default end token character. */ + private static final char DEFAULT_END_TOKEN = '@'; + + /** Data that must be read from, if not null. */ + private String queuedData = null; + + /** Hashtable to hold the replacee-replacer pairs. */ + private Hashtable hash = new Hashtable(); + + /** Begin token. */ + private char beginToken = DEFAULT_BEGIN_TOKEN; + + /** End token. */ + private char endToken = DEFAULT_END_TOKEN; + + /** + * 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 ReplaceTokens() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public ReplaceTokens(final Reader in) { + super(in); + } + + /** + * Replace tokens with values. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + if (queuedData != null && queuedData.length() > 0) { + final int ch = queuedData.charAt(0); + if (queuedData.length() > 1) { + queuedData = queuedData.substring(1); + } else { + queuedData = null; + } + return ch; + } + + int ch = in.read(); + if (ch == beginToken) { + final StringBuffer key = new StringBuffer(""); + do { + ch = in.read(); + if (ch != -1) { + key.append((char) ch); + } else { + break; + } + } while (ch != endToken); + + if (ch == -1) { + queuedData = beginToken + key.toString(); + return read(); + } else { + key.setLength(key.length() - 1); + final String replaceWith = (String) hash.get(key.toString()); + if (replaceWith != null) { + queuedData = replaceWith; + return read(); + } else { + queuedData = beginToken + key.toString() + endToken; + return read(); + } + } + } + return ch; + } + + /** + * Set begin token. + */ + public final void setBeginToken(final char beginToken) { + this.beginToken = beginToken; + } + + /** + * Get begin token. + */ + private final char getBeginToken() { + return beginToken; + } + + /** + * Set end token. + */ + public final void setEndToken(final char endToken) { + this.endToken = endToken; + } + + /** + * Get begin token. + */ + private final char getEndToken() { + return endToken; + } + + /** + * Add a token element. + */ + public final void addConfiguredToken(final Token token) { + hash.put(token.getKey(), token.getValue()); + } + + /** + * Set the tokens. + */ + private void setTokens(final Hashtable hash) { + this.hash = hash; + } + + /** + * Get the tokens. + */ + private final Hashtable getTokens() { + return hash; + } + + /** + * Create a new ReplaceTokens using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + ReplaceTokens newFilter = new ReplaceTokens(rdr); + newFilter.setBeginToken(getBeginToken()); + newFilter.setEndToken(getEndToken()); + newFilter.setTokens(getTokens()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Initialize tokens and load the replacee-replacer hashtable. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (params[i] != null) { + final String type = params[i].getType(); + if ("tokenchar".equals(type)) { + final String name = params[i].getName(); + if ("begintoken".equals(name)) { + beginToken = params[i].getValue().charAt(0); + } else if ("endtoken".equals(name)) { + endToken = params[i].getValue().charAt(0); + } + } else if ("token".equals(type)) { + final String name = params[i].getName(); + final String value = params[i].getValue(); + hash.put(name, value); + } + } + } + } + } + + /** + * Holds a token + */ + public static class Token { + + /** token key */ + private String key; + + /** token value */ + private String value; + + /** + * Set the token key + */ + public final void setKey(String key) { + this.key = key; + } + + /** + * Set the token value + */ + public final void setValue(String value) { + this.value = value; + } + + /** + * Get the token key + */ + public final String getKey() { + return key; + } + + /** + * Get the token value + */ + public final String getValue() { + return value; + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/StringInputStream.java b/src/main/org/apache/tools/ant/filters/StringInputStream.java new file mode 100644 index 000000000..abfc50491 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/StringInputStream.java @@ -0,0 +1,115 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; + +/** + * Wrap a String as an InputStream + * + * @author Magesh Umasankar + * @created 20 February 2002 + */ +public class StringInputStream + extends InputStream +{ + /** Source string is stored as a StringReader */ + private StringReader in; + + /** + * Compose a stream from a String + */ + public StringInputStream(String source) { + in = new StringReader(source); + } + + /** + * Read from the Stringreader + */ + public int read() throws IOException { + return in.read(); + } + + /** + * Close the Stringreader + */ + public void close() throws IOException { + in.close(); + } + + /** + * Mark the read limit of the StringReader + */ + public synchronized void mark(final int limit) { + try { + in.mark(limit); + } catch (IOException ioe) { + throw new RuntimeException(ioe.getMessage()); + } + } + + /** + * Resetthe StringReader + */ + public synchronized void reset() throws IOException { + in.reset(); + } + + public boolean markSupported() { + return true; + } +} + diff --git a/src/main/org/apache/tools/ant/filters/StripJavaComments.java b/src/main/org/apache/tools/ant/filters/StripJavaComments.java new file mode 100644 index 000000000..fb01559b1 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/StripJavaComments.java @@ -0,0 +1,150 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +/** + * This is a java comment and string stripper reader that filters + * these lexical tokens out for purposes of simple Java parsing. + * (if you have more complex Java parsing needs, use a real lexer). + * Since this class heavily relies on the single char read function, + * you are reccomended to make it work on top of a buffered reader. + */ +public final class StripJavaComments + extends BaseFilterReader + implements ChainableReader +{ + /** + * 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 StripJavaComments() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public StripJavaComments(final Reader in) { + super(in); + } + + /** + * Filter out Java Style comments + */ + public final int read() throws IOException { + int ch = in.read(); + if (ch == '/') { + ch = in.read(); + if (ch == '/') { + while (ch != '\n' && ch != -1) { + ch = in.read(); + } + } else if (ch == '*') { + while (ch != -1) { + ch = in.read(); + if (ch == '*') { + ch = in.read(); + while (ch == '*' && ch != -1) { + ch = in.read(); + } + + if (ch == '/') { + ch = read(); + break; + } + } + } + } + } + + if (ch == '"') { + while (ch != -1) { + ch = in.read(); + if (ch == '\\') { + ch = in.read(); + } else if (ch == '"') { + ch = read(); + break; + } + } + } + + if (ch == '\'') { + ch = in.read(); + if (ch == '\\') { + ch = in.read(); + } + ch = in.read(); + ch = read(); + } + + return ch; + } + + /** + * Create a new StripJavaComments object using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + StripJavaComments newFilter = new StripJavaComments(rdr); + return newFilter; + } +} diff --git a/src/main/org/apache/tools/ant/filters/StripLineBreaks.java b/src/main/org/apache/tools/ant/filters/StripLineBreaks.java new file mode 100644 index 000000000..e448bcd31 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/StripLineBreaks.java @@ -0,0 +1,176 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; + +/** + * Filter to flatten the stream to a single line. + * + * <striplinebreaks/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.StripLineBreaks"/> + * + * @author Steve Loughran + * @author Magesh Umasankar + */ +public final class StripLineBreaks + extends BaseParamFilterReader + implements ChainableReader +{ + /** + * 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"; + + + /** Holds the characters that are recognized as line breaks. */ + private String lineBreaks = DEFAULT_LINE_BREAKS; + + /** + * 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 StripLineBreaks() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public StripLineBreaks(final Reader in) { + super(in); + } + + /** + * If the character that is being read in is a + * line break character, ignore it and move on to the + * next one. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = in.read(); + while (ch != -1) { + if (lineBreaks.indexOf(ch) == -1) { + break; + } else { + ch = in.read(); + } + } + return ch; + } + + /** + * Set the line break characters. + */ + public final void setLineBreaks(final String lineBreaks) { + this.lineBreaks = lineBreaks; + } + + /** + * Get the line breaks characters + */ + private final String getLineBreaks() { + return lineBreaks; + } + + /** + * Create a new StripLineBreaks object using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + StripLineBreaks newFilter = new StripLineBreaks(rdr); + newFilter.setLineBreaks(getLineBreaks()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Line break characters set using the param element. + */ + private final void initialize() { + String userDefinedLineBreaks = null; + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (LINE_BREAKS_KEY.equals(params[i].getName())) { + userDefinedLineBreaks = params[i].getValue(); + break; + } + } + } + if (userDefinedLineBreaks != null) { + lineBreaks = userDefinedLineBreaks; + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/StripLineComments.java b/src/main/org/apache/tools/ant/filters/StripLineComments.java new file mode 100644 index 000000000..f9521c65b --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/StripLineComments.java @@ -0,0 +1,227 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; +import java.util.Vector; + +import org.apache.tools.ant.types.Parameter; + +/** + * This is a line comment stripper reader + * + * Example: + * ======= + * + * <striplinecomments> + * <comment value="#"/> + * <comment value="--"/> + * <comment value="REM "/> + * <comment value="rem "/> + * <comment value="//"/> + * </striplinecomments> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.StripLineComments"> + * <param type="comment" value="#"/> + * <param type="comment" value="--"/> + * <param type="comment" value="REM "/> + * <param type="comment" value="rem "/> + * <param type="comment" value="//"/> + * </filterreader> + * + * @author Magesh Umasankar + */ +public final class StripLineComments + extends BaseParamFilterReader + implements ChainableReader +{ + /** The type that param recognizes to set the comments. */ + private static final String COMMENTS_KEY = "comment"; + + /** Vector that holds comments. */ + private Vector comments = new Vector(); + + /** The line that has been read ahead. */ + private String line = null; + + /** + * 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 StripLineComments() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public StripLineComments(final Reader in) { + super(in); + } + + /** + * Read in line by line; Ignore line if it + * begins with a comment string. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (line != null) { + ch = line.charAt(0); + if (line.length() == 1) { + line = null; + } else { + line = line.substring(1); + } + } else { + line = readLine(); + if (line == null) { + ch = -1; + } else { + int commentsSize = comments.size(); + for (int i = 0; i < commentsSize; i++) { + String comment = (String) comments.elementAt(i); + if (line.startsWith(comment)) { + line = null; + break; + } + } + return read(); + } + } + + return ch; + } + + /** + * Add the Comment element. + */ + public final void addConfiguredComment(final Comment comment) { + comments.addElement(comment.getValue()); + } + + /** + * Set the comments vector. + */ + private void setComments(final Vector comments) { + this.comments = comments; + } + + /** + * Get the comments vector. + */ + private final Vector getComments() { + return comments; + } + + /** + * Create a new StripLineComments object using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + StripLineComments newFilter = new StripLineComments(rdr); + newFilter.setComments(getComments()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Comments set using the param element. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (COMMENTS_KEY.equals(params[i].getType())) { + comments.addElement(params[i].getValue()); + } + } + } + } + + /** + * The class that holds a comment. + */ + public static class Comment { + + /** The comment*/ + private String value; + + /** + * Set the comment. + */ + public final void setValue(String comment) { + value = comment; + } + + /** + * Get the comment. + */ + public final String getValue() { + return value; + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/TabsToSpaces.java b/src/main/org/apache/tools/ant/filters/TabsToSpaces.java new file mode 100644 index 000000000..8c91aa286 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/TabsToSpaces.java @@ -0,0 +1,178 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; + +/** + * Converts tabs to spaces. + * + * Example Usage: + * ============= + * + * <tabtospaces tablength="8"/> + * + * Or: + * + * + * + * + * + * @author Magesh Umasankar + */ +public final class TabsToSpaces + extends BaseParamFilterReader + implements ChainableReader +{ + /** The default tab length is 8 */ + private static final int DEFAULT_TAB_LENGTH = 8; + + /** The name that param recognizes to set the tablength. */ + private static final String TAB_LENGTH_KEY = "tablength"; + + /** Default tab length. */ + private int tabLength = DEFAULT_TAB_LENGTH; + + /** How many more spaces must be returned to replace a tab? */ + private int spacesRemaining = 0; + + /** + * 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 TabsToSpaces() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public TabsToSpaces(final Reader in) { + super(in); + } + + /** + * Convert tabs with spaces + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + if (spacesRemaining > 0) { + spacesRemaining--; + ch = ' '; + } else { + ch = in.read(); + if (ch == '\t') { + spacesRemaining = tabLength - 1; + ch = ' '; + } + } + return ch; + } + + /** + * Set the tab length. + */ + public final void setTablength(final int tabLength) { + this.tabLength = tabLength; + } + + /** + * Get the tab length + */ + private final int getTablength() { + return tabLength; + } + + /** + * Create a new TabsToSpaces object using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + TabsToSpaces newFilter = new TabsToSpaces(rdr); + newFilter.setTablength(getTablength()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Initialize tokens + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (params[i] != null) { + if (TAB_LENGTH_KEY.equals(params[i].getName())) { + tabLength = + new Integer(params[i].getValue()).intValue(); + break; + } + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/TailFilter.java b/src/main/org/apache/tools/ant/filters/TailFilter.java new file mode 100644 index 000000000..0f9ccd953 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/TailFilter.java @@ -0,0 +1,218 @@ +/* + * 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.filters; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; + +/** + * Read the last n lines. Default is last 10 lines. + * + * Example: + * ======= + * + * <tailfilter lines="3"/> + * + * Or: + * + * <filterreader classname="org.apache.tools.ant.filters.TailFilter"> + * <param name="lines" value="3"/> + * </filterreader> + * + * @author Magesh Umasankar + */ +public final class TailFilter + extends BaseParamFilterReader + implements ChainableReader +{ + /** The name that param recognizes to set the number of lines. */ + private static final String LINES_KEY = "lines"; + + /** Number of lines currently read in. */ + private long linesRead = 0; + + /** Default number of lines returned. */ + private long lines = 10; + + /** Buffer to hold in characters read ahead. */ + private char[] buffer = new char[4096]; + + /** The character position that has been returned from the buffer. */ + private int returnedCharPos = -1; + + /** Has read ahead been completed? */ + private boolean completedReadAhead = false; + + /** Current index position on the buffer. */ + private int bufferPos = 0; + + /** + * 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 TailFilter() { + super(); + } + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public TailFilter(final Reader in) { + super(in); + } + + /** + * Read ahead and keep in buffer last n lines only at any given + * point. Grow buffer as needed. + */ + public final int read() throws IOException { + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + if (!completedReadAhead) { + int ch = -1; + while ((ch = in.read()) != -1) { + if (buffer.length == bufferPos) { + if (returnedCharPos != -1) { + final char[] tmpBuffer = new char[buffer.length]; + System.arraycopy(buffer, returnedCharPos + 1, tmpBuffer, + 0, buffer.length - (returnedCharPos + 1)); + buffer = tmpBuffer; + bufferPos = bufferPos - (returnedCharPos + 1); + returnedCharPos = -1; + } else { + final char[] tmpBuffer = new char[buffer.length * 2]; + System.arraycopy(buffer, 0, tmpBuffer, 0, bufferPos); + buffer = tmpBuffer; + } + } + + if (ch == '\n' || ch == -1) { + ++linesRead; + + if (linesRead == lines) { + int i = 0; + for (i = returnedCharPos + 1; + buffer[i] != 0 && buffer[i] != '\n'; i++) { + } + returnedCharPos = i; + --linesRead; + } + } + if (ch == -1) { + break; + } + + buffer[bufferPos] = (char) ch; + bufferPos++; + } + completedReadAhead = true; + } + + ++returnedCharPos; + if (returnedCharPos >= bufferPos) { + return -1; + } else { + return buffer[returnedCharPos]; + } + } + + /** + * Set number of lines to be returned. + */ + public final void setLines(final long lines) { + this.lines = lines; + } + + /** + * Get number of lines to be returned. + */ + private final long getLines() { + return lines; + } + + /** + * Create a new TailFilter using the passed in + * Reader for instantiation. + */ + public final Reader chain(final Reader rdr) { + TailFilter newFilter = new TailFilter(rdr); + newFilter.setLines(getLines()); + newFilter.setInitialized(true); + return newFilter; + } + + /** + * Scan for the lines parameter. + */ + private final void initialize() { + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if (LINES_KEY.equals(params[i].getName())) { + setLines(new Long(params[i].getValue()).longValue()); + break; + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java new file mode 100644 index 000000000..384ba17b6 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java @@ -0,0 +1,234 @@ +/* + * 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.filters.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.BaseFilterReader; +import org.apache.tools.ant.filters.ChainableReader; +import org.apache.tools.ant.types.AntFilterReader; +import org.apache.tools.ant.types.FilterChain; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Parameterizable; +import org.apache.tools.ant.util.FileUtils; + +import java.io.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Vector; + +/** + * Process a FilterReader chain. + * + * @author Magesh Umasankar + * @created 23 February 2002 + */ +public final class ChainReaderHelper { + + /** + * The primary reader to which the reader chain is to be attached. + */ + public Reader primaryReader; + + /** + * The size of the buffer to be used. + */ + public int bufferSize = 8192; + + /** + * Chain of filters + */ + public Vector filterChains = new Vector(); + + /** The Ant project */ + private Project project = null; + + /** + * Sets the primary reader + */ + public final void setPrimaryReader(Reader rdr) { + primaryReader = rdr; + } + + /** + * Set the project to work with + */ + public final void setProject(final Project project) { + this.project = project; + } + + /** + * Get the project + */ + public final Project getProject() { + return project; + } + + /** + * Sets the buffer size to be used. Defaults to 4096, + * if this method is not invoked. + */ + public final void setBufferSize(int size) { + bufferSize = size; + } + + /** + * Sets the collection of filter reader sets + */ + public final void setFilterChains(Vector fchain) { + filterChains = fchain; + } + + /** + * Assemble the reader + */ + public final Reader getAssembledReader() throws BuildException { + if (primaryReader == null) { + throw new BuildException("primaryReader must not be null."); + } + + Reader instream = primaryReader; + final int filterReadersCount = filterChains.size(); + final Vector finalFilters = new Vector(); + + for (int i = 0; i < filterReadersCount; i++) { + final FilterChain filterchain = + (FilterChain) filterChains.elementAt(i); + final Vector filterReaders = filterchain.getFilterReaders(); + final int readerCount = filterReaders.size(); + for (int j = 0; j < readerCount; j++) { + finalFilters.addElement(filterReaders.elementAt(j)); + } + } + + final int filtersCount = finalFilters.size(); + + if (filtersCount > 0) { + for (int i = 0; i < filtersCount; i++) { + 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); + } + 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); + } + } + } else if (o instanceof ChainableReader && + o instanceof Reader) { + if (project != null && o instanceof BaseFilterReader) { + ((BaseFilterReader) o).setProject(project); + } + instream = ((ChainableReader) o).chain(instream); + } + } + } + return instream; + } + + /** + * Read data from the reader and return the + * contents as a string. + */ + public final String readFully(Reader rdr) + throws IOException { + return FileUtils.readFully(rdr, bufferSize); + } +} diff --git a/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java b/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java new file mode 100644 index 000000000..809a407a0 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java @@ -0,0 +1,103 @@ +/* + * 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.filters.util; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.apache.bcel.classfile.ClassParser; +import org.apache.bcel.classfile.ConstantValue; +import org.apache.bcel.classfile.Field; +import org.apache.bcel.classfile.JavaClass; + +/** + * Helper class that filters constants from a Java Class + * + * @author Magesh Umasankar + */ +public final class JavaClassHelper { + + /** System specific line separator. */ + private static final String LS = System.getProperty("line.separator"); + + /** + * Get the constants declared in a file as name=value + */ + public static final StringBuffer getConstants(byte[] bytes) + throws IOException { + final StringBuffer sb = new StringBuffer(); + final ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + final ClassParser parser = new ClassParser(bis, ""); + final JavaClass javaClass = parser.parse(); + final Field[] fields = javaClass.getFields(); + for (int i = 0; i < fields.length; i++) { + final Field field = fields[i]; + if (field != null) { + final ConstantValue cv = field.getConstantValue(); + if (cv != null) { + String cvs = cv.toString(); + //Remove start and end quotes if field is a String + if (cvs.startsWith("\"") && cvs.endsWith("\"")) { + cvs = cvs.substring(1, cvs.length() - 1); + } + sb.append(field.getName()); + sb.append('='); + sb.append(cvs); + sb.append(LS); + } + } + } + return sb; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/Copy.java b/src/main/org/apache/tools/ant/taskdefs/Copy.java index ca9020eb7..0a3baf5f6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Copy.java +++ b/src/main/org/apache/tools/ant/taskdefs/Copy.java @@ -60,6 +60,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Mapper; +import org.apache.tools.ant.types.FilterChain; import org.apache.tools.ant.types.FilterSet; import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.util.FileUtils; @@ -91,7 +92,7 @@ import java.util.Enumeration; * * @version $Revision$ * - * @ant.task category="filesystem" + * @ant:task category="filesystem" */ public class Copy extends Task { protected File file = null; // the source file @@ -111,6 +112,7 @@ public class Copy extends Task { protected Hashtable completeDirMap = new Hashtable(); protected Mapper mapperElement = null; + private Vector filterChains = new Vector(); private Vector filterSets = new Vector(); private FileUtils fileUtils; private String encoding = null; @@ -142,6 +144,15 @@ public class Copy extends Task { this.destDir = destDir; } + /** + * Create a nested filterchain + */ + public FilterChain createFilterChain() { + FilterChain filterChain = new FilterChain(); + filterChains.addElement(filterChain); + return filterChain; + } + /** * Create a nested filterset */ @@ -187,6 +198,15 @@ public class Copy extends Task { return filterSets; } + /** + * Get the filterchains being applied to this operation. + * + * @return a vector of FilterChain objects + */ + protected Vector getFilterChains() { + return filterChains; + } + /** * Sets filtering. */ @@ -457,9 +477,9 @@ public class Copy extends Task { for (Enumeration filterEnum = filterSets.elements(); filterEnum.hasMoreElements();) { executionFilters.addFilterSet((FilterSet)filterEnum.nextElement()); } - fileUtils.copyFile(fromFile, toFile, executionFilters, + fileUtils.copyFile(fromFile, toFile, executionFilters, filterChains, forceOverwrite, preserveLastModified, - encoding); + encoding, project); } catch (IOException ioe) { String msg = "Failed to copy " + fromFile + " to " + toFile + " due to " + ioe.getMessage(); diff --git a/src/main/org/apache/tools/ant/taskdefs/LoadFile.java b/src/main/org/apache/tools/ant/taskdefs/LoadFile.java index 1900e8e57..60215517d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/LoadFile.java +++ b/src/main/org/apache/tools/ant/taskdefs/LoadFile.java @@ -56,18 +56,20 @@ 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.FilterChain; +import org.apache.tools.ant.filters.util.ChainReaderHelper; import java.io.*; +import java.util.Vector; /** * Load a file into a property * * @author Steve Loughran - * - * @ant.task category="utility" + * @author Magesh Umasankar + * @created 10 December 2001 */ -public class LoadFile extends Task { +public final class LoadFile extends Task { /** * source file, usually null @@ -90,16 +92,10 @@ public class LoadFile extends Task { */ private String property = null; - - /** flag to control if we flatten the file or no' - * - */ - private boolean makeOneLine=false; - /** - * flag to control whether props get evaluated or not + * Holds FilterChains */ - private boolean evaluateProperties=false; + private final Vector filterChains = new Vector(); /** * Encoding to use for filenames, defaults to the platform's default @@ -112,7 +108,7 @@ public class LoadFile extends Task { * @param encoding The new Encoding value */ - public void setEncoding(String encoding) { + public final void setEncoding(final String encoding) { this.encoding = encoding; } @@ -122,7 +118,7 @@ public class LoadFile extends Task { * * @param property The new Property value */ - public void setProperty(String property) { + public final void setProperty(final String property) { this.property = property; } @@ -132,7 +128,7 @@ public class LoadFile extends Task { * * @param srcFile The new SrcFile value */ - public void setSrcFile(File srcFile) { + public final void setSrcFile(final File srcFile) { this.srcFile = srcFile; } @@ -142,33 +138,17 @@ public class LoadFile extends Task { * * @param fail The new Failonerror value */ - public void setFailonerror(boolean fail) { + public final void setFailonerror(final boolean fail) { failOnError = fail; } - /** - * setter to flatten the file to a single line - * @since 1.6 - */ - public void setMakeOneLine(boolean makeOneLine) { - this.makeOneLine=makeOneLine; - } - - /** - * 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() + public final void execute() throws BuildException { //validation if (srcFile == null) { @@ -182,14 +162,10 @@ public class LoadFile extends Task { Reader instream = null; log("loading "+srcFile+" into property "+property,Project.MSG_VERBOSE); try { - long len = srcFile.length(); + final 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; - char[] buffer = new char[size]; + final int size=(int) len; //open up the file fis = new FileInputStream(srcFile); bis = new BufferedInputStream(fis); @@ -199,57 +175,53 @@ public class LoadFile extends Task { else { instream = new InputStreamReader(bis, encoding); } - instream.read(buffer); - String text = new String(buffer); - if (makeOneLine) { - text=stripLineBreaks(text); - } - if(evaluateProperties) { - text = project.replaceProperties(text); + + ChainReaderHelper crh = new ChainReaderHelper(); + crh.setBufferSize(size); + crh.setPrimaryReader(instream); + crh.setFilterChains(filterChains); + crh.setProject(project); + instream = crh.getAssembledReader(); + + String text = crh.readFully(instream); + + if (text != null) { + project.setNewProperty(property, text); + log("loaded " + text.length() + " characters",Project.MSG_VERBOSE); + log(property+" := "+text,Project.MSG_DEBUG); } - project.setNewProperty(property, text); - log("loaded "+buffer.length+" characters",Project.MSG_VERBOSE); - log(property+" := "+text,Project.MSG_DEBUG); - } catch (IOException ioe) { - String message = "Unable to load file: " + ioe.toString(); + } catch (final IOException ioe) { + final String message = "Unable to load file: " + ioe.toString(); if (failOnError) { throw new BuildException(message, ioe, location); } else { log(message, Project.MSG_ERR); } + } catch (final BuildException be) { + if (failOnError) { + throw be; + } + else { + log(be.getMessage(), Project.MSG_ERR); + } } finally { try { if (fis != null) { fis.close(); } } catch (IOException ioex) { + //ignore } } } /** - * 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. + * Add the FilterChain element. */ - protected String stripLineBreaks(String source) { - //Linebreaks. What do to on funny IBM mainframes with odd line endings? - String linebreaks="\r\n"; - int len=source.length(); - - 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.FilterChain; +import org.apache.tools.ant.filters.StringInputStream; +import org.apache.tools.ant.filters.util.ChainReaderHelper; + +import java.io.*; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Vector; + +/** + * Load a file's contents as Ant Properties. + * + * @author Magesh Umasankar + * @created 20 February 2002 + */ +public final class LoadProperties extends Task { + + /** + * Source file + */ + private File srcFile = null; + + /** + * Holds filterchains + */ + private final Vector filterChains = new Vector(); + + /** + * Sets the srcfile attribute. + * + * @param srcFile The new SrcFile value + */ + public final void setSrcFile(final File srcFile) { + this.srcFile = srcFile; + } + + /** + * read in a source file's contents and load them up as Ant properties + * + * @exception BuildException if something goes wrong with the build + */ + public final void execute() throws BuildException { + //validation + if (srcFile == null) { + throw new BuildException("Source file not defined."); + } + + if (!srcFile.exists()) { + throw new BuildException("Source file does not exist."); + } + + if (!srcFile.isFile()) { + throw new BuildException("Source file is not a file."); + } + + FileInputStream fis = null; + BufferedInputStream bis = null; + Reader instream = null; + + try { + final long len = srcFile.length(); + final int size=(int) len; + + //open up the file + fis = new FileInputStream(srcFile); + bis = new BufferedInputStream(fis); + instream = new InputStreamReader(bis); + + ChainReaderHelper crh = new ChainReaderHelper(); + crh.setBufferSize(size); + crh.setPrimaryReader(instream); + crh.setFilterChains(filterChains); + crh.setProject(project); + instream = crh.getAssembledReader(); + + String text = crh.readFully(instream); + + if (text != null) { + if (!text.endsWith("\n")) { + text = text + "\n"; + } + + final StringInputStream sis = new StringInputStream(text); + final Properties props = new Properties(); + props.load(sis); + final Enumeration e = props.keys(); + while (e.hasMoreElements()) { + final String key = (String) e.nextElement(); + final String value = props.getProperty(key); + if (key != null && value != null + && value.trim().length() > 0) { + project.setNewProperty(key, value); + } + } + sis.close(); + } + + } catch (final IOException ioe) { + final String message = "Unable to load file: " + ioe.toString(); + throw new BuildException(message, ioe, location); + } catch (final BuildException be) { + throw be; + } finally { + try { + if (fis != null) { + fis.close(); + } + } catch (IOException ioex) { + //ignore + } + } + } + + /** + * Add the FilterChain element. + */ + public final void addFilterChain(FilterChain filter) { + filterChains.addElement(filter); + } + +//end class +} diff --git a/src/main/org/apache/tools/ant/taskdefs/Move.java b/src/main/org/apache/tools/ant/taskdefs/Move.java index 73a60980a..269e4b64b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Move.java +++ b/src/main/org/apache/tools/ant/taskdefs/Move.java @@ -84,11 +84,12 @@ import java.util.Vector; * @author Magesh Umasankar * @version $Revision$ * - * @ant.task category="filesystem" + * @ant:task category="filesystem" */ public class Move extends Copy { private Vector filterSets = null; + private Vector filterChains = null; public Move() { super(); @@ -101,6 +102,7 @@ public class Move extends Copy { protected void doFileOperations() { filterSets = getFilterSets(); + filterChains = getFilterChains(); //Attempt complete directory renames, if any, first. if (completeDirMap.size() > 0) { @@ -162,10 +164,10 @@ public class Move extends Copy { for (Enumeration filterEnum = getFilterSets().elements(); filterEnum.hasMoreElements();) { executionFilters.addFilterSet((FilterSet)filterEnum.nextElement()); } - getFileUtils().copyFile(f, d, executionFilters, + getFileUtils().copyFile(f, d, executionFilters, filterChains, forceOverwrite, getPreserveLastModified(), - getEncoding()); + getEncoding(), project); f = new File(fromFile); if (!f.delete()) { @@ -279,7 +281,8 @@ public class Move extends Copy { throws IOException, BuildException { boolean renamed = true; - if (filterSets != null && filterSets.size() > 0) { + if ((filterSets != null && filterSets.size() > 0) || + (filterChains != null && filterChains.size() > 0)) { renamed = false; } else { if (!filtering) { diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index b94cbe17e..e777055a5 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -60,6 +60,7 @@ waitfor=org.apache.tools.ant.taskdefs.WaitFor input=org.apache.tools.ant.taskdefs.Input loadfile=org.apache.tools.ant.taskdefs.LoadFile manifest=org.apache.tools.ant.taskdefs.Manifest +loadproperties=org.apache.tools.ant.taskdefs.LoadProperties # optional tasks script=org.apache.tools.ant.taskdefs.optional.Script diff --git a/src/main/org/apache/tools/ant/types/AntFilterReader.java b/src/main/org/apache/tools/ant/types/AntFilterReader.java new file mode 100644 index 000000000..80f20b648 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/AntFilterReader.java @@ -0,0 +1,141 @@ +/* + * 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.BuildException; +import org.apache.tools.ant.Project; + +/** + * An AntFileReader is a wrapper class that encloses the classname + * and configuration of a Configurable FilterReader. + * + * @author Magesh Umasankar + */ +public final class AntFilterReader + extends DataType + implements Cloneable { + + private String className; + + private final Vector parameters = new Vector(); + + private Path classpath; + + public final void setClassName(final String className) { + this.className = className; + } + + public final String getClassName() { + return className; + } + + public final void addParam(final Parameter param) { + parameters.addElement(param); + } + + /** + * Set the classpath to load the FilterReader through (attribute). + */ + public final void setClasspath(Path classpath) { + if (isReference()) { + throw tooManyAttributes(); + } + if (this.classpath == null) { + this.classpath = classpath; + } else { + this.classpath.append(classpath); + } + } + + /** + * Set the classpath to load the FilterReader through (nested element). + */ + public final Path createClasspath() { + if (isReference()) { + throw noChildrenAllowed(); + } + if (this.classpath == null) { + this.classpath = new Path(getProject()); + } + return this.classpath.createPath(); + } + + /** + * Get the classpath + */ + public final Path getClasspath() { + return classpath; + } + + /** + * Set the classpath to load the FilterReader through via + * reference (attribute). + */ + public void setClasspathRef(Reference r) { + if (isReference()) { + throw tooManyAttributes(); + } + createClasspath().setRefid(r); + } + + public final Parameter[] getParams() { + Parameter[] params = new Parameter[parameters.size()]; + parameters.copyInto(params); + return params; + } +} diff --git a/src/main/org/apache/tools/ant/types/FilterChain.java b/src/main/org/apache/tools/ant/types/FilterChain.java new file mode 100644 index 000000000..d5a8c6b04 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/FilterChain.java @@ -0,0 +1,139 @@ +/* + * 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; + +import org.apache.tools.ant.filters.ClassConstants; +import org.apache.tools.ant.filters.ExpandProperties; +import org.apache.tools.ant.filters.HeadFilter; +import org.apache.tools.ant.filters.LineContains; +import org.apache.tools.ant.filters.LineContainsRegExp; +import org.apache.tools.ant.filters.PrefixLines; +import org.apache.tools.ant.filters.ReplaceTokens; +import org.apache.tools.ant.filters.StripJavaComments; +import org.apache.tools.ant.filters.StripLineBreaks; +import org.apache.tools.ant.filters.StripLineComments; +import org.apache.tools.ant.filters.TabsToSpaces; +import org.apache.tools.ant.filters.TailFilter; + +/** + * FilterChain may contain a chained set of filter readers. + * + * @author Magesh Umasankar + */ +public final class FilterChain { + + private final Vector filterReaders = new Vector(); + + public final void addFilterReader(final AntFilterReader filterReader) { + filterReaders.addElement(filterReader); + } + + public final Vector getFilterReaders() { + return filterReaders; + } + + public final void addClassConstants(final ClassConstants classConstants) { + filterReaders.addElement(classConstants); + } + + public final void addExpandProperties(final ExpandProperties expandProperties) { + filterReaders.addElement(expandProperties); + } + + public final void addHeadFilter(final HeadFilter headFilter) { + filterReaders.addElement(headFilter); + } + + public final void addLineContains(final LineContains lineContains) { + filterReaders.addElement(lineContains); + } + + public final void addLineContainsRegExp(final LineContainsRegExp + lineContainsRegExp) { + filterReaders.addElement(lineContainsRegExp); + } + + public final void addPrefixLines(final PrefixLines prefixLines) { + filterReaders.addElement(prefixLines); + } + + public final void addReplaceTokens(final ReplaceTokens replaceTokens) { + filterReaders.addElement(replaceTokens); + } + + public final void addStripJavaComments(final StripJavaComments + stripJavaComments) { + filterReaders.addElement(stripJavaComments); + } + + public final void addStripLineBreaks(final StripLineBreaks + stripLineBreaks) { + filterReaders.addElement(stripLineBreaks); + } + + public final void addStripLineComments(final StripLineComments + stripLineComments) { + filterReaders.addElement(stripLineComments); + } + + public final void addTabsToSpaces(final TabsToSpaces tabsToSpaces) { + filterReaders.addElement(tabsToSpaces); + } + + public final void addTailFilter(final TailFilter tailFilter) { + filterReaders.addElement(tailFilter); + } +} diff --git a/src/main/org/apache/tools/ant/types/Parameter.java b/src/main/org/apache/tools/ant/types/Parameter.java new file mode 100644 index 000000000..224de23b5 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/Parameter.java @@ -0,0 +1,89 @@ +/* + * 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; + +/** + * A parameter is composed of a name, type and value. + * + * @author Magesh Umasankar + */ +public final class Parameter { + private String name = null; + private String type = null; + private String value = null; + + public final void setName(final String name) { + this.name = name; + } + + public final void setType(final String type) { + this.type = type; + } + + public final void setValue(final String value) { + this.value = value; + } + + public final String getName() { + return name; + } + + public final String getType() { + return type; + } + + public final String getValue() { + return value; + } +} diff --git a/src/main/org/apache/tools/ant/types/Parameterizable.java b/src/main/org/apache/tools/ant/types/Parameterizable.java new file mode 100644 index 000000000..7c4b5e0b5 --- /dev/null +++ b/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.Vector; + +/** + * Parameterizable objects take genric key value pairs. + * + * @author Magesh Umasankar + */ +public interface Parameterizable { + void setParameters(Parameter[] parameters); +} diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java index 7da78bad1..9febac2b4 100644 --- a/src/main/org/apache/tools/ant/util/FileUtils.java +++ b/src/main/org/apache/tools/ant/util/FileUtils.java @@ -66,16 +66,19 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.io.Reader; import java.lang.reflect.Method; import java.text.DecimalFormat; import java.util.Random; import java.util.Stack; import java.util.StringTokenizer; +import java.util.Vector; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.types.FilterSetCollection; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.filters.util.ChainReaderHelper; +import org.apache.tools.ant.types.FilterSetCollection; /** * This class also encapsulates methods which allow Files to be @@ -85,11 +88,12 @@ import org.apache.tools.ant.types.FilterSetCollection; * * @author duncan@x180.com * @author Conor MacNeill - * @author Stefan Bodewig + * @author Stefan Bodewig + * @author Magesh Umasankar * * @version $Revision$ */ - + public class FileUtils { private static Random rand = new Random(System.currentTimeMillis()); private static Object lockReflection = new Object(); @@ -134,27 +138,27 @@ public class FileUtils { * destination specifying if token filtering must be used and if * source files may overwrite newer destination files. * - * @throws IOException + * @throws IOException */ public void copyFile(String sourceFile, String destFile, FilterSetCollection filters, boolean overwrite) throws IOException { - copyFile(new File(sourceFile), new File(destFile), filters, + copyFile(new File(sourceFile), new File(destFile), filters, overwrite, false); } - /** + /** * Convienence method to copy a file from a source to a * destination specifying if token filtering must be used, if * source files may overwrite newer destination files and the * last modified time of destFile file should be made equal * to the last modified time of sourceFile. * - * @throws IOException + * @throws IOException */ public void copyFile(String sourceFile, String destFile, FilterSetCollection filters, boolean overwrite, boolean preserveLastModified) throws IOException { - copyFile(new File(sourceFile), new File(destFile), filters, + copyFile(new File(sourceFile), new File(destFile), filters, overwrite, preserveLastModified); } @@ -165,18 +169,40 @@ public class FileUtils { * last modified time of destFile file should be made equal * to the last modified time of sourceFile. * - * @throws IOException + * @throws IOException * * @since 1.14, Ant 1.5 */ - public void copyFile(String sourceFile, String destFile, - FilterSetCollection filters, boolean overwrite, + public void copyFile(String sourceFile, String destFile, + FilterSetCollection filters, boolean overwrite, boolean preserveLastModified, String encoding) throws IOException { - copyFile(new File(sourceFile), new File(destFile), filters, + copyFile(new File(sourceFile), new File(destFile), filters, overwrite, preserveLastModified, encoding); } + /** + * Convienence method to copy a file from a source to a + * destination specifying if token filtering must be used, if + * filter chains must be used, if source files may overwrite + * newer destination files and the last modified time of + * destFile file should be made equal + * to the last modified time of sourceFile. + * + * @throws IOException + * + * @since 1.15, Ant 1.5 + */ + public void copyFile(String sourceFile, String destFile, + FilterSetCollection filters, Vector filterChains, + boolean overwrite, boolean preserveLastModified, + String encoding, Project project) + throws IOException { + copyFile(new File(sourceFile), new File(destFile), filters, + filterChains, overwrite, preserveLastModified, + encoding, project); + } + /** * Convienence method to copy a file from a source to a destination. * No filtering is performed. @@ -203,7 +229,7 @@ public class FileUtils { * destination specifying if token filtering must be used and if * source files may overwrite newer destination files. * - * @throws IOException + * @throws IOException */ public void copyFile(File sourceFile, File destFile, FilterSetCollection filters, boolean overwrite) throws IOException { @@ -217,12 +243,12 @@ public class FileUtils { * last modified time of destFile file should be made equal * to the last modified time of sourceFile. * - * @throws IOException + * @throws IOException */ public void copyFile(File sourceFile, File destFile, FilterSetCollection filters, boolean overwrite, boolean preserveLastModified) throws IOException { - copyFile(sourceFile, destFile, filters, overwrite, + copyFile(sourceFile, destFile, filters, overwrite, preserveLastModified, null); } @@ -234,15 +260,36 @@ public class FileUtils { * equal to the last modified time of sourceFile and * which character encoding to assume. * - * @throws IOException + * @throws IOException * * @since 1.14, Ant 1.5 */ - public void copyFile(File sourceFile, File destFile, - FilterSetCollection filters, boolean overwrite, + public void copyFile(File sourceFile, File destFile, + FilterSetCollection filters, boolean overwrite, boolean preserveLastModified, String encoding) throws IOException { - + copyFile(sourceFile, destFile, filters, null, overwrite, + preserveLastModified, encoding, null); + } + + /** + * Convienence method to copy a file from a source to a + * destination specifying if token filtering must be used, if + * filter chains must be used, if source files may overwrite + * newer destination files and the last modified time of + * destFile file should be made equal + * to the last modified time of sourceFile. + * + * @throws IOException + * + * @since 1.15, Ant 1.5 + */ + public void copyFile(File sourceFile, File destFile, + FilterSetCollection filters, Vector filterChains, + boolean overwrite, boolean preserveLastModified, + String encoding, Project project) + throws IOException { + if (overwrite || !destFile.exists() || destFile.lastModified() < sourceFile.lastModified()) { @@ -257,7 +304,12 @@ public class FileUtils { parent.mkdirs(); } - if (filters != null && filters.hasFilters()) { + final boolean filterSetsAvailable = (filters != null + && filters.hasFilters()); + final boolean filterChainsAvailable = (filterChains != null + && filterChains.size() > 0); + + if (filterSetsAvailable || filterChainsAvailable) { BufferedReader in = null; BufferedWriter out = null; @@ -265,8 +317,20 @@ public class FileUtils { in = new BufferedReader(new FileReader(sourceFile)); out = new BufferedWriter(new FileWriter(destFile)); } else { - in = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), encoding)); - out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), encoding)); + in = new BufferedReader(new InputStreamReader( + new FileInputStream(sourceFile), encoding)); + out = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(destFile), encoding)); + } + + if (filterChainsAvailable) { + ChainReaderHelper crh = new ChainReaderHelper(); + crh.setBufferSize(8192); + crh.setPrimaryReader(in); + crh.setFilterChains(filterChains); + crh.setProject(project); + Reader rdr = crh.getAssembledReader(); + in = new BufferedReader(rdr); } int length; @@ -276,7 +340,11 @@ public class FileUtils { if (line.length() == 0) { out.newLine(); } else { - newline = filters.replaceTokens(line); + if (filterSetsAvailable) { + newline = filters.replaceTokens(line); + } else { + newline = line; + } out.write(newline); out.newLine(); } @@ -317,8 +385,8 @@ public class FileUtils { synchronized (lockReflection) { if (setLastModified == null) { try { - setLastModified = - java.io.File.class.getMethod("setLastModified", + setLastModified = + java.io.File.class.getMethod("setLastModified", new Class[] {Long.TYPE}); } catch (NoSuchMethodException nse) { throw new BuildException("File.setlastModified not in JDK > 1.1?", @@ -399,7 +467,7 @@ public class FileUtils { helpFile = getParentFile(helpFile); if (helpFile == null) { String msg = "The file or path you specified (" - + filename + ") is invalid relative to " + + filename + ") is invalid relative to " + file.getPath(); throw new BuildException(msg); } @@ -422,7 +490,7 @@ public class FileUtils { *
  • Remove redundant slashes after the drive spec.
  • *
  • resolve all ./, .\, ../ and ..\ sequences.
  • *
  • DOS style paths that start with a drive letter will have - * \ as the separator.
  • + * \ as the separator. * * * @throws java.lang.NullPointerException if the file path is @@ -439,11 +507,11 @@ public class FileUtils { ! (path.length() >= 2 && Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') - ) { + ) { String msg = path + " is not an absolute path"; throw new BuildException(msg); } - + boolean dosWithDrive = false; String root = null; // Eliminate consecutive slashes after the drive spec @@ -473,7 +541,7 @@ public class FileUtils { root = path.substring(0, 3); path = path.substring(3); } - + } else { if (path.length() == 1) { root = File.separator; @@ -515,7 +583,7 @@ public class FileUtils { } sb.append(s.elementAt(i)); } - + path = sb.toString(); if (dosWithDrive) { @@ -552,8 +620,8 @@ public class FileUtils { DecimalFormat fmt = new DecimalFormat("#####"); synchronized (rand) { do { - result = new File(parent, - prefix + fmt.format(rand.nextInt()) + result = new File(parent, + prefix + fmt.format(rand.nextInt()) + suffix); } while (result.exists()); } @@ -579,22 +647,22 @@ public class FileUtils { // two not existing files are equal return true; } - + if (f1.isDirectory() || f2.isDirectory()) { // don't want to compare directory contents for now return false; } - + if (f1.equals(f2)) { // same filename => true return true; } - + if (f1.length() != f2.length()) { // different size =>false return false; } - + InputStream in1 = null; InputStream in2 = null; try { @@ -640,5 +708,37 @@ public class FileUtils { } return null; } + + /** + * Read from reader till EOF + */ + public static final String readFully(Reader rdr) throws IOException { + return readFully(rdr, 8192); + } + + /** + * Read from reader till EOF + */ + public static final String readFully(Reader rdr, int bufferSize) throws IOException { + final char[] buffer = new char[bufferSize]; + int bufferLength = 0; + String text = null; + StringBuffer textBuffer = null; + while (bufferLength != -1) { + bufferLength = rdr.read(buffer); + if (bufferLength != -1) { + if (textBuffer == null) { + textBuffer = new StringBuffer( + new String(buffer, 0, bufferLength)); + } else { + textBuffer.append(new String(buffer, 0, bufferLength)); + } + } + } + if (textBuffer != null) { + text = textBuffer.toString(); + } + return text; + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java b/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java index c42d672b9..f10b7e485 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java @@ -57,7 +57,6 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; - import java.io.File; import java.io.IOException; @@ -126,20 +125,28 @@ public class CopyTest extends BuildFileTest { } - public void testSingleFileFileset() { - executeTarget("test_single_file_fileset"); - File file = new File(getProjectDir(), - "copytest_single_file_fileset.tmp"); - assertTrue(file.exists()); - } - public void testFilterSet() throws IOException { executeTarget("testFilterSet"); FileUtils fileUtils = FileUtils.newFileUtils(); File tmp = new File(getProjectDir(), "copy.filterset.tmp"); - File check = new File(getProjectDir(), - "expected/copy.filterset.filtered"); + File check = new File(getProjectDir(), "expected/copy.filterset.filtered"); + assertTrue(tmp.exists()); + assertTrue(fileUtils.contentEquals(tmp, check)); + } + + public void testFilterChain() throws IOException { + executeTarget("testFilterChain"); + FileUtils fileUtils = FileUtils.newFileUtils(); + File tmp = new File(getProjectDir(), "copy.filterchain.tmp"); + File check = new File(getProjectDir(), "expected/copy.filterset.filtered"); assertTrue(tmp.exists()); assertTrue(fileUtils.contentEquals(tmp, check)); } + + public void testSingleFileFileset() { + executeTarget("test_single_file_fileset"); + File file = new File(getProjectDir(), + "copytest_single_file_fileset.tmp"); + assertTrue(file.exists()); + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java b/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java index 09dd961b3..f4703c314 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java @@ -151,7 +151,7 @@ public class LoadFileTest extends BuildFileTest { } } - /** + /** * A unit test for JUnit */ public void testEvalProps() @@ -162,7 +162,19 @@ public class LoadFileTest extends BuildFileTest { } } - /** + /** + * A unit test for JUnit + */ + public void testFilterChain() + throws BuildException { + executeTarget("testFilterChain"); + if(project.getProperty("testFilterChain").indexOf("World!")<0) { + fail("Filter Chain broken"); + } + } + + + /** * A unit test for JUnit */ public void testOneLine() @@ -171,5 +183,3 @@ public class LoadFileTest extends BuildFileTest { } } - - diff --git a/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java b/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java index d3167c230..ae3cbe12c 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2002 The Apache Software Foundation. All rights + * Copyright (c) 2000-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -87,4 +87,13 @@ public class MoveTest extends BuildFileTest { assertTrue(tmp.exists()); assertTrue(fileUtils.contentEquals(tmp, check)); } + + public void testFilterChain() throws IOException { + executeTarget("testFilterChain"); + FileUtils fileUtils = FileUtils.newFileUtils(); + File tmp = new File(getProjectDir(), "move.filterchain.tmp"); + File check = new File(getProjectDir(), "expected/copy.filterset.filtered"); + assertTrue(tmp.exists()); + assertTrue(fileUtils.contentEquals(tmp, check)); + } }