1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.tomcat.util.res; 19 20 import java.text.MessageFormat; 21 import java.util.Hashtable; 22 import java.util.Locale; 23 import java.util.MissingResourceException; 24 import java.util.ResourceBundle; 25 26 /** 27 * An internationalization / localization helper class which reduces 28 * the bother of handling ResourceBundles and takes care of the 29 * common cases of message formating which otherwise require the 30 * creation of Object arrays and such. 31 * 32 * <p>The StringManager operates on a package basis. One StringManager 33 * per package can be created and accessed via the getManager method 34 * call. 35 * 36 * <p>The StringManager will look for a ResourceBundle named by 37 * the package name given plus the suffix of "LocalStrings". In 38 * practice, this means that the localized information will be contained 39 * in a LocalStrings.properties file located in the package 40 * directory of the classpath. 41 * 42 * <p>Please see the documentation for java.util.ResourceBundle for 43 * more information. 44 * 45 * @version $Revision: 769384 $ $Date: 2009-04-28 15:14:14 +0200 (Tue, 28 Apr 2009) $ 46 * 47 * @author James Duncan Davidson [duncan@eng.sun.com] 48 * @author James Todd [gonzo@eng.sun.com] 49 * @author Mel Martinez [mmartinez@g1440.com] 50 * @see java.util.ResourceBundle 51 */ 52 53 public class StringManager { 54 55 /** 56 * The ResourceBundle for this StringManager. 57 */ 58 59 private ResourceBundle bundle; 60 private Locale locale; 61 62 /** 63 * Creates a new StringManager for a given package. This is a 64 * private method and all access to it is arbitrated by the 65 * static getManager method call so that only one StringManager 66 * per package will be created. 67 * 68 * @param packageName Name of package to create StringManager for. 69 */ 70 71 private StringManager(String packageName) { 72 this( packageName, Locale.getDefault() ); 73 } 74 75 private StringManager(String packageName, Locale loc) { 76 String bundleName = packageName + ".LocalStrings"; 77 bundle = ResourceBundle.getBundle(bundleName, loc); 78 // Get the actual locale, which may be different from the requested one 79 locale = bundle.getLocale(); 80 } 81 82 private StringManager(ResourceBundle bundle ) 83 { 84 this.bundle=bundle; 85 locale = bundle.getLocale(); 86 } 87 88 /** 89 Get a string from the underlying resource bundle or return 90 null if the String is not found. 91 92 @param key to desired resource String 93 @return resource String matching <i>key</i> from underlying 94 bundle or null if not found. 95 @throws IllegalArgumentException if <i>key</i> is null. 96 */ 97 98 public String getString(String key) { 99 if(key == null){ 100 String msg = "key may not have a null value"; 101 102 throw new IllegalArgumentException(msg); 103 } 104 105 String str = null; 106 107 try{ 108 str = bundle.getString(key); 109 }catch(MissingResourceException mre){ 110 //bad: shouldn't mask an exception the following way: 111 // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]"; 112 // because it hides the fact that the String was missing 113 // from the calling code. 114 //good: could just throw the exception (or wrap it in another) 115 // but that would probably cause much havoc on existing 116 // code. 117 //better: consistent with container pattern to 118 // simply return null. Calling code can then do 119 // a null check. 120 str = null; 121 } 122 123 return str; 124 } 125 126 /** 127 * Get a string from the underlying resource bundle and format 128 * it with the given set of arguments. 129 * 130 * @param key 131 * @param args 132 */ 133 134 public String getString(final String key, final Object... args) { 135 String value = getString(key); 136 if (value == null) { 137 value = key; 138 } 139 140 MessageFormat mf = new MessageFormat(value); 141 mf.setLocale(locale); 142 return mf.format(args, new StringBuffer(), null).toString(); 143 } 144 145 // -------------------------------------------------------------- 146 // STATIC SUPPORT METHODS 147 // -------------------------------------------------------------- 148 149 private static Hashtable managers = new Hashtable(); 150 151 /** 152 * Get the StringManager for a particular package. If a manager for 153 * a package already exists, it will be reused, else a new 154 * StringManager will be created and returned. 155 * 156 * @param packageName The package name 157 */ 158 public synchronized static StringManager getManager(String packageName) { 159 StringManager mgr = (StringManager)managers.get(packageName); 160 if (mgr == null) { 161 mgr = new StringManager(packageName); 162 managers.put(packageName, mgr); 163 } 164 return mgr; 165 } 166 167 /** 168 * Get the StringManager for a particular package. If a manager for 169 * a package already exists, it will be reused, else a new 170 * StringManager will be created and returned. 171 * 172 * @param bundle The resource bundle 173 */ 174 public synchronized static StringManager getManager(ResourceBundle bundle) { 175 return new StringManager( bundle ); 176 } 177 178 /** 179 * Get the StringManager for a particular package and Locale. If a manager for 180 * a package already exists, it will be reused, else a new 181 * StringManager will be created for that Locale and returned. 182 * 183 * @param packageName The package name 184 * @param loc The locale 185 */ 186 187 public synchronized static StringManager getManager(String packageName,Locale loc) { 188 StringManager mgr = (StringManager)managers.get(packageName+"_"+loc.toString()); 189 if (mgr == null) { 190 mgr = new StringManager(packageName,loc); 191 managers.put(packageName+"_"+loc.toString(), mgr); 192 } 193 return mgr; 194 } 195 196 }