2 *******************************************************************************
3 * Copyright (C) 2001-2009, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.util;
9 import java.util.Enumeration;
10 import java.util.Locale;
11 import java.util.MissingResourceException;
12 import java.util.ResourceBundle;
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.
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.
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
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.
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.
60 * @see java.util.ResourceBundle
63 * @deprecated ICU 2.4. This class may be removed or modified.
65 // prepare to deprecate in next release
67 public class OverlayBundle extends ResourceBundle {
70 * The array of base names, with the length-1 entry being the base
71 * hierarchy, typically "sun.text.resources.LocaleElements".
73 private String[] baseNames;
76 * The requested locale.
78 private Locale locale;
81 * Loaded bundles. These will be null until they are loaded on
84 private ResourceBundle[] bundles;
87 * Construct an overlay bundle given a sequence of base names and
90 * @deprecated ICU 2.4. This class may be removed or modified.
92 public OverlayBundle(String[] baseNames,
94 this.baseNames = baseNames;
96 bundles = new ResourceBundle[baseNames.length];
100 * ResourceBundle framework method. Delegates to
101 * bundles[i].getObject().
103 * @deprecated ICU 2.4. This class may be removed or modified.
105 protected Object handleGetObject(String key)
106 throws MissingResourceException {
110 for (int i=0; i<bundles.length; ++i) {
113 o = bundles[i].getObject(key);
114 } catch (MissingResourceException e) {
115 if (i == bundles.length-1) {
128 * ResourceBundle framework method. Delegates to
129 * bundles[bundles.length-1].getKeys().
131 * @deprecated ICU 2.4. This class may be removed or modified.
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;
138 return bundles[i].getKeys();
142 * Load the i-th bundle and implement wildcard resolution.
144 private void load(int i)
145 throws MissingResourceException {
147 if (bundles[i] == null) {
148 boolean tryWildcard = false;
150 bundles[i] = ResourceBundle.getBundle(baseNames[i], locale);
151 if (bundles[i].getLocale().equals(locale)) {
154 if (locale.getCountry().length() != 0 && i != bundles.length-1) {
157 } catch (MissingResourceException e) {
158 if (i == bundles.length-1) {
164 Locale wildcard = new Locale("xx", locale.getCountry(),
165 locale.getVariant());
167 bundles[i] = ResourceBundle.getBundle(baseNames[i], wildcard);
168 } catch (MissingResourceException e) {
169 if (bundles[i] == null) {