hlship 2005/06/07 07:22:08
Modified: . status.xml
framework/src/descriptor/META-INF tapestry.request.xml
framework/src/test/org/apache/tapestry/services/impl
TestRequestLocaleManager.java
framework/src/java/org/apache/tapestry/services/impl
RequestLocaleManagerImpl.java
src/documentation/content/xdocs/UsersGuide localization.xml
configuration.xml
Log:
Add configuration property org.apache.tapestry.accepted-locales, used to
limit localization to a finite set of locales.
Revision Changes Path
1.115 +1 -0 jakarta-tapestry/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/status.xml,v
retrieving revision 1.114
retrieving revision 1.115
diff -u -r1.114 -r1.115
--- status.xml 6 Jun 2005 22:28:19 -0000 1.114
+++ status.xml 7 Jun 2005 14:22:08 -0000 1.115
@@ -66,6 +66,7 @@
<action type="fix" dev="HLS">Make inherited bindings (a holdover from
the 3.0 DTDs) override (quietly) default parameter bindings.</action>
<action type="fix" dev="HLS">Properly identify when portal mode or
window state has changed.</action>
<action type="add" dev="HLS">Add deprecated attribute to
<component-specification> and <parameter>.</action>
+ <action type="add" dev="HLS">Add configuration property
org.apache.tapestry.accepted-locales, used to limit localization to a finite
set of locales.</action>
</release>
<release version="4.0-alpha-3" date="May 16 2005">
<action type="add" dev="HLS">Add initial support for the validator:
binding prefix.</action>
1.31 +6 -1
jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.request.xml
Index: tapestry.request.xml
===================================================================
RCS file:
/home/cvs/jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.request.xml,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- tapestry.request.xml 1 Jun 2005 14:25:55 -0000 1.30
+++ tapestry.request.xml 7 Jun 2005 14:22:08 -0000 1.31
@@ -36,15 +36,20 @@
Encapsulates the logic for extracting the locale for the current request.
- <invoke-factory model="threaded">
+ <invoke-factory model="pooled">
<construct class="impl.RequestLocaleManagerImpl">
<set-service property="request"
service-id="tapestry.globals.WebRequest"/>
<set-object property="cookieSource"
value="infrastructure:cookieSource"/>
<set-service property="threadLocale"
service-id="hivemind.ThreadLocale"/>
+ <set-object property="acceptedLocales"
value="app-property:org.apache.tapestry.accepted-locales"/>
</construct>
</invoke-factory>
</service-point>
+ <contribution configuration-id="hivemind.FactoryDefaults">
+ <default symbol="org.apache.tapestry.accepted-locales" value=""/>
+ </contribution>
+
<service-point id="CookieSource">
Allows access to incoming HTTP cookie values for the active (per-thread)
request.
1.7 +45 -2
jakarta-tapestry/framework/src/test/org/apache/tapestry/services/impl/TestRequestLocaleManager.java
Index: TestRequestLocaleManager.java
===================================================================
RCS file:
/home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/services/impl/TestRequestLocaleManager.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestRequestLocaleManager.java 18 Apr 2005 17:07:51 -0000 1.6
+++ TestRequestLocaleManager.java 7 Jun 2005 14:22:08 -0000 1.7
@@ -76,7 +76,7 @@
Locale actual = manager.extractLocaleForCurrentRequest();
- assertSame(Locale.JAPANESE, actual);
+ assertEquals(Locale.JAPANESE, actual);
verifyControls();
}
@@ -175,7 +175,7 @@
Locale actual = manager.extractLocaleForCurrentRequest();
- assertSame(Locale.JAPANESE, actual);
+ assertEquals(Locale.JAPANESE, actual);
verifyControls();
@@ -190,4 +190,47 @@
verifyControls();
}
+
+ public void testGetLocaleValuesAreCached()
+ {
+ RequestLocaleManagerImpl manager = new RequestLocaleManagerImpl();
+
+ Locale l1 = manager.getLocale("en");
+ Locale l2 = manager.getLocale("en");
+
+ assertSame(l1, l2);
+ }
+
+ /**
+ * Test when filtering of incoming locales is disabled.
+ */
+
+ public void testFilterDisabled()
+ {
+ RequestLocaleManagerImpl manager = new RequestLocaleManagerImpl();
+
+ Locale l = manager.filterRequestedLocale("en");
+
+ assertEquals(Locale.ENGLISH, l);
+ }
+
+ /**
+ * Test with filtering enabled.
+ */
+
+ public void testFilterEnabled()
+ {
+ RequestLocaleManagerImpl manager = new RequestLocaleManagerImpl();
+ manager.setAcceptedLocales("en,fr");
+ manager.initializeService();
+
+ assertEquals(Locale.ENGLISH, manager.filterRequestedLocale("en"));
+ assertEquals(Locale.ENGLISH, manager.filterRequestedLocale("en_US"));
+ assertEquals(Locale.FRENCH, manager.filterRequestedLocale("fr"));
+ assertEquals(Locale.FRENCH, manager.filterRequestedLocale("fr_FR"));
+
+ // Unrecognized locales filter to the first accepted locale.
+
+ assertEquals(Locale.ENGLISH,
manager.filterRequestedLocale("foo_bar_BAZ"));
+ }
}
\ No newline at end of file
1.10 +92 -13
jakarta-tapestry/framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java
Index: RequestLocaleManagerImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- RequestLocaleManagerImpl.java 18 Apr 2005 17:06:38 -0000 1.9
+++ RequestLocaleManagerImpl.java 7 Jun 2005 14:22:08 -0000 1.10
@@ -14,19 +14,23 @@
package org.apache.tapestry.services.impl;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import org.apache.hivemind.service.ThreadLocale;
import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.services.CookieSource;
import org.apache.tapestry.services.RequestLocaleManager;
-import org.apache.tapestry.util.StringSplitter;
import org.apache.tapestry.web.WebRequest;
/**
- * Identifies the Locale provided by the client (either in a
Tapestry-specific cookie, or
- * interpolated from the HTTP header. TODO: Add the ability to "filter down"
Locales down to a
- * predifined set (specified using some form of HiveMInd configuration).
+ * Service tapestry.request.RequestLocaleManager. Identifies the Locale
provided by the client
+ * (either in a Tapestry-specific cookie, or interpolated from the HTTP
header.
*
* @author Howard Lewis Ship
* @since 4.0
@@ -47,17 +51,85 @@
private ThreadLocale _threadLocale;
+ /**
+ * Set from symbol org.apache.tapestry.accepted-locales, a
comma-seperated list of locale names.
+ * The first name is the default for requests that can't be matched
against the other locale
+ * names. May also be blank, in which case, whatever locale was provided
in the request is
+ * accepted (which is Tapestry 3.0 behavior).
+ */
+
+ private String _acceptedLocales;
+
+ private Locale _defaultLocale;
+
+ /**
+ * Set of locale names. Incoming requests will be matched to one of
these locales.
+ */
+
+ private Set _acceptedLocaleNamesSet = new HashSet();
+
+ /**
+ * Cache of Locales, keyed on locale name.
+ */
+
+ private Map _localeCache = new HashMap();
+
+ public void initializeService()
+ {
+ String[] names = TapestryUtils.split(_acceptedLocales);
+
+ if (names.length == 0)
+ return;
+
+ _defaultLocale = getLocale(names[0]);
+
+ _acceptedLocaleNamesSet.addAll(Arrays.asList(names));
+
+ }
+
public Locale extractLocaleForCurrentRequest()
{
String localeName =
_cookieSource.readCookieValue(TapestryConstants.LOCALE_COOKIE_NAME);
- _requestLocale = (localeName != null) ? getLocale(localeName) :
_request.getLocale();
+ String requestedLocale = (localeName != null) ? localeName :
_request.getLocale()
+ .toString();
+
+ _requestLocale = filterRequestedLocale(requestedLocale);
_threadLocale.setLocale(_requestLocale);
return _requestLocale;
}
+ /**
+ * Converts the request locale name into a Locale instance; applies
filters (based on
+ * acceptedLocales) if enabled.
+ */
+
+ Locale filterRequestedLocale(String localeName)
+ {
+ if (_acceptedLocaleNamesSet.isEmpty())
+ return getLocale(localeName);
+
+ while (true)
+ {
+ if (_acceptedLocaleNamesSet.contains(localeName))
+ return getLocale(localeName);
+
+ localeName = stripTerm(localeName);
+
+ if (localeName.length() == 0)
+ return _defaultLocale;
+ }
+ }
+
+ private String stripTerm(String localeName)
+ {
+ int scorex = localeName.lastIndexOf('_');
+
+ return scorex < 0 ? "" : localeName.substring(0, scorex);
+ }
+
public void persistLocale()
{
Locale locale = _threadLocale.getLocale();
@@ -68,20 +140,22 @@
_cookieSource.writeCookieValue(TapestryConstants.LOCALE_COOKIE_NAME,
locale.toString());
}
- private Locale getLocale(String name)
+ Locale getLocale(String name)
{
- // There used to be a cache of Locale (keyed on name), but since
this service is
- // threaded, there's no point (short of making it static, which is
too ugly for words).
- // Instead, we should have a LocaleCache service for that purpose.
Have to balance
- // cost of invoking that service vs. the cost of creating new Locale
instances all the time.
+ Locale result = (Locale) _localeCache.get(name);
+
+ if (result == null)
+ {
+ result = constructLocale(name);
+ _localeCache.put(name, result);
+ }
- return constructLocale(name);
+ return result;
}
private Locale constructLocale(String name)
{
- StringSplitter splitter = new StringSplitter('_');
- String[] terms = splitter.splitToArray(name);
+ String[] terms = TapestryUtils.split(name, '_');
switch (terms.length)
{
@@ -115,4 +189,9 @@
{
_threadLocale = threadLocale;
}
+
+ public void setAcceptedLocales(String acceptedLocales)
+ {
+ _acceptedLocales = acceptedLocales;
+ }
}
\ No newline at end of file
1.7 +34 -0
jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/localization.xml
Index: localization.xml
===================================================================
RCS file:
/home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/localization.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- localization.xml 18 Apr 2005 17:09:03 -0000 1.6
+++ localization.xml 7 Jun 2005 14:22:08 -0000 1.7
@@ -295,5 +295,39 @@
</note>
</section>
+
+<section id="localization.accepted-locales">
+ <title>Limiting accepted locales</title>
+
+<p>
+By default, Tapestry accepts incoming locales (as specified in the request
HTTP header) as-is. The requested
+locale is used as-is. This has some implications, primarily in terms of
resource usage.
+</p>
+
+<p>
+Imagine an application that is being accessed by users in the US, the UK and
in Canada. The incoming request
+locales will be "en_US", "en_UK" and "en_CA" (respectively). However, it is
likely that you will only have
+created a single localization, for English in general (locale "en").
Despite this, there will be several different
+versions of each page in the page pool: one for each of the above locales,
even though they will be functionally identical.
+</p>
+
+<p>
+Ideally, what we want is to limit incoming requests so that all of the
listed locales ("en_US", "en_UK" and "en_CA") will
+be 'filtered down' to just "en".
+</p>
+
+<p>
+That functionality is controlled by the org.apache.tapestry.accepted-locales
&configuration-property;. By setting
+this property to a comma-seperated list of local names, incoming requests
will be converted
+to the closest match. For example, the the property could be configured to
"en,fr,de" to support English, French and German.
+</p>
+
+<p>
+Matching takes place by stripping off "terms" (the locale variant, then the
locale country code) from the locale name. So "en_US" would be stripped to
"en" (which would match).
+When no match can be found, the <em>first</em> locale in the list is treated
as the default. In the prior example, Russian users
+would be matched to the "en" locale.
+</p>
+
+</section>
</body>
</document>
\ No newline at end of file
1.14 +10 -0
jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/configuration.xml
Index: configuration.xml
===================================================================
RCS file:
/home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/configuration.xml,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- configuration.xml 18 Apr 2005 17:09:03 -0000 1.13
+++ configuration.xml 7 Jun 2005 14:22:08 -0000 1.14
@@ -325,6 +325,16 @@
</tr>
<tr>
+ <td>org.apache.tapestry.accepted-locales</td>
+ <td>
+ Controls which locales are supported by the application; see the
+ documentation on
+ <link href="localization.html#localization.accepted-locales">limiting
accepted locales</link>
+ for details.
+ </td>
+ </tr>
+
+ <tr>
<td>org.apache.tapestry.asset.dir, org.apache.tapestry.asset.URL</td>
<td>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]