001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.tomcat.util.res;
019:
020: import java.text.MessageFormat;
021: import java.util.Hashtable;
022: import java.util.Locale;
023: import java.util.MissingResourceException;
024: import java.util.ResourceBundle;
025:
026: /**
027: * An internationalization / localization helper class which reduces
028: * the bother of handling ResourceBundles and takes care of the
029: * common cases of message formating which otherwise require the
030: * creation of Object arrays and such.
031: *
032: * <p>The StringManager operates on a package basis. One StringManager
033: * per package can be created and accessed via the getManager method
034: * call.
035: *
036: * <p>The StringManager will look for a ResourceBundle named by
037: * the package name given plus the suffix of "LocalStrings". In
038: * practice, this means that the localized information will be contained
039: * in a LocalStrings.properties file located in the package
040: * directory of the classpath.
041: *
042: * <p>Please see the documentation for java.util.ResourceBundle for
043: * more information.
044: *
045: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
046: *
047: * @author James Duncan Davidson [duncan@eng.sun.com]
048: * @author James Todd [gonzo@eng.sun.com]
049: * @author Mel Martinez [mmartinez@g1440.com]
050: * @see java.util.ResourceBundle
051: */
052:
053: public class StringManager {
054:
055: /**
056: * The ResourceBundle for this StringManager.
057: */
058:
059: private ResourceBundle bundle;
060: private Locale locale;
061:
062: /**
063: * Creates a new StringManager for a given package. This is a
064: * private method and all access to it is arbitrated by the
065: * static getManager method call so that only one StringManager
066: * per package will be created.
067: *
068: * @param packageName Name of package to create StringManager for.
069: */
070:
071: private StringManager(String packageName) {
072: this (packageName, Locale.getDefault());
073: }
074:
075: private StringManager(String packageName, Locale loc) {
076: String bundleName = packageName + ".LocalStrings";
077: bundle = ResourceBundle.getBundle(bundleName, loc);
078: // Get the actual locale, which may be different from the requested one
079: locale = bundle.getLocale();
080: }
081:
082: private StringManager(ResourceBundle bundle) {
083: this .bundle = bundle;
084: locale = bundle.getLocale();
085: }
086:
087: /**
088: Get a string from the underlying resource bundle or return
089: null if the String is not found.
090:
091: @param key to desired resource String
092: @return resource String matching <i>key</i> from underlying
093: bundle or null if not found.
094: @throws IllegalArgumentException if <i>key</i> is null.
095: */
096:
097: public String getString(String key) {
098: if (key == null) {
099: String msg = "key may not have a null value";
100:
101: throw new IllegalArgumentException(msg);
102: }
103:
104: String str = null;
105:
106: try {
107: str = bundle.getString(key);
108: } catch (MissingResourceException mre) {
109: //bad: shouldn't mask an exception the following way:
110: // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]";
111: // because it hides the fact that the String was missing
112: // from the calling code.
113: //good: could just throw the exception (or wrap it in another)
114: // but that would probably cause much havoc on existing
115: // code.
116: //better: consistent with container pattern to
117: // simply return null. Calling code can then do
118: // a null check.
119: str = null;
120: }
121:
122: return str;
123: }
124:
125: /**
126: * Get a string from the underlying resource bundle and format
127: * it with the given set of arguments.
128: *
129: * @param key
130: * @param args
131: */
132:
133: public String getString(String key, Object[] args) {
134: String iString = null;
135: String value = getString(key);
136:
137: // this check for the runtime exception is some pre 1.1.6
138: // VM's don't do an automatic toString() on the passed in
139: // objects and barf out
140:
141: try {
142: // ensure the arguments are not null so pre 1.2 VM's don't barf
143: if (args == null) {
144: args = new Object[1];
145: }
146:
147: Object[] nonNullArgs = args;
148: for (int i = 0; i < args.length; i++) {
149: if (args[i] == null) {
150: if (nonNullArgs == args) {
151: nonNullArgs = (Object[]) args.clone();
152: }
153: nonNullArgs[i] = "null";
154: }
155: }
156: if (value == null)
157: value = key;
158: MessageFormat mf = new MessageFormat(value);
159: mf.setLocale(locale);
160: iString = mf.format(nonNullArgs, new StringBuffer(), null)
161: .toString();
162: } catch (IllegalArgumentException iae) {
163: StringBuffer buf = new StringBuffer();
164: buf.append(value);
165: for (int i = 0; i < args.length; i++) {
166: buf.append(" arg[" + i + "]=" + args[i]);
167: }
168: iString = buf.toString();
169: }
170: return iString;
171: }
172:
173: /**
174: * Get a string from the underlying resource bundle and format it
175: * with the given object argument. This argument can of course be
176: * a String object.
177: *
178: * @param key
179: * @param arg
180: */
181:
182: public String getString(String key, Object arg) {
183: Object[] args = new Object[] { arg };
184: return getString(key, args);
185: }
186:
187: /**
188: * Get a string from the underlying resource bundle and format it
189: * with the given object arguments. These arguments can of course
190: * be String objects.
191: *
192: * @param key
193: * @param arg1
194: * @param arg2
195: */
196:
197: public String getString(String key, Object arg1, Object arg2) {
198: Object[] args = new Object[] { arg1, arg2 };
199: return getString(key, args);
200: }
201:
202: /**
203: * Get a string from the underlying resource bundle and format it
204: * with the given object arguments. These arguments can of course
205: * be String objects.
206: *
207: * @param key
208: * @param arg1
209: * @param arg2
210: * @param arg3
211: */
212:
213: public String getString(String key, Object arg1, Object arg2,
214: Object arg3) {
215: Object[] args = new Object[] { arg1, arg2, arg3 };
216: return getString(key, args);
217: }
218:
219: /**
220: * Get a string from the underlying resource bundle and format it
221: * with the given object arguments. These arguments can of course
222: * be String objects.
223: *
224: * @param key
225: * @param arg1
226: * @param arg2
227: * @param arg3
228: * @param arg4
229: */
230:
231: public String getString(String key, Object arg1, Object arg2,
232: Object arg3, Object arg4) {
233: Object[] args = new Object[] { arg1, arg2, arg3, arg4 };
234: return getString(key, args);
235: }
236:
237: // --------------------------------------------------------------
238: // STATIC SUPPORT METHODS
239: // --------------------------------------------------------------
240:
241: private static Hashtable managers = new Hashtable();
242:
243: /**
244: * Get the StringManager for a particular package. If a manager for
245: * a package already exists, it will be reused, else a new
246: * StringManager will be created and returned.
247: *
248: * @param packageName The package name
249: */
250: public synchronized static StringManager getManager(
251: String packageName) {
252: StringManager mgr = (StringManager) managers.get(packageName);
253: if (mgr == null) {
254: mgr = new StringManager(packageName);
255: managers.put(packageName, mgr);
256: }
257: return mgr;
258: }
259:
260: /**
261: * Get the StringManager for a particular package. If a manager for
262: * a package already exists, it will be reused, else a new
263: * StringManager will be created and returned.
264: *
265: * @param bundle The resource bundle
266: */
267: public synchronized static StringManager getManager(
268: ResourceBundle bundle) {
269: return new StringManager(bundle);
270: }
271:
272: /**
273: * Get the StringManager for a particular package and Locale. If a manager for
274: * a package already exists, it will be reused, else a new
275: * StringManager will be created for that Locale and returned.
276: *
277: * @param packageName The package name
278: * @param loc The locale
279: */
280:
281: public synchronized static StringManager getManager(
282: String packageName, Locale loc) {
283: StringManager mgr = (StringManager) managers.get(packageName
284: + "_" + loc.toString());
285: if (mgr == null) {
286: mgr = new StringManager(packageName, loc);
287: managers.put(packageName + "_" + loc.toString(), mgr);
288: }
289: return mgr;
290: }
291:
292: }
|