View Javadoc
1   /*
2    * Copyright 2006 Assaf Arkin, Ralf Joachim
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   *
14   * $Id: Messages.java 6907 2007-03-28 21:24:52Z rjoachim $
15   */
16  package org.castor.core.util;
17  
18  import java.text.MessageFormat;
19  import java.util.Enumeration;
20  import java.util.Hashtable;
21  import java.util.Locale;
22  import java.util.MissingResourceException;
23  import java.util.ResourceBundle;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /**
29   * I18N message formatting class. A static factory for obtaining messages and formatting messages
30   * with arguments.
31   * <p>
32   * The resource file <tt>org.exolab.castor.util.resources.messages</tt> contains a list of all the
33   * messages in English. Additional resource files can be added for other languages and locales by
34   * placing them in the same package with a language/locale prefix. See the I18N documentation and
35   * use of resource bundles in the JDK docs.
36   *
37   * @author <a href="mailto:arkin AT intalio DOT com">Assaf Arkin</a>
38   * @author <a href="mailto:ralf DOT joachim AT syscon DOT eu">Ralf Joachim</a>
39   * @version $Revision: 6907 $ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
40   * @since 1.0.1
41   */
42  public final class Messages {
43    // --------------------------------------------------------------------------
44  
45    /**
46     * The <a href="http://jakarta.apache.org/commons/logging/">Jakarta Commons Logging </a> instance
47     * used for all logging.
48     */
49    private static final Log LOG = LogFactory.getLog(Messages.class);
50  
51    /**
52     * The name of the resource holding all the messages in the English language. Resources for other
53     * languages and locales use the same name with a language/locale prefix.
54     */
55    public static final String RESOURCE_NAME = "org.castor.messages";
56  
57    /** The resource bundle holds all the messages. */
58    private static ResourceBundle _messages;
59  
60    /** Once a format has been created once, it is cached here. */
61    private static Hashtable<String, MessageFormat> _formats;
62    // --------------------------------------------------------------------------
63  
64    static {
65      setDefaultLocale();
66    }
67  
68    // --------------------------------------------------------------------------
69  
70    /**
71     * Set the default locale to use for loading messages. Calling this method will reload all the
72     * messages based on the new locale name.
73     */
74    public static void setDefaultLocale() {
75      setLocale(Locale.getDefault());
76    }
77  
78    /**
79     * Set the locale to use for loading messages. Calling this method will reload all the messages
80     * based on the new locale name.
81     * 
82     * @param locale the locale for which a resource bundle is desired.
83     */
84    public static void setLocale(final Locale locale) {
85      try {
86        _messages = ResourceBundle.getBundle(RESOURCE_NAME, locale);
87      } catch (Exception except) {
88        _messages = new EmptyResourceBundle();
89        LOG.error("Failed to locate messages resource " + RESOURCE_NAME);
90      }
91      _formats = new Hashtable<>();
92    }
93  
94    /**
95     * Format the named message using a single argument and return the full message text.
96     *
97     * @param message The message name
98     * @param arg1 The first argument
99     * @return The full message text
100    */
101   public static String format(final String message, final Object arg1) {
102     return format(message, new Object[] {arg1});
103   }
104 
105   /**
106    * Format the named message using two argument and return the full message text.
107    *
108    * @param message The message name
109    * @param arg1 The first argument
110    * @param arg2 The second argument
111    * @return The full message text
112    */
113   public static String format(final String message, final Object arg1, final Object arg2) {
114     return format(message, new Object[] {arg1, arg2});
115   }
116 
117   /**
118    * Format the named message using three argument and return the full message text.
119    *
120    * @param message The message name
121    * @param arg1 The first argument
122    * @param arg2 The second argument
123    * @param arg3 The third argument
124    * @return The full message text
125    */
126   public static String format(final String message, final Object arg1, final Object arg2,
127       final Object arg3) {
128     return format(message, new Object[] {arg1, arg2, arg3});
129   }
130 
131   /**
132    * Format the named message using any number of arguments and return the full message text.
133    *
134    * @param message The message name
135    * @param args Argument list
136    * @return The full message text
137    */
138   public static String format(final String message, final Object[] args) {
139 
140     try {
141       MessageFormat mf = (MessageFormat) _formats.get(message);
142       if (mf == null) {
143         String msg;
144         try {
145           msg = _messages.getString(message);
146         } catch (MissingResourceException except) {
147           return message;
148         }
149         mf = new MessageFormat(msg);
150         _formats.put(message, mf);
151       }
152       return mf.format(args);
153     } catch (Exception except) {
154       return "An internal error occured while processing message " + message;
155     }
156   }
157 
158   /**
159    * Return the text of the named message without formatting.
160    *
161    * @param message The message name
162    * @return The full message text
163    */
164   public static String message(final String message) {
165     try {
166       return _messages.getString(message);
167     } catch (MissingResourceException except) {
168       return message;
169     }
170   }
171 
172   // --------------------------------------------------------------------------
173 
174   /**
175    * Hide default constructor of utility class.
176    */
177   private Messages() {}
178 
179   // --------------------------------------------------------------------------
180 
181   /**
182    * A empty resource bundle.
183    */
184   private static class EmptyResourceBundle extends ResourceBundle implements Enumeration<String> {
185     /**
186      * {@inheritDoc}
187      * 
188      * @see java.util.ResourceBundle#getKeys()
189      */
190     public Enumeration<String> getKeys() {
191       return this;
192     }
193 
194     /**
195      * {@inheritDoc}
196      * 
197      * @see java.util.ResourceBundle#handleGetObject(java.lang.String)
198      */
199     protected Object handleGetObject(final String name) {
200       return "[Missing message " + name + "]";
201     }
202 
203     /**
204      * {@inheritDoc}
205      * 
206      * @see java.util.Enumeration#hasMoreElements()
207      */
208     public boolean hasMoreElements() {
209       return false;
210     }
211 
212     /**
213      * {@inheritDoc}
214      * 
215      * @see java.util.Enumeration#nextElement()
216      */
217     public String nextElement() {
218       return null;
219     }
220   }
221 
222   // --------------------------------------------------------------------------
223 }