git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@902004 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -20,8 +20,8 @@ Fixed bugs: | |||||
| * <scp> task didn't report build file location when a remote operation failed | * <scp> task didn't report build file location when a remote operation failed | ||||
| Bugzilla Report 48578. | Bugzilla Report 48578. | ||||
| * <propertyfile> would add the same comment each time it updated an | |||||
| existing property file. | |||||
| * <propertyfile> would add the same comment and a date line each time | |||||
| it updated an existing property file. | |||||
| Bugzilla Report 48558. | Bugzilla Report 48558. | ||||
| Other changes: | Other changes: | ||||
| @@ -232,6 +232,22 @@ public final class DateUtils { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Parses the string in a format suitable for a SMTP date header. | |||||
| * | |||||
| * @param datestr string to be parsed | |||||
| * | |||||
| * @return a java.util.Date object as parsed by the format. | |||||
| * @exception ParseException if the supplied string cannot be parsed by | |||||
| * this pattern. | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public static Date parseDateFromHeader(String datestr) throws ParseException { | |||||
| synchronized (DATE_HEADER_FORMAT_INT) { | |||||
| return DATE_HEADER_FORMAT_INT.parse(datestr); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Parse a string as a datetime using the ISO8601_DATETIME format which is | * Parse a string as a datetime using the ISO8601_DATETIME format which is | ||||
| * <code>yyyy-MM-dd'T'HH:mm:ss</code> | * <code>yyyy-MM-dd'T'HH:mm:ss</code> | ||||
| @@ -253,20 +253,38 @@ public class LayoutPreservingProperties extends Properties { | |||||
| public void store(OutputStream out, String header) throws IOException { | public void store(OutputStream out, String header) throws IOException { | ||||
| OutputStreamWriter osw = new OutputStreamWriter(out, "ISO-8859-1"); | OutputStreamWriter osw = new OutputStreamWriter(out, "ISO-8859-1"); | ||||
| int skipLines = 0; | |||||
| int totalLines = logicalLines.size(); | |||||
| if (header != null) { | if (header != null) { | ||||
| osw.write("#" + header + LS); | osw.write("#" + header + LS); | ||||
| if (totalLines > 0 | |||||
| && logicalLines.get(0) instanceof Comment | |||||
| && header.equals(logicalLines.get(0).toString().substring(1))) { | |||||
| skipLines = 1; | |||||
| } | |||||
| } | } | ||||
| osw.write("#" + (new Date()).toString() + LS); | |||||
| // we may be updatiung a file written by this class, replace | |||||
| // the date comment instead of adding a new one and preserving | |||||
| // the one written last time | |||||
| if (totalLines > skipLines | |||||
| && logicalLines.get(skipLines) instanceof Comment) { | |||||
| try { | |||||
| DateUtils.parseDateFromHeader(logicalLines | |||||
| .get(skipLines) | |||||
| .toString().substring(1)); | |||||
| skipLines++; | |||||
| } catch (java.text.ParseException pe) { | |||||
| // not an existing date comment | |||||
| } | |||||
| } | |||||
| osw.write("#" + DateUtils.getDateForHeader() + LS); | |||||
| boolean writtenSep = false; | boolean writtenSep = false; | ||||
| boolean maySkipComment = header != null; | |||||
| for (Iterator i = logicalLines.iterator(); i.hasNext(); | |||||
| maySkipComment = false) { | |||||
| for (Iterator i = logicalLines.subList(skipLines, totalLines).iterator(); | |||||
| i.hasNext(); ) { | |||||
| LogicalLine line = (LogicalLine) i.next(); | LogicalLine line = (LogicalLine) i.next(); | ||||
| if (maySkipComment && line instanceof Comment && | |||||
| header.equals(line.toString().substring(1))) { | |||||
| continue; | |||||
| } | |||||
| if (line instanceof Pair) { | if (line instanceof Pair) { | ||||
| if (((Pair)line).isNew()) { | if (((Pair)line).isNew()) { | ||||
| if (!writtenSep) { | if (!writtenSep) { | ||||
| @@ -190,4 +190,54 @@ x=1 | |||||
| <au:assertPropertyEquals name="tail.out" value="${tail.in}"/> | <au:assertPropertyEquals name="tail.out" value="${tail.in}"/> | ||||
| </target> | </target> | ||||
| <target name="testRepeatedUpdateWithoutComment" depends="-updateSetUp"> | |||||
| <pf/> | |||||
| <pf/> | |||||
| <local name="head.in"/> | |||||
| <local name="head.out"/> | |||||
| <loadfile srcfile="${input}/initial.properties" property="head.in"/> | |||||
| <!-- skip date --> | |||||
| <loadfile srcfile="${output}/created.properties" property="head.out"> | |||||
| <filterchain> | |||||
| <headfilter skip="1"/> | |||||
| </filterchain> | |||||
| </loadfile> | |||||
| <au:assertPropertyEquals name="head.out" value="${head.in}"/> | |||||
| </target> | |||||
| <target name="testRepeatedUpdateWithSameComment" depends="-updateSetUp"> | |||||
| <pf comment="my comment"/> | |||||
| <pf comment="my comment"/> | |||||
| <local name="head.in"/> | |||||
| <local name="head.out"/> | |||||
| <local name="tail.in"/> | |||||
| <local name="tail.out"/> | |||||
| <!-- just comment --> | |||||
| <loadfile srcfile="${input}/initial.properties" property="head.in"> | |||||
| <filterchain> | |||||
| <headfilter lines="1"/> | |||||
| </filterchain> | |||||
| </loadfile> | |||||
| <!-- just comment --> | |||||
| <loadfile srcfile="${output}/created.properties" property="head.out"> | |||||
| <filterchain> | |||||
| <headfilter lines="1"/> | |||||
| </filterchain> | |||||
| </loadfile> | |||||
| <!-- skip comment --> | |||||
| <loadfile srcfile="${input}/initial.properties" property="tail.in"> | |||||
| <filterchain> | |||||
| <headfilter skip="1"/> | |||||
| </filterchain> | |||||
| </loadfile> | |||||
| <!-- skip comment and date --> | |||||
| <loadfile srcfile="${output}/created.properties" property="tail.out"> | |||||
| <filterchain> | |||||
| <headfilter skip="2"/> | |||||
| </filterchain> | |||||
| </loadfile> | |||||
| <au:assertPropertyEquals name="head.out" value="${head.in}"/> | |||||
| <au:assertPropertyEquals name="tail.out" value="${tail.in}"/> | |||||
| </target> | |||||
| </project> | </project> | ||||