Skip to content

Commit

Permalink
Added UTF-8 support for Lang files. Fixes PHBD-21
Browse files Browse the repository at this point in the history
  • Loading branch information
meiskam committed May 26, 2013
1 parent 38b30d9 commit 4ebbec3
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/main/java/org/shininet/bukkit/playerheads/Lang.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static void init(Plugin instance) {
public static void reload() {
String locale = "";
try {
RESOURCE_BUNDLE0 = ResourceBundle.getBundle(BUNDLE_NAME);
RESOURCE_BUNDLE0 = ResourceBundle.getBundle(BUNDLE_NAME, new UTF8Control());
locale = RESOURCE_BUNDLE0.getLocale().toString();
if (!(locale.equals(""))) {
locale = "_".concat(locale);
Expand All @@ -143,14 +143,14 @@ public static void reload() {

try {
URL[] urls = { plugin.getDataFolder().toURI().toURL() };
RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), new URLClassLoader(urls));
RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), new URLClassLoader(urls), new UTF8Control());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (MissingResourceException e) {
plugin.saveResource(BUNDLE_NAME.concat(locale).replace('.', '/').concat(".properties"), false);
try {
URL[] urls = { plugin.getDataFolder().toURI().toURL() };
RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), new URLClassLoader(urls));
RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), new URLClassLoader(urls), new UTF8Control());
} catch (Exception e2) {
e2.printStackTrace();
}
Expand Down
123 changes: 123 additions & 0 deletions src/main/java/org/shininet/bukkit/playerheads/UTF8Control.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package org.shininet.bukkit.playerheads;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;

public class UTF8Control extends Control { // Copied from jdk1.6.0_38
/**
* Instantiates a resource bundle for the given bundle name of the given format and locale, using the given class loader if necessary. This method returns <code>null</code> if there is no resource bundle available for the given parameters. If a resource bundle can't be instantiated due to an unexpected error, the error must be reported by throwing an <code>Error</code> or <code>Exception</code> rather than simply returning <code>null</code>.
*
* <p>
* If the <code>reload</code> flag is <code>true</code>, it indicates that this method is being called because the previously loaded resource bundle has expired.
*
* <p>
* The default implementation instantiates a <code>ResourceBundle</code> as follows.
*
* <ul>
*
* <li>The bundle name is obtained by calling {@link #toBundleName(String, Locale) toBundleName(baseName, locale)}.</li>
*
* <li>If <code>format</code> is <code>"java.class"</code>, the {@link Class} specified by the bundle name is loaded by calling {@link ClassLoader#loadClass(String)}. Then, a <code>ResourceBundle</code> is instantiated by calling {@link Class#newInstance()}. Note that the <code>reload</code> flag is ignored for loading class-based resource bundles in this default implementation.</li>
*
* <li>If <code>format</code> is <code>"java.properties"</code>, {@link #toResourceName(String, String) toResourceName(bundlename, "properties")} is called to get the resource name. If <code>reload</code> is <code>true</code>, {@link ClassLoader#getResource(String) load.getResource} is called to get a {@link URL} for creating a {@link URLConnection}. This <code>URLConnection</code> is used to {@linkplain URLConnection#setUseCaches(boolean) disable the caches} of the underlying resource loading layers,
* and to {@linkplain URLConnection#getInputStream() get an <code>InputStream</code>}. Otherwise, {@link ClassLoader#getResourceAsStream(String) loader.getResourceAsStream} is called to get an {@link InputStream}. Then, a {@link PropertyResourceBundle} is constructed with the <code>InputStream</code>.</li>
*
* <li>If <code>format</code> is neither <code>"java.class"</code> nor <code>"java.properties"</code>, an <code>IllegalArgumentException</code> is thrown.</li>
*
* </ul>
*
* @param baseName
* the base bundle name of the resource bundle, a fully qualified class name
* @param locale
* the locale for which the resource bundle should be instantiated
* @param format
* the resource bundle format to be loaded
* @param loader
* the <code>ClassLoader</code> to use to load the bundle
* @param reload
* the flag to indicate bundle reloading; <code>true</code> if reloading an expired resource bundle, <code>false</code> otherwise
* @return the resource bundle instance, or <code>null</code> if none could be found.
* @exception NullPointerException
* if <code>bundleName</code>, <code>locale</code>, <code>format</code>, or <code>loader</code> is <code>null</code>, or if <code>null</code> is returned by {@link #toBundleName(String, Locale) toBundleName}
* @exception IllegalArgumentException
* if <code>format</code> is unknown, or if the resource found for the given parameters contains malformed data.
* @exception ClassCastException
* if the loaded class cannot be cast to <code>ResourceBundle</code>
* @exception IllegalAccessException
* if the class or its nullary constructor is not accessible.
* @exception InstantiationException
* if the instantiation of a class fails for some other reason.
* @exception ExceptionInInitializerError
* if the initialization provoked by this method fails.
* @exception SecurityException
* If a security manager is present and creation of new instances is denied. See {@link Class#newInstance()} for details.
* @exception IOException
* if an error occurred when reading resources using any I/O operations
*/
@SuppressWarnings("unchecked")
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
ResourceBundle bundle = null;
if (format.equals("java.class")) {
try {
Class<? extends ResourceBundle> bundleClass = (Class<? extends ResourceBundle>) loader.loadClass(bundleName);

// If the class isn't a ResourceBundle subclass, throw a ClassCastException.
if (ResourceBundle.class.isAssignableFrom(bundleClass)) {
bundle = bundleClass.newInstance();
} else {
throw new ClassCastException(bundleClass.getName() + " cannot be cast to ResourceBundle");
}
} catch (ClassNotFoundException e) {
}
} else if (format.equals("java.properties")) {
final String resourceName = toResourceName(bundleName, "properties");
final ClassLoader classLoader = loader;
final boolean reloadFlag = reload;
InputStream stream = null;
try {
stream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
public InputStream run() throws IOException {
InputStream is = null;
if (reloadFlag) {
URL url = classLoader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
// Disable caches to get fresh data for reloading.
connection.setUseCaches(false);
is = connection.getInputStream();
}
}
} else {
is = classLoader.getResourceAsStream(resourceName);
}
return is;
}
});
} catch (PrivilegedActionException e) {
throw (IOException) e.getException();
}
if (stream != null) {
try {
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8")); // Edited to add UTF-8
} finally {
stream.close();
}
}
} else {
throw new IllegalArgumentException("unknown format: " + format);
}
return bundle;
}
}
2 changes: 1 addition & 1 deletion src/main/resources/lang.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
BEHEAD_GENERIC=%1% was beheaded
BEHEAD_GENERIC=%1% was beheaded
BEHEAD_OTHER=%1% was beheaded by %2%
BEHEAD_SELF=%1% beheaded themselves
BRACKET_LEFT=[
Expand Down

0 comments on commit 4ebbec3

Please sign in to comment.