diff --git a/src/main/java/org/mamute/i18n/MamuteLocalization.java b/src/main/java/org/mamute/i18n/MamuteLocalization.java index 5fd66289c..8c27e5195 100644 --- a/src/main/java/org/mamute/i18n/MamuteLocalization.java +++ b/src/main/java/org/mamute/i18n/MamuteLocalization.java @@ -1,6 +1,7 @@ package org.mamute.i18n; import java.util.Locale; +import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.annotation.Priority; @@ -10,12 +11,16 @@ import javax.interceptor.Interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.jstl.core.Config; +import javax.servlet.jsp.jstl.fmt.LocalizationContext; import br.com.caelum.vraptor.core.JstlLocalization; +import br.com.caelum.vraptor.util.EmptyBundle; +import br.com.caelum.vraptor.util.SafeResourceBundle; +import com.google.common.base.Objects; @Alternative @Priority(Interceptor.Priority.APPLICATION) -public class MamuteLocalization extends JstlLocalization{ +public class MamuteLocalization extends JstlLocalization { private final HttpServletRequest request; @@ -25,27 +30,69 @@ public class MamuteLocalization extends JstlLocalization{ protected MamuteLocalization() { this(null); } - + @Inject public MamuteLocalization(HttpServletRequest request) { super(request); this.request = request; } - - + + @Override @Produces public ResourceBundle getBundle(Locale locale) { Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, null); - ResourceBundle customBundle = super.getBundle(locale); + ResourceBundle customBundle = getUTF8Bundle(locale); Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, "mamute-messages"); - ResourceBundle mamuteBundle = super.getBundle(locale); - + ResourceBundle mamuteBundle = getUTF8Bundle(locale); + return new MamuteResourceBundle(customBundle, mamuteBundle); } - + + public ResourceBundle getUTF8Bundle(Locale locale) { + Object bundle = this.findByKey("javax.servlet.jsp.jstl.fmt.localizationContext"); + ResourceBundle unsafe = this.extractUnsafeBundle(bundle, locale); + return new SafeResourceBundle(unsafe); + } + + + private ResourceBundle extractUnsafeBundle(Object bundle, Locale locale) { + if (!(bundle instanceof String) && bundle != null) { + if (bundle instanceof LocalizationContext) { + return ((LocalizationContext) bundle).getResourceBundle(); + } else { + return new EmptyBundle(); + } + } else { + String baseName = Objects.firstNonNull((String) bundle, "messages"); + try { + if (locale.getLanguage().equals("fa")) + return ResourceBundle.getBundle(baseName, locale, new UTF8Control()); + else + return ResourceBundle.getBundle(baseName, locale); + } catch (MissingResourceException var5) { + return new EmptyBundle(); + } + } + } + + private Object findByKey(String key) { + Object value = Config.get(this.request, key); + if (value != null) { + return value; + } else { + value = Config.get(this.request.getSession(), key); + if (value != null) { + return value; + } else { + value = Config.get(this.request.getServletContext(), key); + return value != null ? value : this.request.getServletContext().getInitParameter(key); + } + } + } + @Override @Produces public Locale getLocale() { return super.getLocale(); } - + } diff --git a/src/main/java/org/mamute/i18n/UTF8Control.java b/src/main/java/org/mamute/i18n/UTF8Control.java new file mode 100644 index 000000000..f50cf6581 --- /dev/null +++ b/src/main/java/org/mamute/i18n/UTF8Control.java @@ -0,0 +1,86 @@ +package org.mamute.i18n; +/* https://gist.github.com/Hasacz89/d93955ec91afc73a06e3 */ + +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; + +public class UTF8Control extends ResourceBundle.Control { + 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); + ResourceBundle bundle = null; + switch (format) { + case "java.class": + try { + @SuppressWarnings("unchecked") + 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) { + } + + break; + case "java.properties": + final String resourceName = toResourceName(bundleName, "properties"); + final ClassLoader classLoader = loader; + final boolean reloadFlag = reload; + InputStream stream; + 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) { + try { + bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8")); + } finally { + stream.close(); + } + } + + break; + default: + throw new IllegalArgumentException("unknown format: " + format); + } + return bundle; + } +} \ No newline at end of file