📄 concat.java
字号:
/** for filtering the concatenated */ private Vector filterChains; /** ignore dates on input files */ private boolean forceOverwrite = true; /** String to place at the start of the concatented stream */ 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; /** outputwriter */ private Writer outputWriter = null; private ReaderFactory resourceReaderFactory = new ReaderFactory() { public Reader getReader(Object o) throws IOException { InputStream is = ((Resource) o).getInputStream(); return new BufferedReader(encoding == null ? new InputStreamReader(is) : new InputStreamReader(is, encoding)); } }; private ReaderFactory identityReaderFactory = new ReaderFactory() { public Reader getReader(Object o) { return (Reader) o; } }; /** * Construct a new Concat task. */ public Concat() { reset(); } /** * Reset state to default. */ public void reset() { 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 = StringUtils.LINE_SEP; rc = null; } // Attribute setters. /** * Sets the destination file, or uses the console if not specified. * @param destinationFile the destination file */ public void setDestfile(File destinationFile) { this.destinationFile = destinationFile; } /** * Sets the behavior when the destination file exists. If set to * <code>true</code> the stream data will be appended to the * existing file, otherwise the existing file will be * overwritten. Defaults to <code>false</code>. * @param append if true append to the file. */ 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 force if true always overwrite, otherwise only overwrite * if the output file is older any of the input files. * @since Ant 1.6 */ public void setForce(boolean force) { this.forceOverwrite = force; } // 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 synchronized void add(ResourceCollection c) { if (rc == null) { rc = c; return; } if (!(rc instanceof Resources)) { Resources newRc = new Resources(); newRc.setProject(getProject()); newRc.add(rc); rc = newRc; } ((Resources) 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(); } 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 && destinationFile == null) { throw new BuildException( "destfile attribute is required for binary concatenation"); } ResourceCollection c = getResources(); if (isUpToDate(c)) { log(destinationFile + " is up-to-date.", Project.MSG_VERBOSE); return; } if (c.size() == 0) { return; } OutputStream out; if (destinationFile == null) { // Log using WARN so it displays in 'quiet' mode. out = new LogOutputStream(this, Project.MSG_WARN); } else { try { // ensure that the parent dir of dest file exists File parent = destinationFile.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } // use getPath() for pre-JDK 1.4 compatibility: out = new FileOutputStream(destinationFile.getPath(), append); } catch (Throwable t) { throw new BuildException("Unable to open " + destinationFile + " for writing", t); } } InputStream catStream; try { catStream = new ConcatResource(c).getInputStream(); } catch (IOException e) { throw new BuildException("error getting concatenated resource content", e); } pump(catStream, out); } /** * Implement ResourceCollection. * @return Iterator<Resource>. */ public Iterator iterator() { validate(); return Collections.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 (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 && 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()); } 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 result = new Restrict(); result.add(EXISTS); result.add(rc); return result; } private boolean isUpToDate(ResourceCollection c) { if (destinationFile == null || forceOverwrite) { return false; } for (Iterator i = c.iterator(); i.hasNext();) { Resource r = (Resource) i.next(); if (r.getLastModified() == 0L || r.getLastModified() > destinationFile.lastModified()) { 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; } } /** * Transfer the contents of <code>in</code> to <code>out</code>. * @param in InputStream * @param out OutputStream */ private void pump(InputStream in, OutputStream out) { 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); FileUtils.close(out); } } 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(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -