From d53f5e961288efbb6a95db34d841b31d9571ea1b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 10 Apr 2002 15:33:09 +0000 Subject: [PATCH] Make concat reset its state (bug 7552 audit), make it use encoding even when not logging to the console, make it fail-fast if nested text has been specified together with nested filesets. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272346 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/CoreTasks/concat.html | 3 +- .../org/apache/tools/ant/taskdefs/Concat.java | 305 +++++++++--------- 2 files changed, 162 insertions(+), 146 deletions(-) diff --git a/docs/manual/CoreTasks/concat.html b/docs/manual/CoreTasks/concat.html index 8abb425af..fbc284f06 100644 --- a/docs/manual/CoreTasks/concat.html +++ b/docs/manual/CoreTasks/concat.html @@ -60,8 +60,7 @@ encoding - Specifies the encoding for the input files, used only when - concatenating files to the console. Please see http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html for a list of possible values. Defaults to the platform's default character encoding. diff --git a/src/main/org/apache/tools/ant/taskdefs/Concat.java b/src/main/org/apache/tools/ant/taskdefs/Concat.java index 0ff07efa1..3c894a6e8 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Concat.java +++ b/src/main/org/apache/tools/ant/taskdefs/Concat.java @@ -64,17 +64,19 @@ import org.apache.tools.ant.types.FileList; import org.apache.tools.ant.util.StringUtils; +import java.io.BufferedReader; import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.io.StringReader; -import java.io.BufferedReader; -import java.io.IOException; import java.util.Vector; // 1.1 import java.util.Enumeration; // 1.1 @@ -213,56 +215,75 @@ public class Concat extends Task { "some text."); } - // Iterate the FileSet collection, concatenating each file as - // it is encountered. - for (Enumeration e = fileSets.elements(); e.hasMoreElements(); ) { - - // Root directory for files. - File fileSetBase = null; - - // List of files. - String[] srcFiles = null; - - // Get the next file set, which could be a FileSet or a - // FileList instance. - Object next = e.nextElement(); - - if (next instanceof FileSet) { - - FileSet fileSet = (FileSet) next; - - // Get a directory scanner from the file set, which will - // determine the files from the set which need to be - // concatenated. - DirectoryScanner scanner = - fileSet.getDirectoryScanner(project); - - // Determine the root path. - fileSetBase = fileSet.getDir(project); - - // Get the list of files. - srcFiles = scanner.getIncludedFiles(); - - } else if (next instanceof FileList) { - - FileList fileList = (FileList) next; - - // Determine the root path. - fileSetBase = fileList.getDir(project); + // If using filesets, disallow inline text. This is similar to + // using GNU 'cat' with file arguments -- stdin is simply + // ignored. + if (fileSets.size() > 0 && textBuffer != null) { + throw new BuildException("Cannot include inline text " + + "when using filesets."); + } - // Get the list of files. - srcFiles = fileList.getFiles(project); + boolean savedAppend = append; + try { + // Iterate the FileSet collection, concatenating each file as + // it is encountered. + for (Enumeration e = fileSets.elements(); e.hasMoreElements(); ) { + + // Root directory for files. + File fileSetBase = null; + + // List of files. + String[] srcFiles = null; + + // Get the next file set, which could be a FileSet or a + // FileList instance. + Object next = e.nextElement(); + + if (next instanceof FileSet) { + + FileSet fileSet = (FileSet) next; + + // Get a directory scanner from the file set, which will + // determine the files from the set which need to be + // concatenated. + DirectoryScanner scanner = + fileSet.getDirectoryScanner(project); + + // Determine the root path. + fileSetBase = fileSet.getDir(project); + + // Get the list of files. + srcFiles = scanner.getIncludedFiles(); + + } else if (next instanceof FileList) { + + FileList fileList = (FileList) next; + + // Determine the root path. + fileSetBase = fileList.getDir(project); + + // Get the list of files. + srcFiles = fileList.getFiles(project); + + } + // Concatenate the files. + if (srcFiles != null) { + catFiles(fileSetBase, srcFiles); + } } - - // Concatenate the files. - catFiles(fileSetBase, srcFiles); + } finally { + append = savedAppend; } - + // Now, cat the inline text, if applicable. catText(); + } - // Reset state to default. + /** + * Reset state to default. + */ + public void reset() { append = false; destinationFile = null; encoding = null; @@ -301,114 +322,118 @@ public class Concat extends Task { } // Next, perform the concatenation. - if (destinationFile == null) { + if (encoding == null) { + OutputStream os = null; + InputStream is = null; - // No destination file, dump to stdout via Ant's logging - // interface, which requires that we assume the input data - // is line-oriented. Generally, this is a safe assumption, - // as most users won't (intentionally) attempt to cat - // binary files to the console. - for (int i = 0; i < len; i++) { + try { - BufferedReader reader = null; - try { - if (encoding == null) { - // Use default encoding. - reader = new BufferedReader( - new FileReader(input[i]) - ); - } else { - // Use specified encoding. - reader = new BufferedReader( - new InputStreamReader( - new FileInputStream(input[i]), - encoding - ) - ); - } + if (destinationFile == null) { + // Log using WARN so it displays in 'quiet' mode. + os = new LogOutputStream(this, Project.MSG_WARN); + } else { + os = + new FileOutputStream(destinationFile.getAbsolutePath(), + append); + + // This flag should only be recognized for the first + // file. In the context of a single 'cat', we always + // want to append. + append = true; + } + + for (int i = 0; i < len; i++) { - String line; - while ((line = reader.readLine()) != null) { - // Log the line, using WARN so it displays in - // 'quiet' mode. - log(line, Project.MSG_WARN); + // Make sure input != output. + if (destinationFile != null && + destinationFile.getAbsolutePath().equals(input[i])) { + log(destinationFile.getName() + ": input file is " + + "output file.", Project.MSG_WARN); } - } catch (IOException ioe) { - throw new BuildException("Error while concatenating " + - "file.", ioe); - } finally { - // Close resources. - if (reader != null) { - try { - reader.close(); - } catch (Exception ignore) {} + is = new FileInputStream(input[i]); + byte[] buffer = new byte[8096]; + while (true) { + int bytesRead = is.read(buffer); + if (bytesRead == -1) { // EOF + break; + } + + // Write the read data. + os.write(buffer, 0, bytesRead); } + os.flush(); + is.close(); + is = null; + } + } catch (IOException ioex) { + throw new BuildException("Error while concatenating: " + + ioex.getMessage(), ioex); + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception ignore) {} + } + if (os != null) { + try { + os.close(); + } catch (Exception ignore) {} } } - } else { - - // Use the provided file, making no assumptions about - // whether or not the file is character or line-oriented. - final int bufferSize = 1024; - OutputStream os = null; - try { - os = new FileOutputStream(destinationFile.getAbsolutePath(), - append); + } else { // user specified encoding, assume line oriented input - // This flag should only be recognized for the first - // file. In the context of a single 'cat', we always - // want to append. - append = true; + PrintWriter out = null; + BufferedReader in = null; - } catch (IOException ioe) { - throw new BuildException("Unable to open destination " + - "file.", ioe); - } - - // Concatenate the file. try { + OutputStream os = null; + if (destinationFile == null) { + // Log using WARN so it displays in 'quiet' mode. + os = new LogOutputStream(this, Project.MSG_WARN); + } else { + os = + new FileOutputStream(destinationFile.getAbsolutePath(), + append); + + // This flag should only be recognized for the first + // file. In the context of a single 'cat', we always + // want to append. + append = true; + } + out = new PrintWriter(new OutputStreamWriter(os, encoding)); for (int i = 0; i < len; i++) { + in = new BufferedReader( + new InputStreamReader( + new FileInputStream(input[i]), + encoding + ) + ); - // Make sure input != output. - if (destinationFile.getAbsolutePath().equals(input[i])) { - log(destinationFile.getName() + ": input file is " + - "output file.", Project.MSG_WARN); - } - - InputStream is = null; - try { - is = new FileInputStream(input[i]); - byte[] buffer = new byte[bufferSize]; - while (true) { - int bytesRead = is.read(buffer); - if (bytesRead == -1) { // EOF - break; - } - - // Write the read data. - os.write(buffer, 0, bytesRead); - } - - os.flush(); - - } catch (IOException ioex) { - throw new BuildException("Error writing file.", ioex); - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception ignore) {} - } + String line; + while ((line = in.readLine()) != null) { + // Log the line, using WARN so it displays in + // 'quiet' mode. + out.println(line); } + in.close(); + in = null; } - + } catch (IOException ioe) { + throw new BuildException("Error while concatenating: " + + ioe.getMessage(), ioe); } finally { - if (os != null) { + // Close resources. + if (in != null) { try { - os.close(); + in.close(); + } catch (Exception ignore) {} + } + if (out != null) { + try { + out.close(); } catch (Exception ignore) {} } } @@ -430,14 +455,6 @@ public class Concat extends Task { String text = textBuffer.toString(); - // If using filesets, disallow inline text. This is similar to - // using GNU 'cat' with file arguments -- stdin is simply - // ignored. - if (fileSets.size() > 0) { - throw new BuildException("Cannot include inline text " + - "when using filesets."); - } - // Replace ${property} strings. text = ProjectHelper.replaceProperties(project, text, project.getProperties());