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 }