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("welcome"); 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 }