[gatein-commits] gatein SVN: r5275 - in portal/trunk/docs/reference-guide/en/modules: PortalDevelopment and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Nov 25 11:37:49 EST 2010


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" />



More information about the gatein-commits mailing list