blob: 5c477574b0b5b7590d3f75e6fa5febc6c5ef498e [file] [log] [blame]
/*
******************************************************************************
* Copyright (C) 2004-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
******************************************************************************
*/
package com.ibm.icu.impl;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Vector;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
/**
* just a wrapper for Java ListResourceBundles and
* @author ram
*
*/
public class ResourceBundleWrapper extends UResourceBundle {
private ResourceBundle bundle = null;
private String localeID = null;
private String baseName = null;
private Vector keys=null;
private int loadingStatus = -1;
private ResourceBundleWrapper(ResourceBundle bundle){
this.bundle=bundle;
}
protected void setLoadingStatus(int newStatus){
loadingStatus = newStatus;
}
protected Object handleGetObject(String key){
ResourceBundleWrapper current = this;
Object obj = null;
while(current!=null){
try{
obj = current.bundle.getObject(key);
break;
}catch(MissingResourceException ex){
current = (ResourceBundleWrapper)current.getParent();
}
}
if (obj == null){
throw new MissingResourceException("Can't find resource for bundle "
+baseName
+", key "+key,
this.getClass().getName(),
key);
}
return obj;
}
public Enumeration getKeys(){
return keys.elements();
}
private void initKeysVector(){
ResourceBundleWrapper current = this;
keys = new Vector();
while(current!=null){
Enumeration e = current.bundle.getKeys();
while(e.hasMoreElements()){
String elem = (String)e.nextElement();
if(!keys.contains(elem)){
keys.add(elem);
}
}
current = (ResourceBundleWrapper)current.getParent();
}
}
protected String getLocaleID(){
return localeID;
}
protected String getBaseName(){
return bundle.getClass().getName().replace('.','/');
}
public ULocale getULocale(){
return new ULocale(localeID);
}
public UResourceBundle getParent(){
return (UResourceBundle)parent;
}
// Flag for enabling/disabling debugging code
private static final boolean DEBUG = ICUDebug.enabled("resourceBundleWrapper");
// This method is for super class's instantiateBundle method
public static UResourceBundle getBundleInstance(String baseName, String localeID,
ClassLoader root, boolean disableFallback){
UResourceBundle b = instantiateBundle(baseName, localeID, root, disableFallback);
if(b==null){
String separator ="_";
if(baseName.indexOf('/')>=0){
separator = "/";
}
throw new MissingResourceException("Could not find the bundle "+ baseName+separator+ localeID,"","");
}
return b;
}
// recursively build bundle and override the super-class method
protected static synchronized UResourceBundle instantiateBundle(String baseName, String localeID,
ClassLoader root, boolean disableFallback) {
if (root == null) {
// we're on the bootstrap
root = ClassLoader.getSystemClassLoader();
}
final ClassLoader cl = root;
String name = baseName;
ULocale defaultLocale = ULocale.getDefault();
if (localeID.length() != 0) {
name = name + "_" + localeID;
}
ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(cl, name, defaultLocale);
if(b==null){
ResourceBundleWrapper parent = null;
int i = localeID.lastIndexOf('_');
if (i != -1) {
String locName = localeID.substring(0, i);
parent = (ResourceBundleWrapper)loadFromCache(cl, baseName+"_"+locName,defaultLocale);
if(parent == null){
parent = (ResourceBundleWrapper)instantiateBundle(baseName, locName , cl, disableFallback);
}
}else if(localeID.length()>0){
parent = (ResourceBundleWrapper)loadFromCache(cl, baseName,defaultLocale);
if(parent==null){
parent = (ResourceBundleWrapper)instantiateBundle(baseName, "", cl, disableFallback);
}
}
try {
Class cls = cl.loadClass(name);
ResourceBundle bx = (ResourceBundle) cls.newInstance();
b = new ResourceBundleWrapper(bx);
if (parent != null) {
b.setParent(parent);
}
b.baseName=baseName;
b.localeID = localeID;
} catch (ClassNotFoundException e) {
final String resName = name.replace('.', '/') + ".properties";
InputStream stream = (InputStream)java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
if (cl != null) {
return cl.getResourceAsStream(resName);
} else {
return ClassLoader.getSystemResourceAsStream(resName);
}
}
}
);
if (stream != null) {
// make sure it is buffered
stream = new java.io.BufferedInputStream(stream);
try {
b = new ResourceBundleWrapper(new PropertyResourceBundle(stream));
if (parent != null) {
b.setParent(parent);
}
b.baseName=baseName;
b.localeID=localeID;
} catch (Exception ex) {
// throw away exception
} finally {
try {
stream.close();
} catch (Exception ex) {
// throw away exception
}
}
}
// if a bogus locale is passed then the parent should be
// the default locale not the root locale!
if (b==null) {
String defaultName = defaultLocale.toString();
if (localeID.length()>0 && localeID.indexOf('_')< 0 && defaultName.indexOf(localeID) == -1) {
b = (ResourceBundleWrapper)loadFromCache(cl,baseName+"_"+defaultName, defaultLocale);
if(b==null){
b = (ResourceBundleWrapper)instantiateBundle(baseName , defaultName, cl, disableFallback);
}
}
}
// if still could not find the bundle then return the parent
if(b==null){
b=parent;
}
} catch (Exception e) {
if (DEBUG)
System.out.println("failure");
if (DEBUG)
System.out.println(e);
}
addToCache(cl, name, defaultLocale, b);
}
if(b!=null){
b.initKeysVector();
}else{
if(DEBUG)System.out.println("Returning null for "+baseName+"_"+localeID);
}
return b;
}
}