ResourceBundle.java revision f5597e626ecf7949d249dea08c1a2964d890ec11
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedAction; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-changed 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// import org.apache.harmony.kernel.vm.VM; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport com.ibm.icu4jni.util.Resources; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport dalvik.system.VMStack; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-changed 30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.util.Msg; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code ResourceBundle} is an abstract class which is the superclass of classes which 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provide {@code Locale}-specific resources. A bundle contains a number of named 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resources, where the names are {@code Strings}. A bundle may have a parent bundle, 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and when a resource is not found in a bundle, the parent bundle is searched for 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the resource. If the fallback mechanism reaches the base bundle and still 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * can't find the resource it throws a {@code MissingResourceException}. 39f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>All bundles for the same group of resources share a common base bundle. 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This base bundle acts as the root and is the last fallback in case none of 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * its children was able to respond to a request.</li> 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The first level contains changes between different languages. Only the 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * differences between a language and the language of the base bundle need to be 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handled by a language-specific {@code ResourceBundle}.</li> 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The second level contains changes between different countries that use 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the same language. Only the differences between a country and the country of 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the language bundle need to be handled by a country-specific {@code ResourceBundle}. 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </li> 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The third level contains changes that don't have a geographic reason 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (e.g. changes that where made at some point in time like {@code PREEURO} where the 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * currency of come countries changed. The country bundle would return the 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * current currency (Euro) and the {@code PREEURO} variant bundle would return the old 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * currency (e.g. DM for Germany).</li> 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 57f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <strong>Examples</strong> 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName (base bundle) 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de (german language bundle) 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_fr (french language bundle) 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de_DE (bundle with Germany specific resources in german) 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de_CH (bundle with Switzerland specific resources in german) 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_fr_CH (bundle with Switzerland specific resources in french) 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de_DE_PREEURO (bundle with Germany specific resources in german of 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the time before the Euro) 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_fr_FR_PREEURO (bundle with France specific resources in french of 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the time before the Euro) 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 71f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It's also possible to create variants for languages or countries. This can be 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * done by just skipping the country or language abbreviation: 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * BaseName_us__POSIX or BaseName__DE_PREEURO. But it's not allowed to 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * circumvent both language and country: BaseName___VARIANT is illegal. 76f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Properties 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see PropertyResourceBundle 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ListResourceBundle 80f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.1 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class ResourceBundle { 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The parent of this {@code ResourceBundle} that is used if this bundle doesn't 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * include the requested resource. 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected ResourceBundle parent; 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Locale locale; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class MissingBundle extends ResourceBundle { 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<String> getKeys() { 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object handleGetObject(String name) { 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final ResourceBundle MISSING = new MissingBundle(); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final ResourceBundle MISSINGBASE = new MissingBundle(); 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final WeakHashMap<Object, Hashtable<String, ResourceBundle>> cache = new WeakHashMap<Object, Hashtable<String, ResourceBundle>>(); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-added 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static Locale defaultLocale = Locale.getDefault(); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-added 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of this class. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ResourceBundle() { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* empty */ 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finds the named resource bundle for the default {@code Locale} and the caller's 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code ClassLoader}. 124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bundleName 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the {@code ResourceBundle}. 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the requested {@code ResourceBundle}. 128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code ResourceBundle} cannot be found. 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final ResourceBundle getBundle(String bundleName) 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws MissingResourceException { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getBundleImpl(bundleName, Locale.getDefault(), VMStack 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getCallingClassLoader()); 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finds the named {@code ResourceBundle} for the specified {@code Locale} and the caller 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code ClassLoader}. 142f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bundleName 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the {@code ResourceBundle}. 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param locale 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Locale}. 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the requested resource bundle. 148f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource bundle cannot be found. 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final ResourceBundle getBundle(String bundleName, 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale locale) { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getBundleImpl(bundleName, locale, 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project VMStack.getCallingClassLoader()); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finds the named resource bundle for the specified {@code Locale} and {@code ClassLoader}. 161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The passed base name and {@code Locale} are used to create resource bundle names. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The first name is created by concatenating the base name with the result 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of {@link Locale#toString()}. From this name all parent bundle names are 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * derived. Then the same thing is done for the default {@code Locale}. This results 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in a list of possible bundle names. 167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <strong>Example</strong> For the basename "BaseName", the {@code Locale} of the 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * German part of Switzerland (de_CH) and the default {@code Locale} en_US the list 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * would look something like this: 171f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ol> 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de_CH</li> 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName_de</li> 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Basename_en_US</li> 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Basename_en</li> 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>BaseName</li> 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ol> 179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This list also shows the order in which the bundles will be searched for a requested 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resource in the German part of Switzerland (de_CH). 182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * As a first step, this method tries to instantiate 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a {@code ResourceBundle} with the names provided. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If such a class can be instantiated and initialized, it is returned and 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * all the parent bundles are instantiated too. If no such class can be 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * found this method tries to load a {@code .properties} file with the names by 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * replacing dots in the base name with a slash and by appending 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "{@code .properties}" at the end of the string. If such a resource can be found 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by calling {@link ClassLoader#getResource(String)} it is used to 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialize a {@link PropertyResourceBundle}. If this succeeds, it will 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * also load the parents of this {@code ResourceBundle}. 193f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For compatibility with older code, the bundle name isn't required to be 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a fully qualified class name. It's also possible to directly pass 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the path to a properties file (without a file extension). 197f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bundleName 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the {@code ResourceBundle}. 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param locale 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Locale}. 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loader 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code ClassLoader} to use. 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the requested {@code ResourceBundle}. 205f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code ResourceBundle} cannot be found. 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static ResourceBundle getBundle(String bundleName, Locale locale, 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassLoader loader) throws MissingResourceException { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loader == null) { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getBundleImpl(bundleName, locale, loader); 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ResourceBundle getBundleImpl(String bundleName, 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale locale, ClassLoader loader) throws MissingResourceException { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bundleName != null) { 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ResourceBundle bundle; 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-added 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!defaultLocale.equals(Locale.getDefault())) { 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cache.clear(); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project defaultLocale = Locale.getDefault(); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-added 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!locale.equals(Locale.getDefault())) { 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String localeName = locale.toString(); 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (localeName.length() > 0) { 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project localeName = "_" + localeName; //$NON-NLS-1$ 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((bundle = handleGetBundle(bundleName, localeName, false, 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loader)) != null) { 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bundle; 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String localeName = Locale.getDefault().toString(); 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (localeName.length() > 0) { 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project localeName = "_" + localeName; //$NON-NLS-1$ 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((bundle = handleGetBundle(bundleName, localeName, true, loader)) != null) { 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bundle; 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw new MissingResourceException(Msg.getString("KA029", bundleName, locale), bundleName + '_' + locale, //$NON-NLS-1$ 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ""); //$NON-NLS-1$ 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the names of the resources contained in this {@code ResourceBundle}. 253f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an {@code Enumeration} of the resource names. 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract Enumeration<String> getKeys(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the {@code Locale} of this {@code ResourceBundle}. In case a bundle was not 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * found for the requested {@code Locale}, this will return the actual {@code Locale} of 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this resource bundle that was found after doing a fallback. 262f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Locale} of this {@code ResourceBundle}. 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Locale getLocale() { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return locale; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the named resource from this {@code ResourceBundle}. If the resource 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cannot be found in this bundle, it falls back to the parent bundle (if 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it's not null) by calling the {@link #handleGetObject} method. If the resource still 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * can't be found it throws a {@code MissingResourceException}. 274f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the resource. 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the resource object. 278f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource is not found. 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object getObject(String key) { 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ResourceBundle last, theParent = this; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object result = theParent.handleGetObject(key); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result != null) { 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project last = theParent; 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theParent = theParent.parent; 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (theParent != null); 291f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw new MissingResourceException(Msg.getString("KA029", last.getClass().getName(), key), last.getClass().getName(), key); //$NON-NLS-1$ 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the named string resource from this {@code ResourceBundle}. 296f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the resource. 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the resource string. 300f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource is not found. 302f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws ClassCastException 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource found is not a string. 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getObject(String) 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getString(String key) { 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (String) getObject(key); 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the named resource from this {@code ResourceBundle}. 312f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the resource. 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the resource string array. 316f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws MissingResourceException 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource is not found. 318f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws ClassCastException 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the resource found is not an array of strings. 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getObject(String) 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String[] getStringArray(String key) { 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (String[]) getObject(key); 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ResourceBundle handleGetBundle(String base, String locale, 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean loadBase, final ClassLoader loader) { 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ResourceBundle bundle = null; 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String bundleName = base + locale; 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object cacheKey = loader != null ? (Object) loader : (Object) "null"; //$NON-NLS-1$ 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Hashtable<String, ResourceBundle> loaderCache; 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (cache) { 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loaderCache = cache.get(cacheKey); 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (loaderCache == null) { 335f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson loaderCache = new Hashtable<String, ResourceBundle>(); 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cache.put(cacheKey, loaderCache); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ResourceBundle result = loaderCache.get(bundleName); 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result != null) { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == MISSINGBASE) { 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == MISSING) { 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!loadBase) { 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String extension = strip(locale); 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extension == null) { 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return handleGetBundle(base, extension, loadBase, loader); 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Intercept loading of ResourceBundles that contain Harmony 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * I18N data. Deliver our special, ICU-based bundles in this case. 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * All other ResourceBundles use the ordinary mechanism, so user 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * code behaves as it should. 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if(bundleName.startsWith("org.apache.harmony.luni.internal.locale.")) { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String icuBundleName = bundleName.substring(40); 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String icuLocale = (locale.length() > 0 ? locale.substring(1) : locale); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // we know that Resources will deliver an assignable class 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle = Resources.getInstance(icuBundleName, icuLocale); 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> bundleClass = Class.forName(bundleName, true, loader); 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ResourceBundle.class.isAssignableFrom(bundleClass)) { 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle = (ResourceBundle) bundleClass.newInstance(); 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (LinkageError e) { 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bundle != null) { 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle.setLocale(locale); 383f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final String fileName = bundleName.replace('.', '/'); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputStream stream = AccessController 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .doPrivileged(new PrivilegedAction<InputStream>() { 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream run() { 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loader == null ? ClassLoader 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getSystemResourceAsStream(fileName 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + ".properties") : loader //$NON-NLS-1$ 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getResourceAsStream(fileName 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + ".properties"); //$NON-NLS-1$ 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (stream != null) { 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle = new PropertyResourceBundle(stream); 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.close(); 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle.setLocale(locale); 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String extension = strip(locale); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bundle != null) { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extension != null) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ResourceBundle parent = handleGetBundle(base, extension, true, 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loader); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parent != null) { 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle.setParent(parent); 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loaderCache.put(bundleName, bundle); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bundle; 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (extension != null && (loadBase || extension.length() > 0)) { 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bundle = handleGetBundle(base, extension, loadBase, loader); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bundle != null) { 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loaderCache.put(bundleName, bundle); 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bundle; 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loaderCache.put(bundleName, loadBase ? MISSINGBASE : MISSING); 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the named resource from this {@code ResourceBundle}, or null if the 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resource is not found. 435f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the resource. 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the resource object. 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract Object handleGetObject(String key); 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the parent resource bundle of this {@code ResourceBundle}. The parent is 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * searched for resources which are not found in this {@code ResourceBundle}. 445f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bundle 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parent {@code ResourceBundle}. 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void setParent(ResourceBundle bundle) { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parent = bundle; 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static String strip(String name) { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = name.lastIndexOf('_'); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index != -1) { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name.substring(0, index); 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void setLocale(String name) { 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String language = "", country = "", variant = ""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() > 1) { 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int nextIndex = name.indexOf('_', 1); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextIndex == -1) { 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextIndex = name.length(); 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project language = name.substring(1, nextIndex); 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextIndex + 1 < name.length()) { 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = nextIndex; 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextIndex = name.indexOf('_', nextIndex + 1); 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextIndex == -1) { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextIndex = name.length(); 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project country = name.substring(index + 1, nextIndex); 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextIndex + 1 < name.length()) { 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project variant = name.substring(nextIndex + 1, name.length()); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project locale = new Locale(language, country, variant); 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 484