package org.webpieces.util.file;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import java.util.function.Supplier;
public class ResourceBundleUtf8 extends Control {
/**
* Use this or have to use the nasty nativetoascii tool to convert property files. This allows one to just
* write the property file in their native language without having to then run it through some build time
* converter (which then by the way has to be converted back again...seems like a waste)
*
* @param baseName
* @param locale
* @return
*/
public static ResourceBundle load(String baseName, Locale locale) {
return ResourceBundle.getBundle(baseName, locale, new ResourceBundleUtf8());
}
//from http://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle
//but modified to use try with resource which has way better failure semantics when input stream and close both fail as
//it sends back the first exception which is way more important
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
bundle = readBundle(() -> getInputStream(connection));
}
}
} else {
bundle = readBundle(() -> loader.getResourceAsStream(resourceName));
}
return bundle;
}
private InputStream getInputStream(URLConnection connection) {
try {
return connection.getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private ResourceBundle readBundle(Supplier<InputStream> supplier) throws UnsupportedEncodingException, IOException {
try (InputStream stream = supplier.get();
Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8.name())) {
// Only this line is changed to make it to read properties files as UTF-8.
return new PropertyResourceBundle(reader);
}
}
}