io.microsphere.util.PropertyResourceBundleControl Maven / Gradle / Ivy
The newest version!
/**
*
*/
package io.microsphere.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static io.microsphere.io.IOUtils.close;
/**
* {@link PropertyResourceBundle} {@link ResourceBundle.Control} Implementation which supports encoding {@link
* Properties} files
*
* @author Mercy
* @version 1.0.0
* @see PropertyResourceBundle
* @see ResourceBundle.Control
* @since 1.0.0
*/
public class PropertyResourceBundleControl extends ResourceBundle.Control {
private static final ConcurrentMap encodingControlMap = new ConcurrentHashMap();
static {
addEncodingControlMap(newControl(SystemUtils.FILE_ENCODING));
addEncodingControlMap(newControl("UTF-8"));
}
private final String encoding;
protected PropertyResourceBundleControl(final String encoding) {
this.encoding = encoding;
}
protected PropertyResourceBundleControl() {
this(SystemUtils.FILE_ENCODING);
}
private static final void addEncodingControlMap(ResourceBundle.Control control) {
PropertyResourceBundleControl control_ = (PropertyResourceBundleControl) control;
encodingControlMap.putIfAbsent(control_.getEncoding(), control_);
}
/**
* Gets an existed instance of {@link PropertyResourceBundleControl}.
*
* @param encoding
* @return an existed instance of {@link PropertyResourceBundleControl}.
* @version 1.0.0
* @since 1.0.0
*/
private static final ResourceBundle.Control getControl(final String encoding) {
return encodingControlMap.get(encoding);
}
/**
* Creates a new instance of {@link PropertyResourceBundleControl} if absent.
*
* @param encoding Encoding
* @return Control
* @throws UnsupportedCharsetException If encoding
is not supported
* @version 1.0.0
* @since 1.0.0
*/
public static final ResourceBundle.Control newControl(final String encoding) throws UnsupportedCharsetException {
// check encoding
Charset.forName(encoding);
final ResourceBundle.Control existedControl = getControl(encoding);
ResourceBundle.Control control = existedControl;
if (existedControl == null) {
control = new PropertyResourceBundleControl(encoding);
encodingControlMap.put(encoding, control);
}
return control;
}
public final List getFormats(String baseName) {
if (baseName == null) {
throw new NullPointerException();
}
return FORMAT_PROPERTIES;
}
public ResourceBundle newBundle(String baseName, Locale locale, String format, final ClassLoader classLoader, final boolean reload) throws IllegalAccessException, InstantiationException, IOException {
String bundleName = super.toBundleName(baseName, locale);
final String resourceName = super.toResourceName(bundleName, "properties");
InputStream stream = null;
Reader reader = null;
ResourceBundle bundle = null;
try {
stream = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public InputStream run() throws IOException {
InputStream is = null;
if (reload) {
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 {
reader = new InputStreamReader(stream, this.getEncoding());
bundle = new PropertyResourceBundle(reader);
} finally {
close(stream);
close(reader);
}
}
return bundle;
}
/**
* Sets the encoding of properties file.
*
* @return the encoding
* @version 1.0.0
* @since 1.0.0
*/
public String getEncoding() {
return encoding;
}
}