2 *******************************************************************************
\r
3 * Copyright (C) 2001-2004, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.util;
\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
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
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
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
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
57 * @see java.util.ResourceBundle
\r
60 * @deprecated ICU 2.4. This class may be removed or modified.
\r
62 // prepare to deprecate in next release
\r
64 public class OverlayBundle extends ResourceBundle {
\r
67 * The array of base names, with the length-1 entry being the base
\r
68 * hierarchy, typically "sun.text.resources.LocaleElements".
\r
70 private String[] baseNames;
\r
73 * The requested locale.
\r
75 private Locale locale;
\r
78 * Loaded bundles. These will be null until they are loaded on
\r
81 private ResourceBundle[] bundles;
\r
84 * Construct an overlay bundle given a sequence of base names and
\r
87 * @deprecated ICU 2.4. This class may be removed or modified.
\r
89 public OverlayBundle(String[] baseNames,
\r
91 this.baseNames = baseNames;
\r
92 this.locale = locale;
\r
93 bundles = new ResourceBundle[baseNames.length];
\r
97 * ResourceBundle framework method. Delegates to
\r
98 * bundles[i].getObject().
\r
100 * @deprecated ICU 2.4. This class may be removed or modified.
\r
102 protected Object handleGetObject(String key)
\r
103 throws MissingResourceException {
\r
107 for (int i=0; i<bundles.length; ++i) {
\r
110 o = bundles[i].getObject(key);
\r
111 } catch (MissingResourceException e) {
\r
112 if (i == bundles.length-1) {
\r
125 * ResourceBundle framework method. Delegates to
\r
126 * bundles[bundles.length-1].getKeys().
\r
128 * @deprecated ICU 2.4. This class may be removed or modified.
\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
135 return bundles[i].getKeys();
\r
139 * Load the i-th bundle and implement wildcard resolution.
\r
141 private void load(int i)
\r
142 throws MissingResourceException {
\r
144 if (bundles[i] == null) {
\r
145 boolean tryWildcard = false;
\r
147 bundles[i] = ResourceBundle.getBundle(baseNames[i], locale);
\r
148 if (bundles[i].getLocale().equals(locale)) {
\r
151 if (locale.getCountry().length() != 0 && i != bundles.length-1) {
\r
152 tryWildcard = true;
\r
154 } catch (MissingResourceException e) {
\r
155 if (i == bundles.length-1) {
\r
158 tryWildcard = true;
\r
161 Locale wildcard = new Locale("xx", locale.getCountry(),
\r
162 locale.getVariant());
\r
164 bundles[i] = ResourceBundle.getBundle(baseNames[i], wildcard);
\r
165 } catch (MissingResourceException e) {
\r
166 if (bundles[i] == null) {
\r