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. | |||
| Bugzilla Report 45227. | |||
| * <propertyfile> didn't preserve the original linefeed style when | |||
| updating a file. | |||
| Bugzilla Report 50049. | |||
| Other changes: | |||
| -------------- | |||
| @@ -32,9 +32,14 @@ very useful when wanting to make unattended modifications to | |||
| configuration files for application servers and | |||
| applications. Currently, the task maintains a working property file | |||
| 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> | |||
| <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> | |||
| <h2><a name="proptask">PropertyFile Task</a></h2> | |||
| <h3>Parameters</h3> | |||
| @@ -27,6 +27,7 @@ import java.io.InputStreamReader; | |||
| import java.io.OutputStream; | |||
| import java.io.OutputStreamWriter; | |||
| import java.io.PrintStream; | |||
| import java.io.PushbackReader; | |||
| import java.util.ArrayList; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| @@ -78,7 +79,7 @@ import java.util.Properties; | |||
| * although the key-value pair <code>beta=two</code> is removed.</p> | |||
| */ | |||
| 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 | |||
| @@ -310,14 +311,15 @@ public class LayoutPreservingProperties extends Properties { | |||
| */ | |||
| private String readLines(InputStream is) throws IOException { | |||
| InputStreamReader isr = new InputStreamReader(is, ResourceUtils.ISO_8859_1); | |||
| BufferedReader br = new BufferedReader(isr); | |||
| PushbackReader pbr = new PushbackReader(isr, 1); | |||
| if (logicalLines.size() > 0) { | |||
| // we add a blank line for spacing | |||
| logicalLines.add(new Blank()); | |||
| } | |||
| String s = br.readLine(); | |||
| String s = readFirstLine(pbr); | |||
| BufferedReader br = new BufferedReader(pbr); | |||
| boolean continuation = false; | |||
| boolean comment = false; | |||
| @@ -366,6 +368,46 @@ public class LayoutPreservingProperties extends Properties { | |||
| 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 | |||
| * <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}"/> | |||
| </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> | |||