UI-Lion: Fix for reading .properties files as UTF-8, when loading ResourceBundles.
Change-Id: I73d3f08c59788fba1b42954aced05eb3a3148009
diff --git a/core/api/src/main/java/org/onosproject/ui/lion/LionUtils.java b/core/api/src/main/java/org/onosproject/ui/lion/LionUtils.java
index c14409a..1f7e51b 100644
--- a/core/api/src/main/java/org/onosproject/ui/lion/LionUtils.java
+++ b/core/api/src/main/java/org/onosproject/ui/lion/LionUtils.java
@@ -20,12 +20,22 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
import java.util.Locale;
+import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Set;
/**
* Utility methods for dealing with Localization Bundles etc.
+ * <p>
+ * Note that each of the {@link #getBundledResource} methods use a custom
+ * {@link ResourceBundle.Control} instance which reads in the input stream
+ * using UTF-8.
*/
public final class LionUtils {
@@ -137,12 +147,31 @@
* a property from the bundle, at which time a
* {@link java.util.MissingResourceException} will be thrown.
*
- * @param basename the (fully qualified) basename of the bundle properties
- * file
+ * @param basename the (fully qualified) basename of the bundle
+ * properties file
* @return the associated resource bundle
*/
public static ResourceBundle getBundledResource(String basename) {
- return ResourceBundle.getBundle(basename);
+ return ResourceBundle.getBundle(basename, new UTF8Control());
+ }
+
+ /**
+ * This method takes a fully qualified name and returns a
+ * {@link ResourceBundle} which is loaded from a properties file with
+ * that base name. The locale to use for bundle selection, and the
+ * class loader to use for the search path are also specified.
+ *
+ * @param basename the (fully qualified) basename of the bundle
+ * properties file
+ * @param locale the locale
+ * @param classLoader the class loader
+ * @return the appropriate resource bundle
+ */
+ public static ResourceBundle getBundledResource(String basename,
+ Locale locale,
+ ClassLoader classLoader) {
+ return ResourceBundle.getBundle(basename, locale, classLoader,
+ new UTF8Control());
}
/**
@@ -172,7 +201,7 @@
* @return the associated resource bundle
*/
public static ResourceBundle getBundledResource(Class<?> c) {
- return ResourceBundle.getBundle(c.getName());
+ return ResourceBundle.getBundle(c.getName(), new UTF8Control());
}
/**
@@ -209,6 +238,56 @@
int dot = className.lastIndexOf(DOT);
sb.append(className.substring(0, dot));
sb.append(DOT).append(baseName);
- return ResourceBundle.getBundle(sb.toString());
+
+ return ResourceBundle.getBundle(sb.toString(), new UTF8Control());
+ }
+
+ /*
+ * Private implementation of a Control for reading .properties files
+ * using UTF-8 (rather than the default ISO-8859-1).
+ *
+ * Ref: https://stackoverflow.com/questions/4659929/
+ * how-to-use-utf-8-in-resource-properties-with-resourcebundle
+ */
+ private static class UTF8Control extends ResourceBundle.Control {
+ private static final String PROPERTIES = "properties";
+ private static final String UTF_8 = "UTF-8";
+
+ @Override
+ public ResourceBundle newBundle(String baseName, Locale locale,
+ String format, ClassLoader loader,
+ boolean reload)
+ throws IllegalAccessException, InstantiationException, IOException {
+
+ // Copy of (some older version of) the default implementation...
+ String bundleName = toBundleName(baseName, locale);
+ String resourceName = toResourceName(bundleName, PROPERTIES);
+ ResourceBundle bundle = null;
+ InputStream stream = null;
+ if (reload) {
+ URL url = loader.getResource(resourceName);
+ if (url != null) {
+ URLConnection connection = url.openConnection();
+ if (connection != null) {
+ connection.setUseCaches(false);
+ stream = connection.getInputStream();
+ }
+ }
+ } else {
+ stream = loader.getResourceAsStream(resourceName);
+ }
+ if (stream != null) {
+ try {
+ // Only this line is changed to make it
+ // read .properties files as UTF-8:
+ bundle = new PropertyResourceBundle(
+ new InputStreamReader(stream, UTF_8)
+ );
+ } finally {
+ stream.close();
+ }
+ }
+ return bundle;
+ }
}
}
diff --git a/core/api/src/test/java/org/onosproject/ui/lion/LionUtilsTest.java b/core/api/src/test/java/org/onosproject/ui/lion/LionUtilsTest.java
index 289ec52..84f98a1 100644
--- a/core/api/src/test/java/org/onosproject/ui/lion/LionUtilsTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/lion/LionUtilsTest.java
@@ -20,7 +20,6 @@
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.onosproject.ui.AbstractUiTest;
@@ -210,21 +209,7 @@
checkLookups("Calcolatore", "Disco", "Schermo", "Tastiera");
}
- // TODO: figure out why extended character sets are not handled properly
- /* For example, the Korean test fails as follows
-
- === messagesInKorean ===
- res locale is ko
- a keyboard in this language is 'í¤ë³´ë'
-
- org.junit.ComparisonFailure: wrong computer
- Expected :컴퓨터
- Actual :ì»´í¨í°
-
- */
-
@Test
- @Ignore("Not chinese friendly, yet...")
public void messagesInZhTw() {
title("messagesInZhTW");
Locale.setDefault(Locale.TRADITIONAL_CHINESE);
@@ -232,7 +217,6 @@
}
@Test
- @Ignore("Not korean friendly, yet...")
public void messagesInKorean() {
title("messagesInKorean");
Locale.setDefault(Locale.KOREA);
@@ -240,7 +224,6 @@
}
@Test
- @Ignore("Not chinese friendly, yet...")
public void messagesInZhCN() {
title("messagesInZhCN");
Locale.setDefault(Locale.SIMPLIFIED_CHINESE);
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/lion/BundleStitcher.java b/web/gui/src/main/java/org/onosproject/ui/impl/lion/BundleStitcher.java
index b6671b8..f2fa27e 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/lion/BundleStitcher.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/lion/BundleStitcher.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableList;
import org.onosproject.ui.lion.LionBundle;
+import org.onosproject.ui.lion.LionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -103,7 +104,7 @@
// for this to work under Karaf, apparently...
Locale locale = Locale.getDefault();
ClassLoader classLoader = getClass().getClassLoader();
- bundle = ResourceBundle.getBundle(fqbn, locale, classLoader);
+ bundle = LionUtils.getBundledResource(fqbn, locale, classLoader);
} catch (MissingResourceException e) {
log.warn("Cannot find resource bundle: {}", fqbn);