KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > jdo > spi > I18NHelper


1 /*
2  * Copyright 2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package javax.jdo.spi;
18
19 import java.util.*;
20 import java.text.MessageFormat JavaDoc;
21 import java.security.AccessController JavaDoc;
22 import java.security.PrivilegedAction JavaDoc;
23
24 import javax.jdo.JDOFatalInternalException;
25
26 /** Helper class for constructing messages from bundles. The intended usage
27  * of this class is to construct a new instance bound to a bundle, as in
28  * <P>
29  * <code>I18NHelper msg = I18NHelper.getInstance("javax.jdo.Bundle");</code>
30  * <P>
31  * This call uses the class loader that loaded the I18NHelper class to find
32  * the specified Bundle. The class provides two overloaded getInstance
33  * methods allowing to specify a different class loader:
34  * {@link #getInstance(Class cls)} looks for a bundle
35  * called "Bundle.properties" located in the package of the specified class
36  * object and {@link #getInstance(String bundleName,ClassLoader loader)}
37  * uses the specified class loader to find the bundle.
38  * <P>
39  * Subsequently, instance methods can be used to format message strings
40  * using the text from the bundle, as in
41  * <P>
42  * <code>throw new JDOFatalInternalException (msg.msg("ERR_NoMetadata", cls.getName()));</code>
43  * @since 1.0.1
44  * @version 1.1
45  */

