Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read resource bundle properties in a managed bean

Using <resource-bundle> files I'm able to have i18n text in my JSF pages.

But is it possible to access these same properties in my managed bean so I can set faces messages with i18n values?

like image 978
Matthieu Riegler Avatar asked Dec 01 '12 01:12

Matthieu Riegler


People also ask

Where does ResourceBundle properties file go?

ResourceBundle property files contain locale-specific objects for use by Java classes. The ResourceBundle property file must be placed somewhere in the CLASSPATH . Typically this is best accomplished by placing the ResourceBundle properties file in the same directory as the gear message class that it maps to.

How do I use resource bundles?

First you need a Locale instance. Then you pass that Locale instance to the ResourceBundle. getBundle() method along with the name of the resource bundle to load. Finally you can access the localized values in the ResourceBundle via its different getString() and getObject() etc.

What is ResourceBundle in JSF?

Resource bundles in JSF are key value pair of strings stored in . properties file extension. Resource bundles helps in maintainability of the application by keeping messages at one place.

What does ResourceBundle do?

ResourceBundle class is used to store text and objects which are locale sensitive. Generally we use property files to store locale specific text and then represent them using ResourceBundle object.


1 Answers

Assuming that you've configured it as follows:

<resource-bundle>
    <base-name>com.example.i18n.text</base-name>
    <var>text</var>
</resource-bundle>

If your bean is request scoped, you can just inject the <resource-bundle> as @ManagedProperty by its <var>:

@ManagedProperty("#{text}")
private ResourceBundle text;

public void someAction() {
    String someKey = text.getString("some.key");
    // ... 
}

Or if you just need some specific key:

@ManagedProperty("#{text['some.key']}")
private String someKey;

public void someAction() {
    // ... 
}

If your bean is however in a broader scope, then evaluate #{text} programmatically in method local scope:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = context.getApplication().evaluateExpressionGet(context, "#{text}", ResourceBundle.class);
    String someKey = text.getString("some.key");
    // ... 
}

Or if you only need some specific key:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    String someKey = context.getApplication().evaluateExpressionGet(context, "#{text['some.key']}", String.class);
    // ... 
}

You can even just get it by the standard ResourceBundle API the same way as JSF itself is already doing under the covers, you'd only need to repeat the base name in code:

public void someAction() {
    FacesContext context = FacesContext.getCurrentInstance();
    ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", context.getViewRoot().getLocale());
    String someKey = text.getString("some.key");
    // ... 
}

Or if you're managing beans by CDI instead of JSF, then you can create a @Producer for that:

public class BundleProducer {

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
    }

}

And inject it as below:

@Inject
private PropertyResourceBundle text;

Alternatively, if you're using the Messages class of the JSF utility library OmniFaces, then you can just set its resolver once to let all Message methods utilize the bundle.

Messages.setResolver(new Messages.Resolver() {
    public String getMessage(String message, Object... params) {
        ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", Faces.getLocale());
        if (bundle.containsKey(message)) {
            message = bundle.getString(message);
        }
        return MessageFormat.format(message, params);
    }
});

See also the example in the javadoc and the showcase page.

like image 186
BalusC Avatar answered Nov 16 '22 04:11

BalusC