]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/util/OverlayBundle.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / util / OverlayBundle.java
1 /**\r
2  *******************************************************************************\r
3  * Copyright (C) 2001-2004, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.util;\r
8 \r
9 import java.util.*;\r
10 \r
11 /**\r
12  * A ResourceBundle that overlays one hierarchy atop another.  This is\r
13  * best explained by example.  Suppose one wants to use the\r
14  * resource hiararchy (in JDK 1.2 and 1.3, but not 1.4) at \r
15  * "java.text.resources.LocaleElements", but one wants to use\r
16  * a modified version of the "NumberPatterns" resource in the\r
17  * fr_FR locale.  One way to do this is to add special case code\r
18  * to the lookup operation to check for fr_FR and the key\r
19  * "NumberPatterns", and in that case, load up custom data.  However,\r
20  * this becomes unwieldy and places some information about the\r
21  * effective resource hierarchy into the code.\r
22  *\r
23  * The OverlayBundle solves this problem by layering another\r
24  * hierarchy, e.g, "com.acme.resources.LocaleElements", on top of a\r
25  * base hierarchy.  When a resource is requested, it is first sought\r
26  * in the overlay hierarchy, and if not found there, it is sought in\r
27  * the base hierarchy.  Multiple overlays are supported, but in\r
28  * practice one is usually sufficient.\r
29  * \r
30  * The OverlayBundle also addresses the problem of country-oriented\r
31  * data.  To specify the default data for a language, one just sets\r
32  * the language resource bundle data.  However, specifying the default\r
33  * data for a country using the standard ResourceBundle mechanism is\r
34  * impossible.  The OverlayBundle recognizes "wildcard" locales with\r
35  * the special language code "xx".  When looking up data for a locale\r
36  * with a non-empty country, if an exact locale match cannot be found,\r
37  * the OverlayBundle looks for data in the locale xx_YY, where YY is\r
38  * the country being sought.  This effectively adds another entry in\r
39  * the fallback sequence for a locale aa_BB: aa_BB, xx_BB, aa, root.\r
40  * Wildcard locales are not implemented for the base hierarchy, only\r
41  * for overlays.\r
42  *\r
43  * The OverlayBundle is implemented as an array of n ResourceBundle\r
44  * base names.  The base names are searched from 0 to n-1.  Base name\r
45  * n-1 is special; it is the base hierarchy.  This should be a\r
46  * well-populated hierarchy with most of the default data, typically,\r
47  * the icu or sun core hierarchies.  The base hierarchy is\r
48  * treated differently from the overlays above it.  It does not get\r
49  * wildcard resolution, and the getKeys() framework method is\r
50  * delegated to the base hierarchy bundle.\r
51  *\r
52  * Usage: Instantiate an OverlayBundle directly (not via a factory\r
53  * method as in ResourceBundle).  Instead of specifying a single base\r
54  * name, pass it an array of 2 or more base names.  After that, use it\r
55  * exactly as you would use ResourceBundle.\r
56  *\r
57  * @see java.util.ResourceBundle\r
58  * @author Alan Liu\r
59  * @internal\r
60  * @deprecated ICU 2.4. This class may be removed or modified.\r
61  */\r
62 // prepare to deprecate in next release\r
63 ///CLOVER:OFF\r
64 public class OverlayBundle extends ResourceBundle {\r
65 \r
66     /**\r
67      * The array of base names, with the length-1 entry being the base\r
68      * hierarchy, typically "sun.text.resources.LocaleElements".\r
69      */\r
70     private String[] baseNames;\r
71 \r
72     /**\r
73      * The requested locale.\r
74      */\r
75     private Locale locale;\r
76 \r
77     /**\r
78      * Loaded bundles.  These will be null until they are loaded on\r
79      * demand.\r
80      */\r
81     private ResourceBundle[] bundles;\r
82 \r
83     /**\r
84      * Construct an overlay bundle given a sequence of base names and\r
85      * a locale.\r
86      * @internal\r
87      * @deprecated ICU 2.4. This class may be removed or modified.\r
88      */\r
89     public OverlayBundle(String[] baseNames,\r
90                          Locale locale) {\r
91         this.baseNames = baseNames;\r
92         this.locale = locale;\r
93         bundles = new ResourceBundle[baseNames.length];\r
94     }\r
95 \r
96     /**\r
97      * ResourceBundle framework method.  Delegates to\r
98      * bundles[i].getObject().\r
99      * @internal\r
100      * @deprecated ICU 2.4. This class may be removed or modified.\r
101      */ \r
102    protected Object handleGetObject(String key) \r
103         throws MissingResourceException {\r
104 \r
105         Object o = null;\r
106 \r
107         for (int i=0; i<bundles.length; ++i) {\r
108             load(i);\r
109             try {\r
110                 o = bundles[i].getObject(key);\r
111             } catch (MissingResourceException e) {\r
112                 if (i == bundles.length-1) {\r
113                     throw e;\r
114                 }\r
115             }\r
116             if (o != null) {\r
117                 break;\r
118             }\r
119         }\r
120 \r
121         return o;\r
122     }\r
123 \r
124     /**\r
125      * ResourceBundle framework method.  Delegates to\r
126      * bundles[bundles.length-1].getKeys().\r
127      * @internal\r
128      * @deprecated ICU 2.4. This class may be removed or modified.\r
129      */\r
130     public Enumeration getKeys() {\r
131         // Return the enumeration of the last bundle, which is the base\r
132         // of our hierarchy stack.\r
133         int i = bundles.length - 1;\r
134         load(i);\r
135         return bundles[i].getKeys();\r
136     }\r
137 \r
138     /**\r
139      * Load the i-th bundle and implement wildcard resolution.\r
140      */\r
141     private void load(int i)\r
142         throws MissingResourceException {\r
143 \r
144         if (bundles[i] == null) {\r
145             boolean tryWildcard = false;\r
146             try {\r
147                 bundles[i] = ResourceBundle.getBundle(baseNames[i], locale);\r
148                 if (bundles[i].getLocale().equals(locale)) {\r
149                     return;\r
150                 }\r
151                 if (locale.getCountry().length() != 0 && i != bundles.length-1) {\r
152                     tryWildcard = true;\r
153                 }\r
154             } catch (MissingResourceException e) {\r
155                 if (i == bundles.length-1) {\r
156                     throw e;\r
157                 }\r
158                 tryWildcard = true;\r
159             }\r
160             if (tryWildcard) {\r
161                 Locale wildcard = new Locale("xx", locale.getCountry(),\r
162                                              locale.getVariant());\r
163                 try {\r
164                     bundles[i] = ResourceBundle.getBundle(baseNames[i], wildcard);\r
165                 } catch (MissingResourceException e) {\r
166                     if (bundles[i] == null) {\r
167                         throw e;\r
168                     }\r
169                 }\r
170             }\r
171         }\r
172     }\r
173 }\r