46 public class I18NHelper {
47
48     /** Bundles that have already been loaded
49      */

50     private static Hashtable bundles = new Hashtable();
51     
52     /** Helper instances that have already been created
53      */

54     private static Hashtable helpers = new Hashtable();
55     
56     /** The default locale for this VM.
57      */

58     private static Locale locale = Locale.getDefault();
59
60     /** The name of the bundle used by this instance of the helper.
61      */

62     private final String JavaDoc bundleName;
63
64     /** The bundle used by this instance of the helper.
65      */

66     private ResourceBundle bundle = null;
67
68     /** Throwable if ResourceBundle couldn't be loaded
69      */

70     private Throwable JavaDoc failure = null;
71
72     /** The unqualified standard name of a bundle. */
73     private static final String JavaDoc bundleSuffix = ".Bundle"; // NOI18N
74

75     /** Constructor */
76     private I18NHelper() {
77         this.bundleName = null;
78     }
79
80     /** Constructor for an instance bound to a bundle.
81      * @param bundleName the name of the resource bundle
82      * @param loader the class loader from which to load the resource
83      * bundle
84      */

85     private I18NHelper (String JavaDoc bundleName, ClassLoader JavaDoc loader) {
86         this.bundleName = bundleName;
87         try {
88             bundle = loadBundle (bundleName, loader);
89         }
90         catch (Throwable JavaDoc e) {
91             failure = e;
92         }
93     }
94     
95     /** An instance bound to a bundle. This method uses the current class
96      * loader to find the bundle.
97      * @param bundleName the name of the bundle
98      * @return the helper instance bound to the bundle
99      */

100     public static I18NHelper getInstance (String JavaDoc bundleName) {
101         return getInstance (bundleName, I18NHelper.class.getClassLoader());
102     }
103
104     /** An instance bound to a bundle. This method figures out the bundle name
105      * for the class object's package and uses the class' class loader to
106      * find the bundle. Note, the specified class object must not be
107      * <code>null</code>.
108      * @param cls the class object from which to load the resource bundle
109      * @return the helper instance bound to the bundle
110      */

111     public static I18NHelper getInstance (final Class JavaDoc cls) {
112         ClassLoader JavaDoc classLoader = (ClassLoader JavaDoc) AccessController.doPrivileged (
113             new PrivilegedAction JavaDoc () {
114                 public Object JavaDoc run () {
115                     return cls.getClassLoader();
116                 }
117             }
118             );
119         String JavaDoc bundle = getPackageName (cls.getName()) + bundleSuffix;
120         return getInstance (bundle, classLoader);
121     }
122
123     /** An instance bound to a bundle. This method uses the specified class
124      * loader to find the bundle. Note, the specified class loader must not
125      * be <code>null</code>.
126      * @param bundleName the name of the bundle
127      * @param loader the class loader from which to load the resource
128      * bundle
129      * @return the helper instance bound to the bundle
130      */

131     public static I18NHelper getInstance (String JavaDoc bundleName,
132                                           ClassLoader JavaDoc loader) {
133         I18NHelper helper = (I18NHelper) helpers.get (bundleName);
134         if (helper != null) {
135             return helper;
136         }
137         helper = new I18NHelper(bundleName, loader);
138         helpers.put (bundleName, helper);
139         // if two threads simultaneously create the same helper, return the first
140
// one to be put into the Hashtable. The other will be garbage collected.
141
return (I18NHelper) helpers.get (bundleName);
142     }
143
144     /** Message formatter
145      * @param messageKey the message key
146      * @return the resolved message text
147      */

148     public String JavaDoc msg (String JavaDoc messageKey) {
149         assertBundle (messageKey);
150         return getMessage (bundle, messageKey);
151     }
152
153     /** Message formatter
154      * @param messageKey the message key
155      * @param arg1 the first argument
156      * @return the resolved message text
157      */

158     public String JavaDoc msg (String JavaDoc messageKey, Object JavaDoc arg1) {
159         assertBundle (messageKey);
160         return getMessage (bundle, messageKey, arg1);
161     }
162
163     /** Message formatter
164      * @param messageKey the message key
165      * @param arg1 the first argument
166      * @param arg2 the second argument
167      * @return the resolved message text
168      */

169     public String JavaDoc msg (String JavaDoc messageKey, Object JavaDoc arg1, Object JavaDoc arg2) {
170         assertBundle (messageKey);
171         return getMessage (bundle, messageKey, arg1, arg2);
172     }
173
174     /** Message formatter
175      * @param messageKey the message key
176      * @param arg1 the first argument
177      * @param arg2 the second argument
178      * @param arg3 the third argument
179      * @return the resolved message text
180      */

181     public String JavaDoc msg (String JavaDoc messageKey, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3) {
182         assertBundle (messageKey);
183         return getMessage (bundle, messageKey, arg1, arg2, arg3);
184     }
185
186     /** Message formatter
187      * @param messageKey the message key
188      * @param args the array of arguments
189      * @return the resolved message text
190      */

191     public String JavaDoc msg (String JavaDoc messageKey, Object JavaDoc[] args) {
192         assertBundle (messageKey);
193         return getMessage (bundle, messageKey, args);
194     }
195
196     /** Message formatter
197      * @param messageKey the message key
198      * @param arg the argument
199      * @return the resolved message text
200      */

201     public String JavaDoc msg (String JavaDoc messageKey, int arg) {
202         assertBundle (messageKey);
203         return getMessage(bundle, messageKey, arg);
204     }
205     
206     /** Message formatter
207      * @param messageKey the message key
208      * @param arg the argument
209      * @return the resolved message text
210      */

211     public String JavaDoc msg (String JavaDoc messageKey, boolean arg) {
212         assertBundle (messageKey);
213         return getMessage(bundle, messageKey, arg);
214     }
215     
216     /** Returns the resource bundle used by this I18NHelper.
217      * @return the associated resource bundle
218      * @since 1.1
219      */

220     public ResourceBundle getResourceBundle () {
221         assertBundle ();
222         return bundle;
223     }
224     
225     //========= Internal helper methods ==========
226

227     /**
228      * Load ResourceBundle by bundle name
229      * @param bundleName the name of the bundle
230      * @param loader the class loader from which to load the resource bundle
231      * @return the ResourceBundle
232      */

233     final private static ResourceBundle loadBundle(
234         String JavaDoc bundleName, ClassLoader JavaDoc loader) {
235         ResourceBundle messages = (ResourceBundle)bundles.get(bundleName);
236
237         if (messages == null) //not found as loaded - add
238
{
239             messages = ResourceBundle.getBundle(bundleName, locale, loader);
240             bundles.put(bundleName, messages);
241         }
242         return messages;
243     }
244
245     /** Assert resources available
246      * @since 1.1
247      * @throws JDOFatalInternalException if the resource bundle could not
248      * be loaded during construction.
249      */

250     private void assertBundle () {
251         if (failure != null)
252             throw new JDOFatalInternalException (
253                 "No resources could be found for bundle:\"" +
254                 bundle + "\" ", failure);
255     }
256     
257     /** Assert resources available
258      * @param key the message key
259      * @since 1.0.2
260      * @throws JDOFatalInternalException if the resource bundle could not
261      * be loaded during construction.
262      */

263     private void assertBundle (String JavaDoc key) {
264         if (failure != null)
265             throw new JDOFatalInternalException (
266                 "No resources could be found to annotate error message key:\"" +
267                 key + "\"", failure);
268     }
269
270     /**
271      * Returns message as <code>String</code>
272      * @param messages the resource bundle
273      * @param messageKey the message key
274      * @return the resolved message text
275      */

276     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey)
277     {
278         return messages.getString(messageKey);
279     }
280
281     /**
282      * Formats message by adding array of arguments
283      * @param messages the resource bundle
284      * @param messageKey the message key
285      * @param msgArgs an array of arguments to substitute into the message
286      * @return the resolved message text
287      */

