Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    DataSource Localization not Loading the Right Properties File

    I am trying to add localization support for my application, and so far I have been able to make most of the interface and messages localization work as expected, but I'm having trouble getting SmartGWT to use the right ResourceBundle properties file to load in order to show the correct labels and values for my databound controls that use a PropertyResourceBundle approach.

    This is my ds.xml file:
    Code:
    <DataSource ID="preferences" serverType="sql" tableName="preferences" xmlns:fmt="WEB-INF/">
        <fmt:bundle basename="co.focuss.bmsimulator.shared.i18n.BMSimulatorResources" encoding="utf-8"/>
        <fields>
        
            <field name="userName" primaryKey="true" canSave="false">
                <title><fmt:message key="userName"/></title>
            </field>
            
            <field name="password">
                <title><fmt:message key="password"/></title>
                <validators>
                    <validator type="lengthRange" min="6">
                        <errorMessage><fmt:message key="passwordMinimumLenghtValidator"/></errorMessage>
                    </validator>
                    <validator type="lengthRange" max="20">
                        <errorMessage><fmt:message key="passwordMaximumLenghtValidator"/></errorMessage>
                    </validator>
                </validators>
            </field>        
            
            <field name="mode">
                <title><fmt:message key="mode"/></title>
                <valueMap>
                    <value id="basic"><fmt:message key="interfaceModeBasic"/></value>
                    <value id="advanced"><fmt:message key="interfaceModeAdvanced"/></value>
                </valueMap>
            </field>
            
            <field name="language">
                <title><fmt:message key="language"/></title>
                <valueMap>
                    <value id="en"><fmt:message key="languageEnglish"/></value>
                    <value id="es"><fmt:message key="languageSpanish"/></value>
                </valueMap>
            </field>
            
        </fields>
    </DataSource>
    I have three properties files located on package co.focuss.bmsimulator.shared.i18n. Their content is:
    Code:
    /* BMSimulatorResources.properties */
    userName=User
    password=Password
    passwordMinimumLenghtValidator=Password length must be 6 or more characters.
    passwordMaximumLenghtValidator=Password length must be 20 or less characters.
    mode=Mode
    interfaceModeBasic=Basic
    interfaceModeAdvanced=Advanced
    language=Simulator Language
    languageEnglish=English
    languageSpanish=Spanish
    
    /* BMSimulatorResources_en.properties */
    userName=User
    password=Password
    passwordMinimumLenghtValidator=Password length must be 6 or more characters.
    passwordMaximumLenghtValidator=Password length must be 20 or less characters.
    mode=Mode
    interfaceModeBasic=Basic
    interfaceModeAdvanced=Advanced
    language=Simulator Language
    languageEnglish=English
    languageSpanish=Spanish
    
    /* BMSimulatorResources_es.properties */
    userName=Usuario
    password=Clave
    passwordMinimumLenghtValidator=La longitud de la clave debe ser 6 caracteres o más.
    passwordMaximumLenghtValidator=La longitud de la clave debe ser 20 caracteres o menos.
    mode=Modo
    interfaceModeBasic=Básico
    interfaceModeAdvanced=Avanzado
    language=Idioma del Simulador
    languageEnglish=Inglés
    languageSpanish=Español
    The problem is that even if the rest of the application elements do show in the correct locale, because the standard GWT Constants and Messages approaches used for that part are detecting the locale correctly, in the form that localizes the DataSource contents there seems to be a problem with detecting the locale correctly, because the mechanism will always use the BMSimulatorResources_es.properties to do the localization.

    What am I missing here?

    ps. I tried following the steps describe here as closely as possible: https://www.smartclient.com/smartgwt...alization.html

    #2
    Most likely, the DataSourceLoader servlet is somehow being prevented from detecting the locale in the normal way - possibly due to a misbehaving filter servlet placed in front of it.

    You could test this theory with a trivial subclass of the DataSourceLoader servlet that just tries to detect the locale via the standard servlet.getLocale() API. If this fails for you, that's the problem, and as soon as you fix that problem, server-side locale access will start working.

    Comment


      #3
      Thanks for your reply. I don't have a DataSourceLoader subclass currently on my project, or any other servlet trying to put filters on it (at least that I know of). I didn't think it was necessary up until now, because I assumed that the PropertyResourceBundle would be read and processed automatically. Or is it just for testing purposes?

      And when you say standard getLocale() API, can you please tell me in what class do I find that method, since that's not a DataSourceLoader method...

      Comment


        #4
        Subclassing DataSourceLoader is not normally necessary. This was suggested purely as a debugging measure.

        Servlet filters are likewise not necessary. This was suggested as a possible source of the problem in your project, not something that is required.

        Normally, localization of DataSources works with no additional steps.

        It looks like you think you are not actually using the DataSourceLoader. How are you loading DataSources then? That's kind of an important thing to tell us if you are seeking help with why DataSource loading isn't working as expected..

        Oh, and, in case you need it, the getLocale() API is on the ServletRequest object in the standard Servlets API.

        Comment


          #5
          Thanks again. Sorry if I wasn't clear about the details you point out, but not knowing what to ask is in part a reflection of my lack of knowledge.

          I'll try again, to the best of my knowledge: I read the article I reference in my first post, and there it says that
          This will cause Smart GWT Server to look for a ResourceBundle called "supplyItem", containing keys "itemTitle" and "itemLengthRangeValidator", and replace the <fmt:message> tags with the values from the resource bundle in the expected way.
          So I looked up the ResourceBundle class in the standard Java documentation, and I saw there that the ResourceBundle class has two subclasses, ListResourceBundle and PropertyResourceBundle, which can be used for the same purpose, but have some additional benefits. Specifically, the PropertyResourceBundle is a class that doesn't need to be subclassed, and that will look automatically for .properties files containing the key-value pairs required to localize the elements that refer to the PropertyResourceBundle.

          Taking advantage of this, what I did was to configure my ds.xml file as shown above, then created all the .properties files (one for each locale, and one for the default one), and tried to run the application, expecting the mechanism that loads the data sources (I deduct,from your initial post that this would be the DataSourceLoader) would detect that I was using the approach of property files. It seemed to work fine, but as I said, the DataSourceLoader is not detecting the locale correctly, although it indeed does load the Spanish properties file to localize the UI.

          I hope I did a better job explaining my problem. Can you please help me figure out what am I missing?

          Comment


            #6
            OK, you didn't actually answer whether you are using the DataSourceLoader (this is covered in the QuickStart Guide), but assuming you are, you should go back to our first reply to troubleshoot why the locale is not being detected correctly. Again, normally this is not required - it is a troubleshooting step to try to determine why your environment is abnormal.

            If you find your subclass of DataSourceLoader is not being invoked, try answering the question of whether or not you are using the DataSourceLoader definitively.
            Last edited by Isomorphic; 20 Dec 2015, 20:20.

            Comment


              #7
              Regarding the specific question: no, currently I'm not subclassing DataSourceLoader in my application. I haven't created DataSourceLoader objects either. But I think I am using it, since I added this header to my bootstrap file:
              Code:
              <script src="bmsimulator/sc/DataSourceLoader?dataSource=preferences"></script>
              And use these lines to bind a DynamicForm to this datasource:
              Code:
              DataSource ds = DataSource.get("preferences");
              form = new DynamicForm();
              form.setDataSource(ds);
              Regarding the suggested test, I am having a really hard time implementing it. Can you please post some sample code or point me to a resource I can study to do it? I just re-read the Quick Start Guide and I can't find any examples of subclassing DataSourceLoader.

              Comment


                #8
                Then yes, you are obviously using DataSourceLoader.

                What we're suggesting is just basic Servlets programming, actually nothing to do with our technology. Subclass DataSourceLoader, implement the standards servlets API doGet(), and see if you can access the Locale.

                Comment


                  #9
                  I found some clues looking closely at the debugging messages, and reading this: http://www.w3.org/International/ques...orities.en.php.

                  What I found is a pattern that suggests that the default DataSourceLoader (as said before, I'm not subclassing it) is not reading the http request locale, or the locale specified in the bootstrap file, but is using instead the Accept-Language http header to decide which properties file to use. Here is proof of this, when trying to run the application using the url http://127.0.0.1:59489/BMSimulator.html?locale=es:
                  Click image for larger version

Name:	accept-language-en.png
Views:	224
Size:	306.6 KB
ID:	233598

                  And here, again using the same url provided above, but after changing the language order in the browser preferences:
                  Click image for larger version

Name:	accept-language-es.png
Views:	202
Size:	305.4 KB
ID:	233599

                  It works consistently, every time I change the language preference order. So, I think the question now is: is this the expected behavior of SmartGWT out of the box? And if so, how can I make the DataSourceLoader respond to the http request locale value, as the Messages and Constants localized elements do, instead of the Accept-Language header?

                  I would really appreciate you helping me figuring this out without asking me to write the kind of code I was hoping to avoid (at least at the beginning of my learning curve) when I bought your Pro license. Thanks!
                  Last edited by carlossierra; 21 Dec 2015, 22:06.

                  Comment


                    #10
                    Of course it's using the Accept-Language header. That's how servlets.getLocale() works, and as we've covered, that's what the DataSourceLoader servlet calls.

                    This is not only standard Java behavior, it's how almost all web applications detect the user's preferred locale - in other words this is what you want to happen!

                    You have just now, finally, revealed that you are trying to force a change in locale for testing purposes. First, consider that the *best* way to test localization is to change the locale of your machine temporarily or manipulate the Accept Language header in the way you've shown. This way you actually test the auto-detection that you want to have happen when your app is deployed.

                    However, if you want to force the locale with an HTTP parameter for whatever reason, we support that too (in the DataSourceLoader and other standard servlets). But of course, for the parameter has to actually be passed to the servlet for that to work, and you are not passing it (just look at your script tag that points at DataSourceLoader).

                    Furthermore, we cover this right in the docs you are reading:

                    It (SmartGWT) obtains the user's Locale from the servlet request, but you can override this if you want to force an application-specific locale, regardless of the user's operating system settings. To do this, specify a "locale" parameter on HTTP requests to the DataSourceLoader and IDACall servlets.
                    Hopefully you appreciate now that not only was our software was doing the right thing, out of the box, with no configuration, but that the particular testing approach you wanted to use is also supported, and documented in the right place!


                    Comment


                      #11
                      Ok. Thanks...

                      In case this can be of use for somebody else in the future, I just had to change the this bootstrap line to include the locale parameter:
                      Code:
                      <script src="bmsimulator/sc/DataSourceLoader?dataSource=preferences&locale=en"></script>

                      Comment

                      Working...
                      X