Pregunta

I was working on Internationalizing the messages/strings in my older JSF-1.x project when I found that the UTF-8 rendering was not being applied on the messages.

I ran across a similar problem here:- i18n with UTF-8 encoded properties files in JSF 2.0 appliaction

But that would work for JSF-2 aplication and I cant register my Custom Resource Bundle in the same way as explained there.(Deployment error of namespace not matching shows up.)

Need help to register my Custom Resource Bundle in faces-config.xml for JSF-1.x.

(We had used message-bundle in there. But I cannot register my bundle class in message-bundle like we can in resource-bundle tag)

¿Fue útil?

Solución

In JSF-1.x , there is no support to register my own Custom ResourceBundle class.

Therefore, need to go forward to create a custom tag <x:loadBundle> which encodes the Properties file in the correct encoding.

Refer Facelets custom tag not rendering to register your Tag Library XML in your web.xml. Then in your TagLibrary XML, have this config:-

<tag>
            <tag-name>loadBundle</tag-name>
            <handler-class>org.somepackage.facelets.tag.jsf.handler.LoadBundleHandler</handler-class>
</tag>

And extend your custom LoadBundleHandler to extend the TagHandler facelets class- (The code would be the same as the LoadBundleHandler @ com.sun.facelets.tag.jsf.core.LoadBundleHandler

And now you could override the Control class as in my referred post in the question. So overall your class would look like this:-

public final class LoadBundleHandler extends TagHandler {


    private static final String BUNDLE_EXTENSION = "properties";    // The default extension for langauge Strings (.properties)

    private static final String CHARSET = "UTF-8";

    private static final Control UTF8_CONTROL = new UTF8Control();  

    private final static class ResourceBundleMap implements Map {
        private final static class ResourceEntry implements Map.Entry {

            protected final String key;

            protected final String value;

            public ResourceEntry(String key, String value) {
                this.key = key;
                this.value = value;
            }

            public Object getKey() {
                return this.key;
            }

            public Object getValue() {
                return this.value;
            }

            public Object setValue(Object value) {
                throw new UnsupportedOperationException();
            }

            public int hashCode() {
                return this.key.hashCode();
            }

            public boolean equals(Object obj) {
                return (obj instanceof ResourceEntry && this.hashCode() == obj
                        .hashCode());
            }
        }

        protected final ResourceBundle bundle;

        public ResourceBundleMap(ResourceBundle bundle) {
            this.bundle = bundle;
        }

        public void clear() {
            throw new UnsupportedOperationException();
        }

        public boolean containsKey(Object key) {
            try {
                bundle.getString(key.toString());
                return true;
            } catch (MissingResourceException e) {
                return false;
            }
        }

        public boolean containsValue(Object value) {
            throw new UnsupportedOperationException();
        }

        public Set entrySet() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            String k;
            while (e.hasMoreElements()) {
                k = (String) e.nextElement();
                s.add(new ResourceEntry(k, this.bundle.getString(k)));
            }
            return s;
        }

        public Object get(Object key) {
            try {
                return this.bundle.getObject((String) key);
            } catch( java.util.MissingResourceException mre ) {
                return "???"+key+"???";
            }
        }

        public boolean isEmpty() {
            return false;
        }

        public Set keySet() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            while (e.hasMoreElements()) {
                s.add(e.nextElement());
            }
            return s;
        }

        public Object put(Object key, Object value) {
            throw new UnsupportedOperationException();
        }

        public void putAll(Map t) {
            throw new UnsupportedOperationException();
        }

        public Object remove(Object key) {
            throw new UnsupportedOperationException();
        }

        public int size() {
            return this.keySet().size();
        }

        public Collection values() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            while (e.hasMoreElements()) {
                s.add(this.bundle.getObject((String) e.nextElement()));
            }
            return s;
        }
    }

    private final TagAttribute basename;

    private final TagAttribute var;


    public LoadBundleHandler(TagConfig config) {
        super(config);
        this.basename = this.getRequiredAttribute("basename");
        this.var = this.getRequiredAttribute("var");
    }


    public void apply(FaceletContext ctx, UIComponent parent)
            throws IOException, FacesException, FaceletException, ELException {
        UIViewRoot root = ComponentSupport.getViewRoot(ctx, parent);
        ResourceBundle bundle = null;
        FacesContext faces = ctx.getFacesContext();
        String name = this.basename.getValue(ctx);
        try {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            if (root != null && root.getLocale() != null) {
                bundle = ResourceBundle.getBundle(name, root.getLocale(), cl, UTF8_CONTROL);
            } else {
                bundle = ResourceBundle
                        .getBundle(name, Locale.getDefault(), cl);
            }
        } catch (Exception e) {
            throw new TagAttributeException(this.tag, null , e);
        }
        ResourceBundleMap map = new ResourceBundleMap(bundle);
        faces.getExternalContext().getRequestMap().put(this.var.getValue(ctx),
                map);
    }



    protected static class UTF8Control extends Control {
        public ResourceBundle newBundle
            (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
                throws IllegalAccessException, InstantiationException, IOException
        {
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
            ResourceBundle bundle = null;
            InputStream stream = null;
            if (reload) {
                URL url = loader.getResource(resourceName);
                if (url != null) {
                    URLConnection connection = url.openConnection();
                    if (connection != null) {
                        connection.setUseCaches(false);
                        stream = connection.getInputStream();
                    }
                }
            } else {
                stream = loader.getResourceAsStream(resourceName);
            }
            if (stream != null) {
                try {
                    bundle = new PropertyResourceBundle(new InputStreamReader(stream, UTF8_CONTROL));
                } finally {
                    stream.close();
                }
            }
            return bundle;
        }
    }


}

You could even skip the basename config in <x:loadbundle var="msg basename="resources"> by removing the basename property in this class.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top