288     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, Object JavaDoc msgArgs[])
289     {
290         for (int i=0; i<msgArgs.length; i++) {
291             if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N
292
}
293         MessageFormat JavaDoc formatter = new MessageFormat JavaDoc(messages.getString(messageKey));
294         return formatter.format(msgArgs);
295     }
296     
297     /**
298      * Formats message by adding an <code>Object</code> argument.
299      * @param messages the resource bundle
300      * @param messageKey the message key
301      * @param arg the argument
302      * @return the resolved message text
303      */

304     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, Object JavaDoc arg)
305     {
306         Object JavaDoc []args = {arg};
307         return getMessage(messages, messageKey, args);
308     }
309     
310     /**
311      * Formats message by adding two <code>Object</code> arguments.
312      * @param messages the resource bundle
313      * @param messageKey the message key
314      * @param arg1 the first argument
315      * @param arg2 the second argument
316      * @return the resolved message text
317      */

318     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, Object JavaDoc arg1,
319                                    Object JavaDoc arg2)
320     {
321         Object JavaDoc []args = {arg1, arg2};
322         return getMessage(messages, messageKey, args);
323     }
324     
325     /**
326      * Formats message by adding three <code>Object</code> arguments.
327      * @param messages the resource bundle
328      * @param messageKey the message key
329      * @param arg1 the first argument
330      * @param arg2 the second argument
331      * @param arg3 the third argument
332      * @return the resolved message text
333      */

334     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, Object JavaDoc arg1,
335                                    Object JavaDoc arg2, Object JavaDoc arg3)
336     {
337         Object JavaDoc []args = {arg1, arg2, arg3};
338         return getMessage(messages, messageKey, args);
339     }
340
341     /**
342      * Formats message by adding an <code>int</code> as an argument.
343      * @param messages the resource bundle
344      * @param messageKey the message key
345      * @param arg the argument
346      * @return the resolved message text
347      */

348     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, int arg)
349     {
350         Object JavaDoc []args = {new Integer JavaDoc(arg)};
351         return getMessage(messages, messageKey, args);
352     }
353     
354     /**
355      * Formats message by adding a <code>boolean</code> as an argument.
356      * @param messages the resource bundle
357      * @param messageKey the message key
358      * @param arg the argument
359      * @return the resolved message text
360      */

361     final private static String JavaDoc getMessage(ResourceBundle messages, String JavaDoc messageKey, boolean arg)
362     {
363         Object JavaDoc []args = {String.valueOf(arg)};
364         return getMessage(messages, messageKey, args);
365     }
366
367     /**
368      * Returns the package portion of the specified class.
369      * @param className the name of the class from which to extract the
370      * package
371      * @return package portion of the specified class
372      */

373     final private static String JavaDoc getPackageName(final String JavaDoc className)
374     {
375         final int index = className.lastIndexOf('.');
376         return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
377
}
378 }
379
Popular Tags