Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Multiple Resource bundles in JSF

I am trying to access multiple resource bundles from a JSF page. I have two resource bundles:

  • general_messages.properties
  • module_message.properties

I want to access both these resource bundles in a JSF file. One way I can do this is to define specific properties for each of these bundles:

<f:loadBundle basename="com.sample.general_messages" var="general"/>
<f:loadBundle basename="com.sample.module_message" var="module"/>

Is there a way I can access both these resource bundles using the same variable name. Something like:

<f:loadBundle basename="com.sample.general_messages, com.sample.module_message" var="general"/>

Or any other best way to access multiple resource bundles?

like image 840
Abdul Avatar asked Jul 22 '11 06:07

Abdul


1 Answers

You tagged your question with Spring, so I recommend you using Spring MessageSource. Spring MessageSource can aggregate many property files even hierarchically. It gives you many advantages over old java ResourceBundle.

You can define spring MessageSource in you spring-config.xml like this:

<!--
Application messages configuration.
-->
<bean id="messageSource" name="resourceBundle"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
    p:fallbackToSystemLocale="false"
    p:cacheSeconds="0">
    <property name="basenames">
        <list>
            <value>/messages/Messages</value>
<!--        <value>${application.messages}</value>-->
        </list>
    </property>
</bean>

Than you can define your Class which extends ResourceBundle like this (Needs some cleaning and refactoring):

public class SpringResourceBundle extends ResourceBundle
{

    private MessageSource messages;
    private FacesContext fc;
    private Locale locale = null;

    public SpringResourceBundle()
    {
        fc = FacesContext.getCurrentInstance();
        WebApplicationContext webAppCtx = (WebApplicationContext) fc.getExternalContext().getApplicationMap().get(
                WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        messages = (MessageSource) webAppCtx.getBean("messageSource");
    }

    @Override
    public Locale getLocale()
    {
        Locale loc = fc.getELContext().getLocale();
        if (fc.getExternalContext() != null) {
            loc = fc.getExternalContext().getRequestLocale();
        }
        try {
            UIViewRoot viewRoot = fc.getViewRoot();
            if (viewRoot != null) {
                loc = viewRoot.getLocale();
            }
            if (loc == null) {
                loc = fc.getApplication().getDefaultLocale();
            }

        } catch (Throwable th) {
            System.out.println(th.getMessage());
            loc = locale;
        }
        locale = loc;
        return loc;
    }

    @Override
    protected Object handleGetObject(String key)
    {
        try {
            return messages.getMessage(key, null, getLocale());
        } catch (NoSuchMessageException e) {
            return "???" + key + "???";
        }
    }

    @Override
    public Enumeration<String> getKeys()
    {
        return Collections.enumeration(Collections.EMPTY_LIST);
    }
}

Finnaly in faces-config.xml declare your resource bundle with Class above. Something like this:

<application>
    <locale-config>
       <default-locale>en</default-locale>
       <supported-locale>cs</supported-locale>
       <supported-locale>de</supported-locale>
       <supported-locale>en</supported-locale>
    </locale-config>
    <message-bundle>your.package.SpringResourceBundle</message-bundle>
</application>

Here you go Spring MessageSource in JSF. Hope it's understandable.

like image 93
Ondrej Bozek Avatar answered Sep 29 '22 22:09

Ondrej Bozek