Browse Source

PR: 13690

Patch that reduces the memory need of the Replace task,
by not creating duplicates of a lot of strings.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277178 13f79535-47bb-0310-9956-ffa450edef68
master
Jacobus Martinus Kruithof 20 years ago
parent
commit
c8c751af8e
1 changed files with 54 additions and 78 deletions
  1. +54
    -78
      src/main/org/apache/tools/ant/taskdefs/Replace.java

+ 54
- 78
src/main/org/apache/tools/ant/taskdefs/Replace.java View File

@@ -92,7 +92,7 @@ public class Replace extends MatchingTask {
* @return the text * @return the text
*/ */
public String getText() { public String getText() {
return buf.substring(0);
return buf.toString();
} }
} }


@@ -162,7 +162,7 @@ public class Replace extends MatchingTask {
return Replace.this.value.getText(); return Replace.this.value.getText();
} else { } else {
//Default is empty string //Default is empty string
return new String("");
return "";
} }
} }


@@ -228,6 +228,21 @@ public class Replace extends MatchingTask {
Properties savedProperties = Properties savedProperties =
properties == null ? null : (Properties) properties.clone(); 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", false);
stringReplace(val, "\n", StringUtils.LINE_SEP, false);
StringBuffer tok = new StringBuffer(token.getText());
stringReplace(tok, "\r\n", "\n", false);
stringReplace(tok, "\n", StringUtils.LINE_SEP, false);
Replacefilter firstFilter = createPrimaryfilter();
firstFilter.setToken(tok.toString());
firstFilter.setValue(val.toString());
}

try { try {
if (replaceFilterFile != null) { if (replaceFilterFile != null) {
Properties props = getProperties(replaceFilterFile); Properties props = getProperties(replaceFilterFile);
@@ -367,67 +382,43 @@ public class Replace extends MatchingTask {
+ " doesn't exist", getLocation()); + " doesn't exist", getLocation());
} }


File temp = fileUtils.createTempFile("rep", ".tmp",
fileUtils.getParentFile(src));
temp.deleteOnExit();

File temp = null;
Reader reader = null; Reader reader = null;
Writer writer = null; Writer writer = null;
try { try {
reader = encoding == null ? new FileReader(src) reader = encoding == null ? new FileReader(src)
: new InputStreamReader(new FileInputStream(src), encoding); : new InputStreamReader(new FileInputStream(src), encoding);
writer = encoding == null ? new FileWriter(temp)
: new OutputStreamWriter(new FileOutputStream(temp), encoding);


BufferedReader br = new BufferedReader(reader); BufferedReader br = new BufferedReader(reader);
BufferedWriter bw = new BufferedWriter(writer);


String buf = FileUtils.readFully(br); String buf = FileUtils.readFully(br);
br.close();
reader = null;

if (buf == null) { if (buf == null) {
buf = ""; buf = "";
} }


//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 val = stringReplace(value.getText(), "\r\n",
"\n", false);
val = stringReplace(val, "\n",
StringUtils.LINE_SEP, false);
String tok = stringReplace(token.getText(), "\r\n",
"\n", false);
tok = stringReplace(tok, "\n",
StringUtils.LINE_SEP, false);

// for each found token, replace with value
log("Replacing in " + src.getPath() + ": " + token.getText()
+ " --> " + value.getText(), Project.MSG_VERBOSE);
newString = stringReplace(newString, tok, val, true);
}
StringBuffer buffer = new StringBuffer(buf);
buf = null;


if (replacefilters.size() > 0) {
newString = processReplacefilters(newString, src.getPath());
}
int repCountStart = replaceCount;


boolean changes = !newString.equals(buf);
if (changes) {
bw.write(newString, 0, newString.length());
bw.flush();
}
processReplacefilters(buffer, src.getPath());


// cleanup
bw.close();
writer = null;
br.close();
reader = null;

// If there were changes, move the new one to the old one;
// otherwise, delete the new one
boolean changes = (replaceCount != repCountStart);
if (changes) { if (changes) {
String out = buffer.toString();
temp = fileUtils.createTempFile("rep", ".tmp",
src.getParentFile());
temp.deleteOnExit();
writer = encoding == null ? new FileWriter(temp)
: new OutputStreamWriter(new FileOutputStream(temp), encoding);
BufferedWriter bw = new BufferedWriter(writer);
bw.write(out, 0, out.length());
bw.flush();
bw.close();
writer = null;
++fileCount; ++fileCount;
fileUtils.rename(temp, src); fileUtils.rename(temp, src);
temp = null; temp = null;
@@ -460,24 +451,19 @@ public class Replace extends MatchingTask {


/** /**
* apply all replace filters to a buffer * apply all replace filters to a buffer
* @param buffer string to filter
* @param buffer stringbuffer to filter
* @param filename filename for logging purposes * @param filename filename for logging purposes
* @return filtered string
*/ */
private String processReplacefilters(String buffer, String filename) {
String newString = new String(buffer);

private void processReplacefilters(StringBuffer buffer, String filename) {
for (int i = 0; i < replacefilters.size(); i++) { for (int i = 0; i < replacefilters.size(); i++) {
Replacefilter filter = (Replacefilter) replacefilters.elementAt(i); Replacefilter filter = (Replacefilter) replacefilters.elementAt(i);


//for each found token, replace with value //for each found token, replace with value
log("Replacing in " + filename + ": " + filter.getToken() log("Replacing in " + filename + ": " + filter.getToken()
+ " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE); + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE);
newString = stringReplace(newString, filter.getToken(),
stringReplace(buffer, filter.getToken(),
filter.getReplaceValue(), true); filter.getReplaceValue(), true);
} }

return newString;
} }




@@ -593,38 +579,28 @@ public class Replace extends MatchingTask {
} }


/** /**
* Replace occurrences of str1 in string str with str2
* Adds the token and value as first &lt;replacefilter&gt; element.
* The token and value are always processed first.
* @return a nested ReplaceFilter 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 String stringReplace(String str, String str1, String str2,
private void stringReplace(StringBuffer str, String str1, String str2,
boolean countReplaces) { boolean countReplaces) {
StringBuffer ret = new StringBuffer();
int start = 0;
int found = str.indexOf(str1); int found = str.indexOf(str1);
while (found >= 0) { while (found >= 0) {
// write everything up to the found str1
if (found > start) {
ret.append(str.substring(start, found));
}

// write the replacement str2
if (str2 != null) {
ret.append(str2);
}

// search again
start = found + str1.length();
found = str.indexOf(str1, start);
str.replace(found, found + str1.length(), str2);
found = str.indexOf(str1, found + str2.length());
if (countReplaces) { if (countReplaces) {
++replaceCount; ++replaceCount;
} }
} }

// write the remaining characters
if (str.length() > start) {
ret.append(str.substring(start, str.length()));
}

return ret.toString();
} }


} }

Loading…
Cancel
Save