View Javadoc

1   /*
2    *
3    * ====================================================================
4    *
5    * Licensed to the Apache Software Foundation (ASF) under one or more
6    * contributor license agreements.  See the NOTICE file distributed with
7    * this work for additional information regarding copyright ownership.
8    * The ASF licenses this file to You under the Apache License, Version 2.0
9    * (the "License"); you may not use this file except in compliance with
10   * the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   *
20   */
21  package org.apache.commons.i18n;
22  
23  import java.text.MessageFormat;
24  import java.util.*;
25  
26  /**
27   * The <code>MessageManager</code> provides methods for retrieving localized
28   * messages and adding custom message providers. 
29   * This class should not be called directly for other purposes than registering a custom
30   * {@link MessageProvider} or retrieving information about available
31   * message entries.
32   * <p>
33   * To access localized messages a subclass of the {@link LocalizedBundle} class
34   * such as <code>LocalizedText </code> should be used:
35   * 
36   * <pre>
37   * LocalizedText welcome = new LocalizedText(&quot;welcome&quot;); 
38   * // Get the german translacion of the retrieved welcome text 
39   * System.out.println(welcome.getText(Locale.GERMAN));       
40   * </pre>
41   * 
42   * <p>
43   * You can call {@link MessageManager#getText(String,String,Object[],Locale) getText} directly,
44   * but if you do so, you have to ensure that the given entry key really
45   * exists and to deal with the {@link MessageNotFoundException} exception that will
46   * be thrown if you try to access a not existing entry.</p>
47   * 
48   */
49  public class MessageManager {
50  
51      private static Map messageProviders = new LinkedHashMap();
52  
53      /**
54       * Add a custom <code>{@link MessageProvider}</code> to the
55       * <code>MessageManager</code>. It will be incorporated in later calls of
56       * the {@link MessageManager#getText(String,String,Object[],Locale) getText}
57       * or {@link #getEntries(String,Locale) getEntries}methods.
58       *
59       * @param providerId Id of the provider used for uninstallation and
60       *          qualified naming.
61       * @param messageProvider
62       *            The <code>MessageProvider</code> to be added.
63       */
64      public static void addMessageProvider(String providerId, MessageProvider messageProvider) {
65          messageProviders.put(providerId, messageProvider);
66      }
67  
68      /**
69       * Remove all <code>{@link MessageProvider}</code>s from the
70       * <code>MessageManager</code>. Used for tearing down unit tests.
71       */
72      static void clearMessageProviders() {
73          messageProviders.clear();
74      }
75  
76      /**
77       * Remove custom <code>{@link MessageProvider}</code> from the
78       * <code>MessageManager</code>. Used for tearing down unit tests.
79       *
80       * @param providerId The ID of the provider to remove.
81       */
82      static void removeMessageProvider(String providerId) {
83          messageProviders.remove(providerId);
84      }
85  
86      /**
87       * Iterates over all registered message providers in order to find the given
88       * entry in the requested message bundle.
89       * 
90       * @param id
91       *            The identifier that will be used to retrieve the message
92       *            bundle
93       * @param entry
94       *            The desired message entry
95       * @param arguments
96       *            The dynamic parts of the message that will be evaluated using
97       *            the standard java text formatting abilities.
98       * @param locale
99       *            The locale in which the message will be printed
100      * @exception MessageNotFoundException
101      *                Will be thrown if no message bundle can be found for the
102      *                given id or if the desired message entry is missing in the
103      *                retrieved bundle
104      * @return The localized text
105      */
106     public static String getText(String id, String entry, Object[] arguments,
107             Locale locale) throws MessageNotFoundException {
108         if(messageProviders.isEmpty())
109             throw new MessageNotFoundException("No MessageProvider registered");
110         for (Iterator i = messageProviders.values().iterator(); i.hasNext();) {
111             String text = ((MessageProvider) i.next()).getText(id, entry,
112                     locale);
113             if(text != null)
114                 return (arguments != null && arguments.length > 0) ?
115                         MessageFormat.format(text, arguments) : text;
116         }
117         throw new MessageNotFoundException(MessageFormat.format(
118                 I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.MESSAGE_ENTRY_NOT_FOUND),
119                 new String[] { id, entry }));
120     }
121 
122     /**
123      * Iterates over all registered message providers in order to find the given
124      * entry in the requested message bundle.
125      * 
126      * @param id
127      *            The identifier that will be used to retrieve the message
128      *            bundle
129      * @param entry
130      *            The desired message entry
131      * @param arguments
132      *            The dynamic parts of the message that will be evaluated using
133      *            the standard java text formatting abilities.
134      * @param locale
135      *            The locale in which the message will be printed
136      * @param defaultText
137      *            If no message bundle or message entry could be found for the
138      *            specified parameters, the default text will be returned.
139      * @return The localized text or the default text if the message could not
140      *         be found
141      */
142     public static String getText(String id, String entry, Object[] arguments,
143             Locale locale, String defaultText) {
144         try {
145             return getText(id, entry, arguments, locale);
146         } catch (MessageNotFoundException e) {
147             return (arguments != null && arguments.length > 0) ?
148                     MessageFormat.format(defaultText, arguments) : defaultText;
149         }
150     }
151 
152     /**
153      * Tries to find the desired entry in the named message provider.
154      * @param providerId The name of the message provider (i.e. source) to use for the message
155      * @param id
156      *            The identifier that will be used to retrieve the message
157      *            bundle
158      * @param entry
159      *            The desired message entry
160      * @param arguments
161      *            The dynamic parts of the message that will be evaluated using
162      *            the standard java text formatting abilities.
163      * @param locale
164      *            The locale in which the message will be printed
165      * @exception MessageNotFoundException
166      *                Will be thrown if the requested message provider cannot be found or
167      *                no message bundle can be found for the given id or if the desired
168      *                message entry is missing in the retrieved bundle
169      * @return The localized text
170      */
171     public static String getText(String providerId, String id, String entry, Object[] arguments,
172             Locale locale) throws MessageNotFoundException {
173         MessageProvider provider = (MessageProvider) messageProviders.get(providerId);
174         if(provider == null)
175             throw new MessageNotFoundException("Provider '" + providerId + "' not installed");
176         String text = provider.getText(id, entry, locale);
177         if(text != null)
178             return (arguments != null && arguments.length > 0) ?
179                     MessageFormat.format(text, arguments) : text;
180         else
181             throw new MessageNotFoundException(MessageFormat.format(
182                     I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.MESSAGE_ENTRY_NOT_FOUND),
183                     new String[] { id, entry }));
184     }
185 
186     /**
187      * Iterates over all registered message providers in order to find the given
188      * entry in the requested message bundle.
189      *
190      * @param providerId The name of the message provider (i.e. source) to use for the message
191      * @param id
192      *            The identifier that will be used to retrieve the message
193      *            bundle
194      * @param entry
195      *            The desired message entry
196      * @param arguments
197      *            The dynamic parts of the message that will be evaluated using
198      *            the standard java text formatting abilities.
199      * @param locale
200      *            The locale in which the message will be printed
201      * @param defaultText
202      *            If no message bundle or message entry could be found for the
203      *            specified parameters, the default text will be returned.
204      * @return The localized text or the default text if the message could not
205      *         be found
206      */
207     public static String getText(String providerId, String id, String entry, Object[] arguments,
208             Locale locale, String defaultText) {
209         try {
210             return getText(providerId, id, entry, arguments, locale);
211         } catch (MessageNotFoundException e) {
212             return (arguments != null && arguments.length > 0) ?
213                     MessageFormat.format(defaultText, arguments) : defaultText;
214         }
215     }
216 
217     /**
218      * Returns a map containing all available message entries for the given
219      * locale. The map contains keys of type {@link String}containing the keys
220      * of the available message entries and values of type {@link String}
221      * containing the localized message entries.
222      */
223     public static Map getEntries(String id, Locale locale)
224             throws MessageNotFoundException {
225         if(messageProviders.isEmpty())
226             throw new MessageNotFoundException("No MessageProvider registered");
227         MessageNotFoundException exception = null;
228         for (Iterator i = messageProviders.values().iterator(); i.hasNext();) {
229             try {
230                 return ((MessageProvider) i.next()).getEntries(id, locale);
231             } catch (MessageNotFoundException e) {
232                 exception = e;
233             }
234         }
235         throw exception;
236     }
237 
238   /**
239    * Returns a map containing all available message entries for the given
240    * locale. The map contains keys of type {@link String}containing the keys
241    * of the available message entries and values of type {@link String}
242    * containing the localized message entries.
243    */
244   public static Map getEntries(String providerId, String id, Locale locale)
245           throws MessageNotFoundException {
246       MessageProvider provider = (MessageProvider) messageProviders.get(providerId);
247       if(provider == null)
248           throw new MessageNotFoundException("Provider '" + providerId + "' not installed");
249       return provider.getEntries(id, locale);
250   }
251 }