How to get locale and timezone of Liferay passed to MyFaces

I do not know, if this is a Liferay specific bug, the locale which is selected by the user in his Liferay profile is not passed to a MyFaces portlet.

Note: On the user mailing list someone reported, that this do not work any longer on Liferay 4.1. It is sucessfully used on version 3.6. The main problem there is the reorganizing of Liferays structure. The Liferay portal libraries are located no longer in global Tomcat classpath than in the ROOT-WebApp of Liferay.

For this I wrote some helper methods. See the following shortened code snippets:

   import com.liferay.portal.model.User;
   import com.liferay.portal.util.PortalUtil;

   [...]

  /**
   * Get the user of the request.
   * @param request request to get user
   * @return the current user of the portal
   */
   public MyUser getUser(final RenderRequest request) {
     MyUser user;

     try {
       final User liferayUser = PortalUtil.getUser(request);
       user =
           new MyUser(liferayUser.getFirstName(),
               liferayUser.getLastName());
       user.setLocale(liferayUser.getLocale());
       user.setTimeZone(liferayUser.getTimeZone());
     }
     catch (final Exception e) {
       user = null;
     }

     return user;
   }

The timezone is currently not defined central in MyFaces and has to be queried everywhere where you need it. For example when you display a time control. MyUser is a simple POJO having setters and getters for

  • firstName (String)
  • lastName (String)
  • locale (Locale)
  • timeZone (TimeZone)

If your portlet has to run in different Portal environments, you have to create something to "find out" in which portal your portlet currently is running and then create the User portal specific (-> factory).

Now you have to create your own phaselistener and extend following:

public class PortletPhaseListener implements PhaseListener {
  [...]

  /**
   * Called to update within Portlet environment the language of Portal.
   * @see PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
   */
  public void beforePhase(final PhaseEvent evt) {
    if (PhaseId.RENDER_RESPONSE.equals(evt.getPhaseId())) {
      final Object request =
          evt.getFacesContext().getExternalContext().getRequest();
      if (request instanceof RenderRequest) {
        //update the locale on every request (could be changed every time by user!)
        final MyUser user =
            PortalUtil.getUser((RenderRequest) request);
        final Locale locale = user.getCurrentLocale();

        evt.getFacesContext().getViewRoot().setLocale(locale);
      }
    }
  }

  [...]
}

Do not forget to add the new PhaseListener to your faces-config.xml:

 <lifecycle>
  <phase-listener>foo.bar.PortletPhaseListener</phase-listener>
 </lifecycle>
  • No labels