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> | ||||