diff --git a/WHATSNEW b/WHATSNEW index 0facf307f..d5c527822 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -604,6 +604,10 @@ Other changes: used to checkout/list files based on a date instead of a label. Bugzilla Report 20578. +* New filter . Adds the content of file at the beginning + or end of a file. Discussion started at + http://marc.theaimsgroup.com/?l=ant-user&m=106336791228585&w=2 + Changes from Ant 1.5.3 to Ant 1.5.4 =================================== diff --git a/src/etc/testcases/filters/concat.xml b/src/etc/testcases/filters/concat.xml new file mode 100644 index 000000000..d631fd674 --- /dev/null +++ b/src/etc/testcases/filters/concat.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/org/apache/tools/ant/filters/ConcatFilter.java b/src/main/org/apache/tools/ant/filters/ConcatFilter.java new file mode 100644 index 000000000..c50e47967 --- /dev/null +++ b/src/main/org/apache/tools/ant/filters/ConcatFilter.java @@ -0,0 +1,246 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 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 "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.io.File; +import java.io.BufferedReader; +import java.io.FileReader; +import org.apache.tools.ant.types.Parameter; + +/** + * Concats a file before and/or after the file. + * + *

Example:

+ * 
+ *     
+ *     
+ *         
+ *     
+ * 
+ * 
+ * Copies all java sources from src to build and adds the + * content of apache-license-java.txt add the beginning of each + * file.

