git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1027179 13f79535-47bb-0310-9956-ffa450edef68master
@@ -183,6 +183,10 @@ Fixed bugs: | |||||
wrong. | wrong. | ||||
Bugzilla Report 45227. | Bugzilla Report 45227. | ||||
* <propertyfile> didn't preserve the original linefeed style when | |||||
updating a file. | |||||
Bugzilla Report 50049. | |||||
Other changes: | Other changes: | ||||
-------------- | -------------- | ||||
@@ -32,9 +32,14 @@ very useful when wanting to make unattended modifications to | |||||
configuration files for application servers and | configuration files for application servers and | ||||
applications. Currently, the task maintains a working property file | applications. Currently, the task maintains a working property file | ||||
with the ability to add properties or make changes to existing | with the ability to add properties or make changes to existing | ||||
ones. Since Ant 1.8.0 comments and layout of the original properties | |||||
ones. <em>Since Ant 1.8.0</em> comments and layout of the original properties | |||||
file are preserved.</p> | file are preserved.</p> | ||||
<p><em>Since Ant 1.8.2</em> the linefeed-style of the original file | |||||
will be preserved as well, as long as style used to be consistent. | |||||
In general, linefeeds of the updated file will be the same as the | |||||
first linefeed found when reading it.</p> | |||||
<hr> | <hr> | ||||
<h2><a name="proptask">PropertyFile Task</a></h2> | <h2><a name="proptask">PropertyFile Task</a></h2> | ||||
<h3>Parameters</h3> | <h3>Parameters</h3> | ||||
@@ -27,6 +27,7 @@ import java.io.InputStreamReader; | |||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.io.OutputStreamWriter; | import java.io.OutputStreamWriter; | ||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import java.io.PushbackReader; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -78,7 +79,7 @@ import java.util.Properties; | |||||
* although the key-value pair <code>beta=two</code> is removed.</p> | * although the key-value pair <code>beta=two</code> is removed.</p> | ||||
*/ | */ | ||||
public class LayoutPreservingProperties extends Properties { | public class LayoutPreservingProperties extends Properties { | ||||
private static final String LS = System.getProperty("line.separator"); | |||||
private String LS = StringUtils.LINE_SEP; | |||||
/** | /** | ||||
* Logical lines have escaping and line continuation taken care | * Logical lines have escaping and line continuation taken care | ||||
@@ -310,14 +311,15 @@ public class LayoutPreservingProperties extends Properties { | |||||
*/ | */ | ||||
private String readLines(InputStream is) throws IOException { | private String readLines(InputStream is) throws IOException { | ||||
InputStreamReader isr = new InputStreamReader(is, ResourceUtils.ISO_8859_1); | InputStreamReader isr = new InputStreamReader(is, ResourceUtils.ISO_8859_1); | ||||
BufferedReader br = new BufferedReader(isr); | |||||
PushbackReader pbr = new PushbackReader(isr, 1); | |||||
if (logicalLines.size() > 0) { | if (logicalLines.size() > 0) { | ||||
// we add a blank line for spacing | // we add a blank line for spacing | ||||
logicalLines.add(new Blank()); | logicalLines.add(new Blank()); | ||||
} | } | ||||
String s = br.readLine(); | |||||
String s = readFirstLine(pbr); | |||||
BufferedReader br = new BufferedReader(pbr); | |||||
boolean continuation = false; | boolean continuation = false; | ||||
boolean comment = false; | boolean comment = false; | ||||
@@ -366,6 +368,46 @@ public class LayoutPreservingProperties extends Properties { | |||||
return fileBuffer.toString(); | return fileBuffer.toString(); | ||||
} | } | ||||
/** | |||||
* Reads the first line and determines the EOL-style of the file | |||||
* (relies on the style to be consistent, of course). | |||||
* | |||||
* <p>Sets LS as a side-effect.</p> | |||||
* | |||||
* @return the first line without any line separator, leaves the | |||||
* reader positioned after the first line separator | |||||
* | |||||
* @since Ant 1.8.2 | |||||
*/ | |||||
private String readFirstLine(PushbackReader r) throws IOException { | |||||
StringBuffer sb = new StringBuffer(80); | |||||
int ch = r.read(); | |||||
boolean hasCR = false; | |||||
// when reaching EOF before the first EOL, assume native line | |||||
// feeds | |||||
LS = StringUtils.LINE_SEP; | |||||
while (ch >= 0) { | |||||
if (hasCR && ch != '\n') { | |||||
// line feed is sole CR | |||||
r.unread(ch); | |||||
break; | |||||
} | |||||
if (ch == '\r') { | |||||
LS = "\r"; | |||||
hasCR = true; | |||||
} else if (ch == '\n') { | |||||
LS = hasCR ? "\r\n" : "\n"; | |||||
break; | |||||
} else { | |||||
sb.append((char) ch); | |||||
} | |||||
ch = r.read(); | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
/** | /** | ||||
* Returns <code>true</code> if the line represented by | * Returns <code>true</code> if the line represented by | ||||
* <code>s</code> is to be continued on the next line of the file, | * <code>s</code> is to be continued on the next line of the file, | ||||
@@ -241,4 +241,49 @@ x=1 | |||||
<au:assertPropertyEquals name="tail.out" value="${tail.in}"/> | <au:assertPropertyEquals name="tail.out" value="${tail.in}"/> | ||||
</target> | </target> | ||||
<target name="testPreservesDosLineEnds" depends="setUp" | |||||
description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049"> | |||||
<property name="test.txt" location="${output}/test.txt"/> | |||||
<echo file="${test.txt}"><![CDATA[ | |||||
bbb=val2 | |||||
aaa=val1 | |||||
]]></echo> | |||||
<fixcrlf eol="dos" file="${test.txt}"/> | |||||
<propertyfile file="${test.txt}" comment="${header}"/> | |||||
<copy file="${test.txt}" tofile="${test.txt}.expected"/> | |||||
<fixcrlf eol="dos" file="${test.txt}.expected"/> | |||||
<au:assertFilesMatch expected="${test.txt}.expected" | |||||
actual="${test.txt}"/> | |||||
</target> | |||||
<target name="testPreservesUnixLineEnds" depends="setUp" | |||||
description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049"> | |||||
<property name="test.txt" location="${output}/test.txt"/> | |||||
<echo file="${test.txt}"><![CDATA[ | |||||
bbb=val2 | |||||
aaa=val1 | |||||
]]></echo> | |||||
<fixcrlf eol="unix" file="${test.txt}"/> | |||||
<propertyfile file="${test.txt}" comment="${header}"/> | |||||
<copy file="${test.txt}" tofile="${test.txt}.expected"/> | |||||
<fixcrlf eol="unix" file="${test.txt}.expected"/> | |||||
<au:assertFilesMatch expected="${test.txt}.expected" | |||||
actual="${test.txt}"/> | |||||
</target> | |||||
<target name="testPreservesMacLineEnds" depends="setUp" | |||||
description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049"> | |||||
<property name="test.txt" location="${output}/test.txt"/> | |||||
<echo file="${test.txt}"><![CDATA[ | |||||
bbb=val2 | |||||
aaa=val1 | |||||
]]></echo> | |||||
<fixcrlf eol="mac" file="${test.txt}"/> | |||||
<propertyfile file="${test.txt}" comment="${header}"/> | |||||
<copy file="${test.txt}" tofile="${test.txt}.expected"/> | |||||
<fixcrlf eol="mac" file="${test.txt}.expected"/> | |||||
<au:assertFilesMatch expected="${test.txt}.expected" | |||||
actual="${test.txt}"/> | |||||
</target> | |||||
</project> | </project> |