All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.analogweb.util.PropertyResourceBundleMessageResource Maven / Gradle / Ivy

The newest version!
package org.analogweb.util;

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

/**
 * @author snowgoose
 */
public class PropertyResourceBundleMessageResource implements MessageResource {

    protected static final String DEFAULT_CHARSET = "UTF-8";
    private final String baseName;
    private final ClassLoader bundleClassLoader;
    private final String charsetName;

    public PropertyResourceBundleMessageResource(String baseName) {
        this(baseName, DEFAULT_CHARSET);
    }

    public PropertyResourceBundleMessageResource(String baseName, String bundleCharsetName) {
        this(baseName, bundleCharsetName, Thread.currentThread().getContextClassLoader());
    }

    public PropertyResourceBundleMessageResource(String baseName, ClassLoader classLoader) {
        this(baseName, DEFAULT_CHARSET, classLoader);
    }

    public PropertyResourceBundleMessageResource(String baseName, String bundleCharserName, ClassLoader classLoader) {
        this.baseName = baseName;
        this.charsetName = bundleCharserName;
        this.bundleClassLoader = classLoader;
    }

    @Override
    public String getMessage(String code) {
        return getMessage(code, Locale.getDefault());
    }

    @Override
    public String getMessage(String code, Object... args) {
        return getMessage(code, Locale.getDefault(), args);
    }

    @Override
    public String getMessage(String code, Locale locale) {
        return getMessage(code, locale, new Object[0]);
    }

    private final Map formatterCache = Maps.newConcurrentHashMap();
    private final Map bundleCache = Maps.newConcurrentHashMap();

    @Override
    public String getMessage(String code, Locale locale, Object... args) {
        if (!bundleCache.containsKey(locale)) {
            bundleCache.put(locale, getBundle(baseName, locale, getControl()));
        }
        ResourceBundle bundle = bundleCache.get(locale);
        if (bundle.containsKey(code) == false) {
            return code;
        }
        if (ArrayUtils.isEmpty(args)) {
            return bundle.getString(code);
        } else {
            String message = bundle.getString(code);
            MessageFormatKey key = MessageFormatKey.create(message, locale);
            if (!formatterCache.containsKey(key)) {
                formatterCache.put(key, new MessageFormat(message, locale));
            }
            MessageFormat formatter = formatterCache.get(key);
            synchronized (formatter) {
                return formatter.format(args);
            }
        }
    }

    protected ClassLoader getBundleClassLoader() {
        return this.bundleClassLoader;
    }

    protected String getBundleResourceCharsetName() {
        return this.charsetName;
    }

    private Control control;

    protected Control getControl() {
        if (control == null) {
            control = new PropertyResourceBundleControl(getBundleResourceCharsetName());
        }
        return control;
    }

    protected ResourceBundle getBundle(String baseName, Locale locale, Control control) {
        if (control == null) {
            return PropertyResourceBundle.getBundle(baseName, locale, getBundleClassLoader());
        } else {
            return PropertyResourceBundle.getBundle(baseName, locale, getBundleClassLoader(), control);
        }
    }

    protected static final class MessageFormatKey implements Serializable {

        private static final long serialVersionUID = 1L;
        private final Locale locale;
        private final String format;

        public static MessageFormatKey create(String formate, Locale locale) {
            return new MessageFormatKey(formate, locale);
        }

        protected MessageFormatKey(String format, Locale locale) {
            this.locale = locale;
            this.format = format;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof MessageFormatKey) {
                MessageFormatKey other = (MessageFormatKey) obj;
                return other.format.equals(format) && other.locale.equals(locale);
            }
            return false;
        }

        @Override
        public int hashCode() {
            int base = 17;
            int result = 0;
            result = base * 37 + locale.hashCode();
            result = result * 37 + format.hashCode();
            return result;
        }
    }

    protected static class PropertyResourceBundleControl extends Control {

        private final String charsetName;

        protected PropertyResourceBundleControl(String charsetName) {
            super();
            this.charsetName = charsetName;
        }

        @Override
        @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 bundleClass = (Class) 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) {
                    return null;
                }
            } 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() {

                        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) {
                    BufferedReader br = null;
                    try {
                        if (charsetName != null) {
                            br = new BufferedReader(new InputStreamReader(stream, charsetName));
                            bundle = new PropertyResourceBundle(br);
                        } else {
                            bundle = new PropertyResourceBundle(stream);
                        }
                    } finally {
                        if (br != null) {
                            br.close();
                        }
                        stream.close();
                    }
                }
            } else {
                throw new IllegalArgumentException("unknown format: " + format);
            }
            return bundle;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy