FileDocCategorySizeDatePackage
Concat.javaAPI DocApache Ant 1.7029417Wed Dec 13 06:16:22 GMT 2006org.apache.tools.ant.taskdefs

Concat

public class Concat extends org.apache.tools.ant.Task
This class contains the 'concat' task, used to concatenate a series of files into a single stream. The destination of this stream may be the system console, or a file. The following is a sample invocation:
<concat destfile="${build.dir}/index.xml"
append="false">

<fileset dir="${xml.root.dir}"
includes="*.xml" />

</concat>

Fields Summary
private static final int
BUFFER_SIZE
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
private static final org.apache.tools.ant.types.resources.selectors.ResourceSelector
EXISTS
private static final org.apache.tools.ant.types.resources.selectors.ResourceSelector
NOT_EXISTS
private File
destinationFile
The destination of the stream. If null, the system console is used.
private boolean
append
Whether or not the stream should be appended if the destination file exists. Defaults to false.
private String
encoding
Stores the input file encoding.
private String
outputEncoding
Stores the output file encoding.
private boolean
binary
Stores the binary attribute
private StringBuffer
textBuffer
This buffer stores the text within the 'concat' element.
private org.apache.tools.ant.types.resources.Resources
rc
Stores a collection of file sets and/or file lists, used to select multiple files for concatenation.
private Vector
filterChains
for filtering the concatenated
private boolean
forceOverwrite
ignore dates on input files
private TextElement
footer
String to place at the start of the concatented stream
private TextElement
header
String to place at the end of the concatented stream
private boolean
fixLastLine
add missing line.separator to files
private String
eolString
endofline for fixlast line
private Writer
outputWriter
outputwriter
Constructors Summary
public Concat()
Construct a new Concat task.


              
      
        reset();
    
Methods Summary
public voidadd(org.apache.tools.ant.types.ResourceCollection c)
Add an arbitrary ResourceCollection.

param
c the ResourceCollection to add.
since
Ant 1.7

        rc = rc == null ? new Resources() : rc;
        rc.add(c);
    
public voidaddFilelist(org.apache.tools.ant.types.FileList list)
List of files to concatenate.

param
list the list of files

        add(list);
    
public voidaddFileset(org.apache.tools.ant.types.FileSet set)
Set of files to concatenate.

param
set the set of files

        add(set);
    
public voidaddFilterChain(org.apache.tools.ant.types.FilterChain filterChain)
Adds a FilterChain.

param
filterChain a filterchain to filter the concatenated input
since
Ant 1.6

        if (filterChains == null) {
            filterChains = new Vector();
        }
        filterChains.addElement(filterChain);
    
public voidaddFooter(org.apache.tools.ant.taskdefs.Concat$TextElement footerToAdd)
Add a footer to the concatenated output

param
footerToAdd the footer
since
Ant 1.6

        this.footer = footerToAdd;
    
public voidaddHeader(org.apache.tools.ant.taskdefs.Concat$TextElement headerToAdd)
Add a header to the concatenated output

param
headerToAdd the header
since
Ant 1.6

        this.header = headerToAdd;
    
public voidaddText(java.lang.String text)
This method adds text which appears in the 'concat' element.

param
text the text to be concated.

        if (textBuffer == null) {
            // Initialize to the size of the first text fragment, with
            // the hopes that it's the only one.
            textBuffer = new StringBuffer(text.length());
        }

        // Append the fragment -- we defer property replacement until
        // later just in case we get a partial property in a fragment.
        textBuffer.append(text);
    
private voidbinaryCat(org.apache.tools.ant.types.ResourceCollection c)
perform the binary concatenation

        log("Binary concatenation of " + c.size()
            + " resources to " + destinationFile);
        FileOutputStream out = null;
        InputStream in = null;
        try {
            try {
                out = new FileOutputStream(destinationFile);
            } catch (Exception t) {
                throw new BuildException("Unable to open "
                    + destinationFile + " for writing", t);
            }
            in = new ConcatResourceInputStream(c);
            ((ConcatResourceInputStream) in).setManagingComponent(this);
            Thread t = new Thread(new StreamPumper(in, out));
            t.start();
            try {
                t.join();
            } catch (InterruptedException e) {
                try {
                    t.join();
                } catch (InterruptedException ee) {
                    // Empty
                }
            }
        } finally {
            FileUtils.close(in);
            if (out != null) {
                try {
                    out.close();
                } catch (Exception ex) {
                    throw new BuildException(
                        "Unable to close " + destinationFile, ex);
                }
            }
        }
    
