6466476: (tz) Introduction of tzdata2005r can introduce incompatility issues with some JDK1.1 3-letter TZ Ids
authorpeytoia
Mon, 08 Sep 2008 15:21:55 +0900
changeset 1315 ad5950a1098c
parent 1314 548758ef551a
child 1316 20fc6d4d57ae
6466476: (tz) Introduction of tzdata2005r can introduce incompatility issues with some JDK1.1 3-letter TZ Ids Reviewed-by: okutsu
jdk/make/java/java/FILES_java.gmk
jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java
jdk/src/share/classes/sun/util/calendar/ZoneInfo.java
jdk/test/java/util/TimeZone/OldIDMappingTest.java
jdk/test/java/util/TimeZone/OldIDMappingTest.sh
--- a/jdk/make/java/java/FILES_java.gmk	Mon Sep 08 14:48:14 2008 +0900
+++ b/jdk/make/java/java/FILES_java.gmk	Mon Sep 08 15:21:55 2008 +0900
@@ -209,6 +209,7 @@
         sun/util/TimeZoneNameUtility.java \
         sun/util/calendar/ZoneInfo.java \
         sun/util/calendar/ZoneInfoFile.java \
+        sun/util/calendar/TzIDOldMapping.java \
     java/util/TooManyListenersException.java \
     java/util/Comparator.java \
     java/util/Collections.java \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java	Mon Sep 08 15:21:55 2008 +0900
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.util.calendar;
+
+import java.util.Map;
+import java.util.HashMap;
+
+class TzIDOldMapping {
+    static final Map<String, String> MAP = new HashMap<String, String>();
+    static {
+        String[][] oldmap = {
+            { "ACT", "Australia/Darwin" },
+            { "AET", "Australia/Sydney" },
+            { "AGT", "America/Argentina/Buenos_Aires" },
+            { "ART", "Africa/Cairo" },
+            { "AST", "America/Anchorage" },
+            { "BET", "America/Sao_Paulo" },
+            { "BST", "Asia/Dhaka" },
+            { "CAT", "Africa/Harare" },
+            { "CNT", "America/St_Johns" },
+            { "CST", "America/Chicago" },
+            { "CTT", "Asia/Shanghai" },
+            { "EAT", "Africa/Addis_Ababa" },
+            { "ECT", "Europe/Paris" },
+            { "EST", "America/New_York" },
+            { "HST", "Pacific/Honolulu" },
+            { "IET", "America/Indianapolis" },
+            { "IST", "Asia/Calcutta" },
+            { "JST", "Asia/Tokyo" },
+            { "MIT", "Pacific/Apia" },
+            { "MST", "America/Denver" },
+            { "NET", "Asia/Yerevan" },
+            { "NST", "Pacific/Auckland" },
+            { "PLT", "Asia/Karachi" },
+            { "PNT", "America/Phoenix" },
+            { "PRT", "America/Puerto_Rico" },
+            { "PST", "America/Los_Angeles" },
+            { "SST", "Pacific/Guadalcanal" },
+            { "VST", "Asia/Saigon" },
+        };
+        for (String[] pair : oldmap) {
+            MAP.put(pair[0], pair[1]);
+        }
+    }
+}
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java	Mon Sep 08 14:48:14 2008 +0900
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java	Mon Sep 08 15:21:55 2008 +0900
@@ -28,10 +28,12 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.lang.ref.SoftReference;
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
@@ -77,6 +79,14 @@
     private static final long ABBR_MASK = 0xf00L;
     private static final int TRANSITION_NSHIFT = 12;
 
