[UIMA-5961] resolve resource-bundles for default locales for internationalized exceptions at the time of the creation of the exception.
git-svn-id: https://svn.apache.org/repos/asf/uima/uimaj/trunk@1862398 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/uimaj-core/src/main/java/org/apache/uima/InternationalizedException.java b/uimaj-core/src/main/java/org/apache/uima/InternationalizedException.java
index ac32aed..b8e5711 100644
--- a/uimaj-core/src/main/java/org/apache/uima/InternationalizedException.java
+++ b/uimaj-core/src/main/java/org/apache/uima/InternationalizedException.java
@@ -20,6 +20,7 @@
package org.apache.uima;
import java.util.Locale;
+import java.util.ResourceBundle;
import org.apache.uima.internal.util.I18nUtil;
@@ -75,6 +76,14 @@
* Deserialized versions have null as their value, which is handled by the users
*/
final transient private ClassLoader originalContextClassLoader;
+
+ // see https://issues.apache.org/jira/browse/UIMA-5961
+ // the resourceBundle associated with the default locale, at the time of creation of this instance
+ final transient private ResourceBundle default_localized_resourceBundle;
+ // the default locale, at the time of creation of this instance
+ final transient private Locale default_locale;
+ // a user specified resource bundle, used when the default_locale is not appropriate
+ transient private ResourceBundle user_specified_resourceBundle = null;
/**
* Creates a new <code>InternationalizedException</code> with a null
@@ -135,6 +144,15 @@
Object[] aArguments, Throwable aCause) {
super();
originalContextClassLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ I18nUtil.setTccl(originalContextClassLoader);
+ default_locale = Locale.getDefault();
+ default_localized_resourceBundle = (aMessageKey == null)
+ ? null
+ : I18nUtil.resolveResourceBundle(aResourceBundleName, default_locale, null);
+ } finally {
+ I18nUtil.removeTccl();
+ }
mCause = aCause;
mResourceBundleName = aResourceBundleName;
mMessageKey = aMessageKey;
@@ -221,8 +239,18 @@
*/
public String getLocalizedMessage(Locale aLocale) {
// check for null message
- if (getMessageKey() == null)
+ if (getMessageKey() == null) {
return null;
+ }
+
+ if (default_localized_resourceBundle != null && aLocale == default_locale) {
+ return I18nUtil.localizeMessage(default_localized_resourceBundle, aLocale, getMessageKey(), getArguments());
+ }
+
+ if (user_specified_resourceBundle != null) {
+ return I18nUtil.localizeMessage(user_specified_resourceBundle, aLocale, getMessageKey(), getArguments());
+ }
+
try {
I18nUtil.setTccl(originalContextClassLoader);
return I18nUtil.localizeMessage(getResourceBundleName(), aLocale, getMessageKey(), getArguments());
@@ -249,7 +277,7 @@
// return "EXCEPTION MESSAGE LOCALIZATION FAILED: " + e.toString();
// }
}
-
+
/**
* Gets the cause of this Exception.
*
@@ -284,4 +312,23 @@
return this;
}
+ /**
+ * For the case where the default locale is not being used for getting messages,
+ * and the lookup path in the classpath for the resource bundle needs to be set
+ * at a specific point, call this method to set the resource bundle at that point in the call stack.
+ *
+ * Example: If in a Pear, and you are throwing an exception, which is defined in a bundle
+ * in the Pear context, but the catcher of the throw is up the stack above where the pear context
+ * exists (and therefore, is no longer present at "catch" time), and
+ * you don't want to use the default-locale for getting the message out of the message bundle,
+ *
+ * then do something like this
+ * Exception e = new AnalysisEngineProcessException(MESSAGE_BUNDLE, "TEST_KEY", objects);
+ * e.setResourceBundle(my_locale); // call this method, pass in the needed locale object
+ * throw e; // or whatever should be done with it
+ * @param aLocale the locale to use when getting the message from the message bundle at a later time
+ */
+ public void setResourceBundle(Locale aLocale) {
+ user_specified_resourceBundle = I18nUtil.resolveResourceBundle(mResourceBundleName, aLocale, null);
+ }
}
diff --git a/uimaj-core/src/main/java/org/apache/uima/internal/util/I18nUtil.java b/uimaj-core/src/main/java/org/apache/uima/internal/util/I18nUtil.java
index 8b5cc23..fbb4d5a 100644
--- a/uimaj-core/src/main/java/org/apache/uima/internal/util/I18nUtil.java
+++ b/uimaj-core/src/main/java/org/apache/uima/internal/util/I18nUtil.java
@@ -26,6 +26,8 @@
/**
* Internationaliation utilities.
*
+ * Static methods only
+ *
*/
public class I18nUtil {
/**
@@ -109,11 +111,38 @@
public static String localizeMessage(String aResourceBundleName, Locale aLocale,
String aMessageKey, Object[] aArguments, ClassLoader aLoader) {
try {
- if (aLoader == null) {
- aLoader = MsgLocalizationClassLoader.getMsgLocalizationClassLoader();
- }
- // locate the resource bundle for this exception's messages
- ResourceBundle bundle = ResourceBundle.getBundle(aResourceBundleName, aLocale, aLoader);
+ ResourceBundle bundle = resolveResourceBundle(aResourceBundleName, aLocale, aLoader);
+ return localizeMessage(bundle, aLocale, aMessageKey, aArguments);
+ } catch (Exception e) {
+ return "MESSAGE LOCALIZATION FAILED: " + e.getMessage();
+ }
+ }
+
+ public static ResourceBundle resolveResourceBundle(String aResourceBundleName, Locale aLocale, ClassLoader aLoader) {
+ if (aLoader == null) {
+ aLoader = MsgLocalizationClassLoader.getMsgLocalizationClassLoader();
+ }
+ // locate the resource bundle for this exception's messages
+ return ResourceBundle.getBundle(aResourceBundleName, aLocale, aLoader);
+ }
+
+ /**
+ * Localize a message to a specified Locale.
+ *
+ * @param aResourceBundle
+ * the resource bundle to use to resolve message keys
+ * @param aLocale
+ * locale to which to localize
+ * @param aMessageKey
+ * key of message to localize
+ * @param aArguments
+ * arguments to message (may be null if none)
+ *
+ * @return localized message. If an exception occurs, returns "MESSAGE LOCALIZATION FAILED:"
+ * followed by the exception message.
+ */
+ public static String localizeMessage(ResourceBundle bundle, Locale aLocale, String aMessageKey, Object[] aArguments) {
+ try {
String message = bundle.getString(aMessageKey);
// if arguments exist, use MessageFormat to include them
if (aArguments != null && aArguments.length > 0) {
@@ -124,7 +153,7 @@
return message;
} catch (Exception e) {
return "MESSAGE LOCALIZATION FAILED: " + e.getMessage();
- }
+ }
}
public static void setTccl(ClassLoader tccl) {