private voidcat(org.apache.tools.ant.types.ResourceCollection c)
perform the concatenation

        OutputStream os = null;
        char[] buffer = new char[BUFFER_SIZE];

        try {
            PrintWriter writer = null;

            if (outputWriter != null) {
                writer = new PrintWriter(outputWriter);
            } else {
                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 = destinationFile.getParentFile();
                    if (!parent.exists()) {
                        parent.mkdirs();
                    }
                    os = new FileOutputStream(destinationFile.getAbsolutePath(),
                                              append);
                }
                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(
                        buffer, writer, new StringReader(header.getValue()));
                } else {
                    writer.print(header.getValue());
                }
            }
            if (c.size() > 0) {
                concatenate(buffer, writer, new MultiReader(c));
            }
            if (footer != null) {
                if (footer.getFiltering()) {
                    concatenate(
                        buffer, writer, new StringReader(footer.getValue()));
                } else {
                    writer.print(footer.getValue());
                }
            }
            writer.flush();
            if (os != null) {
                os.flush();
            }
        } catch (IOException ioex) {
            throw new BuildException("Error while concatenating: "
                                     + ioex.getMessage(), ioex);
        } finally {
            FileUtils.close(os);
        }
    
private voidconcatenate(char[] buffer, java.io.Writer writer, java.io.Reader in)
Concatenate a single reader to the writer using buffer

        if (filterChains != null) {
            ChainReaderHelper helper = new ChainReaderHelper();
            helper.setBufferSize(BUFFER_SIZE);
            helper.setPrimaryReader(in);
            helper.setFilterChains(filterChains);
            helper.setProject(getProject());
            in = new BufferedReader(helper.getAssembledReader());
        }
        while (true) {
            int nRead = in.read(buffer, 0, buffer.length);
            if (nRead == -1) {
                break;
            }
            writer.write(buffer, 0, nRead);
        }
        writer.flush();
    
public org.apache.tools.ant.types.PathcreatePath()
Path of files to concatenate.

return
the path used for concatenating
since
Ant 1.6

        Path path = new Path(getProject());
        add(path);
        return path;
    
public voidexecute()
Execute the concat task.

        ResourceCollection c = validate();
        if (c == null) {
            return;
        }
        // Do nothing if no resources (including nested text)
        if (c.size() < 1 && header == null && footer == null) {
            log("No existing resources and no nested text, doing nothing",
                Project.MSG_INFO);
            return;
        }
        if (binary) {
            binaryCat(c);
        } else {
            cat(c);
        }
    
public voidreset()
Reset state to default.

        append = false;
        forceOverwrite = true;
        destinationFile = null;
        encoding = null;
        outputEncoding = null;
        fixLastLine = false;
        filterChains = null;
        footer = null;
        header = null;
        binary = false;
        outputWriter = null;
        textBuffer = null;
        eolString = System.getProperty("line.separator");
        rc = null;
    
private voidsanitizeText()
Treat empty nested text as no text.

Depending on the XML parser, addText may have been called for "ignorable whitespace" as well.

        if (textBuffer != null) {
            if (textBuffer.substring(0).trim().length() == 0) {
                textBuffer = null;
            }
        }
    
public voidsetAppend(boolean append)
Sets the behavior when the destination file exists. If set to true the stream data will be appended to the existing file, otherwise the existing file will be overwritten. Defaults to false.

param
append if true append to the file.

        this.append = append;
    
public voidsetBinary(boolean binary)
Set the binary attribute. If true, concat will concatenate the files byte for byte. This mode does not allow any filtering or other modifications to the input streams. The default value is false.

since
Ant 1.6.2
param
binary if true, enable binary mode.

        this.binary = binary;
    
public voidsetDestfile(java.io.File destinationFile)
Sets the destination file, or uses the console if not specified.

param
destinationFile the destination file

        this.destinationFile = destinationFile;
    
public voidsetEncoding(java.lang.String encoding)
Sets the character encoding

param
encoding the encoding of the input stream and unless outputencoding is set, the outputstream.

        this.encoding = encoding;
        if (outputEncoding == null) {
            outputEncoding = encoding;
        }
    
public voidsetEol(FixCRLF.CrLf crlf)
Specify the end of line to find and to add if not present at end of each input file. This attribute is used in conjunction with fixlastline.

param
crlf the type of new line to add - cr, mac, lf, unix, crlf, or dos
since
Ant 1.6

        String s = crlf.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";
        }
    
public voidsetFixLastLine(boolean fixLastLine)
Append line.separator to files that do not end with a line.separator, default false.

param
fixLastLine if true make sure each input file has new line on the concatenated stream
since
Ant 1.6

        this.fixLastLine = fixLastLine;
    
public voidsetForce(boolean force)
Force overwrite existing destination file

param
force if true always overwrite, otherwise only overwrite if the output file is older any of the input files.
since
Ant 1.6

        this.forceOverwrite = force;
    
public voidsetOutputEncoding(java.lang.String outputEncoding)
Sets the character encoding for outputting

param
outputEncoding the encoding for the output file
since
Ant 1.6

        this.outputEncoding = outputEncoding;
    
public voidsetWriter(java.io.Writer outputWriter)
Set the output writer. This is to allow concat to be used as a nested element.

param
outputWriter the output writer.
since
Ant 1.6

        this.outputWriter = outputWriter;
    
private org.apache.tools.ant.types.ResourceCollectionvalidate()
Validate configuration options.


        // treat empty nested text as no text
        sanitizeText();

        // if binary check if incompatible attributes are used
        if (binary) {
            if (destinationFile == null) {
                throw new BuildException(
                    "destfile attribute is required for binary concatenation");
            }
            if (textBuffer != null) {
                throw new BuildException(
                    "Nested text is incompatible with binary concatenation");
            }
            if (encoding != null || outputEncoding != null) {
                throw new BuildException(
                    "Seting input or output encoding is incompatible with binary"
                    + " concatenation");
            }
            if (filterChains != null) {
                throw new BuildException(
                    "Setting filters is incompatible with binary concatenation");
            }
            if (fixLastLine) {
                throw new BuildException(
                    "Setting fixlastline is incompatible with binary concatenation");
            }
            if (header != null || footer != null) {
                throw new BuildException(
                    "Nested header or footer is incompatible with binary concatenation");
            }
        }
        if (destinationFile != null && outputWriter != null) {
            throw new BuildException(
                "Cannot specify both a destination file and an output writer");
        }
        // Sanity check our inputs.
        if (rc == null && textBuffer == null) {
            // Nothing to concatenate!
            throw new BuildException(
                "At least one resource must be provided, or some text.");
        }
        if (rc != null) {
            // If using resources, disallow inline text. This is similar to
            // using GNU 'cat' with file arguments -- stdin is simply
            // ignored.
            if (textBuffer != null) {
                throw new BuildException(
                    "Cannot include inline text when using resources.");
            }
            Restrict noexistRc = new Restrict();
            noexistRc.add(NOT_EXISTS);
            noexistRc.add(rc);
            for (Iterator i = noexistRc.iterator(); i.hasNext();) {
                log(i.next() + " does not exist.", Project.MSG_ERR);
            }
            if (destinationFile != null) {
                for (Iterator i = rc.iterator(); i.hasNext();) {
                    Object o = i.next();
                    if (o instanceof FileResource) {
                        File f = ((FileResource) o).getFile();
                        if (FILE_UTILS.fileNameEquals(f, destinationFile)) {
                            throw new BuildException("Input file \""
                                + f + "\" is the same as the output file.");
                        }
                    }
                }
            }
            Restrict existRc = new Restrict();
            existRc.add(EXISTS);
            existRc.add(rc);
            boolean outofdate = destinationFile == null || forceOverwrite;
            if (!outofdate) {
                for (Iterator i = existRc.iterator(); !outofdate && i.hasNext();) {
                    Resource r = (Resource) i.next();
                    outofdate =
                        (r.getLastModified() == 0L
                         || r.getLastModified() > destinationFile.lastModified());
                }
            }
            if (!outofdate) {
                log(destinationFile + " is up-to-date.", Project.MSG_VERBOSE);
                return null; // no need to do anything
            }
            return existRc;
        } else {
            StringResource s = new StringResource();
            s.setProject(getProject());
            s.setValue(textBuffer.toString());
            return s;
        }