I'm creating a portal application with Jetspeed and I needed to be able to change the language on the fly. I found JetspeedLocalizationService but it only worked when there was only one resource bundle was present. I needed a custom bundle plus the standard one.
The problem was the way it delegated methods to the superclass, which would then look for strings in its uninitialized collections.
With the attached patch I can now use $i10n.KEY, where KEY comes either from my own properties files or the stock Jetspeed files, and it all works fine.
It's a bit of a dumb patch because all it does is to cut & paste a whole lot more code from turbine's TurbineLocalizationService. Because of this it was no longer worth extending TurbineLocalizationService, I extended TurbineBaseService instead.
A more elegant solution would be to split out parts of TurbineLocalizationService into an abstract class and extend that instead, if necessary I can do that. What do you think? Would the Turbine folks be happy to take such a patch?
I also went through too much pain trying to find this feature in the first place. What is the best way to submit documentation changes? Check out the website CVS and submit a patch?
Jon
--
Merlin Information Systems Limited,
Merlin House, Gawcott Road, Buckingham, United Kingdom. MK18 1TN
Tel: +44 (0) 1280 824331 Fax: +44 (0) 1280 824112
http://www.misgl.com
Provider of IT Services and Online Portal Support Services.
Confidentiality:
The information contained in this email (including any attachments) is confidential and is intended solely for the use of the named addressee. Access, copying or re-use of the information in it by any other person is not authorised. If you are not the intended recipient, please notify us immediately by telephone or by e-mail to [EMAIL PROTECTED]
*** This mail has been scanned for viruses ***
Index:
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationService.java
===================================================================
RCS file:
/home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationService.java,v
retrieving revision 1.1
diff -u -r1.1 CustomLocalizationService.java
---
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationService.java
14 Nov 2002 20:30:24 -0000 1.1
+++
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationService.java
26 Feb 2003 11:05:12 -0000
@@ -64,9 +64,10 @@
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import org.apache.turbine.services.Service;
+import org.apache.turbine.services.localization.LocalizationService;
import org.apache.turbine.util.RunData;
-public interface CustomLocalizationService extends Service
+public interface CustomLocalizationService extends LocalizationService
{
public abstract String getDefaultBundleName();
@@ -79,5 +80,5 @@
public abstract String getString(String s, Locale locale, String s1);
public static final String SERVICE_NAME = "LocalizationService";
- public static final String ACCEPT_LANGUAGE = "accept-Language";
+ public static final String ACCEPT_LANGUAGE = "Accept-Language";
}
Index:
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationTool.java
===================================================================
RCS file:
/home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationTool.java,v
retrieving revision 1.1
diff -u -r1.1 CustomLocalizationTool.java
---
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationTool.java
14 Nov 2002 20:30:24 -0000 1.1
+++
src/java/org/apache/jetspeed/services/customlocalization/CustomLocalizationTool.java
26 Feb 2003 11:05:12 -0000
@@ -79,8 +79,7 @@
{
try
{
- String s = CustomLocalization.getString(getBundleName(null), getLocale(),
key);
- return s;
+ return CustomLocalization.getString(getBundleName(null), getLocale(),
key);
}
catch(MissingResourceException noKey)
{
Index:
src/java/org/apache/jetspeed/services/customlocalization/JetspeedLocalizationService.java
===================================================================
RCS file:
/home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services/customlocalization/JetspeedLocalizationService.java,v
retrieving revision 1.3
diff -u -r1.3 JetspeedLocalizationService.java
---
src/java/org/apache/jetspeed/services/customlocalization/JetspeedLocalizationService.java
16 Nov 2002 17:30:31 -0000 1.3
+++
src/java/org/apache/jetspeed/services/customlocalization/JetspeedLocalizationService.java
26 Feb 2003 11:05:12 -0000
@@ -64,28 +64,54 @@
// Java imports
import java.util.Hashtable;
import java.util.Locale;
+import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import org.apache.commons.lang.StringUtils;
// Turbine imports
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.turbine.services.localization.LocalizationService;
import org.apache.turbine.services.localization.TurbineLocalizationService;
+import org.apache.turbine.services.localization.LocalizationTool;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.resources.TurbineResources;
import org.apache.turbine.util.RunData;
// Jetspeed imports
import org.apache.jetspeed.om.security.JetspeedUser;
+import org.apache.turbine.services.TurbineBaseService;
+import org.apache.turbine.services.localization.LocaleTokenizer;
-
-public class JetspeedLocalizationService extends TurbineLocalizationService
implements CustomLocalizationService
+public class JetspeedLocalizationService extends TurbineBaseService implements
CustomLocalizationService
{
+ private Hashtable bundles;
+ private String bundleNames[];
+ private Locale defaultLocale;
+ private String defaultLanguage;
+ private String defaultCountry;
+
+ /** Logging */
+ private static Log log = LogFactory.getLog(LocalizationTool.class);
+
public JetspeedLocalizationService()
{
- super();
+ bundles = new Hashtable();
}
public void init() throws InitializationException
{
- super.init();
+ initBundleNames(null);
+
+ Locale jvmDefault = Locale.getDefault();
+ defaultLanguage = TurbineResources
+ .getString("locale.default.language",
+ jvmDefault.getLanguage()).trim();
+ defaultCountry = TurbineResources
+ .getString("locale.default.country",
+ jvmDefault.getCountry()).trim();
+ defaultLocale = new Locale(defaultLanguage, defaultCountry);
+ setInit(true);
}
protected void initBundleNames(String ignored[])
@@ -117,41 +143,138 @@
return bundleNames.length > 0 ? bundleNames[0] : "";
}
+ /**
+ * This method returns a ResourceBundle given the bundle name
+ * "DEFAULT" and the default Locale information supplied in
+ * TurbineProperties.
+ *
+ * @return A localized ResourceBundle.
+ */
public ResourceBundle getBundle()
{
- return super.getBundle();
+ return getBundle(getDefaultBundleName(), (Locale) null);
}
+ /**
+ * This method returns a ResourceBundle given the bundle name and
+ * the default Locale information supplied in TurbineProperties.
+ *
+ * @param bundleName Name of bundle.
+ * @return A localized ResourceBundle.
+ */
public ResourceBundle getBundle(String bundleName)
{
- return super.getBundle(bundleName);
+ return getBundle(bundleName, (Locale) null);
}
+
+ /**
+ * This method returns a ResourceBundle given the bundle name and
+ * the Locale information supplied in the HTTP "Accept-Language"
+ * header.
+ *
+ * @param bundleName Name of bundle.
+ * @param languageHeader A String with the language header.
+ * @return A localized ResourceBundle.
+ */
public ResourceBundle getBundle(String bundleName, String languageHeader)
{
- return super.getBundle(bundleName, languageHeader);
+ return getBundle(bundleName, getLocale(languageHeader));
}
public ResourceBundle getBundle(RunData data)
{
- return super.getBundle(data);
+ return getBundle(getDefaultBundleName(), getLocale(data));
}
public ResourceBundle getBundle(String bundleName, RunData data)
{
- return super.getBundle(bundleName, data);
+ return getBundle(bundleName, getLocale(data));
}
+ /**
+ * This method returns a ResourceBundle for the given bundle name
+ * and the given Locale.
+ *
+ * @param bundleName Name of bundle.
+ * @param locale A Locale.
+ * @return A localized ResourceBundle.
+ */
public ResourceBundle getBundle(String bundleName, Locale locale)
{
- return super.getBundle(bundleName, locale);
- }
-
+ // Assure usable inputs.
+ bundleName = (bundleName == null ? getDefaultBundleName() :
bundleName.trim());
+ if (locale == null)
+ {
+ locale = getLocale((String) null);
+ }
+
+ if (bundles.containsKey(bundleName))
+ {
+ Hashtable locales = (Hashtable) bundles.get(bundleName);
+
+ if (locales.containsKey(locale))
+ {
+ return (ResourceBundle) locales.get(locale);
+ }
+ else
+ {
+ // Try to create a ResourceBundle for this Locale.
+ ResourceBundle rb = ResourceBundle.getBundle(bundleName,
+ locale);
+
+ // Cache the ResourceBundle in memory.
+ locales.put(rb.getLocale(), rb);
+
+ return rb;
+ }
+ }
+ else
+ {
+ // Try to create a ResourceBundle for this Locale.
+ ResourceBundle rb = ResourceBundle.getBundle(bundleName,
+ locale);
+
+ // Cache the ResourceBundle in memory.
+ Hashtable ht = new Hashtable();
+ ht.put(locale, rb);
+
+ // Can't call getLocale(), because that is jdk2. This
+ // needs to be changed back, since the above approach
+ // caches extra Locale and Bundle objects.
+ // ht.put( rb.getLocale(), rb );
+
+ bundles.put(bundleName, ht);
+
+ return rb;
+ }
+ }
+
+ /**
+ * This method sets the name of the first bundle in the search
+ * list (the "default" bundle).
+ *
+ * @param defaultBundle Name of default bundle.
+ */
public void setBundle(String defaultBundle)
{
- super.setBundle(defaultBundle);
+ if (bundleNames.length > 0)
+ {
+ bundleNames[0] = defaultBundle;
+ }
+ else
+ {
+ synchronized (this)
+ {
+ if (bundleNames.length <= 0)
+ {
+ bundleNames = new String[]{defaultBundle};
+ }
+ }
+ }
}
-
+
+
public final Locale getLocale(RunData data)
{
@@ -183,21 +306,95 @@
}
}
}
-
-
+
+ /**
+ * @see
org.apache.turbine.services.localization.LocalizationService#getLocale(String)
+ */
public Locale getLocale(String header)
{
- return super.getLocale(header);
- }
-
+ if (!StringUtils.isEmpty(header))
+ {
+ LocaleTokenizer tok = new LocaleTokenizer(header);
+ if (tok.hasNext())
+ {
+ return (Locale) tok.next();
+ }
+ }
+
+ // Couldn't parse locale.
+ return defaultLocale;
+ }
+
+ /**
+ * @exception MissingResourceException Specified key cannot be matched.
+ * @see
org.apache.turbine.services.localization.LocalizationService#getString(String, Locale,
String)
+ */
public String getString(String bundleName, Locale locale, String key)
{
- return super.getString(bundleName, locale, key);
- }
+ String value = null;
- private Hashtable bundles;
- private String bundleNames[];
- private Locale defaultLocale;
- private String defaultLanguage;
- private String defaultCountry;
-}
+ if (locale == null)
+ {
+ locale = getLocale((String) null);
+ }
+
+ // Look for text in requested bundle.
+ ResourceBundle rb = getBundle(bundleName, locale);
+ value = getStringOrNull(rb, key);
+
+ // Look for text in list of default bundles.
+ if (value == null && bundleNames.length > 0)
+ {
+ String name;
+ for (int i = 0; i < bundleNames.length; i++)
+ {
+ name = bundleNames[i];
+ //System.out.println("getString(): name=" + name +
+ // ", locale=" + locale + ", i=" + i);
+ if (!name.equals(bundleName))
+ {
+ rb = getBundle(name, locale);
+ value = getStringOrNull(rb, key);
+ if (value != null)
+ {
+ locale = rb.getLocale();
+ break;
+ }
+ }
+ }
+ }
+
+ if (value == null)
+ {
+ String loc = locale.toString();
+ log.debug(LocalizationService.SERVICE_NAME +
+ " noticed missing resource: " +
+ "bundleName=" + bundleName + ", locale=" + loc +
+ ", key=" + key);
+ // Text not found in requested or default bundles.
+ throw new MissingResourceException(bundleName, loc, key);
+ }
+
+ return value;
+ }
+
+ /**
+ * Gets localized text from a bundle if it's there. Otherwise,
+ * returns <code>null</code> (ignoring a possible
+ * <code>MissingResourceException</code>).
+ */
+ protected final String getStringOrNull(ResourceBundle rb, String key)
+ {
+ if (rb != null)
+ {
+ try
+ {
+ return rb.getString(key);
+ }
+ catch (MissingResourceException ignored)
+ {
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