+    // Flag for supporting JDK backward compatible IDs, such as "EST".
+    private static final boolean USE_OLDMAPPING;
+    static {
+      String oldmapping = AccessController.doPrivileged(
+          new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
+      USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
+    }
+
     private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
 
     /**
@@ -595,9 +605,21 @@
      * time zone of the ID.
      */
     public static TimeZone getTimeZone(String ID) {
-        ZoneInfo zi = null;
+        String givenID = null;
 
-        zi = ZoneInfoFile.getZoneInfo(ID);
+        /*
+         * If old JDK compatibility is specified, get the old alias
+         * name.
+         */
+        if (USE_OLDMAPPING) {
+            String compatibleID = TzIDOldMapping.MAP.get(ID);
+            if (compatibleID != null) {
+                givenID = ID;
+                ID = compatibleID;
+            }
+        }
+
+        ZoneInfo zi = ZoneInfoFile.getZoneInfo(ID);
         if (zi == null) {
             // if we can't create an object for the ID, try aliases.
             try {
@@ -616,6 +638,10 @@
                 // ignore exceptions
             }
         }
+
+        if (givenID != null && zi != null) {
+            zi.setID(givenID);
+        }
         return zi;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/TimeZone/OldIDMappingTest.java	Mon Sep 08 15:21:55 2008 +0900
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * See OldMappingTest.sh
+ */
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public class OldIDMappingTest {
+    private static final String MAPPING_PROPERTY_NAME = "sun.timezone.ids.oldmapping";
+    private static final Map<String, String> newmap = new HashMap<String, String>();
+    static {
+        // Add known new mappings
+        newmap.put("EST", "EST");
+        newmap.put("MST", "MST");
+        newmap.put("HST", "HST");
+    }
+
+    public static void main(String[] args) {
+        boolean useOldMapping = true;
+        String arg = args[0];
+        if (arg.equals("-new")) {
+            useOldMapping = false;
+        } else if (arg.equals("-old")) {
+            useOldMapping = true;
+        } else {
+            throw new RuntimeException("-old or -new must be specified; got " + arg);
+        }
+
+        // Get a Field for TzIDOldMapping in sun.util.calendar.
+        Map<String, String> oldmap = null;
+        try {
+            Class<?> oldmapClass = Class.forName("sun.util.calendar.TzIDOldMapping");
+            Field map = oldmapClass.getDeclaredField("MAP");
+            map.setAccessible(true);
+            oldmap = (Map<String, String>) map.get(null);
+        } catch (Exception e) {
+            throw new RuntimeException("can't get TzIDOldMapping.MAP", e);
+        }
+
+        String prop = System.getProperty(MAPPING_PROPERTY_NAME);
+        System.out.println(MAPPING_PROPERTY_NAME + "=" + prop);
+
+        // Try the test multiple times with modifying TimeZones to
+        // make sure TimeZone instances for the old mapping are
+        // properly copied (defensive copy).
+        for (int count = 0; count < 3; count++) {
+            for (String id : oldmap.keySet()) {
+                TimeZone tzAlias = TimeZone.getTimeZone(id);
+                TimeZone tz = TimeZone.getTimeZone(oldmap.get(id));
+                if (useOldMapping) {
+                    if (!tzAlias.hasSameRules(tz)) {
+                        throw new RuntimeException("OLDMAP: " + MAPPING_PROPERTY_NAME + "=" + prop + ": "
+                                                   + id + " isn't an alias of " + oldmap.get(id));
+                    }
+                    if (count == 0) {
+                        System.out.println("    " + id + " => " + oldmap.get(id));
+                    }
+                    tzAlias.setRawOffset(tzAlias.getRawOffset() * count);
+                } else {
+                    if (!newmap.containsKey(id)) {
+                        // ignore ids not contained in the new map
+                        if (count == 0) {
+                            System.out.println("    " + id + " => " + oldmap.get(id));
+                        }
+                        tzAlias.setRawOffset(tzAlias.getRawOffset() * count);
+                        continue;
+                    }
+                    if (tzAlias.hasSameRules(tz)) {
+                        throw new RuntimeException("NEWMAP: " + MAPPING_PROPERTY_NAME + "=" + prop + ": "
+                                                   + id + " is an alias of " + oldmap.get(id));
+                    }
+                    tz = TimeZone.getTimeZone(newmap.get(id));
+                    if (!tzAlias.hasSameRules(tz)) {
+                        throw new RuntimeException("NEWMAP: " + MAPPING_PROPERTY_NAME + "=" + prop + ": "
+                                                   + id + " isn't an alias of " + newmap.get(id));
+                    }
+                    if (count == 0) {
+                        System.out.println("    " + id + " => " + newmap.get(id));
+                    }
+                    tzAlias.setRawOffset(tzAlias.getRawOffset() * count);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/TimeZone/OldIDMappingTest.sh	Mon Sep 08 15:21:55 2008 +0900
@@ -0,0 +1,59 @@
+# Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+
+# @test
+# @bug 6466476
+# @summary Compatibility test for the old JDK ID mapping and Olson IDs
+# @build OldIDMappingTest
+# @run shell OldIDMappingTest.sh
+
+: ${TESTJAVA:=${JAVA_HOME}}
+: ${TESTCLASSES:="`pwd`"}
+
+JAVA="${TESTJAVA}/bin/java"
+
+STATUS=0
+
+# Expecting the new (Olson compatible) mapping (default)
+for I in "" " " no No NO false False FALSE Hello
+do
+    if [ x"$I" != x ]; then
+	D="-Dsun.timezone.ids.oldmapping=${I}"
+    fi
+    if ! ${JAVA} ${D} -cp ${TESTCLASSES} OldIDMappingTest -new; then
+	STATUS=1
+    fi
+done
+
+# Expecting the old mapping
+for I in true True TRUE yes Yes YES
+do
+    if [ "x$I" != x ]; then
+	D="-Dsun.timezone.ids.oldmapping=${I}"
+    fi
+    if ! ${JAVA} ${D} -cp ${TESTCLASSES} OldIDMappingTest -old; then
+	STATUS=1
+    fi
+done
+
+exit ${STATUS}