KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > serializer > utils > Messages


1 /*
2  * Copyright 2004 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  * $Id: Messages.java,v 1.1.4.1 2005/09/08 11:03:10 suresh_emailid Exp $
18  */

19 package com.sun.org.apache.xml.internal.serializer.utils;
20
21 import java.util.ListResourceBundle JavaDoc;
22 import java.util.Locale JavaDoc;
23 import java.util.MissingResourceException JavaDoc;
24 import java.util.ResourceBundle JavaDoc;
25
26 /**
27  * A utility class for issuing error messages.
28  *
29  * A user of this class normally would create a singleton
30  * instance of this class, passing the name
31  * of the message class on the constructor. For example:
32  * <CODE>
33  * static Messages x = new Messages("org.package.MyMessages");
34  * </CODE>
35  * Later the message is typically generated this way if there are no
36  * substitution arguments:
37  * <CODE>
38  * String msg = x.createMessage(org.package.MyMessages.KEY_ONE, null);
39  * </CODE>
40  * If there are arguments substitutions then something like this:
41  * <CODE>
42  * String filename = ...;
43  * String directory = ...;
44  * String msg = x.createMessage(org.package.MyMessages.KEY_TWO,
45  * new Object[] {filename, directory) );
46  * </CODE>
47  *
48  * The constructor of an instance of this class must be given
49  * the class name of a class that extends java.util.ListResourceBundle
50  * ("org.package.MyMessages" in the example above).
51  * The name should not have any language suffix
52  * which will be added automatically by this utility class.
53  *
54  * The message class ("org.package.MyMessages")
55  * must define the abstract method getContents() that is
56  * declared in its base class, for example:
57  * <CODE>
58  * public Object[][] getContents() {return contents;}
59  * </CODE>
60  *
61  * It is suggested that the message class expose its
62  * message keys like this:
63  * <CODE>
64  * public static final String KEY_ONE = "KEY1";
65  * public static final String KEY_TWO = "KEY2";
66  * . . .
67  * </CODE>
68  * and used through their names (KEY_ONE ...) rather than
69  * their values ("KEY1" ...).
70  *
71  * The field contents (returned by getContents()
72  * should be initialized something like this:
73  * <CODE>
74  * public static final Object[][] contents = {
75  * { KEY_ONE, "Something has gone wrong!" },
76  * { KEY_TWO, "The file ''{0}'' does not exist in directory ''{1}''." },
77  * . . .
78  * { KEY_N, "Message N" } }
79  * </CODE>
80  *
81  * Where that section of code with the KEY to Message mappings
82  * (where the message classes 'contents' field is initialized)
83  * can have the Message strings translated in an alternate language
84  * in a errorResourceClass with a language suffix.
85  *
86  * More sophisticated use of this class would be to pass null
87  * when contructing it, but then call loadResourceBundle()
88  * before creating any messages.
89  *
90  * This class is not a public API, it is only public because it is
91  * used in com.sun.org.apache.xml.internal.serializer.
92  *
93  * @xsl.usage internal
94  */

