View Javadoc

1   /*
2    *
3    * ====================================================================
4    *
5    * Copyright 2004 The Apache Software Foundation 
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   *
19   */
20  package org.apache.commons.i18n;
21  
22  import java.text.MessageFormat;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.Map;
28  import java.util.ResourceBundle;
29  
30  /***
31   * The <code>MessageManager</code> provides methods for retrieving localized
32   * messages and adding custom message providers. 
33   * This class should not be called directly for other purposes than registering a custom
34   * {@link MessageProvider} or retrieving information about available
35   * message entries.
36   * <p>
37   * To access localized messages a subclass of the {@link LocalizedBundle} class
38   * such as <code>LocalizedText </code> should be used:
39   * 
40   * <pre>
41   * LocalizedText welcome = new LocalizedText(&quot;welcome&quot;); 
42   * // Get the german translacion of the retrieved welcome text 
43   * System.out.println(welcome.getText(Locale.GERMAN));       
44   * </pre>
45   * 
46   * <p>
47   * You can call {@link MessageManager#getText(String,String,Object[],Locale) getText} directly,
48   * but if you do so, you have to ensure that the given entry key really
49   * exists and to deal with the {@link MessageNotFound} exception that will 
50   * be thrown if you try to access a not existing entry.</p>
51   * 
52   * @author Daniel Florey
53   * 
54   */
55  public class MessageManager {
56      static final String INTERNAL_MESSAGE_NOT_FOUND = "Internal I18n error: Message not found";
57      
58      static final String MESSAGE_NOT_FOUND = "messageNotFound";
59      static final String NO_MESSAGE_ENTRIES_FOUND = "noMessageEntriesFound";
60      static final String MESSAGE_ENTRY_NOT_FOUND = "messageEntryNotFound";
61      static final String RESOURCE_BUNDLE_NOT_FOUND = "resourceBundleNotFound";
62      public static final String MESSAGE_PARSING_ERROR = "messageParsingError";
63  
64      public static final ResourceBundle INTERNAL_MESSAGES = ResourceBundle.getBundle("messages", Locale.getDefault());
65      
66      private static List messageProviders = new ArrayList();
67  
68      static {
69          // Add default message providers
70          messageProviders.add(new XMLMessageProvider());
71          messageProviders.add(new ResourceBundleMessageProvider());
72      }
73  
74      /***
75       * Add a custom <code>{@link MessageProvider}</code> to the
76       * <code>MessageManager</code>. It will be incorporated in later calls of
77       * the {@link MessageManager#getText(String,String,Object[],Locale) getText}
78       * or {@link #getEntries(String,Locale) getEntries}methods.
79       * 
80       * @param messageProvider
81       *            The <code>MessageProvider</code> to be added.
82       */
83      public static void addMessageProvider(MessageProvider messageProvider) {
84          messageProviders.add(messageProvider);
85      }
86  
87      /***
88       * Iterates over all registered message providers in order to find the given
89       * entry in the requested message bundle.
90       * 
91       * @param id
92       *            The identifier that will be used to retrieve the message
93       *            bundle
94       * @param entry
95       *            The desired message entry
96       * @param arguments
97       *            The dynamic parts of the message that will be evaluated using
98       *            the standard java text formatting abilities.
99       * @param locale
100      *            The locale in which the message will be printed
101      * @exception MessageNotFoundException
102      *                Will be thrown if no message bundle can be found for the
103      *                given id or if the desired message entry is missing in the
104      *                retrieved bundle
105      * @return The localized text
106      */
107     public static String getText(String id, String entry, Object[] arguments,
108             Locale locale) throws MessageNotFoundException {
109         MessageNotFoundException exception = null;
110         for (Iterator i = messageProviders.iterator(); i.hasNext();) {
111             try {
112                 String text = ((MessageProvider) i.next()).getText(id, entry,
113                         locale);
114                 return MessageFormat.format(text, arguments);
115             } catch (MessageNotFoundException e) {
116                 exception = e;
117             }
118         }
119         throw exception;
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             String text = getText(id, entry, arguments, locale);
146             return MessageFormat.format(text, arguments);
147         } catch (MessageNotFoundException e) {
148             return defaultText;
149         }
150     }
151 
152     /***
153      * Returns a map containing all available message entries for the given
154      * locale. The map contains keys of type {@link String}containing the keys
155      * of the available message entries and values of type {@link String}
156      * containing the localized message entries.
157      */
158     public static Map getEntries(String id, Locale locale)
159             throws MessageNotFoundException {
160         MessageNotFoundException exception = null;
161         for (Iterator i = messageProviders.iterator(); i.hasNext();) {
162             try {
163                 Map entries = ((MessageProvider) i.next()).getEntries(id,
164                         locale);
165                 return entries;
166             } catch (MessageNotFoundException e) {
167                 exception = e;
168             }
169         }
170         throw exception;
171     }
172 }