Author: mstruk
Date: 2010-11-25 11:37:48 -0500 (Thu, 25 Nov 2010)
New Revision: 5275
Added:
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/LocalizationConfiguration.xml
Modified:
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml
Log:
GTNPORTAL-1694 Add LocalePolicy documentation to Reference Guide
Added:
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/LocalizationConfiguration.xml
===================================================================
---
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/LocalizationConfiguration.xml
(rev 0)
+++
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/LocalizationConfiguration.xml 2010-11-25
16:37:48 UTC (rev 5275)
@@ -0,0 +1,274 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Reference_Guide.ent">
+%BOOK_ENTITIES;
+]>
+
+<section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy">
+ <title>Pluggable Locale Policy</title>
+
+ <para>Every request processed by every portlet is invoked within a context of
current <literal>Locale</literal>.
+ Current <literal>Locale</literal> can be retrieved by calling
<literal>getLocale()</literal> method of
+ <literal>javax.portlet.PortletRequest</literal> interface.
+ </para>
+ <para>The exact algorithm for determining the current
<literal>Locale</literal> is not specified by Portlet Specification,
+ and is left to portlet containers to implement the way they deem most appropriate.
+ </para>
+ <para>In &PRODUCT; each portal instance has a default language which can be
used to present content for new users.
+ Another option is to use each user’s browser language preference, provided it
matches one of the available
+ localizations that &PRODUCT; supports, and only fallback to portal default
language if no match is found.
+ Every user, while visiting a portal, has an option to change the language of the
user interface by using a Language chooser.
+ The choice can be remembered for the duration of the session, or it can be
remembered for a longer period using a browser cookie,
+ or - for registered and logged-in users - it can be saved into user’s profile.
+ </para>
+ <para>So, we can see that there is more than one way to determine the
<literal>Locale</literal> to be used for displaying a portal page
+ to the user. For this reason the mechanism for determining the current
<literal>Locale</literal> of the request
+ is pluggable in &PRODUCT;, so the exact algorithm can be customized.
+ </para>
+
+ <section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy-Locale_Policy_API">
+ <title>LocalePolicy API</title>
+
+ <para>Customization is achieved by using LocalePolicy API, which is a
simple API consisting of one interface,
+ and one class:
+ </para>
+ <itemizedlist>
+ <listitem>
+
<para><literal>org.exoplatform.services.resources.LocalePolicy</literal>
interface</para>
+ </listitem>
+ <listitem>
+
<para><literal>org.exoplatform.services.resources.LocaleContextInfo</literal>
class</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><literal>LocalePolicy</literal> interface defines a
single method that’s invoked on the installed
+ <literal>LocalePolicy</literal> service implementation:
+ </para>
+
+ <programlisting><![CDATA[public interface LocalePolicy
+{
+ public Locale determineLocale(LocaleContextInfo localeContext);
+}]]>
+ </programlisting>
+ <para><literal>Locale</literal> returned by determineLocale()
method is the <literal>Locale</literal>
+ that will be returned to portlets when they call
<literal>javax.portlet.PortletRequest.getLocale()</literal> method.
+ </para>
+ <para>The returned <literal>Locale</literal> has to be one of
the locales supported by portal,
+ otherwise it will fallback to portal-default
<literal>Locale</literal>.
+ </para>
+
+ <para>The supported locales are listed in
<filename>gatein.ear/02portal.war/WEB-INF/conf/common/locales-config.xml</filename>
file
+ as described in <xref
linkend="sect-Reference_Guide-Internationalization_Configuration-Locales_configuration"/>
.
+ </para>
+
+ <para>The <literal>determineLocale()</literal> method takes a
parameter of type <literal>LocaleContextInfo</literal>,
+ which represents a compilation of preferred locales from different sources -
user’s profile, portal default,
+ browser language settings, current session, browser cookie … All these
different sources of <literal>Locale</literal>
+ configuration or preference are used as input to
<literal>LocalePolicy</literal> implementation
+ that decides which <literal>Locale</literal> should be used.
+ </para>
+
+ </section>
+ <section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy-Default_LocalePolicy">
+ <title>Default <literal>LocalePolicy</literal></title>
+ <para>By default,
<literal>org.exoplatform.portal.application.localization.DefaultLocalePolicyService</literal>
- an implementation
+ of <literal>LocalePolicy</literal> - is installed to provide
the default behaviour.
+ This, however, can easily be extended and overriden. A completely new
implementation can also be written from scratch.
+ </para>
+ <para><literal>DefaultLocalePolicyService</literal> treats
logged-in users slightly differently than anonymous users.
+ Logged-in users have a profile that can contain language preference, while
anonymous users don't.
+ </para>
+ <para>Here is an algorithm used for anonymous users.</para>
+ <procedure>
+ <title>An algorithm for anonymous users</title>
+ <step>
+ <para>
+ Iterate over <literal>LocaleContextInfo</literal>
properties in the following order:
+ </para>
+ <itemizedlist>
+ <listitem>
+
<para><literal>cookieLocales</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>sessionLocale</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>browserLocales</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>portalLocale</literal></para>
+ </listitem>
+ </itemizedlist>
+ </step>
+ <step>
+ <para>Get each property's value - if it's a collection, get
the first value.
+ </para>
+ </step>
+ <step>
+ <para>If value is one of the supported locales return it as a
result.
+ </para>
+ </step>
+ <step>
+ <para>If value is not in the supported locales set, try to remove
country information,
+ and check if a language matching locale is in the list of supported
locales.
+ If so, return it as a result.
+ </para>
+ </step>
+ <step>
+ <para>Otherwise, continue with the next property.
+ </para>
+ </step>
+ </procedure>
+ <para>If no supported locale is found the return locale eventually
defaults to <literal>portalLocale</literal>.
+ </para>
+ <para>The algorithm for logged-in users is virtually the same except that
the first <literal>Locale</literal>
+ source checked is user's profile.</para>
+ <procedure>
+ <title>An algorithm for logged-in users</title>
+ <step>
+ <para>
+ Iterate over <literal>LocaleContextInfo</literal>
properties in the following order:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>userProfile</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>cookieLocales</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>sessionLocale</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>browserLocales</literal></para>
+ </listitem>
+ <listitem>
+
<para><literal>portalLocale</literal></para>
+ </listitem>
+ </itemizedlist>
+ </step>
+ <step>
+ <para>The rest is the same as for anonymous users ...</para>
+ </step>
+ </procedure>
+
+ </section>
+ <section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy-Custom_LocalePolicy">
+ <title>Custom <literal>LocalePolicy</literal></title>
+ <para>The easiest way to customize the
<literal>LocalePolicy</literal> is to extend
<literal>DefaultLocalePolicyService</literal>.
+ The study of its source code will be required. There is ample JavaDoc that
provides thorough information.
+ Most customizations will involve simply overriding one or more of its
protected methods.
+ </para>
+ <para>
+ An example of a customization is an already provided
<literal>NoBrowserLocalePolicyService</literal>.
+ By overriding just one method, it skips any use of browser language
preference.
+ </para>
+ <programlisting><![CDATA[public class NoBrowserLocalePolicyService
extends DefaultLocalePolicyService
+{
+ /**
+ * Override super method with no-op.
+ *
+ * @param context locale context info available to implementations in order to
determine appropriate Locale
+ * @return null
+ */
+ @Override
+ protected Locale getLocaleConfigFromBrowser(LocaleContextInfo context)
+ {
+ return null;
+ }
+}]]>
+ </programlisting>
+ </section>
+
+ <section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy-Configuration">
+ <title>LocalePolicy Configuration</title>
+
+ <para>The <literal>LocalePolicy</literal> framework is enabled
for portlets by configuring LocalizationLifecycle class in portal's webui
configuration file:
+
<filename>gatein.ear/02portal.war/WEB-INF/webui-configuration.xml</filename>:</para>
+
+ <programlisting role="XML"><![CDATA[
<application-lifecycle-listeners>
+ ...
+
<listener>org.exoplatform.portal.application.localization.LocalizationLifecycle</listener>
+ </application-lifecycle-listeners>]]>
+ </programlisting>
+
+ <para>The default <literal>LocalePolicy</literal>
implementation is installed as GateIn Kernel portal service via
+
<filename>gatein.ear/lib/exo.portal.webui.portal-VERSION.jar/conf/portal/configuration.xml</filename>.
+ </para>
+ <para>The following fragment is responsible for installing the service:
+ </para>
+ <programlisting role="XML"><![CDATA[ <component>
+ <key>org.exoplatform.services.resources.LocalePolicy</key>
+
<type>org.exoplatform.portal.application.localization.DefaultLocalePolicyService</type>
+ </component>]]>
+ </programlisting>
+ <para>Besides implementing <literal>LocalePolicy</literal>,
the service class also needs to implement
+ <literal>org.picocontainer.Startable</literal> interface in order
to get installed.
+ </para>
+ <para>This configuration file should not be changed. The configuration in
it can be overriden by placing it into portal's .war file:
+
<filename>gatein.ear/02portal.war/WEB-INF/conf/configuration.xml</filename>
(usually as another file included into this one).
+ </para>
+ </section>
+
+ <section
id="sect-Reference_Guide-Localization_Configuration-Pluggable_Locale_Policy-Non_bridged">
+ <title>Keeping non-bridged resources in sync with current
Locale</title>
+ <para>In portals all the resources that are not portlets themselves but
are accessed through portlets - reading
+ data through <literal>PortletRequest</literal>, and writing to
<literal>PortletResponse</literal> - are
+ referred to as 'bridged'. Any resources that are accessed directly,
bypassing portal filters and servlets,
+ are referred to as 'non-bridged'.
+ </para>
+ <para>Non-bridged servlets, and .jsps have no access to
<literal>PortalRequest</literal>. They don't use
+ <literal>PortletRequest.getLocale()</literal> to determine
current <literal>Locale</literal>.
+ Instead, they use <literal>ServletRequest.getLocale()</literal>
which is subject to precise semantics
+ defined by Servlet specification - it reflects browser's language
preference.
+ </para>
+ <para>In other words, non-bridged resources don't have a notion of
current <literal>Locale</literal>
+ in the same sense that portlets do. The result is that when mixing portlets
and non-bridged resources there
+ may be a localization mismatch - an inconsistency in the language used by
different resources composing your portal
+ page.
+ </para>
+ <para>This problem is addressed by
<literal>LocalizationFilter</literal>. This is a filter that changes the
behaviour
+ of <literal>ServletRequest.getLocale()</literal> method so that
it behaves the same way as
+ <literal>PortletRequest.getLocale()</literal>. That way even
localization of servlets, and .jsps
+ accessed in a non-bridged manner can stay in sync with portlet localization.
+ </para>
+ <para><literal>LocalizationFilter</literal> is installed
through portal's web.xml file:
<filename>gatein.ear/02portal.war/WEB-INF/web.xml</filename>
+ </para>
+ <programlisting role="XML"><![CDATA[ <filter>
+ <filter-name>LocalizationFilter</filter-name>
+ <filter-class>org.exoplatform.portal.application.localization.LocalizationFilter</filter-class>
+ </filter>
+
+ ...
+
+ <filter-mapping>
+ <filter-name>LocalizationFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>INCLUDE</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>ERROR</dispatcher>
+ </filter-mapping>]]>
+ </programlisting>
+ <para>There is a tiny limitation with this mechanism in that it is unable
to determine the current portal,
+ and consequently its default language. As a result the portalLocale defaults
to <literal>English</literal>, but can be configured
+ to something else by using filter's
<literal>PortalLocale</literal> init param. For example:
+ </para>
+ <programlisting role="XML"><![CDATA[ <filter>
+ <filter-name>LocalizationFilter</filter-name>
+ <filter-class>org.exoplatform.portal.application.localization.LocalizationFilter</filter-class>
+ <init-param>
+ <param-name>PortalLocale</param-name>
+ <param-value>fr_FR</param-value>
+ </init-param>
+ </filter> ]]>
+ </programlisting>
+ <para>By default, <literal>LocalizationFilter</literal> is
applied very broadly to cover all the resources automatically.
+ &PRODUCT; uses some non-bridged .jsps that require
<literal>LocalizationFilter</literal>, so narrowing
+ the mapping to *.jsp is enough for &PRODUCT; to still function correctly.
Additionally deployed portlets,
+ and portal applications, however, may require broader mapping to cover their
non-bridged resources.
+ </para>
+ <para>Narrowing the mapping might improve performance. This is something
to consider, when optimizing for speed.
+ </para>
+ </section>
+ </section>
\ No newline at end of file
Modified: portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml
===================================================================
--- portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml 2010-11-25 16:30:36
UTC (rev 5274)
+++ portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml 2010-11-25 16:37:48
UTC (rev 5275)
@@ -11,6 +11,7 @@
<xi:include
href="PortalDevelopment/DefaultPortalPermissionConfiguration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include
href="PortalDevelopment/DefaultPortalNavigationConfiguration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/InternationalizationConfiguration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="PortalDevelopment/LocalizationConfiguration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/RTLFramework.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/XMLResourceBundles.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include
href="PortalDevelopment/JavascriptInterApplicationCommunication.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />