You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by bu...@apache.org on 2003/03/06 12:06:12 UTC

DO NOT REPLY [Bug 17715] New: - JetspeedLocalizationService only looks at first resource bundle

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17715>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17715

JetspeedLocalizationService only looks at first resource bundle

           Summary: JetspeedLocalizationService only looks at first resource
                    bundle
           Product: Jetspeed
           Version: 1.4b4-dev /CVS
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Major
          Priority: Other
         Component: Miscellaneous
        AssignedTo: jetspeed-dev@jakarta.apache.org
        ReportedBy: evansj@helpmagic.com


All of my portlets are localized to 2 (in one project) or 5 (in another)
languages.  I have my own resource bundle set containing the strings for the
portlets.

I am using JetspeedLocalizationService because I need the users to be able to
switch locale on the fly by clicking a link on the page.  Also it's a great
sales feature when the customer sees that.

JetspeedLocalizationService doesn't work if you have more than one bundle
defined in locale.default.bundles.  It only looks at the first bundle.  You get
a null pointer exception when you try to look up a key that isn't in the first
bundle in the list.

If you look at the class, it extends TurbineLocalizationService.
JetspeedLocalizationService implements an initBundleNames() method
which populates an instance variable String[] bundleNames.  But all of
the getString(...) methods call super.getString(...), where
TurbineLocalizationService will use its own instance variables and will
not find the strings.

Let me put it another way.  Each class defines an identical set of instance
variables, like this:

JetspeedLocalizationService     TurbineLocalizationService
=============================== ===============================
private Hashtable bundles;      private Hashtable bundles;
private String bundleNames[];   private String bundleNames[];
private Locale defaultLocale;   private Locale defaultLocale;
private String defaultLanguage; private String defaultLanguage;
private String defaultCountry;  private String defaultCountry;

After JetspeedLocalizationService.init() is called they look like this:

JetspeedLocalizationService TurbineLocalizationService
=========================== ==========================
bundles          null       bundles         set
bundleNames[]    set        bundleNames[]   null
defaultLocale    null       defaultLocale   set
defaultLanguage  null       defaultLanguage set
defaultCountry   null       defaultCountry  set

when getString(String bundleName, Locale locale, String key) is called
in JetspeedLocalizationService, it calls super.getString(...).  This
calls getBundle(String, Locale), which is implemented in
JetspeedLocalizationService as a call to super.getBundle(String,
Locale), so we are back to the code in TurbineLocalizationService.

getBundle(String, Locale) in TurbineLocalizationService returns the
default bundle to the getString(...) method.

Back in getString(String bundleName, Locale locale, String key), we
look up the requested key in the bundle, using getStringOrNull(), which returns
null because the string I'm looking for isn't in the first bundle, it's in the
second.

The next test is intended to determine whether we need to check the
other bundles for the key.  The test is:

        // Look for text in list of default bundles.
        if (value == null && bundleNames.length > 0)

At this point we throw a NullPointerException because bundleNames is
null (it was never set in TurbineLocalizationService, only in
JetspeedLocalizationService).

The bizarre thing is that although it extends TurbineLocalizationService, it
needlessly re-implements most of the methods with bodies which just call
super.<method>.

The whole of the JetspeedLocalizationService class can be reduced to a single
function, getLocale(RunData runData).  I will attach a patch to this bug which
does this.  My development copy of Jetspeed is patched like this and it works fine.

---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jetspeed-dev-help@jakarta.apache.org