4 Replies Latest reply: Apr 24, 2012 4:10 AM by Ivo Maixner RSS

How to override UserLocaleProducer?

Ivo Maixner Newbie

The org.jboss.seam.international.locale.UserLocaleProducer produces Locale bound to user session, which needs to be changed by explicitly sending an "@Alter @Client Locale" event.

 

I want my application to accept the locale set by the users in their browser's preferences.

 

When the user changes locale in browser, the @Client Locale does not reflect this change and everything bound to this locale remains in the locale that was set at the time the session started. Specifically, messages created by Messages.error(BundleKey).

 

What is the recommended way to approach such a requirement?

 

I can write a producer:

@RequestScoped
public class ClientLocaleRequestProducer {
     @Inject FacesContext facesContext;

     @Produces @Client @Named public Locale getClientLocale() {
          return facesContext.getViewRoot().getLocale();
     }
}

but how do I disable or override the org.jboss.seam.international.locale.UserLocaleProducer, that is now causing the "Ambiguous dependencies" deployment exception?

  • 1. Re: How to override UserLocaleProducer?
    Ken Finnigan Master

    To base it off the Browser locale, as opposed to allowing the user to switch the locale with a UI component, your best option is to have a phase listener run before RESTORE_VIEW that checks the current locale of Seam International compared to Faces Context.

     

    If they are different, then fire an event to update Seam International as described in the documentation

  • 2. Re: How to override UserLocaleProducer?
    mechu Newbie

    Hi,

    Im not using seam international but using own impl.

    Try with this, changing UserLocale to your Client qualifier

     

    public class SessionGlobals implements Serializable {
    
        private static final long serialVersionUID = -1L;
        
        @Inject
        @Alter
        @UserLocale
        private Event<Locale> event;
        
        public void facesLocales(@Observes @Initialized HttpServletRequest p_request) {
            event.fire(FacesContext.getCurrentInstance().getViewRoot().getLocale());
        }
    }
    
  • 3. Re: How to override UserLocaleProducer?
    Ivo Maixner Newbie

    As for observing before RESTORE_VIEW phase, that appears not viable, as the view root is not accessible at that time. The following throws NPE:

    public void overrideClientLocaleWithRequest(
              @Observes @Before @RestoreView PhaseEvent event) {
         UIViewRoot viewRoot = facesContext.getViewRoot();
         Locale requestLocale = viewRoot.getLocale(); // NPE thrown here
         ... check and fire event ...
    }
    

    However, observing AFTER the RESTORE_VIEW phase did the trick:

     

    public class RequestClientLocaleOverride {
         @Inject @Client private Locale clientLocale;
         @Inject FacesContext facesContext;
         @Inject @Client @Alter private Event<Locale> alterLocale;
    
         public void overrideClientLocaleWithRequest(
                   @Observes @After @RestoreView PhaseEvent event) {
              Locale requestLocale = facesContext.getViewRoot().getLocale();
              if (!clientLocale.equals(requestLocale)) {
                   alterLocale.fire(requestLocale);
              }
         }
    }
    

    This works fine. Thanks.

     

    UPDATE: The FacesContext may be released when an exception is being processed. In such a case, the code above throws IllegalStateException from facesContext.getViewRoot() call.

    Added an

    if (!facesContext.isReleased())
    

    within the whole method.

  • 4. Re: How to override UserLocaleProducer?
    Ivo Maixner Newbie

    Tried to observe @Initialized HttpServletRequest as well. Throws "ContextNotActiveException: FacesContext is not active".