ICEfaces
  1. ICEfaces
  2. ICE-2419

Locale reverts when dynamically set

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7DR#2
    • Fix Version/s: 1.7DR#3, 1.7
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      n/a

      Description

      If you set the locale dynamically, it is only temporally changed. The next time D2DViewHandler.createView() is called, calculateLocale() will be called, which effectively reverts the locale to the one specified on the HTTP header. A common use case is to allow the user to set the locale dynamically, by clicking on a flag icon on the page. The way we handle locales prevents this use case

        Issue Links

          Activity

          Hide
          Mircea Toma added a comment -

          I believe the right thing to do would be to modify the order of the supported locales (see Application.setSupportedLocales) or just change the default locale (see Application.setSupportedLocale).

          Show
          Mircea Toma added a comment - I believe the right thing to do would be to modify the order of the supported locales (see Application.setSupportedLocales) or just change the default locale (see Application.setSupportedLocale).
          Hide
          Michael Thiem added a comment -

          demo application, tested on tomcat 5.5

          Show
          Michael Thiem added a comment - demo application, tested on tomcat 5.5
          Hide
          Michael Thiem added a comment -

          source code for test application

          Show
          Michael Thiem added a comment - source code for test application
          Hide
          Mark Collette added a comment -

          I fixed ICE-1505, and along with Mircea, ICE-2485, which partially addresses this issue. Basically, now you can call UIViewRoot.setLocale(Locale) and it sticks. Here's an application code example:

          Bean.java

          public SelectItem[] getLocales() {
          ArrayList items = new ArrayList();
          Application application = FacesContext.getCurrentInstance().getApplication();
          Iterator supportedLocales = application.getSupportedLocales();
          while (supportedLocales.hasNext())

          { Locale locale = (Locale) supportedLocales.next(); items.add(new SelectItem(locale.toString(), locale.getDisplayName())); }

          SelectItem[] locales = new SelectItem[items.size()];
          items.toArray(locales);
          return locales;
          }

          public String getSelectedLocale()

          { Locale selectedLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale(); return selectedLocale.toString(); }

          public void setSelectedLocale(String localeString) {
          Application application = FacesContext.getCurrentInstance().getApplication();
          Iterator supportedLocales = application.getSupportedLocales();
          while (supportedLocales.hasNext()) {
          Locale locale = (Locale) supportedLocales.next();
          if(locale.toString().equals(localeString))

          { FacesContext.getCurrentInstance().getViewRoot().setLocale(locale); }

          }
          }

          page.jspx

          <ice:selectOneMenu value="#

          {bean.selectedLocale}

          " partialSubmit="true">
          <f:selectItems value="#

          {bean.locales}

          "/>
          </ice:selectOneMenu>

          faces-config.xml

          <faces-config >
          <application>
          <locale-config>
          <default-locale>en_US</default-locale>
          <supported-locale>fr_CA</supported-locale>
          <supported-locale>fr</supported-locale>
          <supported-locale>en_US</supported-locale>
          <supported-locale>en_CA</supported-locale>
          <supported-locale>en</supported-locale>
          </locale-config>
          </application>
          ...
          </faces-config >

          Show
          Mark Collette added a comment - I fixed ICE-1505 , and along with Mircea, ICE-2485 , which partially addresses this issue. Basically, now you can call UIViewRoot.setLocale(Locale) and it sticks. Here's an application code example: Bean.java public SelectItem[] getLocales() { ArrayList items = new ArrayList(); Application application = FacesContext.getCurrentInstance().getApplication(); Iterator supportedLocales = application.getSupportedLocales(); while (supportedLocales.hasNext()) { Locale locale = (Locale) supportedLocales.next(); items.add(new SelectItem(locale.toString(), locale.getDisplayName())); } SelectItem[] locales = new SelectItem [items.size()] ; items.toArray(locales); return locales; } public String getSelectedLocale() { Locale selectedLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale(); return selectedLocale.toString(); } public void setSelectedLocale(String localeString) { Application application = FacesContext.getCurrentInstance().getApplication(); Iterator supportedLocales = application.getSupportedLocales(); while (supportedLocales.hasNext()) { Locale locale = (Locale) supportedLocales.next(); if(locale.toString().equals(localeString)) { FacesContext.getCurrentInstance().getViewRoot().setLocale(locale); } } } page.jspx <ice:selectOneMenu value="# {bean.selectedLocale} " partialSubmit="true"> <f:selectItems value="# {bean.locales} "/> </ice:selectOneMenu> faces-config.xml <faces-config > <application> <locale-config> <default-locale>en_US</default-locale> <supported-locale>fr_CA</supported-locale> <supported-locale>fr</supported-locale> <supported-locale>en_US</supported-locale> <supported-locale>en_CA</supported-locale> <supported-locale>en</supported-locale> </locale-config> </application> ... </faces-config >
          Hide
          Mark Collette added a comment -

          I'm looking into why using <f:view locale="#

          {prefs.locale}

          "> doesn't seem to work. But, quite separately from that, is the issue that f:loadBundle does not work with dynamic locales. I'll explain why in a later comment. But basically, we'll have to roll our own if we want message bundle values to dynamically update in a long-lived request.

          Show
          Mark Collette added a comment - I'm looking into why using <f:view locale="# {prefs.locale} "> doesn't seem to work. But, quite separately from that, is the issue that f:loadBundle does not work with dynamic locales. I'll explain why in a later comment. But basically, we'll have to roll our own if we want message bundle values to dynamically update in a long-lived request.
          Hide
          Mark Collette added a comment -

          The <f:loadBundle> tag isn't really Ajax/ICEfaces friendly, when used with JSP. But, it works just fine with Facelets though.

          The JSF 1.2 JSP tag for it takes the messages.properties file, parses it all into a Map object, and throws it into the request map. So, since our JSP Tag code only runs once, when we build the component tree, then it won't update the bundle text if you change locales. The JSF 1.2 <f:loadBundle> JSP Tag code has a JSF 1.1 compatibility mode that will make an actual UIComponent in the component tree, that will put that Map into the request map on every render. BUT, it doesn't rebuild that Map, but just re-puts the same old Map in every time.

          On the other hand, with Facelets, we reevaluate the FaceletHandlers on every render pass, and the Facelets LoadBundleHandler does NOT cache the Map, but grabs it fresh from the ResourceBundle every time. I've tested the component-showcase, where we have American and English spellings of "Colour", and it does change dynamically.

          Show
          Mark Collette added a comment - The <f:loadBundle> tag isn't really Ajax/ICEfaces friendly, when used with JSP. But, it works just fine with Facelets though. The JSF 1.2 JSP tag for it takes the messages.properties file, parses it all into a Map object, and throws it into the request map. So, since our JSP Tag code only runs once, when we build the component tree, then it won't update the bundle text if you change locales. The JSF 1.2 <f:loadBundle> JSP Tag code has a JSF 1.1 compatibility mode that will make an actual UIComponent in the component tree, that will put that Map into the request map on every render. BUT, it doesn't rebuild that Map, but just re-puts the same old Map in every time. On the other hand, with Facelets, we reevaluate the FaceletHandlers on every render pass, and the Facelets LoadBundleHandler does NOT cache the Map, but grabs it fresh from the ResourceBundle every time. I've tested the component-showcase, where we have American and English spellings of "Colour", and it does change dynamically.
          Hide
          Mark Collette added a comment -

          Similarly to the <f:loadBundle> issue, <f:view locale="#

          {prefs.locale}

          "> doesn't work with JSP. I read the JSF 1.2 source-code, and saw that com.sun.faces.taglib.jsf_core.ViewTag.setProperties(UIComponent) is where UIViewRoot.setLocale(Locale) should be called. But it's not. That's probably because we special-case the Tag handling for <f:view> in our JSP parsing code, and do something that interferes with it.

          I haven't empirically tested it with Facelets, but I read its com.sun.facelets.tag.jsf.core.ViewHandler class, and think that it should work fine there. There's one caveat though, that UIViewRoot.getLocale() will try to return its locale field first, before trying to evaluate the ValueBinding / ValueExpression. So, D2DViewHandler setting an initial Locale, will interfere with this.

          So, that gives two tasks to do:

          1. Fix ICEfaces JSP ViewTag handling, so that ViewTag.setProperties(UIComponent) is called, with UIViewRoot as the argument.

          2. Make D2DViewHandler.createView() not call UIViewRoot.setLocale( calculateLocale(context) ) which is kind of redundant anyway.

          Show
          Mark Collette added a comment - Similarly to the <f:loadBundle> issue, <f:view locale="# {prefs.locale} "> doesn't work with JSP. I read the JSF 1.2 source-code, and saw that com.sun.faces.taglib.jsf_core.ViewTag.setProperties(UIComponent) is where UIViewRoot.setLocale(Locale) should be called. But it's not. That's probably because we special-case the Tag handling for <f:view> in our JSP parsing code, and do something that interferes with it. I haven't empirically tested it with Facelets, but I read its com.sun.facelets.tag.jsf.core.ViewHandler class, and think that it should work fine there. There's one caveat though, that UIViewRoot.getLocale() will try to return its locale field first, before trying to evaluate the ValueBinding / ValueExpression. So, D2DViewHandler setting an initial Locale, will interfere with this. So, that gives two tasks to do: 1. Fix ICEfaces JSP ViewTag handling, so that ViewTag.setProperties(UIComponent) is called, with UIViewRoot as the argument. 2. Make D2DViewHandler.createView() not call UIViewRoot.setLocale( calculateLocale(context) ) which is kind of redundant anyway.
          Hide
          Mark Collette added a comment -

          Fixed #2 with a subsequent commit for ICE-1505.

          Show
          Mark Collette added a comment - Fixed #2 with a subsequent commit for ICE-1505 .
          Hide
          Mark Collette added a comment -

          #1 has been spun off into ICE-2551, to be fixed in the next release.

          Show
          Mark Collette added a comment - #1 has been spun off into ICE-2551 , to be fixed in the next release.
          Hide
          Ken Fyten added a comment -

          Automated regression test failed on Feb. 1 @ 10pm. Likely related to changes in ICE-2551. Re-opened.

          Show
          Ken Fyten added a comment - Automated regression test failed on Feb. 1 @ 10pm. Likely related to changes in ICE-2551 . Re-opened.
          Hide
          Ken Fyten added a comment -

          False alarm. Test is passing.

          Show
          Ken Fyten added a comment - False alarm. Test is passing.
          Hide
          Vladimir Putin added a comment -

          Unfortunately FacesContext.getCurrentInstance().getViewRoot().setLocale(locale) do not work in my environment: ICEFaces 1.7.2 SP1 + Seam 2.1SP1. I tried this to make workaround for problem with non-working Seam's LocaleSelector (ICE-2147) but have no success.

          Show
          Vladimir Putin added a comment - Unfortunately FacesContext.getCurrentInstance().getViewRoot().setLocale(locale) do not work in my environment: ICEFaces 1.7.2 SP1 + Seam 2.1SP1. I tried this to make workaround for problem with non-working Seam's LocaleSelector ( ICE-2147 ) but have no success.
          Hide
          Hugues Flament added a comment -

          Hi,

          I have exactly the same issue. using Netbeans 6.5 (ICEFaces 1.7.2).

          The call to FacesContext.getCurrentInstance().getViewRoot().setLocale(locale) doesn't seem to work at all.

          This piece of code was working fine in Netbeans 6.1 (Woodstock components).

          Any suggestion would be very welcome.

          Show
          Hugues Flament added a comment - Hi, I have exactly the same issue. using Netbeans 6.5 (ICEFaces 1.7.2). The call to FacesContext.getCurrentInstance().getViewRoot().setLocale(locale) doesn't seem to work at all. This piece of code was working fine in Netbeans 6.1 (Woodstock components). Any suggestion would be very welcome.
          Hide
          Stephan Ehlen added a comment -

          Is it possible that this is again an issue in ICEfaces 1.8 RC1? I've upgraded the libraries for testing purposes in an existing project and I'm experiencing this behaviour now.

          I'm setting the locale by FacesContext.getCurrentInstance().getViewRoot().setLocale(locale).

          Show
          Stephan Ehlen added a comment - Is it possible that this is again an issue in ICEfaces 1.8 RC1? I've upgraded the libraries for testing purposes in an existing project and I'm experiencing this behaviour now. I'm setting the locale by FacesContext.getCurrentInstance().getViewRoot().setLocale(locale).

            People

            • Assignee:
              Unassigned
              Reporter:
              Philip Breau
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: