diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/util/NLS.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/util/NLS.java index 2895530f68b..49bdc89fe1b 100644 --- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/util/NLS.java +++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/util/NLS.java @@ -13,10 +13,14 @@ *******************************************************************************/ package org.eclipse.osgi.util; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -141,18 +145,49 @@ public static String bind(String message, Object[] bindings) { * * @param baseName the base name of a fully qualified message properties file. * @param clazz the class where the constants will exist + * @param charset the charset for the given properties file */ - public static void initializeMessages(final String baseName, final Class clazz) { + public static void initializeMessages(final String baseName, final Class clazz, final Charset charset) { if (System.getSecurityManager() == null) { - load(baseName, clazz); + load(baseName, clazz, charset); return; } AccessController.doPrivileged((PrivilegedAction) () -> { - load(baseName, clazz); + load(baseName, clazz, charset); return null; }); } + /** + * Initialize the given class with the values from the message properties specified by the + * base name. The base name specifies a fully qualified base name to a message properties file, + * including the package where the message properties file is located. The class loader of the + * specified class will be used to load the message properties resources. Values from the file + * are decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}. + *

This method works as if invoking it were equivalent to evaluating the + * expression: + *

{@link + * #initializeMessages(String, Class, Charset) + * NLS.initializeMessages(path, clazz, StandardCharsets.UTF_8) + * }
+ *

+ * For example, if the locale is set to en_US and org.eclipse.example.nls.messages + * is used as the base name then the following resources will be searched using the class + * loader of the specified class: + *

+ *
+	 *   org/eclipse/example/nls/messages_en_US.properties
+	 *   org/eclipse/example/nls/messages_en.properties
+	 *   org/eclipse/example/nls/messages.properties
+	 * 
+ * + * @param baseName the base name of a fully qualified message properties file. + * @param clazz the class where the constants will exist + */ + public static void initializeMessages(final String baseName, final Class clazz) { + initializeMessages(baseName, clazz, StandardCharsets.UTF_8); + } + /* * Perform the string substitution on the given message with the specified args. * See the class comment for exact details. @@ -321,9 +356,9 @@ private static void computeMissingMessages(String bundleName, Class clazz, Ma } /* - * Load the given resource bundle using the specified class loader. + * Load the given resource bundle in the specified charset using the specified class loader. */ - static void load(final String bundleName, Class clazz) { + static void load(final String bundleName, Class clazz, Charset charset) { long start = System.currentTimeMillis(); final Field[] fieldArray = clazz.getDeclaredFields(); ClassLoader loader = clazz.getClassLoader(); @@ -347,7 +382,12 @@ static void load(final String bundleName, Class clazz) { continue; try { final MessagesProperties properties = new MessagesProperties(fields, bundleName, isAccessible); - properties.load(input); + if (charset == StandardCharsets.ISO_8859_1) { + // preserves legacy behavior while also serving as a fast-path + properties.load(input); + } else { + properties.load(new BufferedReader(new InputStreamReader(input, charset))); + } } catch (IOException e) { log(SEVERITY_ERROR, "Error loading " + variant, e); //$NON-NLS-1$ } finally {