Author: julien(a)jboss.com
Date: 2007-05-06 17:01:14 -0400 (Sun, 06 May 2007)
New Revision: 7203
Added:
trunk/common/src/main/org/jboss/portal/common/i18n/AbstractLocaleFormat.java
trunk/common/src/main/org/jboss/portal/common/i18n/CachingLocaleFormat.java
Modified:
trunk/common/src/main/org/jboss/portal/common/i18n/DefaultLocaleFormat.java
trunk/common/src/main/org/jboss/portal/common/i18n/LocaleFormat.java
trunk/common/src/main/org/jboss/portal/common/i18n/RFC3066LanguageTagLocaleFormat.java
trunk/common/src/main/org/jboss/portal/test/common/LocaleFormatTestCase.java
Log:
added LocaleFormat caching using a concurrent hashmap
Added: trunk/common/src/main/org/jboss/portal/common/i18n/AbstractLocaleFormat.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/i18n/AbstractLocaleFormat.java
(rev 0)
+++
trunk/common/src/main/org/jboss/portal/common/i18n/AbstractLocaleFormat.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.common.i18n;
+
+import org.jboss.portal.common.util.ConversionException;
+import org.jboss.portal.common.util.NullConversionException;
+import org.jboss.portal.common.io.UndeclaredIOException;
+
+import java.util.Locale;
+import java.io.Writer;
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractLocaleFormat implements LocaleFormat
+{
+
+ public Locale getLocale(String value) throws ConversionException
+ {
+ if (value == null)
+ {
+ throw new NullConversionException("No null locale value accepted");
+ }
+ return internalGetLocale(value);
+ }
+
+ public String toString(Locale locale) throws ConversionException
+ {
+ if (locale == null)
+ {
+ throw new NullConversionException("No null locale accepted");
+ }
+ return internalToString(locale);
+ }
+
+ public void write(Locale locale, Writer writer) throws IOException,
ConversionException
+ {
+ if (locale == null)
+ {
+ throw new NullConversionException("No null locale accepted");
+ }
+ if (writer == null)
+ {
+ throw new IllegalArgumentException("No null writer accepted");
+ }
+ internalWrite(locale, writer);
+ }
+
+ protected abstract Locale internalGetLocale(String value) throws ConversionException;
+
+ protected String internalToString(Locale locale) throws ConversionException
+ {
+ try
+ {
+ StringWriter writer = new StringWriter();
+ internalWrite(locale, writer);
+ return writer.toString();
+ }
+ catch (IOException e)
+ {
+ throw new UndeclaredIOException(e);
+ }
+ }
+
+ protected abstract void internalWrite(Locale locale, Writer writer) throws
IOException, ConversionException;
+
+}
Added: trunk/common/src/main/org/jboss/portal/common/i18n/CachingLocaleFormat.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/i18n/CachingLocaleFormat.java
(rev 0)
+++ trunk/common/src/main/org/jboss/portal/common/i18n/CachingLocaleFormat.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -0,0 +1,106 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.common.i18n;
+
+import org.jboss.portal.common.util.ConversionException;
+
+import java.util.Locale;
+import java.io.Writer;
+import java.io.IOException;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 1.1 $
+ */
+public class CachingLocaleFormat implements LocaleFormat
+{
+
+ /** . */
+ private final LocaleFormat delegate;
+
+ /** . */
+ private final ConcurrentHashMap localeCache;
+
+ /** . */
+ private final ConcurrentHashMap stringCache;
+
+ /**
+ * @param delegate the delegate when the cache value has not been found
+ * @throws IllegalArgumentException if the delegate object provided is null
+ */
+ public CachingLocaleFormat(LocaleFormat delegate) throws IllegalArgumentException
+ {
+ if (delegate == null)
+ {
+ throw new IllegalArgumentException("No null delegate is possible");
+ }
+ this.delegate = delegate;
+ this.localeCache = new ConcurrentHashMap();
+ this.stringCache = new ConcurrentHashMap();
+ }
+
+ public Locale getLocale(String value) throws ConversionException
+ {
+ Locale locale = (Locale)localeCache.get(value);
+
+ //
+ if (locale != null)
+ {
+ return locale;
+ }
+ else
+ {
+ locale = delegate.getLocale(value);
+ localeCache.put(value, locale);
+ }
+
+ //
+ return locale;
+ }
+
+ public String toString(Locale locale) throws ConversionException
+ {
+ String string = (String)stringCache.get(locale);
+
+ //
+ if (string != null)
+ {
+ return string;
+ }
+ else
+ {
+ string = delegate.toString(locale);
+ stringCache.put(locale, string);
+ }
+
+ //
+ return string;
+ }
+
+ public void write(Locale locale, Writer writer) throws IOException,
ConversionException
+ {
+ delegate.write(locale, writer);
+ }
+}
Modified: trunk/common/src/main/org/jboss/portal/common/i18n/DefaultLocaleFormat.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/i18n/DefaultLocaleFormat.java 2007-05-06
19:50:29 UTC (rev 7202)
+++ trunk/common/src/main/org/jboss/portal/common/i18n/DefaultLocaleFormat.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -25,6 +25,9 @@
import org.jboss.portal.common.util.FormatConversionException;
import java.util.Locale;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
import java.io.Writer;
import java.io.IOException;
@@ -34,10 +37,24 @@
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
-class DefaultLocaleFormat extends LocaleFormat
+class DefaultLocaleFormat extends AbstractLocaleFormat
{
/** . */
+ private static final Map CACHE = new HashMap();
+
+ static
+ {
+ for (Iterator i = LocaleManager.getLocales().iterator();i.hasNext();)
+ {
+ Locale locale = (Locale)i.next();
+
+ //
+ CACHE.put(locale.toString(), locale);
+ }
+ }
+
+ /** . */
private LocaleFactory factory;
public DefaultLocaleFormat(LocaleFactory factory)
@@ -52,6 +69,13 @@
protected Locale internalGetLocale(String value) throws FormatConversionException
{
+ Locale locale = (Locale)CACHE.get(value);
+ if (locale != null)
+ {
+ return locale;
+ }
+
+ //
int p1 = value.lastIndexOf('_');
if (p1 < 0)
{
Modified: trunk/common/src/main/org/jboss/portal/common/i18n/LocaleFormat.java
===================================================================
--- trunk/common/src/main/org/jboss/portal/common/i18n/LocaleFormat.java 2007-05-06
19:50:29 UTC (rev 7202)
+++ trunk/common/src/main/org/jboss/portal/common/i18n/LocaleFormat.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -22,75 +22,35 @@
******************************************************************************/
package org.jboss.portal.common.i18n;
-import org.jboss.portal.common.io.UndeclaredIOException;
import org.jboss.portal.common.util.ConversionException;
-import org.jboss.portal.common.util.NullConversionException;
import java.util.Locale;
import java.io.Writer;
import java.io.IOException;
-import java.io.StringWriter;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
-public abstract class LocaleFormat
+public interface LocaleFormat
{
/** . */
- public static final LocaleFormat RFC3066_LANGUAGE_TAG = new
RFC3066LanguageTagLocaleFormat();
+ final LocaleFormat RFC3066_LANGUAGE_TAG = new RFC3066LanguageTagLocaleFormat();
/** . */
- public static final LocaleFormat DEFAULT = new DefaultLocaleFormat();
+ final LocaleFormat DEFAULT = new DefaultLocaleFormat();
- public Locale getLocale(String value) throws ConversionException
- {
- if (value == null)
- {
- throw new NullConversionException("No null locale value accepted");
- }
- return internalGetLocale(value);
- }
+ /** . */
+ final LocaleFormat RFC3066_LANGUAGE_TAG_NO_CACHE = new CachingLocaleFormat(new
RFC3066LanguageTagLocaleFormat());
- public String toString(Locale locale) throws ConversionException
- {
- if (locale == null)
- {
- throw new NullConversionException("No null locale accepted");
- }
- return internalToString(locale);
- }
+ /** . */
+ final LocaleFormat DEFAULT_NO_CACHE = new CachingLocaleFormat(new
DefaultLocaleFormat());
- public void write(Locale locale, Writer writer) throws IOException,
ConversionException
- {
- if (locale == null)
- {
- throw new NullConversionException("No null locale accepted");
- }
- if (writer == null)
- {
- throw new IllegalArgumentException("No null writer accepted");
- }
- internalWrite(locale, writer);
- }
+ Locale getLocale(String value) throws ConversionException;
- protected abstract Locale internalGetLocale(String value) throws ConversionException;
+ String toString(Locale locale) throws ConversionException;
- protected String internalToString(Locale locale) throws ConversionException
- {
- try
- {
- StringWriter writer = new StringWriter();
- internalWrite(locale, writer);
- return writer.toString();
- }
- catch (IOException e)
- {
- throw new UndeclaredIOException(e);
- }
- }
+ void write(Locale locale, Writer writer) throws IOException, ConversionException;
- protected abstract void internalWrite(Locale locale, Writer writer) throws
IOException, ConversionException;
-
}
Modified:
trunk/common/src/main/org/jboss/portal/common/i18n/RFC3066LanguageTagLocaleFormat.java
===================================================================
---
trunk/common/src/main/org/jboss/portal/common/i18n/RFC3066LanguageTagLocaleFormat.java 2007-05-06
19:50:29 UTC (rev 7202)
+++
trunk/common/src/main/org/jboss/portal/common/i18n/RFC3066LanguageTagLocaleFormat.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -35,7 +35,7 @@
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 1.1 $
*/
-class RFC3066LanguageTagLocaleFormat extends LocaleFormat
+class RFC3066LanguageTagLocaleFormat extends AbstractLocaleFormat
{
/**
Modified: trunk/common/src/main/org/jboss/portal/test/common/LocaleFormatTestCase.java
===================================================================
---
trunk/common/src/main/org/jboss/portal/test/common/LocaleFormatTestCase.java 2007-05-06
19:50:29 UTC (rev 7202)
+++
trunk/common/src/main/org/jboss/portal/test/common/LocaleFormatTestCase.java 2007-05-06
21:01:14 UTC (rev 7203)
@@ -25,8 +25,14 @@
import junit.framework.TestCase;
import java.util.Locale;
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Writer;
+import java.io.IOException;
import org.jboss.portal.common.i18n.LocaleFormat;
+import org.jboss.portal.common.i18n.CachingLocaleFormat;
+import org.jboss.portal.common.i18n.AbstractLocaleFormat;
import org.jboss.portal.common.util.FormatConversionException;
import org.jboss.portal.common.util.ConversionException;
@@ -39,13 +45,13 @@
public void testgetLocaleFromDefaultFormat() throws ConversionException
{
- assertEquals(new Locale("a"),
LocaleFormat.DEFAULT.getLocale("a"));
- assertEquals(new Locale("a", "b"),
LocaleFormat.DEFAULT.getLocale("a_b"));
- assertEquals(new Locale("", "b"),
LocaleFormat.DEFAULT.getLocale("_b"));
- assertEquals(new Locale("a", "b", "c"),
LocaleFormat.DEFAULT.getLocale("a_b_c"));
- assertEquals(new Locale("a", "", "b"),
LocaleFormat.DEFAULT.getLocale("a__b"));
- assertEquals(new Locale("", "a", "b"),
LocaleFormat.DEFAULT.getLocale("_a_b"));
- assertEquals(new Locale(""),
LocaleFormat.DEFAULT.getLocale(""));
+ assertEquals(new Locale("a"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("a"));
+ assertEquals(new Locale("a", "b"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("a_b"));
+ assertEquals(new Locale("", "b"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("_b"));
+ assertEquals(new Locale("a", "b", "c"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("a_b_c"));
+ assertEquals(new Locale("a", "", "b"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("a__b"));
+ assertEquals(new Locale("", "a", "b"),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("_a_b"));
+ assertEquals(new Locale(""),
LocaleFormat.DEFAULT_NO_CACHE.getLocale(""));
//
try
@@ -58,7 +64,7 @@
}
try
{
- assertEquals(new Locale("", "", ""),
LocaleFormat.DEFAULT.getLocale("__"));
+ assertEquals(new Locale("", "", ""),
LocaleFormat.DEFAULT_NO_CACHE.getLocale("__"));
fail();
}
catch (ConversionException expected)
@@ -76,34 +82,34 @@
public void testToStringFromDefaultFormat() throws ConversionException
{
- assertEquals("a", LocaleFormat.DEFAULT.toString(new
Locale("a")));
- assertEquals("", LocaleFormat.DEFAULT.toString(new
Locale("")));
+ assertEquals("a", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a")));
+ assertEquals("", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("")));
//
- assertEquals("", LocaleFormat.DEFAULT.toString(new Locale("",
"")));
- assertEquals("a_B", LocaleFormat.DEFAULT.toString(new
Locale("a", "b")));
- assertEquals("a", LocaleFormat.DEFAULT.toString(new Locale("a",
"")));
- assertEquals("_A", LocaleFormat.DEFAULT.toString(new Locale("",
"a")));
+ assertEquals("", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "")));
+ assertEquals("a_B", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "b")));
+ assertEquals("a", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "")));
+ assertEquals("_A", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "a")));
//
- assertEquals("a_B_c", LocaleFormat.DEFAULT.toString(new
Locale("a", "b", "c")));
- assertEquals("_A_b", LocaleFormat.DEFAULT.toString(new
Locale("", "a", "b")));
- assertEquals("a__b", LocaleFormat.DEFAULT.toString(new
Locale("a", "", "b")));
- assertEquals("a_B", LocaleFormat.DEFAULT.toString(new
Locale("a", "b", "")));
- assertEquals("", LocaleFormat.DEFAULT.toString(new Locale("",
"", "a")));
- assertEquals("a", LocaleFormat.DEFAULT.toString(new Locale("a",
"", "")));
- assertEquals("_A", LocaleFormat.DEFAULT.toString(new Locale("",
"a", "")));
- assertEquals("", LocaleFormat.DEFAULT.toString(new Locale("",
"", "")));
+ assertEquals("a_B_c", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "b", "c")));
+ assertEquals("_A_b", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "a", "b")));
+ assertEquals("a__b", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "", "b")));
+ assertEquals("a_B", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "b", "")));
+ assertEquals("", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "", "a")));
+ assertEquals("a", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("a", "", "")));
+ assertEquals("_A", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "a", "")));
+ assertEquals("", LocaleFormat.DEFAULT_NO_CACHE.toString(new
Locale("", "", "")));
}
public void testGetLocaleFromRFC3066LanguageTag() throws ConversionException
{
- assertEquals(new Locale("en"),
LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("en"));
- assertEquals(new Locale("en", "US"),
LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("en-US"));
+ assertEquals(new Locale("en"),
LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("en"));
+ assertEquals(new Locale("en", "US"),
LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("en-US"));
try
{
- LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("wrong");
+ LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("wrong");
fail("Should have failed since an invalid String was passed.");
}
catch (FormatConversionException e)
@@ -113,7 +119,7 @@
try
{
- LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("zz");
+ LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("zz");
fail("Should have failed since an invalid language code was
passed.");
}
catch (FormatConversionException e)
@@ -123,7 +129,7 @@
try
{
- LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("fr-ZZ");
+ LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("fr-ZZ");
fail("Should have failed since an invalid country code was passed.");
}
catch (FormatConversionException e)
@@ -132,12 +138,80 @@
}
// weird combination should work as well
- LocaleFormat.RFC3066_LANGUAGE_TAG.getLocale("fr-US");
+ LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.getLocale("fr-US");
}
public void testGetRFC3066LanguageTagFromLocale() throws ConversionException
{
- assertEquals("en", LocaleFormat.RFC3066_LANGUAGE_TAG.toString(new
Locale("en")));
- assertEquals("en-US", LocaleFormat.RFC3066_LANGUAGE_TAG.toString(new
Locale("en", "US")));
+ assertEquals("en",
LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.toString(new Locale("en")));
+ assertEquals("en-US",
LocaleFormat.RFC3066_LANGUAGE_TAG_NO_CACHE.toString(new Locale("en",
"US")));
}
+
+ public void testCachingLocaleFormat() throws ConversionException
+ {
+ TestLocaleFormat delegate = new TestLocaleFormat();
+ delegate.put(new Locale("abc"), "abc");
+ CachingLocaleFormat format = new CachingLocaleFormat(delegate);
+
+ //
+ assertEquals(new Locale("abc"), format.getLocale("abc"));
+ assertEquals("abc", format.toString(new Locale("abc")));
+
+ //
+ try
+ {
+ format.getLocale("def");
+ fail();
+ }
+ catch (ConversionException e)
+ {
+ }
+
+ //
+ try
+ {
+ format.toString(new Locale("def"));
+ fail();
+ }
+ catch (ConversionException e)
+ {
+ }
+ }
+
+ private static class TestLocaleFormat extends AbstractLocaleFormat
+ {
+
+ /** . */
+ private final Map localeToString = new HashMap();
+
+ /** . */
+ private final Map stringToLocale = new HashMap();
+
+ private void put(Locale locale, String string)
+ {
+ localeToString.put(locale, string);
+ stringToLocale.put(string, locale);
+ }
+
+ protected Locale internalGetLocale(String value) throws ConversionException
+ {
+ Locale locale = (Locale)stringToLocale.get(value);
+ if (locale == null)
+ {
+ throw new ConversionException();
+ }
+ return locale;
+ }
+
+ protected void internalWrite(Locale locale, Writer writer) throws IOException,
ConversionException
+ {
+ String string = (String)localeToString.get(locale);
+ if (string == null)
+ {
+ throw new ConversionException();
+ }
+ writer.write(string);
+ }
+ }
+
}