1 /* 2 * Copyright 2007-2011 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.exceptions.i18n; 17 18 import java.util.Locale; 19 20 import org.apache.commons.lang.StringUtils; 21 22 import de.smartics.exceptions.AbstractCoreRuntimeException; 23 import de.smartics.exceptions.core.Code; 24 import de.smartics.exceptions.i18n.message.LocalizedInfo; 25 import de.smartics.exceptions.i18n.message.MessageType; 26 27 /** 28 * The base implementation of exceptions that support Internationalization for 29 * unchecked exceptions. 30 * 31 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 32 * @version $Revision$ 33 */ 34 public abstract class AbstractLocalizedRuntimeException extends 35 AbstractCoreRuntimeException implements LocalizedException 36 { 37 // ********************************* Fields ********************************* 38 39 // --- constants ------------------------------------------------------------ 40 41 /** 42 * The class version identifier. 43 */ 44 private static final long serialVersionUID = 1L; 45 46 // ... resource key ......................................................... 47 48 // --- members -------------------------------------------------------------- 49 50 /** 51 * The localized information controls the localization information. 52 * 53 * @serial 54 */ 55 protected final LocalizedInfo localizedInfo; 56 57 // ****************************** Initializer ******************************* 58 59 // ****************************** Constructors ****************************** 60 61 /** 62 * Constructor. 63 * 64 * @param code the error or exception code of the exception. 65 * @see #AbstractLocalizedRuntimeException(Throwable,Code) 66 */ 67 protected AbstractLocalizedRuntimeException(final Code code) 68 { 69 this(null, code); 70 } 71 72 /** 73 * Constructor. 74 * 75 * @param code the error or exception code of the exception. 76 * @param bundleBaseName the fully qualified name of the bundle to use. 77 * @see #AbstractLocalizedRuntimeException(Throwable,Code,String) 78 */ 79 protected AbstractLocalizedRuntimeException(final Code code, 80 final String bundleBaseName) 81 { 82 this(null, code, bundleBaseName); 83 } 84 85 /** 86 * Constructor. 87 * 88 * @param cause the cause (which is saved for later retrieval by the 89 * {@link #getCause()} method). (A <tt>null</tt> value is permitted, 90 * and indicates that the cause is nonexistent or unknown.) 91 * @param code the error or exception code of the exception. 92 * @see #AbstractLocalizedRuntimeException(Throwable,Code,String) 93 */ 94 protected AbstractLocalizedRuntimeException(final Throwable cause, 95 final Code code) 96 { 97 this(cause, code, null); 98 } 99 100 /** 101 * Constructor. 102 * 103 * @param cause the cause (which is saved for later retrieval by the 104 * {@link #getCause()} method). (A <tt>null</tt> value is permitted, 105 * and indicates that the cause is nonexistent or unknown.) 106 * @param code the error or exception code of the exception. 107 * @param bundleBaseName the fully qualified name of the bundle to use. 108 * @see #AbstractLocalizedRuntimeException(Throwable,Code,String,String) 109 */ 110 protected AbstractLocalizedRuntimeException(final Throwable cause, 111 final Code code, final String bundleBaseName) 112 { 113 this(cause, code, bundleBaseName, null); 114 } 115 116 /** 117 * Constructor. 118 * 119 * @param cause the cause (which is saved for later retrieval by the 120 * {@link #getCause()} method). (A <tt>null</tt> value is permitted, 121 * and indicates that the cause is nonexistent or unknown.) 122 * @param code the error or exception code of the exception. 123 * @param bundleBaseName the fully qualified name of the bundle to use. 124 * @param resourceKey the localization key to fetch messages from message 125 * bundles. 126 * @see AbstractCoreRuntimeException#AbstractCoreRuntimeException(String, 127 * Throwable, Code) 128 */ 129 protected AbstractLocalizedRuntimeException(final Throwable cause, 130 final Code code, final String bundleBaseName, final String resourceKey) 131 { 132 super(null, cause, code); 133 this.localizedInfo = new LocalizedInfo(code, bundleBaseName, resourceKey); 134 } 135 136 // ****************************** Inner Classes ***************************** 137 138 // ********************************* Methods ******************************** 139 140 // --- init ----------------------------------------------------------------- 141 142 // --- get&set -------------------------------------------------------------- 143 144 /** 145 * Returns the localization key to fetch messages from message bundles. If 146 * this value is not set, the {@link String} representation of the 147 * {@link #getCode()} instance is used. 148 * 149 * @return the localization key to fetch messages from message bundles. 150 */ 151 public String getResourceKey() 152 { 153 return localizedInfo.getResourceKey(); 154 } 155 156 /** 157 * Returns the fully qualified base name of the bundle to use. 158 * 159 * @return the fully qualified base name of the bundle to use. 160 */ 161 public String getBundleBaseName() 162 { 163 return localizedInfo.getBundleBaseName(); 164 } 165 166 // --- business ------------------------------------------------------------- 167 168 // ... get message .......................................................... 169 170 /** 171 * Returns the message for the given message type and the system's default 172 * locale. 173 * 174 * @param messageType the type if message to return. 175 * @return the message for the given message type. 176 */ 177 public String getMessage(final MessageType messageType) 178 { 179 final Locale locale = Locale.getDefault(); 180 return getMessage(locale, messageType); 181 } 182 183 /** 184 * {@inheritDoc} 185 * <p> 186 * Returns the localized message for the default locale. 187 * 188 * @see java.lang.Throwable#getMessage() 189 */ 190 @Override 191 public String getMessage() 192 { 193 return getLocalizedMessage(); 194 } 195 196 /** 197 * Returns the message for the given message type. 198 * 199 * @param locale the locale to select the localized message. 200 * @param messageType the type if message to return. 201 * @return the message for the given message type. 202 */ 203 public String getMessage(final Locale locale, final MessageType messageType) 204 { 205 final String resourceKey = localizedInfo.getResourceKey(); 206 return getLocalizedMessage(resourceKey, locale, messageType, null); // , 207 // null 208 // ); 209 } 210 211 // ... throwable standard message 212 213 /** 214 * Returns the localized message according to the system's default locale. 215 * <p> 216 * {@inheritDoc} 217 */ 218 @Override 219 public String getLocalizedMessage() 220 { 221 return getLocalizedMessage(Locale.getDefault()); 222 } 223 224 /** 225 * Returns the localized message for the given locale. 226 * 227 * @param locale the locale for which the message is requested. 228 * @return returns the localized message of this exception. 229 */ 230 public String getLocalizedMessage(final Locale locale) 231 { 232 return getLocalizedMessage(locale, null); // , null); 233 } 234 235 /** 236 * Returns the localized message for the given locale. 237 * 238 * @param locale the locale for which the message is requested. 239 * @param loader the loader to read the message bundle. 240 * @return returns the localized message of this exception. 241 */ 242 public String getLocalizedMessage( 243 final Locale locale, 244 final ClassLoader loader) 245 { 246 final String keyPrefix = getCode().getCode(); 247 return getLocalizedMessage(keyPrefix, locale, MessageType.SUMMARY, loader); 248 } 249 250 // /** 251 // * Returns the localized message for the given locale. 252 // * 253 // * @param locale the locale for which the message is requested. 254 // * @param control the controller to load the resource bundle. 255 // * @return returns the localized message of this exception. 256 // * @todo Should we really provide these methods with class loader and 257 // control? 258 // * What is the user scenario for this? 259 // */ 260 // public String getLocalizedMessage( 261 // final Locale locale, 262 // final ResourceBundle.Control control) 263 // { 264 // return getLocalizedMessage(locale, null, control); 265 // } 266 267 // /** 268 // * Returns the localized message for the given locale. 269 // * 270 // * @param locale the locale for which the message is requested. 271 // * @param loader the loader to read the message bundle. 272 // * @param control the controller to load the resource bundle. 273 // * @return returns the localized message of this exception. 274 // */ 275 // public String getLocalizedMessage( 276 // final Locale locale, 277 // final ClassLoader loader, 278 // final ResourceBundle.Control control) 279 // { 280 // final String message = localizedInfo.getLocalizedMessage(this, locale, 281 // loader, control); 282 // return message; 283 // } 284 285 // ... fetcher for all messages 286 287 /** 288 * Returns the localized message for the given locale. 289 * 290 * @param keyPrefix the prefix of the key to load from the bundle. 291 * @param locale the locale for which the message is requested. 292 * @param messageType the type of message to localize. 293 * @param loader the loader to read the message bundle. 294 * @return returns the localized message of this exception. 295 * @todo Should we really provide these methods with class loader and control? 296 * What is the user scenario for this? 297 */ 298 public String getLocalizedMessage( 299 final String keyPrefix, 300 final Locale locale, 301 final MessageType messageType, 302 final ClassLoader loader) // , 303 // final ResourceBundle.Control control) 304 { 305 final String message = 306 localizedInfo.getLocalizedMessage(this, keyPrefix, locale, messageType, 307 loader); // , control); 308 return message; 309 } 310 311 /** 312 * {@inheritDoc} 313 * 314 * @see de.smartics.exceptions.i18n.LocalizedException#getMessages() 315 */ 316 public String getMessages() 317 { 318 return getMessages(Locale.getDefault()); 319 } 320 321 /** 322 * {@inheritDoc} 323 * 324 * @see de.smartics.exceptions.i18n.LocalizedException#getMessages(java.util.Locale) 325 */ 326 public String getMessages(final Locale locale) 327 { 328 final StringBuilder buffer = new StringBuilder(); 329 for (MessageType type : MessageType.values()) 330 { 331 buffer.append(type.name()).append('=').append(getMessage(locale, type)) 332 .append(' '); 333 } 334 return StringUtils.chop(buffer.toString()); 335 } 336 337 // --- object basics -------------------------------------------------------- 338 339 }