+ * + * @since 1.6 + * @version 2003-09-17 + * @author Jan Matèrne + */ +public final class ConcatFilter extends BaseParamFilterReader + implements ChainableReader { + + /** File to add before the content. */ + private File before; + + /** File to add after the content. */ + private File after; + + /** Reader for before-file. */ + private Reader beforeReader = new EmptyReader(); + + /** Reader for after-file. */ + private Reader afterReader = new EmptyReader(); + + /** + * Constructor for "dummy" instances. + * + * @see BaseFilterReader#BaseFilterReader() + */ + public ConcatFilter() { + super(); + } + + /** + * Creates a new filtered reader. + * + * @param in A Reader object providing the underlying stream. + * Must not be null. + */ + public ConcatFilter(final Reader in) { + super(in); + } + + /** + * Returns the next character in the filtered stream. If the desired + * number of lines have already been read, the resulting stream is + * effectively at an end. Otherwise, the next character from the + * underlying stream is read and returned. + * + * @return the next character in the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + public int read() throws IOException { + // do the "singleton" initialization + if (!getInitialized()) { + initialize(); + setInitialized(true); + } + + int ch = -1; + + // The readers return -1 if they end. So simply read the "before" + // after that the "content" and at the end the "after" file. + ch = beforeReader.read(); + if (ch == -1) { + ch = super.read(); + } + if (ch == -1) { + ch = afterReader.read(); + } + + return ch; + } + + /** + * Sets before attribute. + * @param before new value + */ + public void setBefore(final File before) { + this.before = before; + } + + /** + * Returns before attribute. + * @return before attribute + */ + public File getBefore() { + return before; + } + + /** + * Sets after attribute. + * @param after new value + */ + public void setAfter(final File after) { + this.after = after; + } + + /** + * Returns after attribute. + * @return after attribute + */ + public File getAfter() { + return after; + } + + /** + * Creates a new ConcatReader using the passed in + * Reader for instantiation. + * + * @param rdr A Reader object providing the underlying stream. + * Must not be null. + * + * @return a new filter based on this configuration, but filtering + * the specified reader + */ + public Reader chain(final Reader rdr) { + ConcatFilter newFilter = new ConcatFilter(rdr); + newFilter.setBefore(getBefore()); + newFilter.setAfter(getAfter()); + // Usually the initialized is set to true. But here it must not. + // Because the before and after readers have to be instantiated + // on runtime + //newFilter.setInitialized(true); + return newFilter; + } + + /** + * Scans the parameters list for the "lines" parameter and uses + * it to set the number of lines to be returned in the filtered stream. + * also scan for skip parameter. + */ + private void initialize() throws IOException { + // get parameters + Parameter[] params = getParameters(); + if (params != null) { + for (int i = 0; i < params.length; i++) { + if ("before".equals(params[i].getName())) { + setBefore(new File(params[i].getValue())); + continue; + } + if ("after".equals(params[i].getName())) { + setAfter(new File(params[i].getValue())); + continue; + } + } + } + if (before != null) { + if (!before.isAbsolute()) { + before = new File(getProject().getBaseDir(), before.getPath()); + } + beforeReader = new BufferedReader(new FileReader(before)); + } + if (after != null) { + if (!after.isAbsolute()) { + after = new File(getProject().getBaseDir(), after.getPath()); + } + afterReader = new BufferedReader(new FileReader(after)); + } + } + + /** + * Reader which is always at the end of file. + * Used for easier algorithm (polymorphism instead if-cascades). + */ + private class EmptyReader extends Reader { + public int read(char[] ch, int i1, int i2) { return -1; } + public void close() { } + } + +} \ No newline at end of file diff --git a/src/testcases/org/apache/tools/ant/filters/ConcatFilterTest.java b/src/testcases/org/apache/tools/ant/filters/ConcatFilterTest.java new file mode 100644 index 000000000..15d7be6b1 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/filters/ConcatFilterTest.java @@ -0,0 +1,195 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 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 "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.File; +import java.io.IOException; + +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.util.FileUtils; + +/** + * JUnit Testcases for ConcatReader + * @author Jan Matèrne + */ +public class ConcatFilterTest extends BuildFileTest { + + private static FileUtils fu = FileUtils.newFileUtils(); + private static final String lSep = System.getProperty("line.separator"); + + private static final String FILE_BEGINNING_WITH = + "this-should-be-the-first-line" + lSep + + "Line 1" + lSep + + "Line 2" + lSep + + "Line 3" + lSep + + "Line 4" + lSep + ; + + private static final String FILE_BEGINNING = + "Line 1" + lSep + + "Line 2" + lSep + + "Line 3" + lSep + + "Line 4" + lSep + + "Line 5" + lSep + ; + + private static final String FILE_ENDING_WITH = + "Line 57" + lSep + + "Line 58" + lSep + + "Line 59" + lSep + + "Line 60" + lSep + + "this-should-be-the-last-line" + lSep + ; + + private static final String FILE_ENDING = + "Line 56" + lSep + + "Line 57" + lSep + + "Line 58" + lSep + + "Line 59" + lSep + + "Line 60" + lSep + ; + + + public ConcatFilterTest(String name) { + super(name); + } + + public void setUp() { + configureProject("src/etc/testcases/filters/concat.xml"); + } + + public void tearDown() { + // I dont know why - but on my machine I always get a + // "Unable to delete file ...result\after.txt" (or before.txt) + // from Delete.removeDir(Delete.java:612). + // Win2000, JDK 1.4.1_02 + // A before doesn´t work. From 10ms to 3000ms. + // I modified the taskdefs.Delete.DELETE_RETRY_SLEEP_MILLIS + // from 10 up to 2000 ms, but no success. + // So I give up - and hope for a suggestion from another one. + // But this shouldn´t let the testcases fail, so I do the cleanup + // inside a try-block + // Jan + try { + executeTarget("cleanup"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void testFilterReaderNoArgs() throws IOException { + executeTarget("testFilterReaderNoArgs"); + File expected = getProject().resolveFile("input/concatfilter.test"); + File result = getProject().resolveFile("result/concat.filterReaderNoArgs.test"); + assertTrue("testFilterReaderNoArgs: Result not like expected", fu.contentEquals(expected, result)); + } + + public void testFilterReaderBefore() throws IOException { + executeTarget("testFilterReaderBefore"); + File resultFile = getProject().resolveFile("result/concat.filterReaderBefore.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING_WITH)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING)); + } + + public void testFilterReaderAfter() throws IOException { + executeTarget("testFilterReaderAfter"); + File resultFile = getProject().resolveFile("result/concat.filterReaderAfter.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING_WITH)); + } + + public void testFilterReaderBeforeAfter() throws IOException { + executeTarget("testFilterReaderBeforeAfter"); + File resultFile = getProject().resolveFile("result/concat.filterReaderBeforeAfter.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING_WITH)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING_WITH)); + } + + public void testConcatFilter() throws IOException { + executeTarget("testConcatFilter"); + File resultFile = getProject().resolveFile("result/concat.concatfilter.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING)); + } + + public void testConcatFilterBefore() throws IOException { + executeTarget("testConcatFilterBefore"); + File resultFile = getProject().resolveFile("result/concat.concatfilterBefore.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING_WITH)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING)); + } + + public void testConcatFilterAfter() throws IOException { + executeTarget("testConcatFilterAfter"); + File resultFile = getProject().resolveFile("result/concat.concatfilterAfter.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING_WITH)); + } + + public void testConcatFilterBeforeAfter() throws IOException { + executeTarget("testConcatFilterBeforeAfter"); + File resultFile = getProject().resolveFile("result/concat.concatfilterBeforeAfter.test"); + String resultContent = fu.readFully(new java.io.FileReader(resultFile)); + assertTrue("First 5 lines differs.", resultContent.startsWith(FILE_BEGINNING_WITH)); + assertTrue("Last 5 lines differs.", resultContent.endsWith(FILE_ENDING_WITH)); + } + +} \ No newline at end of file