/** * Copyright (C) 2012 cogroo <cogroo@cogroo.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.cogroo.exceptions; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; public class InternationalizedException extends Exception { private static final long serialVersionUID = 1218000142275850583L; private String resourceBundleName; private String messageKey; private Object[] arguments; private Throwable cause; public InternationalizedException() { this(null, null, null, null); } public InternationalizedException(Throwable aCause) { this(null, null, null, aCause); } public InternationalizedException(String aResourceBundleName, String aMessageKey, Object[] aArguments) { this(aResourceBundleName, aMessageKey, aArguments, null); } public InternationalizedException(String aResourceBundleName, String aMessageKey, Object[] aArguments, Throwable aCause) { super(); cause = aCause; resourceBundleName = aResourceBundleName; messageKey = aMessageKey; arguments = aArguments; // if null message and mCause is Internationalized exception, "promote" // message if (resourceBundleName == null && messageKey == null) { if (cause instanceof InternationalizedException) { resourceBundleName = ((InternationalizedException) cause) .getResourceBundleName(); messageKey = ((InternationalizedException) cause).getMessageKey(); arguments = ((InternationalizedException) cause).getArguments(); } else if (cause instanceof InternationalizedRuntimeException) { resourceBundleName = ((InternationalizedRuntimeException) cause) .getResourceBundleName(); messageKey = ((InternationalizedRuntimeException) cause) .getMessageKey(); arguments = ((InternationalizedRuntimeException) cause).getArguments(); } } } public String getResourceBundleName() { return resourceBundleName; } public String getMessageKey() { return messageKey; } public Object[] getArguments() { if (arguments == null) return new Object[0]; Object[] result = new Object[arguments.length]; System.arraycopy(arguments, 0, result, 0, arguments.length); return result; } public String getMessage() { return getLocalizedMessage(Locale.ENGLISH); } public String getLocalizedMessage() { return getLocalizedMessage(Locale.getDefault()); } public String getLocalizedMessage(Locale aLocale) { // check for null message if (getMessageKey() == null) return null; try { // locate the resource bundle for this exception's messages // turn over the classloader of the current object explicitly, so that the // message resolving also works for derived exception classes ResourceBundle bundle = ResourceBundle.getBundle(getResourceBundleName(), aLocale, this.getClass().getClassLoader()); // retrieve the message from the resource bundle String message = bundle.getString(getMessageKey()); // if arguments exist, use MessageFormat to include them if (getArguments().length > 0) { MessageFormat fmt = new MessageFormat(message); fmt.setLocale(aLocale); return fmt.format(getArguments()); } else return message; } catch (Exception e) { return "EXCEPTION MESSAGE LOCALIZATION FAILED: " + e.toString(); } } public Throwable getCause() { return cause; } public boolean hasMessageKey(String messageKey) { if (messageKey.equals(this.getMessageKey())) { return true; } Throwable cause = getCause(); if (cause != null && cause instanceof InternationalizedException) { return ((InternationalizedException) cause).hasMessageKey(messageKey); } return false; } public synchronized Throwable initCause(Throwable aCause) { cause = aCause; return this; } }