|
|
@@ -55,15 +55,17 @@ |
|
|
package org.apache.tools.ant.taskdefs; |
|
|
package org.apache.tools.ant.taskdefs; |
|
|
|
|
|
|
|
|
import org.apache.tools.ant.*; |
|
|
import org.apache.tools.ant.*; |
|
|
|
|
|
import org.apache.tools.ant.taskdefs.*; |
|
|
import java.io.*; |
|
|
import java.io.*; |
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Replaces all the occurrences of the given string token with the given |
|
|
|
|
|
* string value of the indicated files. |
|
|
|
|
|
|
|
|
* Replaces all occurrences of one or more string tokens with given |
|
|
|
|
|
* values in the indicated files. Each value can be either a string |
|
|
|
|
|
* or the value of a property available in a designated property file. |
|
|
* |
|
|
* |
|
|
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a> |
|
|
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a> |
|
|
* @author <a href="mailto:erik@desknetinc.com">Erik Langenbach</a> |
|
|
|
|
|
|
|
|
* @author <a href="mailto:erik@desknetinc.com">Erik Langenbach</a> |
|
|
*/ |
|
|
*/ |
|
|
public class Replace extends MatchingTask { |
|
|
public class Replace extends MatchingTask { |
|
|
|
|
|
|
|
|
@@ -71,8 +73,13 @@ public class Replace extends MatchingTask { |
|
|
private NestedString token = null; |
|
|
private NestedString token = null; |
|
|
private NestedString value = new NestedString(); |
|
|
private NestedString value = new NestedString(); |
|
|
|
|
|
|
|
|
|
|
|
private File propertyFile = null; |
|
|
|
|
|
private Properties properties = null; |
|
|
|
|
|
private Vector replacefilters = new Vector(); |
|
|
|
|
|
|
|
|
private File dir = null; |
|
|
private File dir = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Inner class |
|
|
public class NestedString { |
|
|
public class NestedString { |
|
|
|
|
|
|
|
|
private StringBuffer buf = new StringBuffer(); |
|
|
private StringBuffer buf = new StringBuffer(); |
|
|
@@ -86,49 +93,170 @@ public class Replace extends MatchingTask { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Inner class |
|
|
|
|
|
public class Replacefilter |
|
|
|
|
|
{ |
|
|
|
|
|
private String token; |
|
|
|
|
|
private String value; |
|
|
|
|
|
private String property; |
|
|
|
|
|
|
|
|
|
|
|
public void validate() throws BuildException { |
|
|
|
|
|
//Validate mandatory attributes |
|
|
|
|
|
if (token == null) { |
|
|
|
|
|
String message = "token is a mandatory attribute " + "of replacefilter."; |
|
|
|
|
|
throw new BuildException(message); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//value and property are mutually exclusive attributes |
|
|
|
|
|
if ((value != null) && (property != null)) { |
|
|
|
|
|
String message = "Either value or property " + "can be specified, but a replacefilter " + "element cannot have both."; |
|
|
|
|
|
throw new BuildException(message); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((property != null)) { |
|
|
|
|
|
//the property attribute must have access to a property file |
|
|
|
|
|
if (propertyFile == null) { |
|
|
|
|
|
String message = "The replacefilter's property attribute " + "can only be used with the replacetask's " + "propertyFile attribute."; |
|
|
|
|
|
throw new BuildException(message); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Make sure property exists in property file |
|
|
|
|
|
if (properties == null || |
|
|
|
|
|
properties.getProperty(property) == null) { |
|
|
|
|
|
String message = "property \"" + property + "\" was not found in " + propertyFile.getPath(); |
|
|
|
|
|
throw new BuildException(message); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getReplaceValue() |
|
|
|
|
|
{ |
|
|
|
|
|
if (property != null) { |
|
|
|
|
|
return (String)properties.getProperty(property); |
|
|
|
|
|
} |
|
|
|
|
|
else if (value != null) { |
|
|
|
|
|
return value; |
|
|
|
|
|
} |
|
|
|
|
|
else if (Replace.this.value != null) { |
|
|
|
|
|
return Replace.this.value.getText(); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
//Default is empty string |
|
|
|
|
|
return new String(""); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void setToken(String token) { |
|
|
|
|
|
this.token = token; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getToken() { |
|
|
|
|
|
return token; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void setValue(String value) { |
|
|
|
|
|
this.value = value; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getValue() { |
|
|
|
|
|
return value; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void setProperty(String property) { |
|
|
|
|
|
this.property = property; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getProperty() { |
|
|
|
|
|
return property; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Do the execution. |
|
|
* Do the execution. |
|
|
*/ |
|
|
*/ |
|
|
public void execute() throws BuildException { |
|
|
public void execute() throws BuildException { |
|
|
|
|
|
|
|
|
if (token == null) { |
|
|
|
|
|
throw new BuildException("replace token must not be null", location); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
validateAttributes(); |
|
|
|
|
|
|
|
|
if (token.getText().equals("")) { |
|
|
|
|
|
throw new BuildException("replace token must not be empty", location); |
|
|
|
|
|
|
|
|
if (propertyFile != null) { |
|
|
|
|
|
properties = getProperties(propertyFile); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (src == null && dir == null) { |
|
|
|
|
|
throw new BuildException("Either the file or the dir attribute must be specified", location); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
log("Replacing " + token.getText() + " --> " + value.getText()); |
|
|
|
|
|
|
|
|
validateReplacefilters(); |
|
|
|
|
|
|
|
|
if (src != null) { |
|
|
if (src != null) { |
|
|
processFile(src); |
|
|
processFile(src); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (dir != null) { |
|
|
if (dir != null) { |
|
|
DirectoryScanner ds = super.getDirectoryScanner(dir); |
|
|
|
|
|
|
|
|
DirectoryScanner ds = super.getDirectoryScanner(dir); |
|
|
String[] srcs = ds.getIncludedFiles(); |
|
|
String[] srcs = ds.getIncludedFiles(); |
|
|
|
|
|
|
|
|
for(int i=0; i<srcs.length; i++) { |
|
|
for(int i=0; i<srcs.length; i++) { |
|
|
File file = new File(dir,srcs[i]); |
|
|
|
|
|
|
|
|
File file = new File(dir,srcs[i]); |
|
|
processFile(file); |
|
|
processFile(file); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 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, location); |
|
|
|
|
|
} |
|
|
|
|
|
if (propertyFile != null && !propertyFile.exists()) { |
|
|
|
|
|
String message = "Property file " + propertyFile.getPath() + " does not exist."; |
|
|
|
|
|
throw new BuildException(message, location); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 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(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Properties getProperties(File propertyFile) throws BuildException { |
|
|
|
|
|
Properties properties = new Properties(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
properties.load(new FileInputStream(propertyFile)); |
|
|
|
|
|
} |
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return properties; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Perform the replacement on the given file. |
|
|
* Perform the replacement on the given file. |
|
|
* |
|
|
* |
|
|
* The replacement is performed on a temporary file which then replaces the original file. |
|
|
|
|
|
|
|
|
* The replacement is performed on a temporary file which then |
|
|
|
|
|
* replaces the original file. |
|
|
* |
|
|
* |
|
|
* @param src the source file |
|
|
* @param src the source file |
|
|
*/ |
|
|
*/ |
|
|
private void processFile(File src) throws BuildException { |
|
|
private void processFile(File src) throws BuildException { |
|
|
if (!src.exists()) { |
|
|
|
|
|
|
|
|
if (!src.exists()) { |
|
|
throw new BuildException("Replace: source file " + src.getPath() + " doesn't exist", location); |
|
|
throw new BuildException("Replace: source file " + src.getPath() + " doesn't exist", location); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -155,27 +283,39 @@ public class Replace extends MatchingTask { |
|
|
// create a String so we can use indexOf |
|
|
// create a String so we can use indexOf |
|
|
String buf = new String(tmpBuf); |
|
|
String buf = new String(tmpBuf); |
|
|
|
|
|
|
|
|
// line separators in values and tokens are "\n" |
|
|
|
|
|
// in order to compare with the file contents, replace them |
|
|
|
|
|
// as needed |
|
|
|
|
|
String linesep = System.getProperty("line.separator"); |
|
|
|
|
|
String val = stringReplace(value.getText(), "\n", linesep); |
|
|
|
|
|
String tok = stringReplace(token.getText(), "\n", linesep); |
|
|
|
|
|
|
|
|
//Preserve original string (buf) so we can compare the result |
|
|
|
|
|
String newString = new String(buf); |
|
|
|
|
|
|
|
|
|
|
|
if (token != null) |
|
|
|
|
|
{ |
|
|
|
|
|
// line separators in values and tokens are "\n" |
|
|
|
|
|
// in order to compare with the file contents, replace them |
|
|
|
|
|
// as needed |
|
|
|
|
|
String linesep = System.getProperty("line.separator"); |
|
|
|
|
|
String val = stringReplace(value.getText(), "\n", linesep); |
|
|
|
|
|
String tok = stringReplace(token.getText(), "\n", linesep); |
|
|
|
|
|
|
|
|
|
|
|
// for each found token, replace with value |
|
|
|
|
|
log("Replacing in " + src.getPath() + ": " + token.getText() + " --> " + value.getText(), Project.MSG_VERBOSE); |
|
|
|
|
|
newString = stringReplace(newString, tok, val); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// for each found token, replace with value |
|
|
|
|
|
String newString = stringReplace(buf, tok, val); |
|
|
|
|
|
boolean changes = !newString.equals(buf); |
|
|
|
|
|
|
|
|
if (replacefilters.size() > 0) { |
|
|
|
|
|
newString = processReplacefilters(newString, src.getPath()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean changes = !newString.equals(buf); |
|
|
if (changes) { |
|
|
if (changes) { |
|
|
bw.write(newString,0,newString.length()); |
|
|
bw.write(newString,0,newString.length()); |
|
|
bw.flush(); |
|
|
bw.flush(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cleanup |
|
|
// cleanup |
|
|
bw.close(); |
|
|
bw.close(); |
|
|
br.close(); |
|
|
br.close(); |
|
|
|
|
|
|
|
|
// If there were changes, move the new one to the old one, otherwise, delete the new one |
|
|
|
|
|
|
|
|
// If there were changes, move the new one to the old one; |
|
|
|
|
|
// otherwise, delete the new one |
|
|
if (changes) { |
|
|
if (changes) { |
|
|
src.delete(); |
|
|
src.delete(); |
|
|
temp.renameTo(src); |
|
|
temp.renameTo(src); |
|
|
@@ -185,7 +325,21 @@ public class Replace extends MatchingTask { |
|
|
} catch (IOException ioe) { |
|
|
} catch (IOException ioe) { |
|
|
ioe.printStackTrace(); |
|
|
ioe.printStackTrace(); |
|
|
throw new BuildException(ioe, location); |
|
|
throw new BuildException(ioe, location); |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String processReplacefilters(String buffer, String filename) { |
|
|
|
|
|
String newString = new String(buffer); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < replacefilters.size(); i++) { |
|
|
|
|
|
Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); |
|
|
|
|
|
|
|
|
|
|
|
//for each found token, replace with value |
|
|
|
|
|
log("Replacing in " + filename + ": " + filter.getToken() + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE); |
|
|
|
|
|
newString = stringReplace(newString, filter.getToken(), filter.getReplaceValue()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return newString; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -234,6 +388,22 @@ public class Replace extends MatchingTask { |
|
|
return value; |
|
|
return value; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Sets a file to be searched for property values. |
|
|
|
|
|
*/ |
|
|
|
|
|
public void setPropertyFile(String filename) { |
|
|
|
|
|
propertyFile = project.resolveFile(filename); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Add nested <replacefilter> element. |
|
|
|
|
|
*/ |
|
|
|
|
|
public Replacefilter createReplacefilter() { |
|
|
|
|
|
Replacefilter filter = new Replacefilter(); |
|
|
|
|
|
replacefilters.addElement(filter); |
|
|
|
|
|
return filter; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Replace occurrences of str1 in string str with str2 |
|
|
* Replace occurrences of str1 in string str with str2 |
|
|
*/ |
|
|
*/ |
|
|
|