diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java | 955 |
1 files changed, 0 insertions, 955 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java deleted file mode 100644 index 1338f2a4..00000000 --- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java +++ /dev/null @@ -1,955 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.tools.ant.taskdefs; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.Vector; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.ProjectComponent; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.filters.util.ChainReaderHelper; -import org.apache.tools.ant.types.FileList; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.FilterChain; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.Resource; -import org.apache.tools.ant.types.ResourceCollection; -import org.apache.tools.ant.types.resources.FileResource; -import org.apache.tools.ant.types.resources.Intersect; -import org.apache.tools.ant.types.resources.LogOutputResource; -import org.apache.tools.ant.types.resources.Resources; -import org.apache.tools.ant.types.resources.Restrict; -import org.apache.tools.ant.types.resources.StringResource; -import org.apache.tools.ant.types.resources.selectors.Exists; -import org.apache.tools.ant.types.resources.selectors.Not; -import org.apache.tools.ant.types.resources.selectors.ResourceSelector; -import org.apache.tools.ant.types.selectors.SelectorUtils; -import org.apache.tools.ant.util.ConcatResourceInputStream; -import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.util.ReaderInputStream; -import org.apache.tools.ant.util.ResourceUtils; -import org.apache.tools.ant.util.StringUtils; - -/** - * 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: - * - * <pre> - * <concat destfile="${build.dir}/index.xml" - * append="false"> - * - * <fileset dir="${xml.root.dir}" - * includes="*.xml" /> - * - * </concat> - * </pre> - * - */ -public class Concat extends Task implements ResourceCollection { - - // The size of buffers to be used - private static final int BUFFER_SIZE = 8192; - - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); - - private static final ResourceSelector EXISTS = new Exists(); - private static final ResourceSelector NOT_EXISTS = new Not(EXISTS); - - /** - * sub element points to a file or contains text - */ - public static class TextElement extends ProjectComponent { - private String value = ""; - private boolean trimLeading = false; - private boolean trim = false; - private boolean filtering = true; - private String encoding = null; - - /** - * whether to filter the text in this element - * or not. - * - * @param filtering true if the text should be filtered. - * the default value is true. - */ - public void setFiltering(boolean filtering) { - this.filtering = filtering; - } - - /** return the filtering attribute */ - private boolean getFiltering() { - return filtering; - } - - /** - * The encoding of the text element - * - * @param encoding the name of the charset used to encode - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * set the text using a file - * @param file the file to use - * @throws BuildException if the file does not exist, or cannot be - * read - */ - public void setFile(File file) throws BuildException { - // non-existing files are not allowed - if (!file.exists()) { - throw new BuildException("File " + file + " does not exist."); - } - - BufferedReader reader = null; - try { - if (this.encoding == null) { - reader = new BufferedReader(new FileReader(file)); - } else { - reader = new BufferedReader( - new InputStreamReader(new FileInputStream(file), - this.encoding)); - } - value = FileUtils.safeReadFully(reader); - } catch (IOException ex) { - throw new BuildException(ex); - } finally { - FileUtils.close(reader); - } - } - - /** - * set the text using inline - * @param value the text to place inline - */ - public void addText(String value) { - this.value += getProject().replaceProperties(value); - } - - /** - * s:^\s*:: on each line of input - * @param strip if true do the trim - */ - public void setTrimLeading(boolean strip) { - this.trimLeading = strip; - } - - /** - * whether to call text.trim() - * @param trim if true trim the text - */ - public void setTrim(boolean trim) { - this.trim = trim; - } - - /** - * @return the text, after possible trimming - */ - public String getValue() { - if (value == null) { - value = ""; - } - if (value.trim().length() == 0) { - value = ""; - } - if (trimLeading) { - char[] current = value.toCharArray(); - StringBuffer b = new StringBuffer(current.length); - boolean startOfLine = true; - int pos = 0; - while (pos < current.length) { - char ch = current[pos++]; - if (startOfLine) { - if (ch == ' ' || ch == '\t') { - continue; - } - startOfLine = false; - } - b.append(ch); - if (ch == '\n' || ch == '\r') { - startOfLine = true; - } - } - value = b.toString(); - } - if (trim) { - value = value.trim(); - } - return value; - } - } - - private interface ReaderFactory<S> { - Reader getReader(S s) throws IOException; - } - - /** - * This class reads from each of the source files in turn. - * The concatentated result can then be filtered as - * a single stream. - */ - private final class MultiReader<S> extends Reader { - private Reader reader = null; - private int lastPos = 0; - private char[] lastChars = new char[eolString.length()]; - private boolean needAddSeparator = false; - private Iterator<S> readerSources; - private ReaderFactory<S> factory; - - private MultiReader(Iterator<S> readerSources, ReaderFactory<S> factory) { - this.readerSources = readerSources; - this.factory = factory; - } - - private Reader getReader() throws IOException { - if (reader == null && readerSources.hasNext()) { - reader = factory.getReader(readerSources.next()); - Arrays.fill(lastChars, (char) 0); - } - return reader; - } - - private void nextReader() throws IOException { - close(); - reader = null; - } - - /** - * Read a character from the current reader object. Advance - * to the next if the reader is finished. - * @return the character read, -1 for EOF on the last reader. - * @exception IOException - possibly thrown by the read for a reader - * object. - */ - public int read() throws IOException { - if (needAddSeparator) { - if (lastPos >= eolString.length()) { - lastPos = 0; - needAddSeparator = false; - } else { - return eolString.charAt(lastPos++); - } - } - while (getReader() != null) { - int ch = getReader().read(); - if (ch == -1) { - nextReader(); - if (isFixLastLine() && isMissingEndOfLine()) { - needAddSeparator = true; - lastPos = 1; - return eolString.charAt(0); - } - } else { - addLastChar((char) ch); - return ch; - } - } - return -1; - } - - /** - * Read into the buffer <code>cbuf</code>. - * @param cbuf The array to be read into. - * @param off The offset. - * @param len The length to read. - * @exception IOException - possibly thrown by the reads to the - * reader objects. - */ - public int read(char[] cbuf, int off, int len) - throws IOException { - - int amountRead = 0; - while (getReader() != null || needAddSeparator) { - if (needAddSeparator) { - cbuf[off] = eolString.charAt(lastPos++); - if (lastPos >= eolString.length()) { - lastPos = 0; - needAddSeparator = false; - } - len--; - off++; - amountRead++; - if (len == 0) { - return amountRead; - } - continue; - } - int nRead = getReader().read(cbuf, off, len); - if (nRead == -1 || nRead == 0) { - nextReader(); - if (isFixLastLine() && isMissingEndOfLine()) { - needAddSeparator = true; - lastPos = 0; - } - } else { - if (isFixLastLine()) { - for (int i = nRead; - i > (nRead - lastChars.length); - --i) { - if (i <= 0) { - break; - } - addLastChar(cbuf[off + i - 1]); - } - } - len -= nRead; - off += nRead; - amountRead += nRead; - if (len == 0) { - return amountRead; - } - } - } - if (amountRead == 0) { - return -1; - } else { - return amountRead; - } - } - - /** - * 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; - } - - private boolean isFixLastLine() { - return fixLastLine && textBuffer == null; - } - } - - private final class ConcatResource extends Resource { - private ResourceCollection c; - - private ConcatResource(ResourceCollection c) { - this.c = c; - } - public InputStream getInputStream() throws IOException { - if (binary) { - ConcatResourceInputStream result = new ConcatResourceInputStream(c); - result.setManagingComponent(this); - return result; - } - Reader resourceReader = getFilteredReader( - new MultiReader<Resource>(c.iterator(), resourceReaderFactory)); - Reader rdr; - if (header == null && footer == null) { - rdr = resourceReader; - } else { - int readerCount = 1; - if (header != null) { - readerCount++; - } - if (footer != null) { - readerCount++; - } - Reader[] readers = new Reader[readerCount]; - int pos = 0; - if (header != null) { - readers[pos] = new StringReader(header.getValue()); - if (header.getFiltering()) { - readers[pos] = getFilteredReader(readers[pos]); - } - pos++; - } - readers[pos++] = resourceReader; - if (footer != null) { - readers[pos] = new StringReader(footer.getValue()); - if (footer.getFiltering()) { - readers[pos] = getFilteredReader(readers[pos]); - } - } - rdr = new MultiReader<Reader>(Arrays.asList(readers).iterator(), - identityReaderFactory); - } - return outputEncoding == null ? new ReaderInputStream(rdr) - : new ReaderInputStream(rdr, outputEncoding); - } - public String getName() { - return resourceName == null - ? "concat (" + String.valueOf(c) + ")" : resourceName; - } - } - - // Attributes. - - /** - * The destination of the stream. If <code>null</code>, the system - * console is used. - */ - private Resource dest; - - /** - * Whether or not the stream should be appended if the destination file - * exists. - * Defaults to <code>false</code>. - */ - private boolean append; - - /** - * Stores the input file encoding. - */ - private String encoding; - - /** Stores the output file encoding. */ - private String outputEncoding; - - /** Stores the binary attribute */ - private boolean binary; - - // Child elements. - - /** - * This buffer stores the text within the 'concat' element. - */ - private StringBuffer textBuffer; - - /** - * Stores a collection of file sets and/or file lists, used to - * select multiple files for concatenation. - */ - private Resources rc; - - /** for filtering the concatenated */ - private Vector<FilterChain> filterChains; - /** ignore dates on input files */ - private boolean forceOverwrite = true; - /** overwrite read-only files */ - private boolean force = false; - /** String to place at the start of the concatenated stream */ - private TextElement footer; - /** String to place at the end of the concatenated stream */ - private TextElement header; - /** add missing line.separator to files **/ - private boolean fixLastLine = false; - /** endofline for fixlast line */ - private String eolString; - /** outputwriter */ - private Writer outputWriter = null; - /** whether to not create dest if no source files are - * available */ - private boolean ignoreEmpty = true; - /** exposed resource name */ - private String resourceName; - - private ReaderFactory<Resource> resourceReaderFactory = new ReaderFactory<Resource>() { - public Reader getReader(Resource o) throws IOException { - InputStream is = o.getInputStream(); - return new BufferedReader(encoding == null - ? new InputStreamReader(is) - : new InputStreamReader(is, encoding)); - } - }; - - private ReaderFactory<Reader> identityReaderFactory = new ReaderFactory<Reader>() { - public Reader getReader(Reader o) { - return o; - } - }; - - /** - * Construct a new Concat task. - */ - public Concat() { - reset(); - } - - /** - * Reset state to default. - */ - public void reset() { - append = false; - forceOverwrite = true; - dest = null; - encoding = null; - outputEncoding = null; - fixLastLine = false; - filterChains = null; - footer = null; - header = null; - binary = false; - outputWriter = null; - textBuffer = null; - eolString = StringUtils.LINE_SEP; - rc = null; - ignoreEmpty = true; - force = false; - } - - // Attribute setters. - - /** - * Sets the destination file, or uses the console if not specified. - * @param destinationFile the destination file - */ - public void setDestfile(File destinationFile) { - setDest(new FileResource(destinationFile)); - } - - /** - * Set the resource to write to. - * @param dest the Resource to write to. - * @since Ant 1.8 - */ - public void setDest(Resource dest) { - this.dest = dest; - } - - /** - * Sets the behavior when the destination exists. If set to - * <code>true</code> the task will append the stream data an - * {@link Appendable} resource; otherwise existing content will be - * overwritten. Defaults to <code>false</code>. - * @param append if true append output. - */ - public void setAppend(boolean append) { - this.append = append; - } - - /** - * Sets the character encoding - * @param encoding the encoding of the input stream and unless - * outputencoding is set, the outputstream. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - if (outputEncoding == null) { - outputEncoding = encoding; - } - } - - /** - * Sets the character encoding for outputting - * @param outputEncoding the encoding for the output file - * @since Ant 1.6 - */ - public void setOutputEncoding(String outputEncoding) { - this.outputEncoding = outputEncoding; - } - - /** - * Force overwrite existing destination file - * @param forceOverwrite if true always overwrite, otherwise only - * overwrite if the output file is older any of the - * input files. - * @since Ant 1.6 - * @deprecated use #setOverwrite instead - */ - public void setForce(boolean forceOverwrite) { - this.forceOverwrite = forceOverwrite; - } - - /** - * Force overwrite existing destination file - * @param forceOverwrite if true always overwrite, otherwise only - * overwrite if the output file is older any of the - * input files. - * @since Ant 1.8.2 - */ - public void setOverwrite(boolean forceOverwrite) { - setForce(forceOverwrite); - } - - /** - * Whether read-only destinations will be overwritten. - * - * <p>Defaults to false</p> - * - * @since Ant 1.8.2 - */ - public void setForceReadOnly(boolean f) { - force = f; - } - - /** - * Sets the behavior when no source resource files are available. If set to - * <code>false</code> the destination file will always be created. - * Defaults to <code>true</code>. - * @param ignoreEmpty if false honour destinationfile creation. - * @since Ant 1.8.0 - */ - public void setIgnoreEmpty(boolean ignoreEmpty) { - this.ignoreEmpty = ignoreEmpty; - } - - /** - * Set the name that will be reported by the exposed {@link Resource}. - * @param resourceName to set - * @since Ant 1.8.3 - */ - public void setResourceName(String resourceName) { - this.resourceName = resourceName; - } - - // Nested element creators. - - /** - * Path of files to concatenate. - * @return the path used for concatenating - * @since Ant 1.6 - */ - public Path createPath() { - Path path = new Path(getProject()); - add(path); - return path; - } - - /** - * Set of files to concatenate. - * @param set the set of files - */ - public void addFileset(FileSet set) { - add(set); - } - - /** - * List of files to concatenate. - * @param list the list of files - */ - public void addFilelist(FileList list) { - add(list); - } - - /** - * Add an arbitrary ResourceCollection. - * @param c the ResourceCollection to add. - * @since Ant 1.7 - */ - public void add(ResourceCollection c) { - synchronized (this) { - if (rc == null) { - rc = new Resources(); - rc.setProject(getProject()); - rc.setCache(true); - } - } - rc.add(c); - } - - /** - * Adds a FilterChain. - * @param filterChain a filterchain to filter the concatenated input - * @since Ant 1.6 - */ - public void addFilterChain(FilterChain filterChain) { - if (filterChains == null) { - filterChains = new Vector<FilterChain>(); - } - filterChains.addElement(filterChain); - } - - /** - * This method adds text which appears in the 'concat' element. - * @param text the text to be concated. - */ - public void addText(String text) { - 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); - } - - /** - * Add a header to the concatenated output - * @param headerToAdd the header - * @since Ant 1.6 - */ - public void addHeader(TextElement headerToAdd) { - this.header = headerToAdd; - } - - /** - * Add a footer to the concatenated output - * @param footerToAdd the footer - * @since Ant 1.6 - */ - public void addFooter(TextElement footerToAdd) { - this.footer = footerToAdd; - } - - /** - * 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 - */ - 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. 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 - */ - public void setEol(FixCRLF.CrLf crlf) { - 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"; - } - } - - /** - * 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 - */ - public void setWriter(Writer outputWriter) { - this.outputWriter = outputWriter; - } - - /** - * 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. - */ - public void setBinary(boolean binary) { - this.binary = binary; - } - - /** - * Execute the concat task. - */ - public void execute() { - validate(); - if (binary && dest == null) { - throw new BuildException( - "dest|destfile attribute is required for binary concatenation"); - } - ResourceCollection c = getResources(); - if (isUpToDate(c)) { - log(dest + " is up-to-date.", Project.MSG_VERBOSE); - return; - } - if (c.size() == 0 && ignoreEmpty) { - return; - } - try { - //most of these are defaulted because the concat-as-a-resource code hijacks a lot: - ResourceUtils.copyResource(new ConcatResource(c), dest == null - ? new LogOutputResource(this, Project.MSG_WARN) - : dest, - null, null, true, false, append, null, - null, getProject(), force); - } catch (IOException e) { - throw new BuildException("error concatenating content to " + dest, e); - } - } - - /** - * Implement ResourceCollection. - * @return Iterator<Resource>. - */ - public Iterator<Resource> iterator() { - validate(); - return Collections.<Resource>singletonList(new ConcatResource(getResources())).iterator(); - } - - /** - * Implement ResourceCollection. - * @return 1. - */ - public int size() { - return 1; - } - - /** - * Implement ResourceCollection. - * @return false. - */ - public boolean isFilesystemOnly() { - return false; - } - - /** - * Validate configuration options. - */ - private void validate() { - - // treat empty nested text as no text - sanitizeText(); - - // if binary check if incompatible attributes are used - if (binary) { - if (textBuffer != null) { - throw new BuildException( - "Nested text is incompatible with binary concatenation"); - } - if (encoding != null || outputEncoding != null) { - throw new BuildException( - "Setting 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 (dest != null && outputWriter != null) { - throw new BuildException( - "Cannot specify both a destination resource 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 && textBuffer != null) { - // If using resources, disallow inline text. This is similar to - // using GNU 'cat' with file arguments--stdin is simply ignored. - throw new BuildException( - "Cannot include inline text when using resources."); - } - } - - /** - * Get the resources to concatenate. - */ - private ResourceCollection getResources() { - if (rc == null) { - return new StringResource(getProject(), textBuffer.toString()); - } - if (dest != null) { - Intersect checkDestNotInSources = new Intersect(); - checkDestNotInSources.setProject(getProject()); - checkDestNotInSources.add(rc); - checkDestNotInSources.add(dest); - if (checkDestNotInSources.size() > 0) { - throw new BuildException("Destination resource " + dest - + " was specified as an input resource."); - } - } - Restrict noexistRc = new Restrict(); - noexistRc.add(NOT_EXISTS); - noexistRc.add(rc); - for (Resource r : noexistRc) { - log(r + " does not exist.", Project.MSG_ERR); - } - Restrict result = new Restrict(); - result.add(EXISTS); - result.add(rc); - return result; - } - - private boolean isUpToDate(ResourceCollection c) { - if (dest == null || forceOverwrite) { - return false; - } - for (Resource r : c) { - if (SelectorUtils.isOutOfDate(r, dest, FILE_UTILS.getFileTimestampGranularity())) { - return false; - } - } - return true; - } - - /** - * Treat empty nested text as no text. - * - * <p>Depending on the XML parser, addText may have been called - * for "ignorable whitespace" as well.</p> - */ - private void sanitizeText() { - if (textBuffer != null && "".equals(textBuffer.toString().trim())) { - textBuffer = null; - } - } - - private Reader getFilteredReader(Reader r) { - if (filterChains == null) { - return r; - } - ChainReaderHelper helper = new ChainReaderHelper(); - helper.setBufferSize(BUFFER_SIZE); - helper.setPrimaryReader(r); - helper.setFilterChains(filterChains); - helper.setProject(getProject()); - //used to be a BufferedReader here, but we should be buffering lower: - return helper.getAssembledReader(); - } - -} |