Search code examples
xpagesxsp

How to set resource bundle "On-The-Fly"?


I have a combobox where users can select an available language. The application contains properties files for each language. In the resources section of the page the resource bundle is calculates according to a language tag ( DE, EN ... ) in a user config document.

Is there any easy way to change the language in the onChange event according to the value of the combobox? I thought of context.setProperty(???). Any suggestion?


Solution

  • To implement this application wide you could use a phase listener. In this example, the locale to use is stored in a sessionScope variable named "Language".

    Just add a combobox to your XPage(s) containing all allowed locales.

    <xp:comboBox id="comboBox1" value="#{sessionScope.Language}">
        <xp:selectItem itemLabel="Chinese" itemValue="zh"></xp:selectItem>
        <xp:selectItem itemLabel="German" itemValue="de"></xp:selectItem>
        <xp:selectItem itemLabel="Turkish" itemValue="tr"></xp:selectItem>
        <xp:eventHandler event="onchange" submit="true" refreshMode="complete" />
    </xp:comboBox>
    

    Then you have to use a phase listener like this one:

    package ch.hasselba.xpages.jsf.core;
    
    import javax.faces.context.FacesContext;
    import javax.faces.application.Application;
    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;
    import javax.faces.component.UIViewRoot;
    import java.util.Locale;
    import java.util.Map;
    
    public class LocalizationSetter implements PhaseListener {
    
        private static final long serialVersionUID = -1L;
        private static final String scopeVarName = "Language";
        private static final String scopeName = "sessionScope"; 
    
        public void afterPhase(PhaseEvent event) {}
    
        public void beforePhase(PhaseEvent event) {
            FacesContext facesContext = event.getFacesContext();
            UIViewRoot view = facesContext.getViewRoot();
            view.setLocale( getLanguage(facesContext) ) ;
        }
    
        public PhaseId getPhaseId() {
            return PhaseId.RENDER_RESPONSE;
        }
    
        private Locale getLanguage( FacesContext facesContext ){
            try{
                Application app = facesContext.getApplication();
                Object obj = app.getVariableResolver().resolveVariable(facesContext, scopeName );
                Object lang = ((Map) obj).get( scopeVarName );
                if( lang != null ){
                    return new Locale((String) lang);
                }
            }catch(Exception e){}
    
            return Locale.getDefault();
        }
    }
    

    You can add lookups / etc. to access the user profiles in the "getLanguag()" method.

    Hope this helps Sven