From 77fbe3782fbca6b7cc0af5a381207c32d34d9bd5 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sun, 31 Jul 2016 09:29:41 +0200 Subject: [PATCH] fix the patterns used by touch and date selectors https://bz.apache.org/bugzilla/show_bug.cgi?id=59909 --- WHATSNEW | 9 +++++ manual/Tasks/touch.html | 6 ++-- manual/Types/resources.html | 5 +-- manual/Types/selectors.html | 9 ++--- .../org/apache/tools/ant/taskdefs/Touch.java | 34 +++++++++++-------- .../ant/types/resources/selectors/Date.java | 13 ++++--- .../ant/types/selectors/BaseSelector.java | 17 ++++++++-- .../ant/types/selectors/DateSelector.java | 14 ++++---- .../ant/types/selectors/DateSelectorTest.java | 2 +- 9 files changed, 69 insertions(+), 40 deletions(-) diff --git a/WHATSNEW b/WHATSNEW index 9a36711f5..50128b852 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -40,6 +40,15 @@ Fixed bugs: worked on OSes where sed is GNU sed. Bugzilla Report 59898 + * 's default pattern as well as the default patterns used by + the (resource) selectors depended on the JDK being used - or + rather the locale provider being used and the default locale + provider changed with Java 9. + They are now fixed and the documentation has been updated to + reflect the real patterns used rather than a non-formal description + of the expected format. + Bugzilla Report 59909 + Other changes: -------------- diff --git a/manual/Tasks/touch.html b/manual/Tasks/touch.html index 263ea7075..8adee3805 100644 --- a/manual/Tasks/touch.html +++ b/manual/Tasks/touch.html @@ -74,8 +74,10 @@ resource collections (which also includes directories). Prior to Apache Ant pattern - SimpleDateFormat-compatible pattern string. - Defaults to MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM. + SimpleDateFormat-compatible pattern string using + the current locale. + Defaults to "MM/dd/YYYY hh:mm a" or "MM/dd/yyyy hh:mm:ss a" + using the US locale. Since Ant 1.6.3 No diff --git a/manual/Types/resources.html b/manual/Types/resources.html index 58cefde1a..8ba77aa12 100644 --- a/manual/Types/resources.html +++ b/manual/Types/resources.html @@ -641,9 +641,10 @@ platforms. pattern SimpleDateFormat-compatible pattern - for use with the datetime attribute + for use with the datetime attribute using the + current locale - No, default is "MM/DD/YYYY HH:MM AM_or_PM" + No, default is "MM/dd/yyyy hh:mm a" using the US locale granularity diff --git a/manual/Types/selectors.html b/manual/Types/selectors.html index 560b416c7..402c711f5 100644 --- a/manual/Types/selectors.html +++ b/manual/Types/selectors.html @@ -173,9 +173,9 @@ datetime Specifies the date and time to test for. - Should be in the format MM/DD/YYYY HH:MM AM_or_PM, or - an alternative pattern specified via the pattern - attribute. + Should be in the format "MM/dd/yyyy hh:mm a" using the US + locale, or an alternative pattern specified via + the pattern attribute. At least one of the two. @@ -212,7 +212,8 @@ pattern The SimpleDateFormat-compatible pattern - to use when interpreting the datetime attribute. + to use when interpreting the datetime attribute using + the current locale. Since Ant 1.6.2 No diff --git a/src/main/org/apache/tools/ant/taskdefs/Touch.java b/src/main/org/apache/tools/ant/taskdefs/Touch.java index 4a4118cef..c6d79b7bd 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Touch.java +++ b/src/main/org/apache/tools/ant/taskdefs/Touch.java @@ -61,23 +61,29 @@ public class Touch extends Task { public static final DateFormatFactory DEFAULT_DF_FACTORY = new DateFormatFactory() { - /* - * The initial version used DateFormat.SHORT for the - * time format, which ignores seconds. If we want - * seconds as well, we need DateFormat.MEDIUM, which - * in turn would break all old build files. - * - * First try to parse with DateFormat.SHORT and if - * that fails with MEDIUM - throw an exception if both - * fail. - */ + + private ThreadLocal primary = + new ThreadLocal() { + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("MM/dd/yyyy hh:mm a", + Locale.US); + } + }; + private ThreadLocal fallback = + new ThreadLocal() { + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", + Locale.US); + } + }; + public DateFormat getPrimaryFormat() { - return DateFormat.getDateTimeInstance(DateFormat.SHORT, - DateFormat.SHORT, Locale.US); + return primary.get(); } public DateFormat getFallbackFormat() { - return DateFormat.getDateTimeInstance(DateFormat.SHORT, - DateFormat.MEDIUM, Locale.US); + return fallback.get(); } }; private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java index 8541e8580..0719a1855 100644 --- a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java +++ b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java @@ -137,10 +137,10 @@ public class Date implements ResourceSelector { throw new BuildException(MILLIS_OR_DATETIME); } if (millis == null) { - DateFormat df = ((pattern == null) - ? DateFormat.getDateTimeInstance( - DateFormat.SHORT, DateFormat.SHORT, Locale.US) - : new SimpleDateFormat(pattern)); + String p = pattern == null ? "MM/dd/yyyy hh:mm a" : pattern; + DateFormat df = pattern == null + ? new SimpleDateFormat(p, Locale.US) + : new SimpleDateFormat(p); try { long m = df.parse(dateTime).getTime(); if (m < 0) { @@ -151,9 +151,8 @@ public class Date implements ResourceSelector { setMillis(m); } catch (ParseException pe) { throw new BuildException("Date of " + dateTime - + " Cannot be parsed correctly. It should be in" - + (pattern == null - ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format."); + + " Cannot be parsed correctly. It should be in '" + + p + "' format."); } } return when.evaluate(r.getLastModified(), millis.longValue(), granularity); diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java index 61d7a1a27..414390edf 100644 --- a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java @@ -34,7 +34,7 @@ import org.apache.tools.ant.types.DataType; public abstract class BaseSelector extends DataType implements FileSelector { private String errmsg = null; - + private Throwable cause; /** * Do nothing constructor. @@ -54,6 +54,19 @@ public abstract class BaseSelector extends DataType implements FileSelector { } } + /** + * Allows all selectors to indicate a setup error. Note that only + * the first error message is recorded. + * + * @param msg The error message any BuildException should throw. + */ + public void setError(String msg, Throwable cause) { + if (errmsg == null) { + errmsg = msg; + this.cause = cause; + } + } + /** * Returns any error messages that have been set. * @@ -87,7 +100,7 @@ public abstract class BaseSelector extends DataType implements FileSelector { verifySettings(); } if (getError() != null) { - throw new BuildException(errmsg); + throw new BuildException(errmsg, cause); } if (!isReference()) { dieOnCircularReference(); diff --git a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java index aea94a8be..8232e45f3 100644 --- a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java @@ -209,11 +209,10 @@ public class DateSelector extends BaseExtendSelector { setError("You must provide a datetime or the number of " + "milliseconds."); } else if (millis < 0 && dateTime != null) { - // check millis and only set it once. - DateFormat df = ((pattern == null) - ? DateFormat.getDateTimeInstance( - DateFormat.SHORT, DateFormat.SHORT, Locale.US) - : new SimpleDateFormat(pattern)); + String p = pattern == null ? "MM/dd/yyyy hh:mm a" : pattern; + DateFormat df = pattern == null + ? new SimpleDateFormat(p, Locale.US) + : new SimpleDateFormat(p); try { setMillis(df.parse(dateTime).getTime()); @@ -224,9 +223,8 @@ public class DateSelector extends BaseExtendSelector { } } catch (ParseException pe) { setError("Date of " + dateTime - + " Cannot be parsed correctly. It should be in" - + ((pattern == null) - ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format."); + + " Cannot be parsed correctly. It should be in '" + + p + "' format.", pe); } } } diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java index 43278f491..7eb9501a9 100644 --- a/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java +++ b/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java @@ -73,7 +73,7 @@ public class DateSelectorTest { } catch (BuildException be3) { assertEquals("Date of this is not a date" + " Cannot be parsed correctly. It should be in" - + " MM/DD/YYYY HH:MM AM_PM format.", be3.getMessage()); + + " 'MM/dd/yyyy hh:mm a' format.", be3.getMessage()); } s = new DateSelector();