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