]> granicus.if.org Git - icu/commitdiff
ICU-9987 Fixed getWithFallback problem with a resource path including alias table...
authorYoshito Umaoka <y.umaoka@gmail.com>
Sat, 2 Mar 2013 00:22:00 +0000 (00:22 +0000)
committerYoshito Umaoka <y.umaoka@gmail.com>
Sat, 2 Mar 2013 00:22:00 +0000 (00:22 +0000)
X-SVN-Rev: 33353

icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java
icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalInfo.java
icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java

index 967fb708ee9f6f751ab8096ea77e5328712da34f..afe34ab235a8e1f8341fe9a369fe40592eb25794 100644 (file)
@@ -781,40 +781,44 @@ public  class ICUResourceBundle extends UResourceBundle {
         if (requested == null) {
             requested = actualBundle;
         }
-        while (actualBundle != null) {
-            ICUResourceBundle current = (ICUResourceBundle) actualBundle;
+
+        ICUResourceBundle base = (ICUResourceBundle) actualBundle;
+        String basePath = ((ICUResourceBundle)actualBundle).resPath.length() > 0 ?
+                ((ICUResourceBundle)actualBundle).resPath : "";
+
+        while (base != null) {
             if (path.indexOf('/') == -1) { // skip the tokenizer
-                sub = (ICUResourceBundle) current.handleGet(path, null, requested);
+                sub = (ICUResourceBundle) base.handleGet(path, null, requested);
                 if (sub != null) {
                     break;
                 }
             } else {
+                ICUResourceBundle currentBase = base;
                 StringTokenizer st = new StringTokenizer(path, "/");
                 while (st.hasMoreTokens()) {
                     String subKey = st.nextToken();
-                    sub = (ICUResourceBundle) current.handleGet(subKey, null, requested);
+                    sub = ICUResourceBundle.findResourceWithFallback(subKey, currentBase, requested);
                     if (sub == null) {
                         break;
                     }
-                    current = sub;
+                    currentBase = sub;
                 }
                 if (sub != null) {
                     //we found it
                     break;
                 }
             }
-            if (((ICUResourceBundle)actualBundle).resPath.length() != 0) {
-                path = ((ICUResourceBundle)actualBundle).resPath + "/" + path;
-            }
-            // if not try the parent bundle
-            actualBundle = ((ICUResourceBundle) actualBundle).getParent();
-
+            // if not try the parent bundle - note, getParent() returns the bundle root
+            base = (ICUResourceBundle)base.getParent();
+            path = basePath.length() > 0 ? basePath + "/" + path : path;
+            basePath = "";
         }
         if(sub != null){
             sub.setLoadingStatus(((ICUResourceBundle)requested).getLocaleID());
         }
         return sub;
     }
+
     public boolean equals(Object other) {
         if (this == other) {
             return true;
index ee256ebd152b2e7eec88fa821a6a2834bafb3fbf..c17d2eea9226c0a68a990589cfbb4ab8513b1fe8 100644 (file)
@@ -12,7 +12,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.MissingResourceException;
@@ -390,20 +389,16 @@ public class DateIntervalInfo implements Cloneable, Freezable<DateIntervalInfo>,
                 }
 
                 ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,currentLocale);
-                ICUResourceBundle calBundle = rb.getWithFallback("calendar");
-                ICUResourceBundle calTypeBundle = calBundle.getWithFallback(calendarTypeToUse);
-                // Start hack to force inheriting sideways from generic before up to parent locale.
-                // This happens in ICU4C just via the aliases in root, not sure why not here.
-                // This is added per #9952, #9964 for better long-term fix.
-                if (calTypeBundle != null && !calendarTypeToUse.equals("gregorian") && !calendarTypeToUse.equals("chinese")) {
-                    Locale desiredLocale = rb.getLocale();
-                    Locale calDataLocale = calTypeBundle.getLocale();
-                    if (!calDataLocale.equals(desiredLocale)) {
-                        calTypeBundle = calBundle.getWithFallback("generic");
-                    }
-                }
-                // End hack
-                ICUResourceBundle itvDtPtnResource =calTypeBundle.getWithFallback("intervalFormats");
+                // Note:
+                //      ICU4J getWithFallback does not work well when
+                //      1) A nested table is an alias to /LOCALE/...
+                //      2) getWithFallback is called multiple times for going down hierarchical resource path
+                //      #9987 resolved the issue of alias table when full path is specified in getWithFallback,
+                //      but there is no easy solution when the equivalent operation is done by multiple operations.
+                //      This issue is addressed in #9964.
+//                ICUResourceBundle calBundle = rb.getWithFallback("calendar");
+//                ICUResourceBundle calTypeBundle = calBundle.getWithFallback(calendarTypeToUse);
+                ICUResourceBundle itvDtPtnResource =rb.getWithFallback("calendar/" + calendarTypeToUse + "/intervalFormats");
                 // look for fallback first, since it establishes the default order
                 String fallback = itvDtPtnResource.getStringWithFallback(FALLBACK_STRING);
                 setFallbackIntervalPattern(fallback);
@@ -417,7 +412,7 @@ public class DateIntervalInfo implements Cloneable, Freezable<DateIntervalInfo>,
                     if ( skeleton.compareTo(FALLBACK_STRING) == 0 ) {
                         continue;
                     }
-                    ICUResourceBundle intervalPatterns =itvDtPtnResource.getWithFallback(skeleton);
+                    ICUResourceBundle intervalPatterns = (ICUResourceBundle)itvDtPtnResource.get(skeleton);
                     int ptnNum = intervalPatterns.getSize();
                     for ( int ptnIndex = 0; ptnIndex < ptnNum; ++ptnIndex) {
                         String key = intervalPatterns.get(ptnIndex).getKey();
index 34fb17f73167266fa0b4ac2537d593393b73be44..21a9a2d0d751fc308d17675421801e8859548dca 100644 (file)
@@ -15,7 +15,6 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.Set;
@@ -187,26 +186,14 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
         }
 
         // Get data for that calendar
-        ICUResourceBundle calBundle = rb.getWithFallback("calendar");
-        ICUResourceBundle calTypeBundle = calBundle.getWithFallback(calendarTypeToUse);
-        // Start hack to force inheriting sideways from generic before up to parent locale.
-        // This happens in ICU4C just via the aliases in root, not sure why not here.
-        // This is added per #9952, #9964 for better long-term fix. Part 2 is below.
-        if (calTypeBundle != null && !calendarTypeToUse.equals("gregorian") && !calendarTypeToUse.equals("chinese")) {
-            Locale desiredLocale = rb.getLocale();
-            Locale calDataLocale = calTypeBundle.getLocale();
-            if (!calDataLocale.equals(desiredLocale)) {
-                calTypeBundle = calBundle.getWithFallback("generic");
-            }
-        }
-        // End hack
-
-        // CLDR item formats
-
-
-        // (hmm, do we need aliases in root for all non-gregorian calendars?)
         try {
-            ICUResourceBundle itemBundle = calTypeBundle.getWithFallback("appendItems");
+            //      ICU4J getWithFallback does not work well when
+            //      1) A nested table is an alias to /LOCALE/...
+            //      2) getWithFallback is called multiple times for going down hierarchical resource path
+            //      #9987 resolved the issue of alias table when full path is specified in getWithFallback,
+            //      but there is no easy solution when the equivalent operation is done by multiple operations.
+            //      This issue is addressed in #9964.
+            ICUResourceBundle itemBundle = rb.getWithFallback("calendar/" + calendarTypeToUse + "/appendItems");
             for (int i=0; i<itemBundle.getSize(); ++i) {
                 ICUResourceBundle formatBundle = (ICUResourceBundle)itemBundle.get(i);
                 String formatName = itemBundle.get(i).getKey();
@@ -235,7 +222,13 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
         // set the AvailableFormat in CLDR
         ICUResourceBundle availFormatsBundle = null;
         try {
-            availFormatsBundle = calTypeBundle.getWithFallback("availableFormats");
+            //      ICU4J getWithFallback does not work well when
+            //      1) A nested table is an alias to /LOCALE/...
+            //      2) getWithFallback is called multiple times for going down hierarchical resource path
+            //      #9987 resolved the issue of alias table when full path is specified in getWithFallback,
+            //      but there is no easy solution when the equivalent operation is done by multiple operations.
+            //      This issue is addressed in #9964.
+            availFormatsBundle = rb.getWithFallback("calendar/" + calendarTypeToUse + "/availableFormats");
         } catch (MissingResourceException e) {
             // fall through
         }
@@ -257,20 +250,8 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
             if (pbundle == null) {
                 break;
             }
-            calBundle = pbundle.getWithFallback("calendar");
-            calTypeBundle = calBundle.getWithFallback(calendarTypeToUse);
-            // Start hack for sideways inheritance, part 2
-            // This is added per #9952, #9964 for better long-term fix.
-            if (calTypeBundle != null && !calendarTypeToUse.equals("gregorian") && !calendarTypeToUse.equals("chinese")) {
-                Locale desiredLocale = pbundle.getLocale();
-                Locale calDataLocale = calTypeBundle.getLocale();
-                if (!calDataLocale.equals(desiredLocale)) {
-                    calTypeBundle = calBundle.getWithFallback("generic");
-                }
-            }
-            // End hack part 2
             try {
-                availFormatsBundle = calTypeBundle.getWithFallback("availableFormats");
+                availFormatsBundle = pbundle.getWithFallback("calendar/" + calendarTypeToUse + "/availableFormats");
             } catch (MissingResourceException e) {
                 availFormatsBundle = null;
             }
index fad623d1e16f05ece2f32878ad13feb98d36c3bd..996073062964ce831dcbbde3ae0a95d5a4942276 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * Copyright (C) 2001-2012, International Business Machines Corporation and    *
+ * Copyright (C) 2001-2013, International Business Machines Corporation and    *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
@@ -1187,4 +1187,18 @@ public class DateFormatRegressionTest extends com.ibm.icu.dev.test.TestFmwk {
             errln("Parsing failed: day of month should be '7' with pattern: \"" + pattern + "\" for text: \"" + text + "\"");
         }
     }
+
+    // Date formatting with Dangi calendar in en locale (#9987)
+    public void TestDangiFormat() {
+        DateFormat fmt = DateFormat.getDateInstance(DateFormat.MEDIUM, new ULocale("en@calendar=dangi"));
+        String calType = fmt.getCalendar().getType();
+        assertEquals("Incorrect calendar type used by the date format instance", "dangi", calType);
+
+        GregorianCalendar gcal = new GregorianCalendar();
+        gcal.set(2013, Calendar.MARCH, 1, 0, 0, 0);
+        Date d = gcal.getTime();
+
+        String dangiDateStr = fmt.format(d);
+        assertEquals("Bad date format", "Mo1 20, gui-si", dangiDateStr);
+    }
 }