KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > util > MessageResources


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

18
19 package org.apache.struts.util;
20
21 import java.io.Serializable JavaDoc;
22 import java.text.MessageFormat JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Locale JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * General purpose abstract class that describes an API for retrieving
31  * Locale-sensitive messages from underlying resource locations of an
32  * unspecified design, and optionally utilizing the <code>MessageFormat</code>
33  * class to produce internationalized messages with parametric replacement.
34  * <p>
35  * Calls to <code>getMessage()</code> variants without a <code>Locale</code>
36  * argument are presumed to be requesting a message string in the default
37  * <code>Locale</code> for this JVM.
38  * <p>
39  * Calls to <code>getMessage()</code> with an unknown key, or an unknown
40  * <code>Locale</code> will return <code>null</code> if the
41  * <code>returnNull</code> property is set to <code>true</code>. Otherwise,
42  * a suitable error message will be returned instead.
43  * <p>
44  * <strong>IMPLEMENTATION NOTE</strong> - Classes that extend this class
45  * must be Serializable so that instances may be used in distributable
46  * application server environments.
47  *
48  * @version $Rev: 54929 $ $Date: 2004-10-16 17:38:42 +0100 (Sat, 16 Oct 2004) $
49  */

50 public abstract class MessageResources implements Serializable JavaDoc {
51
52     // ------------------------------------------------------------- Properties
53

54     /**
55      * Commons Logging instance.
56      */

57     protected static Log log = LogFactory.getLog(MessageResources.class);
58
59     /**
60      * The configuration parameter used to initialize this MessageResources.
61      */

62     protected String JavaDoc config = null;
63
64     /**
65      * The configuration parameter used to initialize this MessageResources.
66      * @return parameter used to initialize this MessageResources
67      */

68     public String JavaDoc getConfig() {
69         return (this.config);
70     }
71
72     /**
73      * The default Locale for our environment.
74      */

75     protected Locale JavaDoc defaultLocale = Locale.getDefault();
76
77     /**
78      * The <code>MessageResourcesFactory</code> that created this instance.
79      */

80     protected MessageResourcesFactory factory = null;
81
82     /**
83      * The <code>MessageResourcesFactory</code> that created this instance.
84      * @return <code>MessageResourcesFactory</code> that created instance
85      */

86     public MessageResourcesFactory getFactory() {
87         return (this.factory);
88     }
89
90     /**
91      * The set of previously created MessageFormat objects, keyed by the
92      * key computed in <code>messageKey()</code>.
93      */

94     protected HashMap JavaDoc formats = new HashMap JavaDoc();
95
96     /**
97      * Indicate is a <code>null</code> is returned instead of an error message string
98      * when an unknown Locale or key is requested.
99      */

100     protected boolean returnNull = false;
101
102     /**
103      * Indicates that a <code>null</code> is returned instead of an error message string
104      * if an unknown Locale or key is requested.
105      * @return true if null is returned if unknown key or locale is requested
106      */

107     public boolean getReturnNull() {
108         return (this.returnNull);
109     }
110
111     /**
112      * Indicates that a <code>null</code> is returned instead of an error message string
113      * if an unknown Locale or key is requested.
114      * @param returnNull true Indicates that a <code>null</code> is returned
115      * if an unknown Locale or key is requested.
116      */

117     public void setReturnNull(boolean returnNull) {
118         this.returnNull = returnNull;
119     }
120
121     // ----------------------------------------------------------- Constructors
122

123     /**
124      * Construct a new MessageResources according to the specified parameters.
125      *
126      * @param factory The MessageResourcesFactory that created us
127      * @param config The configuration parameter for this MessageResources
128      */

129     public MessageResources(MessageResourcesFactory factory, String JavaDoc config) {
130
131         this(factory, config, false);
132
133     }
134
135     /**
136      * Construct a new MessageResources according to the specified parameters.
137      *
138      * @param factory The MessageResourcesFactory that created us
139      * @param config The configuration parameter for this MessageResources
140      * @param returnNull The returnNull property we should initialize with
141      */

142     public MessageResources(
143         MessageResourcesFactory factory,
144         String JavaDoc config,
145         boolean returnNull) {
146
147         super();
148         this.factory = factory;
149         this.config = config;
150         this.returnNull = returnNull;
151
152     }
153
154     // --------------------------------------------------------- Public Methods
155

156     /**
157      * Returns a text message for the specified key, for the default Locale.
158      *
159      * @param key The message key to look up
160      */

161     public String JavaDoc getMessage(String JavaDoc key) {
162
163         return this.getMessage((Locale JavaDoc) null, key, null);
164
165     }
166
167     /**
168      * Returns a text message after parametric replacement of the specified
169      * parameter placeholders.
170      *
171      * @param key The message key to look up
172      * @param args An array of replacement parameters for placeholders
173      */

174     public String JavaDoc getMessage(String JavaDoc key, Object JavaDoc args[]) {
175
176         return this.getMessage((Locale JavaDoc) null, key, args);
177
178     }
179
180     /**
181      * Returns a text message after parametric replacement of the specified
182      * parameter placeholders.
183      *
184      * @param key The message key to look up
185      * @param arg0 The replacement for placeholder {0} in the message
186      */

187     public String JavaDoc getMessage(String JavaDoc key, Object JavaDoc arg0) {
188
189         return this.getMessage((Locale JavaDoc) null, key, arg0);
190
191     }
192
193     /**
194      * Returns a text message after parametric replacement of the specified
195      * parameter placeholders.
196      *
197      * @param key The message key to look up
198      * @param arg0 The replacement for placeholder {0} in the message
199      * @param arg1 The replacement for placeholder {1} in the message
200      */

201     public String JavaDoc getMessage(String JavaDoc key, Object JavaDoc arg0, Object JavaDoc arg1) {
202
203         return this.getMessage((Locale JavaDoc) null, key, arg0, arg1);
204
205     }
206
207     /**
208      * Returns a text message after parametric replacement of the specified
209      * parameter placeholders.
210      *
211      * @param key The message key to look up
212      * @param arg0 The replacement for placeholder {0} in the message
213      * @param arg1 The replacement for placeholder {1} in the message
214      * @param arg2 The replacement for placeholder {2} in the message
215      */

216     public String JavaDoc getMessage(String JavaDoc key, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2) {
217
218         return this.getMessage((Locale JavaDoc) null, key, arg0, arg1, arg2);
219
220     }
221
222     /**
223      * Returns a text message after parametric replacement of the specified
224      * parameter placeholders.
225      *
226      * @param key The message key to look up
227      * @param arg0 The replacement for placeholder {0} in the message
228      * @param arg1 The replacement for placeholder {1} in the message
229      * @param arg2 The replacement for placeholder {2} in the message
230      * @param arg3 The replacement for placeholder {3} in the message
231      */

232     public String JavaDoc getMessage(
233         String JavaDoc key,
234         Object JavaDoc arg0,
235         Object JavaDoc arg1,
236         Object JavaDoc arg2,
237         Object JavaDoc arg3) {
238
239         return this.getMessage((Locale JavaDoc) null, key, arg0, arg1, arg2, arg3);
240
241     }
242
243     /**
244      * Returns a text message for the specified key, for the default Locale.
245      * A null string result will be returned by this method if no relevant
246      * message resource is found for this key or Locale, if the
247      * <code>returnNull</code> property is set. Otherwise, an appropriate
248      * error message will be returned.
249      * <p>
250      * This method must be implemented by a concrete subclass.
251      *
252      * @param locale The requested message Locale, or <code>null</code>
253      * for the system default Locale
254      * @param key The message key to look up
255      */

256     public abstract String JavaDoc getMessage(Locale JavaDoc locale, String JavaDoc key);
257
258     /**
259      * Returns a text message after parametric replacement of the specified
260      * parameter placeholders. A null string result will be returned by
261      * this method if no resource bundle has been configured.
262      *
263      * @param locale The requested message Locale, or <code>null</code>
264      * for the system default Locale
265      * @param key The message key to look up
266      * @param args An array of replacement parameters for placeholders
267      */

268     public String JavaDoc getMessage(Locale JavaDoc locale, String JavaDoc key, Object JavaDoc args[]) {
269
270         // Cache MessageFormat instances as they are accessed
271
if (locale == null) {
272             locale = defaultLocale;
273         }
274
275         MessageFormat JavaDoc format = null;
276         String JavaDoc formatKey = messageKey(locale, key);
277
278         synchronized (formats) {
279             format = (MessageFormat JavaDoc) formats.get(formatKey);
280             if (format == null) {
281                 String JavaDoc formatString = getMessage(locale, key);
282
283                 if (formatString == null) {
284                     return returnNull ? null : ("???" + formatKey + "???");
285                 }
286
287                 format = new MessageFormat JavaDoc(escape(formatString));
288                 format.setLocale(locale);
289                 formats.put(formatKey, format);
290             }
291
292         }
293
294         return format.format(args);
295     }
296
297     /**
298      * Returns a text message after parametric replacement of the specified
299      * parameter placeholders. A null string result will never be returned
300      * by this method.
301      *
302      * @param locale The requested message Locale, or <code>null</code>
303      * for the system default Locale
304      * @param key The message key to look up
305      * @param arg0 The replacement for placeholder {0} in the message
306      */

307     public String JavaDoc getMessage(Locale JavaDoc locale, String JavaDoc key, Object JavaDoc arg0) {
308         return this.getMessage(locale, key, new Object JavaDoc[] { arg0 });
309     }
310
311     /**
312      * Returns a text message after parametric replacement of the specified
313      * parameter placeholders. A null string result will never be returned
314      * by this method.
315      *
316      * @param locale The requested message Locale, or <code>null</code>
317      * for the system default Locale
318      * @param key The message key to look up
319      * @param arg0 The replacement for placeholder {0} in the message
320      * @param arg1 The replacement for placeholder {1} in the message
321      */

322     public String JavaDoc getMessage(Locale JavaDoc locale, String JavaDoc key, Object JavaDoc arg0, Object JavaDoc arg1) {
323         return this.getMessage(locale, key, new Object JavaDoc[] { arg0, arg1 });
324     }
325
326     /**
327      * Returns a text message after parametric replacement of the specified
328      * parameter placeholders. A null string result will never be returned
329      * by this method.
330      *
331      * @param locale The requested message Locale, or <code>null</code>
332      * for the system default Locale
333      * @param key The message key to look up
334      * @param arg0 The replacement for placeholder {0} in the message
335      * @param arg1 The replacement for placeholder {1} in the message
336      * @param arg2 The replacement for placeholder {2} in the message
337      */

338     public String JavaDoc getMessage(
339         Locale JavaDoc locale,
340         String JavaDoc key,
341         Object JavaDoc arg0,
342         Object JavaDoc arg1,
343         Object JavaDoc arg2) {
344
345         return this.getMessage(locale, key, new Object JavaDoc[] { arg0, arg1, arg2 });
346     }
347
348     /**
349      * Returns a text message after parametric replacement of the specified
350      * parameter placeholders. A null string result will never be returned
351      * by this method.
352      *
353      * @param locale The requested message Locale, or <code>null</code>
354      * for the system default Locale
355      * @param key The message key to look up
356      * @param arg0 The replacement for placeholder {0} in the message
357      * @param arg1 The replacement for placeholder {1} in the message
358      * @param arg2 The replacement for placeholder {2} in the message
359      * @param arg3 The replacement for placeholder {3} in the message
360      */

361     public String JavaDoc getMessage(
362         Locale JavaDoc locale,
363         String JavaDoc key,
364         Object JavaDoc arg0,
365         Object JavaDoc arg1,
366         Object JavaDoc arg2,
367         Object JavaDoc arg3) {
368
369         return this.getMessage(locale, key, new Object JavaDoc[] { arg0, arg1, arg2, arg3 });
370     }
371
372     /**
373      * Return <code>true</code> if there is a defined message for the specified
374      * key in the system default locale.
375      *
376      * @param key The message key to look up
377      */

378     public boolean isPresent(String JavaDoc key) {
379
380         return this.isPresent(null, key);
381
382     }
383
384     /**
385      * Return <code>true</code> if there is a defined message for the specified
386      * key in the specified Locale.
387      *
388      * @param locale The requested message Locale, or <code>null</code>
389      * for the system default Locale
390      * @param key The message key to look up
391      */

392     public boolean isPresent(Locale JavaDoc locale, String JavaDoc key) {
393
394         String JavaDoc message = getMessage(locale, key);
395
396         if (message == null) {
397             return false;
398
399         } else if (message.startsWith("???") && message.endsWith("???")) {
400             return false; // FIXME - Only valid for default implementation
401

402         } else {
403             return true;
404         }
405
406     }
407
408     // ------------------------------------------------------ Protected Methods
409

410     /**
411      * Escape any single quote characters that are included in the specified
412      * message string.
413      *
414      * @param string The string to be escaped
415      */

416     protected String JavaDoc escape(String JavaDoc string) {
417
418         if ((string == null) || (string.indexOf('\'') < 0)) {
419             return string;
420         }
421
422         int n = string.length();
423         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(n);
424
425         for (int i = 0; i < n; i++) {
426             char ch = string.charAt(i);
427
428             if (ch == '\'') {
429                 sb.append('\'');
430             }
431
432             sb.append(ch);
433         }
434
435         return sb.toString();
436
437     }
438
439     /**
440      * Compute and return a key to be used in caching information by a Locale.
441      * <strong>NOTE</strong> - The locale key for the default Locale in our
442      * environment is a zero length String.
443      *
444      * @param locale The locale for which a key is desired
445      */

446     protected String JavaDoc localeKey(Locale JavaDoc locale) {
447         return (locale == null) ? "" : locale.toString();
448     }
449
450     /**
451      * Compute and return a key to be used in caching information
452      * by Locale and message key.
453      *
454      * @param locale The Locale for which this format key is calculated
455      * @param key The message key for which this format key is calculated
456      */

457     protected String JavaDoc messageKey(Locale JavaDoc locale, String JavaDoc key) {
458
459         return (localeKey(locale) + "." + key);
460
461     }
462
463     /**
464      * Compute and return a key to be used in caching information
465      * by locale key and message key.
466      *
467      * @param localeKey The locale key for which this cache key is calculated
468      * @param key The message key for which this cache key is calculated
469      */

470     protected String JavaDoc messageKey(String JavaDoc localeKey, String JavaDoc key) {
471
472         return (localeKey + "." + key);
473
474     }
475
476     // --------------------------------------------------------- Static Methods
477

478     /**
479      * The default MessageResourcesFactory used to create MessageResources
480      * instances.
481      */

482     protected static MessageResourcesFactory defaultFactory = null;
483
484     /**
485      * Create and return an instance of <code>MessageResources</code> for the
486      * created by the default <code>MessageResourcesFactory</code>.
487      *
488      * @param config Configuration parameter for this message bundle.
489      */

490     public synchronized static MessageResources getMessageResources(String JavaDoc config) {
491
492         if (defaultFactory == null) {
493             defaultFactory = MessageResourcesFactory.createFactory();
494         }
495
496         return defaultFactory.createResources(config);
497     }
498
499     /**
500      * Log a message to the Writer that has been configured for our use.
501      *
502      * @param message The message to be logged
503      */

504     public void log(String JavaDoc message) {
505         log.debug(message);
506     }
507
508     /**
509      * Log a message and exception to the Writer that has been configured
510      * for our use.
511      *
512      * @param message The message to be logged
513      * @param throwable The exception to be logged
514      */

515     public void log(String JavaDoc message, Throwable JavaDoc throwable) {
516         log.debug(message, throwable);
517     }
518
519 }
520
Popular Tags