📄 replace.java
字号:
void flush() throws IOException { process(); writer.flush(); } /** * Closes the file. * @throws IOException When the file cannot be closed. */ void close() throws IOException { writer.close(); } /** * Closes file but doesn't throw exception */ void closeQuietly() { FileUtils.close(writer); } } /** * Do the execution. * @throws BuildException if we cant build */ public void execute() throws BuildException { Vector savedFilters = (Vector) replacefilters.clone(); Properties savedProperties = properties == null ? null : (Properties) properties.clone(); if (token != null) { // line separators in values and tokens are "\n" // in order to compare with the file contents, replace them // as needed StringBuffer val = new StringBuffer(value.getText()); stringReplace(val, "\r\n", "\n"); stringReplace(val, "\n", StringUtils.LINE_SEP); StringBuffer tok = new StringBuffer(token.getText()); stringReplace(tok, "\r\n", "\n"); stringReplace(tok, "\n", StringUtils.LINE_SEP); Replacefilter firstFilter = createPrimaryfilter(); firstFilter.setToken(tok.toString()); firstFilter.setValue(val.toString()); } try { if (replaceFilterFile != null) { Properties props = getProperties(replaceFilterFile); Enumeration e = props.keys(); while (e.hasMoreElements()) { String tok = e.nextElement().toString(); Replacefilter replaceFilter = createReplacefilter(); replaceFilter.setToken(tok); replaceFilter.setValue(props.getProperty(tok)); } } validateAttributes(); if (propertyFile != null) { properties = getProperties(propertyFile); } validateReplacefilters(); fileCount = 0; replaceCount = 0; if (src != null) { processFile(src); } if (dir != null) { DirectoryScanner ds = super.getDirectoryScanner(dir); String[] srcs = ds.getIncludedFiles(); for (int i = 0; i < srcs.length; i++) { File file = new File(dir, srcs[i]); processFile(file); } } if (summary) { log("Replaced " + replaceCount + " occurrences in " + fileCount + " files.", Project.MSG_INFO); } } finally { replacefilters = savedFilters; properties = savedProperties; } // end of finally } /** * Validate attributes provided for this task in .xml build file. * * @exception BuildException if any supplied attribute is invalid or any * mandatory attribute is missing. */ public void validateAttributes() throws BuildException { if (src == null && dir == null) { String message = "Either the file or the dir attribute " + "must be specified"; throw new BuildException(message, getLocation()); } if (propertyFile != null && !propertyFile.exists()) { String message = "Property file " + propertyFile.getPath() + " does not exist."; throw new BuildException(message, getLocation()); } if (token == null && replacefilters.size() == 0) { String message = "Either token or a nested replacefilter " + "must be specified"; throw new BuildException(message, getLocation()); } if (token != null && "".equals(token.getText())) { String message = "The token attribute must not be an empty string."; throw new BuildException(message, getLocation()); } } /** * Validate nested elements. * * @exception BuildException if any supplied attribute is invalid or any * mandatory attribute is missing. */ public void validateReplacefilters() throws BuildException { for (int i = 0; i < replacefilters.size(); i++) { Replacefilter element = (Replacefilter) replacefilters.elementAt(i); element.validate(); } } /** * Load a properties file. * @param propertyFile the file to load the properties from. * @return loaded <code>Properties</code> object. * @throws BuildException if the file could not be found or read. */ public Properties getProperties(File propertyFile) throws BuildException { Properties props = new Properties(); FileInputStream in = null; try { in = new FileInputStream(propertyFile); props.load(in); } catch (FileNotFoundException e) { String message = "Property file (" + propertyFile.getPath() + ") not found."; throw new BuildException(message); } catch (IOException e) { String message = "Property file (" + propertyFile.getPath() + ") cannot be loaded."; throw new BuildException(message); } finally { FileUtils.close(in); } return props; } /** * Perform the replacement on the given file. * * The replacement is performed on a temporary file which then * replaces the original file. * * @param src the source <code>File</code>. */ private void processFile(File src) throws BuildException { if (!src.exists()) { throw new BuildException("Replace: source file " + src.getPath() + " doesn't exist", getLocation()); } File temp = null; FileInput in = null; FileOutput out = null; try { in = new FileInput(src); temp = FILE_UTILS.createTempFile("rep", ".tmp", src.getParentFile(), false, true); out = new FileOutput(temp); int repCountStart = replaceCount; logFilterChain(src.getPath()); out.setInputBuffer(buildFilterChain(in.getOutputBuffer())); while (in.readChunk()) { if (processFilterChain()) { out.process(); } } flushFilterChain(); out.flush(); in.close(); in = null; out.close(); out = null; boolean changes = (replaceCount != repCountStart); if (changes) { fileCount++; FILE_UTILS.rename(temp, src); temp = null; } } catch (IOException ioe) { throw new BuildException("IOException in " + src + " - " + ioe.getClass().getName() + ":" + ioe.getMessage(), ioe, getLocation()); } finally { if (null != in) { in.closeQuietly(); } if (null != out) { out.closeQuietly(); } if (temp != null) { if (!temp.delete()) { temp.deleteOnExit(); } } } } /** * Flushes all filters. */ private void flushFilterChain() { for (int i = 0; i < replacefilters.size(); i++) { Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); filter.flush(); } } /** * Performs the normal processing of the filters. * @return true if the filter chain produced new output. */ private boolean processFilterChain() { for (int i = 0; i < replacefilters.size(); i++) { Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); if (!filter.process()) { return false; } } return true; } /** * Creates the chain of filters to operate. * @param inputBuffer <code>StringBuffer</code> containing the input for the * first filter. * @return <code>StringBuffer</code> containing the output of the last filter. */ private StringBuffer buildFilterChain(StringBuffer inputBuffer) { StringBuffer buf = inputBuffer; for (int i = 0; i < replacefilters.size(); i++) { Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); filter.setInputBuffer(buf); buf = filter.getOutputBuffer(); } return buf; } /** * Logs the chain of filters to operate on the file. * @param filename <code>String</code>. */ private void logFilterChain(String filename) { for (int i = 0; i < replacefilters.size(); i++) { Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); log("Replacing in " + filename + ": " + filter.getToken() + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE); } } /** * Set the source file; required unless <code>dir</code> is set. * @param file source <code>File</code>. */ public void setFile(File file) { this.src = file; } /** * Indicates whether a summary of the replace operation should be * produced, detailing how many token occurrences and files were * processed; optional, default=<code>false</code>. * * @param summary <code>boolean</code> whether a summary of the * replace operation should be logged. */ public void setSummary(boolean summary) { this.summary = summary; } /** * Sets the name of a property file containing filters; optional. * Each property will be treated as a replacefilter where token is the name * of the property and value is the value of the property. * @param replaceFilterFile <code>File</code> to load. */ public void setReplaceFilterFile(File replaceFilterFile) { this.replaceFilterFile = replaceFilterFile; } /** * The base directory to use when replacing a token in multiple files; * required if <code>file</code> is not defined. * @param dir <code>File</code> representing the base directory. */ public void setDir(File dir) { this.dir = dir; } /** * Set the string token to replace; required unless a nested * <code>replacetoken</code> element or the <code>replacefilterfile</code> * attribute is used. * @param token token <code>String</code>. */ public void setToken(String token) { createReplaceToken().addText(token); } /** * Set the string value to use as token replacement; * optional, default is the empty string "". * @param value replacement value. */ public void setValue(String value) { createReplaceValue().addText(value); } /** * Set the file encoding to use on the files read and written by the task; * optional, defaults to default JVM encoding. * * @param encoding the encoding to use on the files. */ public void setEncoding(String encoding) { this.encoding = encoding; } /** * Create a token to filter as the text of a nested element. * @return nested token <code>NestedString</code> to configure. */ public NestedString createReplaceToken() { if (token == null) { token = new NestedString(); } return token; } /** * Create a string to replace the token as the text of a nested element. * @return replacement value <code>NestedString</code> to configure. */ public NestedString createReplaceValue() { return value; } /** * The name of a property file from which properties specified using nested * <code><replacefilter></code> elements are drawn; required only if * the <i>property</i> attribute of <code><replacefilter></code> is used. * @param propertyFile <code>File</code> to load. */ public void setPropertyFile(File propertyFile) { this.propertyFile = propertyFile; } /** * Add a nested <replacefilter> element. * @return a nested <code>Replacefilter</code> object to be configured. */ public Replacefilter createReplacefilter() { Replacefilter filter = new Replacefilter(); replacefilters.addElement(filter); return filter; } /** * Adds the token and value as first <replacefilter> element. * The token and value are always processed first. * @return a nested <code>Replacefilter</code> object to be configured. */ private Replacefilter createPrimaryfilter() { Replacefilter filter = new Replacefilter(); replacefilters.insertElementAt(filter, 0); return filter; } /** * Replace occurrences of str1 in StringBuffer str with str2. */ private void stringReplace(StringBuffer str, String str1, String str2) { int found = str.toString().indexOf(str1); while (found >= 0) { str.replace(found, found + str1.length(), str2); found = str.toString().indexOf(str1, found + str2.length()); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -