You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@apache.org on 2003/05/09 15:32:07 UTC
cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs ConcatTest.java
bodewig 2003/05/09 06:32:07
Modified: . WHATSNEW
docs/manual/CoreTasks concat.html
src/etc/testcases/taskdefs concat.xml
src/main/org/apache/tools/ant/taskdefs Concat.java
src/testcases/org/apache/tools/ant/taskdefs ConcatTest.java
Log:
outputencoding and fixlastline attributes for <concat>
PR: 12511
Submitted by: Peter Reilly <peter dot reilly at corvil dot com>
Revision Changes Path
1.412 +4 -0 ant/WHATSNEW
Index: WHATSNEW
===================================================================
RCS file: /home/cvs/ant/WHATSNEW,v
retrieving revision 1.411
retrieving revision 1.412
diff -u -r1.411 -r1.412
--- WHATSNEW 9 May 2003 13:01:00 -0000 1.411
+++ WHATSNEW 9 May 2003 13:32:06 -0000 1.412
@@ -308,6 +308,10 @@
* There is a new data type <propertyset> that can be used to collect
properties.
+* <concat> can now control the encoding of the output as well and optionally
+ add new-line characters at the end files that get concatenated but
+ don't end in newlines. Bugzilla Report 12511.
+
Changes from Ant 1.5.2 to Ant 1.5.3
===================================
1.8 +48 -1 ant/docs/manual/CoreTasks/concat.html
Index: concat.html
===================================================================
RCS file: /home/cvs/ant/docs/manual/CoreTasks/concat.html,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- concat.html 28 Mar 2003 12:41:01 -0000 1.7
+++ concat.html 9 May 2003 13:32:07 -0000 1.8
@@ -76,6 +76,53 @@
</td>
<td valign="top" align="center">No</td>
</tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">
+ The encoding to use when writing the output file
+ <em>since Ant 1.6</em>.
+ Defaults to the value of the encoding attribute
+ if given or the default JVM encoding otherwise.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fixlastline</td>
+ <td valign="top">
+ Specifies whether or not to check if
+ each file concatenated is terminated by
+ a new line. If this attribute is "yes"
+ a new line will be appended to the stream if
+ the file did not end in a new line.
+ <em>since Ant 1.6</em>.
+ Defaults to "no".
+ This attribute does not apply to embedded text.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">eol</td>
+ <td valign="top">
+ Specifies what the end of line character are
+ for use by the fixlastline attribute.
+ <em>since Ant 1.6</em>
+ Valid values for this property are:
+ <ul>
+ <li>cr: a single CR</li>
+ <li>lf: a single LF</li>
+ <li>crlf: the pair CRLF</li>
+ <li>mac: a single CR</li>
+ <li>unix: a single LF</li>
+ <li>dos: the pair CRLF</li>
+ </ul>
+ The default is "platform".
+ For Unix platforms, the default is "lf".
+ For DOS based systems (including Windows),
+ the default is "crlf".
+ For Mac OS, the default is "cr".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
</table>
@@ -86,7 +133,7 @@
<p>
This is a <a href="../CoreTypes/path.html">Path</a>. This is
used to select file files to be concatenated. Note that
- if a file can only appear once in a path. If this is
+ a file can only appear once in a path. If this is
an issue consider using multiple paths.
</p>
1.7 +33 -1 ant/src/etc/testcases/taskdefs/concat.xml
Index: concat.xml
===================================================================
RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/concat.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- concat.xml 28 Mar 2003 12:41:01 -0000 1.6
+++ concat.xml 9 May 2003 13:32:07 -0000 1.7
@@ -11,7 +11,11 @@
<delete file="TESTDEST"/>
<delete file="${tmp.file}"/>
<delete file="${tmp.file.2}"/>
- </target>
+ <delete file="concat.line4"/>
+ <delete file="concat.noeol"/>
+ <delete file="concat.linecr"/>
+ <delete file="concat.utf8"/>
+ </target>
<target name="test1">
<concat>
@@ -153,4 +157,32 @@
</filterchain>
</concat>
</target>
+
+ <target name="create-noel">
+ <concat destfile="concat.noeol">This has no end of line</concat>
+ </target>
+
+ <target name="testfixlastline" depends="create-noel">
+ <concat destfile="concat.line4" fixlastline="yes">
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ </concat>
+ </target>
+
+ <target name="testfixlastlineeol" depends="create-noel">
+ <concat destfile="concat.linecr" fixlastline="yes" eol="mac">
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ </concat>
+ </target>
+
+ <target name="testTranscoding">
+ <concat destfile="concat.utf8"
+ encoding="ISO8859_1" outputencoding="UTF8">
+ <path path="copy/input/iso8859-1"/>
+ </concat>
+ </target>
+
</project>
1.20 +190 -34 ant/src/main/org/apache/tools/ant/taskdefs/Concat.java
Index: Concat.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Concat.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- Concat.java 18 Apr 2003 23:40:22 -0000 1.19
+++ Concat.java 9 May 2003 13:32:07 -0000 1.20
@@ -122,6 +122,9 @@
*/
private String encoding = null;
+ /** Stores the output file encoding. */
+ private String outputEncoding = null;
+
// Child elements.
/**
@@ -143,6 +146,14 @@
private TextElement footer;
/** String to place at the end of the concatented stream */
private TextElement header;
+ /** add missing line.separator to files **/
+ private boolean fixLastLine = false;
+ /** endofline for fixlast line */
+ private String eolString = System.getProperty("line.separator");
+ /** outputwriter */
+ private Writer outputWriter = null;
+
+ /** internal variable - used to collect the source files from sources */
private Vector sourceFiles = new Vector();
/** 1.1 utilities and copy utilities */
@@ -179,6 +190,17 @@
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
+ if (outputEncoding == null) {
+ outputEncoding = encoding;
+ }
+ }
+
+ /**
+ * Sets the character encoding for outputting
+ * @since Ant 1.6
+ */
+ public void setOutputEncoding(String outputEncoding) {
+ this.outputEncoding = outputEncoding;
}
/**
@@ -220,8 +242,9 @@
* @since Ant 1.6
*/
public void addFilterChain(FilterChain filterChain) {
- if (filterChains == null)
+ if (filterChains == null) {
filterChains = new Vector();
+ }
filterChains.addElement(filterChain);
}
@@ -244,19 +267,52 @@
* Add a header to the concatenated output
* @since Ant 1.6
*/
- public void addHeader(TextElement el) {
- this.header = el;
+ public void addHeader(TextElement header) {
+ this.header = header;
}
/**
* Add a footer to the concatenated output
* @since Ant 1.6
*/
- public void addFooter(TextElement el) {
- this.footer = el;
+ public void addFooter(TextElement footer) {
+ this.footer = footer;
+ }
+
+ /**
+ * Append line.separator to files that do not end
+ * with a line.separator, default false.
+ * @since Ant 1.6
+ */
+ public void setFixLastLine(boolean fixLastLine) {
+ this.fixLastLine = fixLastLine;
+ }
+
+ /**
+ * Specify the end of line to find and to add if
+ * not present at end of each input file.
+ */
+ public void setEol(FixCRLF.CrLf enum) {
+ String s = enum.getValue();
+ if (s.equals("cr") || s.equals("mac")) {
+ eolString = "\r";
+ } else if (s.equals("lf") || s.equals("unix")) {
+ eolString = "\n";
+ } else if (s.equals("crlf") || s.equals("dos")) {
+ eolString = "\r\n";
+ }
}
/**
+ * set the output writer, this is to allow
+ * concat to be used as a nested element
+ * @since Ant 1.6
+ */
+ public void setWriter(Writer outputWriter) {
+ this.outputWriter = outputWriter;
+ }
+
+ /**
* This method performs the concatenation.
*/
public void execute()
@@ -265,6 +321,11 @@
// treat empty nested text as no text
sanitizeText();
+ if (destinationFile != null && outputWriter != null) {
+ throw new BuildException(
+ "Cannot specify both a destination file and an output writer");
+ }
+
// Sanity check our inputs.
if (sources.size() == 0 && textBuffer == null) {
// Nothing to concatenate!
@@ -339,6 +400,8 @@
forceOverwrite = true;
destinationFile = null;
encoding = null;
+ outputEncoding = null;
+ fixLastLine = false;
sources.removeAllElements();
sourceFiles.removeAllElements();
filterChains = null;
@@ -371,32 +434,36 @@
try {
- if (destinationFile == null) {
- // Log using WARN so it displays in 'quiet' mode.
- os = new LogOutputStream(this, Project.MSG_WARN);
+ PrintWriter writer = null;
+
+ if (outputWriter != null) {
+ writer = new PrintWriter(outputWriter);
} else {
- // ensure that the parent dir of dest file exists
- File parent = fileUtils.getParentFile(destinationFile);
- if (!parent.exists()) {
- parent.mkdirs();
- }
+ if (destinationFile == null) {
+ // Log using WARN so it displays in 'quiet' mode.
+ os = new LogOutputStream(this, Project.MSG_WARN);
+ } else {
+ // ensure that the parent dir of dest file exists
+ File parent = fileUtils.getParentFile(destinationFile);
+ if (!parent.exists()) {
+ parent.mkdirs();
+ }
- os = new FileOutputStream(destinationFile.getAbsolutePath(),
- append);
- }
+ os = new FileOutputStream(destinationFile.getAbsolutePath(),
+ append);
+ }
- PrintWriter writer = null;
- if (encoding == null) {
- writer = new PrintWriter(
- new BufferedWriter(
- new OutputStreamWriter(os)));
- } else {
- writer = new PrintWriter(
- new BufferedWriter(
- new OutputStreamWriter(os, encoding)));
+ if (outputEncoding == null) {
+ writer = new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(os)));
+ } else {
+ writer = new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(os, outputEncoding)));
+ }
}
-
if (header != null) {
if (header.getFiltering()) {
concatenate(
@@ -425,7 +492,9 @@
}
writer.flush();
- os.flush();
+ if (os != null) {
+ os.flush();
+ }
} catch (IOException ioex) {
throw new BuildException("Error while concatenating: "
@@ -486,6 +555,7 @@
private boolean trimLeading = false;
private boolean trim = false;
private boolean filtering = true;
+ private String encoding = null;
/**
* whether to filter the text in this element
@@ -502,6 +572,10 @@
private boolean getFiltering() {
return filtering;
}
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
/**
* set the text using a file
@@ -517,7 +591,13 @@
BufferedReader reader = null;
try {
- reader = new BufferedReader(new FileReader(file));
+ if (this.encoding == null) {
+ reader = new BufferedReader(new FileReader(file));
+ } else {
+ reader = new BufferedReader(
+ new InputStreamReader(new FileInputStream(file),
+ this.encoding));
+ }
value = fileUtils.readFully(reader);
} catch (IOException ex) {
throw new BuildException(ex);
@@ -596,9 +676,12 @@
* a single stream.
*/
private class MultiReader extends Reader {
- private int pos = 0;
+ private int pos = 0;
private Reader reader = null;
-
+ private int lastPos = 0;
+ private char[] lastChars = new char[eolString.length()];
+ private boolean needAddSeparator = false;
+
private Reader getReader() throws IOException {
if (reader == null) {
if (encoding == null) {
@@ -611,7 +694,10 @@
new FileInputStream(
(File) sourceFiles.elementAt(pos)),
encoding));
- }
+ }
+ for (int i = 0; i < lastChars.length; ++i) {
+ lastChars[i] = 0;
+ }
}
return reader;
}
@@ -624,12 +710,26 @@
* object.
*/
public int read() throws IOException {
+ if (needAddSeparator) {
+ int ret = eolString.charAt(lastPos++);
+ if (lastPos >= eolString.length()) {
+ lastPos = 0;
+ needAddSeparator = false;
+ }
+ return ret;
+ }
+
while (pos < sourceFiles.size()) {
int ch = getReader().read();
if (ch == -1) {
reader.close();
reader = null;
+ if (fixLastLine && isMissingEndOfLine()) {
+ needAddSeparator = true;
+ lastPos = 0;
+ }
} else {
+ addLastChar((char) ch);
return ch;
}
pos++;
@@ -647,15 +747,45 @@
*/
public int read(char cbuf[], int off, int len)
throws IOException {
+
int amountRead = 0;
int iOff = off;
- while (pos < sourceFiles.size()) {
+ while (pos < sourceFiles.size() || (needAddSeparator)) {
+ if (needAddSeparator) {
+ cbuf[off] = eolString.charAt(lastPos++);
+ if (lastPos >= eolString.length()) {
+ lastPos = 0;
+ needAddSeparator = false;
+ pos++;
+ }
+ len--;
+ off++;
+ amountRead++;
+ if (len == 0)
+ return amountRead;
+ continue;
+ }
+
int nRead = getReader().read(cbuf, off, len);
if (nRead == -1 || nRead == 0) {
reader.close();
reader = null;
- pos++;
+ if (fixLastLine && isMissingEndOfLine()) {
+ needAddSeparator = true;
+ lastPos = 0;
+ } else {
+ pos++;
+ }
} else {
+ if (fixLastLine) {
+ for (int i = nRead; i > (nRead-lastChars.length);
+ --i) {
+ if (i < 0) {
+ break;
+ }
+ addLastChar(cbuf[off+i]);
+ }
+ }
len -= nRead;
off += nRead;
amountRead += nRead;
@@ -671,11 +801,37 @@
}
}
+ /**
+ * Close the current reader
+ */
public void close() throws IOException {
if (reader != null) {
reader.close();
}
}
+ /**
+ * if checking for end of line at end of file
+ * add a character to the lastchars buffer
+ */
+ private void addLastChar(char ch) {
+ for (int i = lastChars.length-2; i >= 0; --i) {
+ lastChars[i] = lastChars[i+1];
+ }
+ lastChars[lastChars.length-1] = ch;
+ }
+
+ /**
+ * return true if the lastchars buffer does
+ * not contain the lineseparator
+ */
+ private boolean isMissingEndOfLine() {
+ for (int i = 0; i < lastChars.length; ++i) {
+ if (lastChars[i] != eolString.charAt(i))
+ return true;
+ }
+ return false;
+ }
}
- }
+
+}
1.7 +69 -0 ant/src/testcases/org/apache/tools/ant/taskdefs/ConcatTest.java
Index: ConcatTest.java
===================================================================
RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/ConcatTest.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ConcatTest.java 28 Mar 2003 12:41:01 -0000 1.6
+++ ConcatTest.java 9 May 2003 13:32:07 -0000 1.7
@@ -55,8 +55,12 @@
package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.util.FileUtils;
import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
/**
* A test class for the 'concat' task, used to concatenate a series of
@@ -241,5 +245,70 @@
assertTrue(getLog().indexOf("Bye") > -1);
assertTrue(getLog().indexOf("Hello") == -1);
}
+ /**
+ * Check if fixlastline works
+ */
+ public void testfixlastline()
+ throws IOException
+ {
+ expectFileContains(
+ "testfixlastline", "concat.line4",
+ "end of line" + System.getProperty("line.separator")
+ + "This has");
+ }
+
+ /**
+ * Check if fixlastline works with eol
+ */
+ public void testfixlastlineeol()
+ throws IOException
+ {
+ expectFileContains(
+ "testfixlastlineeol", "concat.linecr",
+ "end of line\rThis has");
+ }
+
+ // ------------------------------------------------------
+ // Helper methods - should be in BuildFileTest
+ // -----------------------------------------------------
+
+ private String getFileString(String filename)
+ throws IOException
+ {
+ Reader r = null;
+ try {
+ r = new FileReader(getProject().resolveFile(filename));
+ return FileUtils.newFileUtils().readFully(r);
+ }
+ finally {
+ try {r.close();} catch (Throwable ignore) {}
+ }
+ }
+
+ private String getFileString(String target, String filename)
+ throws IOException
+ {
+ executeTarget(target);
+ return getFileString(filename);
+ }
+
+ private void expectFileContains(
+ String target, String filename, String contains)
+ throws IOException
+ {
+ String content = getFileString(target, filename);
+ assertTrue(
+ "expecting file " + filename + " to contain " +
+ contains +
+ " but got " + content, content.indexOf(contains) > -1);
+ }
+
+ public void testTranscoding() throws IOException {
+ executeTarget("testTranscoding");
+ FileUtils fileUtils = FileUtils.newFileUtils();
+ File f1 = getProject().resolveFile("copy/expected/utf-8");
+ File f2 = getProject().resolveFile("concat.utf8");
+ assertTrue(fileUtils.contentEquals(f1, f2));
+ }
}