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".