1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html#License
3/*
4 *******************************************************************************
5 * Copyright (C) 2009-2014, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
8 */
9package com.ibm.icu.impl;
10
11import com.ibm.icu.util.ULocale;
12import com.ibm.icu.util.UResourceBundle;
13
14/**
15 * Static utility functions for probing resource tables, used by ULocale and
16 * LocaleDisplayNames.
17 */
18public class ICUResourceTableAccess {
19    /**
20     * Utility to fetch locale display data from resource bundle tables.  Convenience
21     * wrapper for {@link #getTableString(ICUResourceBundle, String, String, String, String)}.
22     */
23    public static String getTableString(String path, ULocale locale, String tableName,
24            String itemName, String defaultValue) {
25        ICUResourceBundle bundle = (ICUResourceBundle) UResourceBundle.
26            getBundleInstance(path, locale.getBaseName());
27        return getTableString(bundle, tableName, null, itemName, defaultValue);
28    }
29
30    /**
31     * Utility to fetch locale display data from resource bundle tables.  Uses fallback
32     * through the "Fallback" resource if available.
33     */
34    public static String getTableString(ICUResourceBundle bundle, String tableName,
35            String subtableName, String item, String defaultValue) {
36        String result = null;
37        try {
38            for (;;) {
39                ICUResourceBundle table = bundle.findWithFallback(tableName);
40                if (table == null) {
41                    return defaultValue;
42                }
43                ICUResourceBundle stable = table;
44                if (subtableName != null) {
45                    stable = table.findWithFallback(subtableName);
46                }
47                if (stable != null) {
48                    result = stable.findStringWithFallback(item);
49                    if (result != null) {
50                        break; // possible real exception
51                    }
52                }
53
54                // if we get here, stable was null, or there was no string for the item
55                if (subtableName == null) {
56                    // may be a deprecated code
57                    String currentName = null;
58                    if (tableName.equals("Countries")) {
59                        currentName = LocaleIDs.getCurrentCountryID(item);
60                    } else if (tableName.equals("Languages")) {
61                        currentName = LocaleIDs.getCurrentLanguageID(item);
62                    }
63                    if (currentName != null) {
64                        result = table.findStringWithFallback(currentName);
65                        if (result != null) {
66                            break; // possible real exception
67                        }
68                    }
69                }
70
71                // still can't figure it out? try the fallback mechanism
72                String fallbackLocale = table.findStringWithFallback("Fallback"); // again, possible exception
73                if (fallbackLocale == null) {
74                    return defaultValue;
75                }
76
77                if (fallbackLocale.length() == 0) {
78                    fallbackLocale = "root";
79                }
80
81                if (fallbackLocale.equals(table.getULocale().getName())) {
82                    return defaultValue;
83                }
84
85                bundle = (ICUResourceBundle) UResourceBundle.getBundleInstance(
86                        bundle.getBaseName(), fallbackLocale);
87            }
88        } catch (Exception e) {
89            // If something is seriously wrong, we might call getString on a resource that is
90            // not a string.  That will throw an exception, which we catch and ignore here.
91        }
92
93        // If the result is empty return item instead
94        return ((result != null && result.length() > 0) ? result : defaultValue);
95    }
96}
97