95 public final class Messages
96 {
97     /** The local object to use. */
98     private final Locale JavaDoc m_locale = Locale.getDefault();
99
100     /** The language specific resource object for messages. */
101     private ListResourceBundle JavaDoc m_resourceBundle;
102
103     /** The class name of the error message string table with no language suffix. */
104     private String JavaDoc m_resourceBundleName;
105
106
107
108     /**
109      * Constructor.
110      * @param resourceBundle the class name of the ListResourceBundle
111      * that the instance of this class is associated with and will use when
112      * creating messages.
113      * The class name is without a language suffix. If the value passed
114      * is null then loadResourceBundle(errorResourceClass) needs to be called
115      * explicitly before any messages are created.
116      *
117      * @xsl.usage internal
118      */

119     Messages(String JavaDoc resourceBundle)
120     {
121
122         m_resourceBundleName = resourceBundle;
123     }
124     
125     /*
126      * Set the Locale object to use. If this method is not called the
127      * default locale is used. This method needs to be called before
128      * loadResourceBundle().
129      *
130      * @param locale non-null reference to Locale object.
131      * @xsl.usage internal
132      */

133 // public void setLocale(Locale locale)
134
// {
135
// m_locale = locale;
136
// }
137

138     /**
139      * Get the Locale object that is being used.
140      *
141      * @return non-null reference to Locale object.
142      * @xsl.usage internal
143      */

144     private Locale JavaDoc getLocale()
145     {
146         return m_locale;
147     }
148
149     /**
150      * Get the ListResourceBundle being used by this Messages instance which was
151      * previously set by a call to loadResourceBundle(className)
152      * @xsl.usage internal
153      */

154     private ListResourceBundle JavaDoc getResourceBundle()
155     {
156         return m_resourceBundle;
157     }
158
159     /**
160      * Creates a message from the specified key and replacement
161      * arguments, localized to the given locale.
162      *
163      * @param msgKey The key for the message text.
164      * @param args The arguments to be used as replacement text
165      * in the message created.
166      *
167      * @return The formatted message string.
168      * @xsl.usage internal
169      */

170     public final String JavaDoc createMessage(String JavaDoc msgKey, Object JavaDoc args[])
171     {
172         if (m_resourceBundle == null)
173             m_resourceBundle = loadResourceBundle(m_resourceBundleName);
174
175         if (m_resourceBundle != null)
176         {
177             return createMsg(m_resourceBundle, msgKey, args);
178         }
179         else
180             return "Could not load the resource bundles: "+ m_resourceBundleName;
181     }
182
183     /**
184      * Creates a message from the specified key and replacement
185      * arguments, localized to the given locale.
186      *
187      * @param errorCode The key for the message text.
188      *
189      * @param fResourceBundle The resource bundle to use.
190      * @param msgKey The message key to use.
191      * @param args The arguments to be used as replacement text
192      * in the message created.
193      *
194      * @return The formatted message string.
195      * @xsl.usage internal
196      */

197     private final String JavaDoc createMsg(
198         ListResourceBundle JavaDoc fResourceBundle,
199         String JavaDoc msgKey,
200         Object JavaDoc args[]) //throws Exception
201
{
202
203         String JavaDoc fmsg = null;
204         boolean throwex = false;
205         String JavaDoc msg = null;
206
207         if (msgKey != null)
208             msg = fResourceBundle.getString(msgKey);
209         else
210             msgKey = "";
211
212         if (msg == null)
213         {
214             throwex = true;
215             /* The message is not in the bundle . . . this is bad,
216              * so try to get the message that the message is not in the bundle
217              */

218             try
219             {
220
221                 msg =
222                     java.text.MessageFormat.format(
223                         MsgKey.BAD_MSGKEY,
224                         new Object JavaDoc[] { msgKey, m_resourceBundleName });
225             }
226             catch (Exception JavaDoc e)
227             {
228                 /* even the message that the message is not in the bundle is
229                  * not there ... this is really bad
230                  */

231                 msg =
232                     "The message key '"
233                         + msgKey
234                         + "' is not in the message class '"
235                         + m_resourceBundleName+"'";
236             }
237         }
238         else if (args != null)
239         {
240             try
241             {
242                 // Do this to keep format from crying.
243
// This is better than making a bunch of conditional
244
// code all over the place.
245
int n = args.length;
246
247                 for (int i = 0; i < n; i++)
248                 {
249                     if (null == args[i])
250                         args[i] = "";
251                 }
252
253                 fmsg = java.text.MessageFormat.format(msg, args);
254                 // if we get past the line above we have create the message ... hurray!
255
}
256             catch (Exception JavaDoc e)
257             {
258                 throwex = true;
259                 try
260                 {
261                     // Get the message that the format failed.
262
fmsg =
263                         java.text.MessageFormat.format(
264                             MsgKey.BAD_MSGFORMAT,
265                             new Object JavaDoc[] { msgKey, m_resourceBundleName });
266                     fmsg += " " + msg;
267                 }
268                 catch (Exception JavaDoc formatfailed)
269                 {
270                     // We couldn't even get the message that the format of
271
// the message failed ... so fall back to English.
272
fmsg =
273                         "The format of message '"
274                             + msgKey
275                             + "' in message class '"
276                             + m_resourceBundleName
277                             + "' failed.";
278                 }
279             }
280         }
281         else
282             fmsg = msg;
283
284         if (throwex)
285         {
286             throw new RuntimeException JavaDoc(fmsg);
287         }
288
289         return fmsg;
290     }
291
292     /**
293      * Return a named ResourceBundle for a particular locale. This method mimics the behavior
294      * of ResourceBundle.getBundle().
295      *
296      * @param className the name of the class that implements ListResourceBundle,
297      * without language suffix.
298      * @return the ResourceBundle
299      * @throws MissingResourceException
300      * @xsl.usage internal
301      */

302     private ListResourceBundle JavaDoc loadResourceBundle(String JavaDoc resourceBundle)
303         throws MissingResourceException JavaDoc
304     {
305         m_resourceBundleName = resourceBundle;
306         Locale JavaDoc locale = getLocale();
307
308         ListResourceBundle JavaDoc lrb;
309
310         try
311         {
312
313             ResourceBundle JavaDoc rb =
314                 ResourceBundle.getBundle(m_resourceBundleName, locale);
315             lrb = (ListResourceBundle JavaDoc) rb;
316         }
317         catch (MissingResourceException JavaDoc e)
318         {
319             try // try to fall back to en_US if we can't load
320
{
321
322                 // Since we can't find the localized property file,
323
// fall back to en_US.
324
lrb =
325                     (ListResourceBundle JavaDoc) ResourceBundle.getBundle(
326                         m_resourceBundleName,
327                         new Locale JavaDoc("en", "US"));
328             }
329             catch (MissingResourceException JavaDoc e2)
330             {
331
332                 // Now we are really in trouble.
333
// very bad, definitely very bad...not going to get very far
334
throw new MissingResourceException JavaDoc(
335                     "Could not load any resource bundles." + m_resourceBundleName,
336                     m_resourceBundleName,
337                     "");
338             }
339         }
340         m_resourceBundle = lrb;
341         return lrb;
342     }
343
344     /**
345      * Return the resource file suffic for the indicated locale
346      * For most locales, this will be based the language code. However
347      * for Chinese, we do distinguish between Taiwan and PRC
348      *
349      * @param locale the locale
350      * @return an String suffix which can be appended to a resource name
351      * @xsl.usage internal
352      */

353     private static String JavaDoc getResourceSuffix(Locale JavaDoc locale)
354     {
355
356         String JavaDoc suffix = "_" + locale.getLanguage();
357         String JavaDoc country = locale.getCountry();
358
359         if (country.equals("TW"))
360             suffix += "_" + country;
361
362         return suffix;
363     }
364 }
365
Popular Tags