2 ******************************************************************************
\r
3 * Copyright (C) 2004-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 ******************************************************************************
\r
8 package com.ibm.icu.impl;
\r
10 import java.io.InputStream;
\r
11 import java.util.Enumeration;
\r
12 import java.util.MissingResourceException;
\r
13 import java.util.PropertyResourceBundle;
\r
14 import java.util.ResourceBundle;
\r
15 import java.util.Vector;
\r
17 import com.ibm.icu.util.ULocale;
\r
18 import com.ibm.icu.util.UResourceBundle;
\r
21 * just a wrapper for Java ListResourceBundles and
\r
25 public class ResourceBundleWrapper extends UResourceBundle {
\r
26 private ResourceBundle bundle = null;
\r
27 private String localeID = null;
\r
28 private String baseName = null;
\r
29 private Vector<String> keys = null;
\r
30 // private int loadingStatus = -1;
\r
32 private ResourceBundleWrapper(ResourceBundle bundle){
\r
36 protected void setLoadingStatus(int newStatus){
\r
37 // loadingStatus = newStatus;
\r
40 protected Object handleGetObject(String aKey){
\r
41 ResourceBundleWrapper current = this;
\r
43 while(current!=null){
\r
45 obj = current.bundle.getObject(aKey);
\r
47 }catch(MissingResourceException ex){
\r
48 current = (ResourceBundleWrapper)current.getParent();
\r
52 throw new MissingResourceException("Can't find resource for bundle "
\r
55 this.getClass().getName(),
\r
61 public Enumeration<String> getKeys(){
\r
62 return keys.elements();
\r
65 private void initKeysVector(){
\r
66 ResourceBundleWrapper current = this;
\r
67 keys = new Vector<String>();
\r
68 while(current!=null){
\r
69 Enumeration<String> e = current.bundle.getKeys();
\r
70 while(e.hasMoreElements()){
\r
71 String elem = e.nextElement();
\r
72 if(!keys.contains(elem)){
\r
76 current = (ResourceBundleWrapper)current.getParent();
\r
79 protected String getLocaleID(){
\r
83 protected String getBaseName(){
\r
84 return bundle.getClass().getName().replace('.','/');
\r
87 public ULocale getULocale(){
\r
88 return new ULocale(localeID);
\r
91 public UResourceBundle getParent(){
\r
92 return (UResourceBundle)parent;
\r
95 // Flag for enabling/disabling debugging code
\r
96 private static final boolean DEBUG = ICUDebug.enabled("resourceBundleWrapper");
\r
98 // This method is for super class's instantiateBundle method
\r
99 public static UResourceBundle getBundleInstance(String baseName, String localeID,
\r
100 ClassLoader root, boolean disableFallback){
\r
101 UResourceBundle b = instantiateBundle(baseName, localeID, root, disableFallback);
\r
103 String separator ="_";
\r
104 if(baseName.indexOf('/')>=0){
\r
107 throw new MissingResourceException("Could not find the bundle "+ baseName+separator+ localeID,"","");
\r
111 // recursively build bundle and override the super-class method
\r
112 protected static synchronized UResourceBundle instantiateBundle(String baseName, String localeID,
\r
113 ClassLoader root, boolean disableFallback) {
\r
114 if (root == null) {
\r
115 root = Utility.getFallbackClassLoader();
\r
117 final ClassLoader cl = root;
\r
118 String name = baseName;
\r
119 ULocale defaultLocale = ULocale.getDefault();
\r
120 if (localeID.length() != 0) {
\r
121 name = name + "_" + localeID;
\r
124 ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(cl, name, defaultLocale);
\r
126 ResourceBundleWrapper parent = null;
\r
127 int i = localeID.lastIndexOf('_');
\r
129 boolean loadFromProperties = false;
\r
131 String locName = localeID.substring(0, i);
\r
132 parent = (ResourceBundleWrapper)loadFromCache(cl, baseName+"_"+locName,defaultLocale);
\r
133 if(parent == null){
\r
134 parent = (ResourceBundleWrapper)instantiateBundle(baseName, locName , cl, disableFallback);
\r
136 }else if(localeID.length()>0){
\r
137 parent = (ResourceBundleWrapper)loadFromCache(cl, baseName,defaultLocale);
\r
139 parent = (ResourceBundleWrapper)instantiateBundle(baseName, "", cl, disableFallback);
\r
143 Class<? extends ResourceBundle> cls = cl.loadClass(name).asSubclass(ResourceBundle.class);
\r
144 ResourceBundle bx = cls.newInstance();
\r
145 b = new ResourceBundleWrapper(bx);
\r
146 if (parent != null) {
\r
147 b.setParent(parent);
\r
149 b.baseName=baseName;
\r
150 b.localeID = localeID;
\r
152 } catch (ClassNotFoundException e) {
\r
153 loadFromProperties = true;
\r
154 } catch (NoClassDefFoundError e) {
\r
155 loadFromProperties = true;
\r
156 } catch (Exception e) {
\r
158 System.out.println("failure");
\r
160 System.out.println(e);
\r
163 if (loadFromProperties) {
\r
165 final String resName = name.replace('.', '/') + ".properties";
\r
166 InputStream stream = java.security.AccessController.doPrivileged(
\r
167 new java.security.PrivilegedAction<InputStream>() {
\r
168 public InputStream run() {
\r
170 return cl.getResourceAsStream(resName);
\r
172 return ClassLoader.getSystemResourceAsStream(resName);
\r
177 if (stream != null) {
\r
178 // make sure it is buffered
\r
179 stream = new java.io.BufferedInputStream(stream);
\r
181 b = new ResourceBundleWrapper(new PropertyResourceBundle(stream));
\r
182 if (parent != null) {
\r
183 b.setParent(parent);
\r
185 b.baseName=baseName;
\r
186 b.localeID=localeID;
\r
187 } catch (Exception ex) {
\r
188 // throw away exception
\r
192 } catch (Exception ex) {
\r
193 // throw away exception
\r
198 // if a bogus locale is passed then the parent should be
\r
199 // the default locale not the root locale!
\r
201 String defaultName = defaultLocale.toString();
\r
202 if (localeID.length()>0 && localeID.indexOf('_')< 0 && defaultName.indexOf(localeID) == -1) {
\r
203 b = (ResourceBundleWrapper)loadFromCache(cl,baseName+"_"+defaultName, defaultLocale);
\r
205 b = (ResourceBundleWrapper)instantiateBundle(baseName , defaultName, cl, disableFallback);
\r
209 // if still could not find the bundle then return the parent
\r
213 } catch (Exception e) {
\r
215 System.out.println("failure");
\r
217 System.out.println(e);
\r
220 b = (ResourceBundleWrapper)addToCache(cl, name, defaultLocale, b);
\r
224 b.initKeysVector();
\r
226 if(DEBUG)System.out.println("Returning null for "+baseName+"_"+localeID);
\r