1/* 2****************************************************************************** 3* Copyright (C) 2004-2015, International Business Machines Corporation and * 4* others. All Rights Reserved. * 5****************************************************************************** 6*/ 7 8package com.ibm.icu.impl; 9 10import java.io.InputStream; 11import java.util.ArrayList; 12import java.util.Collections; 13import java.util.Enumeration; 14import java.util.List; 15import java.util.MissingResourceException; 16import java.util.PropertyResourceBundle; 17import java.util.ResourceBundle; 18 19import com.ibm.icu.util.ULocale; 20import com.ibm.icu.util.UResourceBundle; 21 22/** 23 * just a wrapper for Java ListResourceBundles and 24 * @author ram 25 * 26 */ 27public class ResourceBundleWrapper extends UResourceBundle { 28 private ResourceBundle bundle = null; 29 private String localeID = null; 30 private String baseName = null; 31 private List<String> keys = null; 32// private int loadingStatus = -1; 33 34 private ResourceBundleWrapper(ResourceBundle bundle){ 35 this.bundle=bundle; 36 } 37 38 protected void setLoadingStatus(int newStatus){ 39// loadingStatus = newStatus; 40 } 41 42 protected Object handleGetObject(String aKey){ 43 ResourceBundleWrapper current = this; 44 Object obj = null; 45 while(current!=null){ 46 try{ 47 obj = current.bundle.getObject(aKey); 48 break; 49 }catch(MissingResourceException ex){ 50 current = (ResourceBundleWrapper)current.getParent(); 51 } 52 } 53 if (obj == null){ 54 throw new MissingResourceException("Can't find resource for bundle " 55 +baseName 56 +", key "+aKey, 57 this.getClass().getName(), 58 aKey); 59 } 60 return obj; 61 } 62 63 public Enumeration<String> getKeys(){ 64 return Collections.enumeration(keys); 65 } 66 67 private void initKeysVector(){ 68 ResourceBundleWrapper current = this; 69 keys = new ArrayList<String>(); 70 while(current!=null){ 71 Enumeration<String> e = current.bundle.getKeys(); 72 while(e.hasMoreElements()){ 73 String elem = e.nextElement(); 74 if(!keys.contains(elem)){ 75 keys.add(elem); 76 } 77 } 78 current = (ResourceBundleWrapper)current.getParent(); 79 } 80 } 81 protected String getLocaleID(){ 82 return localeID; 83 } 84 85 protected String getBaseName(){ 86 return bundle.getClass().getName().replace('.','/'); 87 } 88 89 public ULocale getULocale(){ 90 return new ULocale(localeID); 91 } 92 93 public UResourceBundle getParent(){ 94 return (UResourceBundle)parent; 95 } 96 97 // Flag for enabling/disabling debugging code 98 private static final boolean DEBUG = ICUDebug.enabled("resourceBundleWrapper"); 99 100 // This method is for super class's instantiateBundle method 101 public static UResourceBundle getBundleInstance(String baseName, String localeID, 102 ClassLoader root, boolean disableFallback){ 103 UResourceBundle b = instantiateBundle(baseName, localeID, root, disableFallback); 104 if(b==null){ 105 String separator ="_"; 106 if(baseName.indexOf('/')>=0){ 107 separator = "/"; 108 } 109 throw new MissingResourceException("Could not find the bundle "+ baseName+separator+ localeID,"",""); 110 } 111 return b; 112 } 113 // recursively build bundle and override the super-class method 114 protected static synchronized UResourceBundle instantiateBundle(String baseName, String localeID, 115 ClassLoader root, boolean disableFallback) { 116 if (root == null) { 117 root = ClassLoaderUtil.getClassLoader(); 118 } 119 final ClassLoader cl = root; 120 String name = baseName; 121 ULocale defaultLocale = ULocale.getDefault(); 122 if (localeID.length() != 0) { 123 name = name + "_" + localeID; 124 } 125 126 ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(cl, name, defaultLocale); 127 if(b==null){ 128 ResourceBundleWrapper parent = null; 129 int i = localeID.lastIndexOf('_'); 130 131 boolean loadFromProperties = false; 132 if (i != -1) { 133 String locName = localeID.substring(0, i); 134 parent = (ResourceBundleWrapper)loadFromCache(cl, baseName+"_"+locName,defaultLocale); 135 if(parent == null){ 136 parent = (ResourceBundleWrapper)instantiateBundle(baseName, locName , cl, disableFallback); 137 } 138 }else if(localeID.length()>0){ 139 parent = (ResourceBundleWrapper)loadFromCache(cl, baseName,defaultLocale); 140 if(parent==null){ 141 parent = (ResourceBundleWrapper)instantiateBundle(baseName, "", cl, disableFallback); 142 } 143 } 144 try { 145 Class<? extends ResourceBundle> cls = cl.loadClass(name).asSubclass(ResourceBundle.class); 146 ResourceBundle bx = cls.newInstance(); 147 b = new ResourceBundleWrapper(bx); 148 if (parent != null) { 149 b.setParent(parent); 150 } 151 b.baseName=baseName; 152 b.localeID = localeID; 153 154 } catch (ClassNotFoundException e) { 155 loadFromProperties = true; 156 } catch (NoClassDefFoundError e) { 157 loadFromProperties = true; 158 } catch (Exception e) { 159 if (DEBUG) 160 System.out.println("failure"); 161 if (DEBUG) 162 System.out.println(e); 163 } 164 165 if (loadFromProperties) { 166 try { 167 final String resName = name.replace('.', '/') + ".properties"; 168 InputStream stream = java.security.AccessController.doPrivileged( 169 new java.security.PrivilegedAction<InputStream>() { 170 public InputStream run() { 171 if (cl != null) { 172 return cl.getResourceAsStream(resName); 173 } else { 174 return ClassLoader.getSystemResourceAsStream(resName); 175 } 176 } 177 } 178 ); 179 if (stream != null) { 180 // make sure it is buffered 181 stream = new java.io.BufferedInputStream(stream); 182 try { 183 b = new ResourceBundleWrapper(new PropertyResourceBundle(stream)); 184 if (parent != null) { 185 b.setParent(parent); 186 } 187 b.baseName=baseName; 188 b.localeID=localeID; 189 } catch (Exception ex) { 190 // throw away exception 191 } finally { 192 try { 193 stream.close(); 194 } catch (Exception ex) { 195 // throw away exception 196 } 197 } 198 } 199 200 // if a bogus locale is passed then the parent should be 201 // the default locale not the root locale! 202 if (b==null) { 203 String defaultName = defaultLocale.toString(); 204 if (localeID.length()>0 && localeID.indexOf('_')< 0 && defaultName.indexOf(localeID) == -1) { 205 b = (ResourceBundleWrapper)loadFromCache(cl,baseName+"_"+defaultName, defaultLocale); 206 if(b==null){ 207 b = (ResourceBundleWrapper)instantiateBundle(baseName , defaultName, cl, disableFallback); 208 } 209 } 210 } 211 // if still could not find the bundle then return the parent 212 if(b==null){ 213 b=parent; 214 } 215 } catch (Exception e) { 216 if (DEBUG) 217 System.out.println("failure"); 218 if (DEBUG) 219 System.out.println(e); 220 } 221 } 222 b = (ResourceBundleWrapper)addToCache(cl, name, defaultLocale, b); 223 } 224 225 if(b!=null){ 226 b.initKeysVector(); 227 }else{ 228 if(DEBUG)System.out.println("Returning null for "+baseName+"_"+localeID); 229 } 230 231 return b; 232 } 233} 234