Author: thomas.heute(a)jboss.com
Date: 2010-04-15 06:43:53 -0400 (Thu, 15 Apr 2010)
New Revision: 2652
Added:
portal/trunk/docs/reference-guide/en/images/Advanced/
portal/trunk/docs/reference-guide/en/images/Advanced/Foundations/
portal/trunk/docs/reference-guide/en/modules/Advanced/
portal/trunk/docs/reference-guide/en/modules/Advanced/Foundations.xml
Removed:
portal/trunk/docs/reference-guide/en/images/PortalDevelopment/Foundations/
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/Foundations.xml
Modified:
portal/trunk/docs/reference-guide/en/master.xml
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml
Log:
Moved Foundation chapter in a new "Advanced" section
Copied: portal/trunk/docs/reference-guide/en/images/Advanced/Foundations (from rev 2648,
portal/trunk/docs/reference-guide/en/images/PortalDevelopment/Foundations)
Modified: portal/trunk/docs/reference-guide/en/master.xml
===================================================================
--- portal/trunk/docs/reference-guide/en/master.xml 2010-04-15 10:32:55 UTC (rev 2651)
+++ portal/trunk/docs/reference-guide/en/master.xml 2010-04-15 10:43:53 UTC (rev 2652)
@@ -89,4 +89,5 @@
<xi:include href="modules/GadgetDevelopment.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/AuthenticationAndIdentity.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/WSRP.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/Advanced.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>
Copied: portal/trunk/docs/reference-guide/en/modules/Advanced/Foundations.xml (from rev
2648, portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/Foundations.xml)
===================================================================
--- portal/trunk/docs/reference-guide/en/modules/Advanced/Foundations.xml
(rev 0)
+++ portal/trunk/docs/reference-guide/en/modules/Advanced/Foundations.xml 2010-04-15
10:43:53 UTC (rev 2652)
@@ -0,0 +1,733 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter 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-Foundations">
+
+ <title>Foundations</title>
+ <section id="sect-Reference_Guide-Foundations-Kernel">
+ <title>GateIn Kernel</title>
+ <para>
+ &PRODUCT; is built as a set of services on top of a dependency injection
kernel. The kernel provides configuration, lifecycle handling, component scopes, and some
core services.
+ </para>
+ <para>
+ Service components exist in two scopes. First scope is represented by
<emphasis role="bold">RootContainer</emphasis> - it contains
services that exist independently of any portal, and can be
+ accessed by all portals.
+ </para>
+ <para>
+ Second scope is portal-private in the form of <emphasis
role="bold">PortalContainer</emphasis>. Each portal lives in an
instance of PortalContainer.
+ This scope contains services that are common for a set of portals, and services
which should not be shared by all portals.
+ </para>
+ <para>
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata
fileref="images/Advanced/Foundations/PortalContainers.png"
format="PNG" align="center" scale="100" />
+ </imageobject>
+ <imageobject role="fo">
+ <imagedata
fileref="images/Advanced/Foundations/PortalContainers.png"
format="PNG" align="center" contentwidth="150mm" />
+ </imageobject>
+ </mediaobject>
+ </para>
+ <para>
+ Whenever a specific service is looked up through PortalContainer, and the
service is not available, the lookup is
+ delegated further up to RootContainer. We can therefore have default instance of
a certain component in
+ RootContainer, and portal specific instances in some or all PortalContainers,
that override the default
+ instance.
+ </para>
+ <para>
+ Whenever your portal application has to be integrated more closely with GateIn
services, the way to do it is by
+ looking up these services through PortalContainer. Be careful though - only
officially documented services
+ should be accessed this way, and used according to documentation, as most of the
services are an implementation
+ detail of GateIn, and subject to change without notice.
+ </para>
+ </section>
+
+ <section id="sect-Reference_Guide-Foundations-Configuring_services">
+ <title>Configuring services</title>
+
+ <para>GateIn Kernel uses dependency injection to create services based on
<emphasis role="bold">configuration.xml</emphasis> configuration
files.
+ The location of the configuration files determines if services are placed into
RootContainer scope, or into PortalContainer scope.
+ All configuration.xml files located at <emphasis
role="bold">conf/configuration.xml</emphasis> in the classpath (any
directory, or any jar in the classpath) will have their
+ services configured at RootContainer scope.
+ All configuration.xml files located at <emphasis
role="bold">conf/portal/configuration.xml</emphasis> in the classpath
will have their services configured at PortalContainer scope.
+ Additionally, <emphasis role="bold">portal
extensions</emphasis> can contain configuration in <emphasis
role="bold">WEB-INF/conf/configuration.xml</emphasis>, and will also
have their services configured at PortalContainer scope.
+ </para>
+ <note>
+ <para>Portal extensions are described later on.</para>
+ </note>
+
+ </section>
+
+ <section id="sect-Reference_Guide-Foundations-Configuration_syntax">
+ <title>Configuration syntax</title>
+
+ <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Component">
+ <title>Components</title>
+ <para>A service component is defined in <emphasis
role="bold">configuration.xml</emphasis> by using <emphasis
role="bold"><component></emphasis> element.</para>
+ <para>There is only one required information when defining a service - the
service implementation class, specified using <emphasis
role="bold"><type></emphasis></para>
+ <para>Every component has a <emphasis
role="bold"><key></emphasis> that identifies it. If not
explicitly set, a key defaults to the value of <type>.
+ If key can be loaded as a class, a Class object is used as a key, otherwise a
String is used.</para>
+ <para>The usual approach is to specify an interface as a
key.</para>
+
+ <example>
+ <title>Example of service component configuration:</title>
+ <programlisting role="XML"><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
+
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+
<type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+
+ ...
+
+ </component>
+</configuration>
+ ]]></programlisting>
+ </example>
+ </section>
+ <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-External_plugins">
+ <title>External Plugins</title>
+ <para>GateIn Kernel supports non-component objects that can be configured,
instantiated, and injected into registered components, using method calls.
+ The mechanism is called 'plugins', and allows portal extensions to add
additional configurations to core services.</para>
+ <para>External plugin is defined by using <emphasis
role="bold"><external-component-plugins></emphasis>
wrapper element which contains one or more
+ <emphasis
role="bold"><component-plugin></emphasis> definitions.
<external-component-plugins> uses <emphasis
role="bold"><target-component></emphasis> to specify a
target service component that will receive injected objects.</para>
+ <para>Every <component-plugin> defines an implementation
type, and a method on target component
+ to use for injection (<emphasis
role="bold"><set-method></emphasis>). </para>
+ <para>A plugin implementation class has to implement <emphasis
role="bold">org.exoplatform.container.component.
ComponentPlugin</emphasis> interface.</para>
+ <para>In the following example <emphasis
role="bold">PortalContainerDefinitionPlugin</emphasis> implements
ComponentPlugin:</para>
+ <example>
+ <title>PortalContainerDefinitionPlugin</title>
+ <programlisting role="XML"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
+
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+
+ <external-component-plugins>
+
<target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Add PortalContainer Definitions</name>
+
+ <!-- The name of the method to call on the PortalContainerConfig
+ in order to register the PortalContainerDefinitions -->
+ <set-method>registerPlugin</set-method>
+
+ <!-- The fully qualified name of the PortalContainerDefinitionPlugin -->
+
<type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
+
+ ...
+
+ </component-plugin>
+ </external-component-plugins>
+</configuration>
+ ]]></programlisting>
+ </example>
+ </section>
+
+ <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Includes">
+ <title>Includes, and special URLs</title>
+ <para>It is possible to break <emphasis
role="bold">configuration.xml</emphasis> file into many smaller files,
that are then included into a 'master' configuration file.
+ The included files are complete configuration xml documents by themselves - they
are not fragments of text.</para>
+ <para>An example configuration.xml that 'outsources' its content
into several files:</para>
+ <programlisting role="XML"><![CDATA[
+<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
+
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+
+ <import>war:/conf/sample-ext/jcr/jcr-configuration.xml</import>
+ <import>war:/conf/sample-ext/portal/portal-configuration.xml</import>
+
+</configuration>
+ ]]></programlisting>
+
+ <para>We see a special URL being used to reference another configuration
file.
+ URL schema <emphasis
role="bold">'war:'</emphasis> means, that the path that follows
is resolved relative to current PortalContainer's servlet context resource path,
starting at <emphasis role="bold">WEB-INF</emphasis> as a
root.</para>
+ <note>
+ <para>Current PortalContainer is really a newly created
PortalContainer, as war: URLs only make sense for PortalContainer scoped
configuration.</para>
+ </note>
+ <para>Also, thanks to extension mechanism, the servlet context used for
resource loading is a <emphasis role="bold">unified servlet
context</emphasis> (as explaned in a later section).</para>
+ <para>To have include path resolved relative to current classpath (context
classloader), use <emphasis role="bold">'jar:'</emphasis>
URL schema.</para>
+ </section>
+
+ <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars">
+ <title>Special variables</title>
+ <para>Configuration files may contain a <emphasis
role="bold">special variable</emphasis> reference
<emphasis>${container.name.suffix}</emphasis>. This variable resolves to the
name of the current portal container, prefixed by underscore (_).
+ This facilitates reuse of configuration files in situations where portal
specific unique names need to be assigned to some resources
+ (i.e. JNDI names, Database / DataSource names, JCR repository names, etc
...).</para>
+ <para>This variable is only defined when there is a current
PortalContainer available - only for PortalContainer scoped services.</para>
+ <para>A good example for this is <emphasis
role="bold">HibernateService</emphasis>:</para>
+ <example
id="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars-Example">
+ <title>HibernateService using variables</title>
+ <programlisting role="XML"><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
+
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+
+ <component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <jmx-name>database:type=HibernateService</jmx-name>
+
<type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+ <init-params>
+ <properties-param>
+ <name>hibernate.properties</name>
+ <description>Default Hibernate Service</description>
+ <property name="hibernate.show_sql" value="false"
/>
+ <property name="hibernate.cglib.use_reflection_optimizer"
value="true" />
+ <property name="hibernate.connection.url"
+
value="jdbc:hsqldb:file:../temp/data/exodb${container.name.suffix}" />
+ <property name="hibernate.connection.driver_class"
value="org.hsqldb.jdbcDriver" />
+ <property name="hibernate.connection.autocommit"
value="true" />
+ <property name="hibernate.connection.username"
value="sa" />
+ <property name="hibernate.connection.password"
value="" />
+ <property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect" />
+ <property name="hibernate.c3p0.min_size" value="5"
/>
+ <property name="hibernate.c3p0.max_size" value="20"
/>
+ <property name="hibernate.c3p0.timeout" value="1800"
/>
+ <property name="hibernate.c3p0.max_statements"
value="50" />
+ </properties-param>
+ </init-params>
+ </component>
+</configuration>
+ ]]></programlisting>
+ </example>
+
+ </section>
+ </section>
+
+
+ <section id="sect-Reference_Guide-Foundations-Init_params">
+ <title>InitParams configuration object</title>
+
+ <para>
+ <literal>InitParams</literal> is a configuration object that is
essentially a map of key-value pairs,
+ where key is always a <literal>String</literal>, and value can be
any type that can be described
+ using kernel configuration xml.
+ </para>
+
+ <para>
+ Service components that form the &PRODUCT; insfrastructure use
<literal>InitParams</literal> object to configure themselves.
+ A component can have one instance of InitParams injected at most. If the service
component's constructor takes InitParams
+ as any of the parameters it will automatically be injected at component
instantiation time. The xml configuration
+ for a service component that expects InitParams object must include
<init-params> element (even if an empty one).
+ </para>
+
+ <para>
+ Let's use an example to see how the kernel xml configuration syntax looks
for creating <literal>InitParams</literal> instances.
+ </para>
+
+ <example>
+ <title>InitParams - properties-param</title>
+ <programlisting role="XML"><![CDATA[
+<component>
+ <key>org.exoplatform.services.naming.InitialContextInitializer</key>
+ <type>org.exoplatform.services.naming.InitialContextInitializer</type>
+ <init-params>
+ <properties-param>
+ <name>default-properties</name>
+ <description>Default initial context properties</description>
+ <property name="java.naming.factory.initial"
+ value="org.exoplatform.services.naming.SimpleContextFactory"
/>
+ </properties-param>
+ </init-params>
+</component>
+ ]]></programlisting>
+ </example>
+
+ <para>
+ InitParams object description begins with <init-params> element.
It can have zero or more children elements
+ each of which is one of <value-param>,
<values-param>, <properties-param>, or
<object-param>.
+ Each of these child elements takes a <name> that serves as a map
entry key, and an optional <description>.
+ It also takes a type-specific value specification.
+ </para>
+
+ <para>
+ For <properties-param> the value specification is in the form of
one or more <property> elements,
+ each of which specifies two strings - a property name, and a property value.
Each <properties-params>
+ defines one <literal>java.util.Properties</literal> instance. Also
see
+ <xref
linkend="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars-Example"/>
for an example.
+ </para>
+
+ <example>
+ <title>InitParams - value-param</title>
+ <programlisting role="XML"><![CDATA[
+<component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+
<type>org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>5</value>
+ </value-param>
+ </init-params>
+</component>
+ ]]></programlisting>
+ </example>
+
+ <para>
+ For <value-param> the value specification is in the form of
<value> element, which defines
+ one <literal>String</literal> instance.
+ </para>
+
+ <example>
+ <title>InitParams - values-param</title>
+ <programlisting role="XML"><![CDATA[
+<component>
+ <key>org.exoplatform.services.resources.ResourceBundleService</key>
+
<type>org.exoplatform.services.resources.impl.SimpleResourceBundleService</type>
+ <init-params>
+ <values-param>
+ <name>classpath.resources</name>
+ <description>The resources that start with the following package name
should be load from file system</description>
+ <value>locale.portlet</value>
+ </values-param>
+
+ <values-param>
+ <name>init.resources</name>
+ <description>Store the following resources into the db for the first
launch </description>
+ <value>locale.test.resources.test</value>
+ </values-param>
+
+ <values-param>
+ <name>portal.resource.names</name>
+ <description>The properties files of the portal , those file will be
merged
+ into one ResourceBundle properties </description>
+ <value>local.portal.portal</value>
+ <value>local.portal.custom</value>
+ </values-param>
+ </init-params>
+</component>
+ ]]></programlisting>
+ </example>
+
+ <para>
+ For <values-param> the value specification is in the form of one or
more <value> elements,
+ each of which represents one <literal>String</literal> instance,
where all the <literal>String</literal> values
+ are then collected into a <literal>java.util.List</literal>
instance.
+ </para>
+
+ <example>
+ <title>InitParams - object-param</title>
+ <programlisting role="XML"><![CDATA[
+<component>
+ <key>org.exoplatform.services.cache.CacheService</key>
+ <jmx-name>cache:type=CacheService</jmx-name>
+ <type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
+ <init-params>
+ <object-param>
+ <name>cache.config.default</name>
+ <description>The default cache configuration</description>
+ <object type="org.exoplatform.services.cache.ExoCacheConfig">
+ <field name="name">
+ <string>default</string>
+ </field>
+ <field name="maxSize">
+ <int>300</int>
+ </field>
+ <field name="liveTime">
+ <long>300</long>
+ </field>
+ <field name="distributed">
+ <boolean>false</boolean>
+ </field>
+ <field name="implementation">
+
<string>org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+</component>
+ ]]></programlisting>
+ </example>
+
+ <para>
+ For <object-param> in our case, the value specification comes in a
form of <object> element, which is
+ used for POJO style object specification (you specify an implementation class -
<type>, and property values - <field>).
+ </para>
+
+ <para>
+ Also see <xref
linkend="sect-Reference_Guide-Foundations-Configuring_portal_Container_declaration_example"
/>
+ for an example of specifying a field of
<literal>Collection</literal> type.
+ </para>
+
+ <para>
+ The <literal>InitParams</literal> structure - the names and types of
entries is specific for each service,
+ as it is the code inside service components's class that decides what entry
names to look up and what types
+ it expects to find.
+ </para>
+ </section>
+
+
+ <section id="sect-Reference_Guide-Foundations-Configuring_portal">
+ <title>Configuring a portal container</title>
+
+ <para>
+ A <emphasis role="bold">portal container</emphasis> is
defined by several attributes.
+ </para>
+
+ <para>
+ First, there is a <emphasis role="bold">portal container
name</emphasis>, which is always equal to URL context to which the current portal is
bound.
+ </para>
+
+ <para>
+ Second, there is a <emphasis role="bold">REST context
name</emphasis>, which is used for REST access to portal application - every portal
has
+ exactly one (unique) REST context name.
+ </para>
+
+ <para>
+ Then, there is a <emphasis role="bold">realm
name</emphasis> which is the name of security realm used for authentication when
users log into the
+ portal.
+ </para>
+
+ <para>
+ Finally, there is a list of <emphasis
role="bold">Dependencies</emphasis> - other web applications, whose
resources are visible to current
+ portal (via extension mechanism described later), and are searched in the
specified order.
+ </para>
+
+ <example
id="sect-Reference_Guide-Foundations-Configuring_portal_Container_declaration_example">
+ <title>Portal container declaration example</title>
+ <programlisting role="XML"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
+
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+
+ <external-component-plugins>
+ <!-- The full qualified name of the PortalContainerConfig -->
+
<target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
+
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Add PortalContainer Definitions</name>
+
+ <!-- The name of the method to call on the PortalContainerConfig
+ in order to register the PortalContainerDefinitions -->
+ <set-method>registerPlugin</set-method>
+
+ <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
+
<type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
+
+ <init-params>
+ <object-param>
+ <name>portal</name>
+ <object
type="org.exoplatform.container.definition.PortalContainerDefinition">
+ <!-- The name of the portal container -->
+ <field
name="name"><string>portal</string></field>
+
+ <!-- The name of the context name of the rest web application
-->
+ <field
name="restContextName"><string>rest</string></field>
+
+ <!-- The name of the realm -->
+ <field
name="realmName"><string>exo-domain</string></field>
+
+ <!-- All the dependencies of the portal container ordered by loading
priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>eXoResources</string>
+ </value>
+ <value>
+ <string>portal</string>
+ </value>
+ <value>
+ <string>dashboard</string>
+ </value>
+ <value>
+ <string>exoadmin</string>
+ </value>
+ <value>
+ <string>eXoGadgets</string>
+ </value>
+ <value>
+ <string>eXoGadgetServer</string>
+ </value>
+ <value>
+ <string>rest</string>
+ </value>
+ <value>
+ <string>web</string>
+ </value>
+ <value>
+ <string>wsrp-producer</string>
+ </value>
+ <!-- The sample-ext has been added at the end of the
dependency list
+ in order to have the highest priority -->
+ <value>
+ <string>sample-ext</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration>
+ ]]>
+</programlisting>
+ </example>
+
+
+ <note>
+ <para>Dependencies are part of the extension mechanism.</para>
+ </note>
+
+ <para>
+ Every <emphasis role="bold">portal container</emphasis> is
represented by a <emphasis role="bold">PortalContainer
instance</emphasis>, which contains:
+ <itemizedlist>
+ <listitem>
+ <para>associated <emphasis
role="bold">ExoContainerContext</emphasis>, which contains information
about the portal</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">unified servlet
context</emphasis>, for web-archive-relative resource loading</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">unified
classloader</emphasis>, for classpath based resource loading</para>
+ </listitem>
+ <listitem>
+ <para>methods for retrieving services</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ <emphasis role="bold">Unified servlet context</emphasis>,
and <emphasis role="bold">unified classloader</emphasis> are part of
the <emphasis role="bold">extension mechanism</emphasis> (explained
in next section),
+ and provide standard API (ServletContext, ClassLoader) with specific resource
loading behavior - visibility into associated web application archives,
+ configured with Dependencies property of PortalContainerDefinition. Resources
from other web applications are queried in the order specified by Dependencies.
+ The later entries in the list override the previous ones.
+ </para>
+ </section>
+
+ <section id="sect-Reference_Guide-Foundations-Extension_mechanism">
+ <title>GateIn Extension Mechanism, and Portal Extensions</title>
+
+ <para>
+ <emphasis role="bold">Extension mechanism</emphasis> is a
functionality that makes it possible to override portal resources in an almost
+ plug-and-play fashion - just drop in a .war archive with the resources, and
configure its position on the portal's
+ classpath.
+ This way any customizations of the portal don't have to involve unpacking
and repacking the original portal
+ .war archives. Instead, you create your own .war archive with changed resources,
that override the resources in
+ the original archive.
+ </para>
+
+ <para>
+ A web archive packaged in a way to be used through extension mechanism is called
<emphasis role="bold">portal extension</emphasis>.
+ </para>
+ <para>
+ There are two steps necessary to create a portal extension.
+ </para>
+ <para>
+ First, declare <emphasis
role="bold">PortalConfigOwner</emphasis> servlet context listener in
web.xml of your web application.
+ </para>
+ <example><title>Example of a portal extension called
sample-ext:</title>
+
+ <programlisting role="XML"><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE web-app PUBLIC -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN
+
http://java.sun.com/dtd/web-app_2_3.dtd>
+<web-app>
+
+ <display-name>sample-ext</display-name>
+
+ <listener>
+
<listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
+ </listener>
+
+ ...
+
+</web-app>
+ ]]></programlisting>
+ </example>
+ <para>
+ Then, add the servlet context name of this web application in proper place in
the list of Dependencies of the PortalContainerDefinition
+ of all the portal containers that you want to have access to its resources.
+ </para>
+ <para>
+ After this step your web archive will be on portal's unified classpath, and
unified servlet context resource path.
+ The later in the Dependencies list your application is, the higher priority it
has when resources are loaded by portal.
+ </para>
+
+ <note>
+ <para>See 'Configuring a portal' section for example of
PortalContainerDefinition, that has sample-ext at the end of its list of
Dependencies.</para>
+ </note>
+
+ </section>
+
+
+ <section id="sect-Reference_Guide-Foundations-Multiple_portals">
+ <title>Running Multiple Portals</title>
+
+ <para>
+ It is possible to run several independent portal containers - each bound to a
different URL context - within
+ the same JVM instance. This kind of setup is very efficient from administration
and resource consumption
+ aspect. The most elegant way to <emphasis
role="bold">reuse</emphasis> configuration for different coexisting
portals is by way of extension
+ mechanism - by <emphasis role="bold">inheriting</emphasis>
resources and configuration from existing web archives, and just <emphasis
role="bold">adding</emphasis> extra resources to it,
+ and <emphasis role="bold">overriding</emphasis> those that
need to be changed by including modified copies.
+ </para>
+
+ <para>
+ In order for a portal application to correctly function when deployed in
multiple portals, the application may
+ have to dynamically query the information about the current portal container.
The application should not make
+ any assumptions about the name, and other information of the current portal, as
there are now multiple different portals in play.
+ </para>
+
+ <para>
+ At any point during request processing, or lifecycle event processing, your
application can retrieve this
+ information through <emphasis
role="bold">org.exoplatform.container. ExoContainerContext</emphasis>.
+ Sometimes your application needs to make sure that the proper <emphasis
role="bold">PortalContainer</emphasis>
+ - the source of <emphasis
role="bold">ExoContainerContext</emphasis> - is associated with the
current call.
+ </para>
+
+ <para>
+ If you ship servlets or servlet filters as part of your portal application, and
if you need to access portal
+ specific resources at any time during the processing of the servlet or filter
request, then you need to make
+ sure the servlet/filter is associated with the current container.
+ </para>
+ <para>
+ The proper way to do that is to make your servlet extend <emphasis
role="bold">org.exoplatform.container.web.
AbstractHttpServlet</emphasis>
+ class.
+ This will not only properly initialize current <emphasis
role="bold">PortalContainer</emphasis> for you, but will also set the
current thread's
+ context classloader to one that looks for resources in associated web
applications in the order specified by
+ <emphasis role="bold">Dependencies</emphasis>
configuration (as explained in Extension mechanism section).
+ </para>
+ <para>
+ Similarly for filters, make sure your filter class extends <emphasis
role="bold">org.exoplatform.container.web. AbstractFilter</emphasis>.
+ Both <emphasis role="bold">AbstractHttpServlet</emphasis>,
and <emphasis role="bold">AbstractFilter</emphasis> have a method
<emphasis role="bold">getContainer()</emphasis>,
+ which returns the current <emphasis
role="bold">PortalContainer</emphasis>.
+
+ If your servlet handles the requests by implementing a <emphasis
role="bold">service()</emphasis> method, you need to rename that method
to match
+ the following signature:</para>
+ <programlisting role="JAVA"><![CDATA[
+/**
+ * Use this method instead of Servlet.service()
+ */
+protected void onService(ExoContainer container, HttpServletRequest req,
+ HttpServletResponse res) throws ServletException, IOException;
+ ]]></programlisting>
+ <note>
+ <para>
+ The reason is that AbstractHttpServlet implements service() to perform its
interception, and you don't want to
+ overwrite (by overriding) this functionality.
+ </para>
+ </note>
+ <para>
+ You may also need to access portal information within your <emphasis
role="bold">HttpSessionListener</emphasis>. Again, make sure to extend
the
+ provided abstract class - <emphasis
role="bold">org.exoplatform.container.web.
AbstractHttpSessionListener</emphasis>.
+ Also, modify your method signatures as follows:</para>
+ <programlisting role="JAVA"><![CDATA[
+/**
+ * Use this method instead of HttpSessionListener.sessionCreated()
+ */
+protected void onSessionCreated(ExoContainer container, HttpSessionEvent event);
+
+/**
+ * Use this method instead of HttpSessionListener.sessionDestroyed()
+ */
+protected void onSessionDestroyed(ExoContainer container, HttpSessionEvent event);
+ ]]></programlisting>
+ <para>
+ There is another method you have to implement in this case:</para>
+ <programlisting role="JAVA"><![CDATA[
+/**
+ * Method should return true if unified servlet context,
+ * and unified classloader should be made available
+ */
+protected boolean requirePortalEnvironment();
+ ]]></programlisting>
+ <para>
+ If this method returns true, current thread's context classloader is set up
according to <emphasis role="bold">Dependencies</emphasis>
+ configuration, and availability of the associated web applications. If it
returns false, the standard
+ application separation rules are used for resource loading (effectively turning
off the
+ extension mechanism). This method exists on <emphasis
role="bold">AbstractHttpServlet</emphasis> and <emphasis
role="bold">AbstractFilter</emphasis> as well, where there is a
+ default implementation that automatically returns true, when it detects there is
a current PortalContainer
+ present, otherwise it returns false.
+
+ </para>
+
+ <para>
+ We still have to explain how to properly perform <emphasis
role="bold">ServletContextListener</emphasis> based initialization,
when you need
+ access to current PortalContainer.
+ </para>
+
+ <para>
+ GateIn has no direct control over the deployment of application archives (.war,
.ear files) - it is the
+ application server that performs the deployment. For <emphasis
role="bold">extension mechanism</emphasis> to work properly, the
applications,
+ associated with the portal via <emphasis
role="bold">Dependencies</emphasis> configuration, have to be deployed
before the portal, that depends
+ on them, is initialized. On the other hand, these applications may require an
already initialized PortalContainer
+ to properly initialize themselves - we have a recursive dependency problem. To
resolve this problem, a
+ mechanism of <emphasis role="bold">initialization
tasks</emphasis>, and <emphasis role="bold">task
queues</emphasis>, was put in place. Web applications that depend on current
+ PortalContainer for their initialization have to avoid performing their
initialization directly in some
+ ServletContextListener executed during their deployment (before any
PortalContainer was initialized). Instead,
+ a web application should package its initialization logic into an init task of
appropriate type, and only use
+ ServletContextListener to insert the init task instance into the proper init
tasks queue.
+ </para>
+
+ <para>An example of this is Gadgets application which registers Google
gadgets with the current PortalContainer:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[
+public class GadgetRegister implements ServletContextListener
+{
+ public void contextInitialized(ServletContextEvent event)
+ {
+ // Create a new post-init task
+ final PortalContainerPostInitTask task = new PortalContainerPostInitTask() {
+
+ public void execute(ServletContext context, PortalContainer portalContainer)
+ {
+ try
+ {
+ SourceStorage sourceStorage =
+ (SourceStorage)
portalContainer.getComponentInstanceOfType(SourceStorage.class);
+ ...
+ }
+ catch (RuntimeException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Initialization failed: ", e);
+ }
+ }
+ };
+
+ // Add post-init task for execution on all the portal containers
+ // that depend on the given ServletContext according to
+ // PortalContainerDefinitions (via Dependencies configuration)
+ PortalContainer.addInitTask(event.getServletContext(), task);
+ }
+}
+ ]]></programlisting>
+
+ <para>
+ The above example uses <emphasis
role="bold">PortalContainerPostInitTask</emphasis>, which gets executed
after the portal container has been
+ initialized. In some situations you may want to execute initialization after
portal container was instantiated,
+ but before it was initialized - use <emphasis
role="bold">PortalContainerPreInitTask</emphasis> in that case. Or, you
may want to execute
+ initialization after all the post-init tasks have been executed - use
<emphasis role="bold">PortalContainerPostCreateTask</emphasis> in
that case.
+ </para>
+
+ <para>
+ One more area that may need your attention are <emphasis
role="bold">LoginModules</emphasis>. If you use custom LoginModules,
that require
+ current ExoContainer, make sure they extend <emphasis
role="bold">org.exoplatform.services.security.jaas.AbstractLoginModule</emphasis>
for
+ proper initialization. AbstractLoginModule also takes care of the basic
configuration - it recognizes two
+ initialization options - <emphasis
role="bold">portalContainerName</emphasis>, and <emphasis
role="bold">realmName</emphasis> whose values you can access via
protected fields of
+ the same name.
+ </para>
+
+ </section>
+
+</section>
Deleted: portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/Foundations.xml
===================================================================
---
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/Foundations.xml 2010-04-15
10:32:55 UTC (rev 2651)
+++
portal/trunk/docs/reference-guide/en/modules/PortalDevelopment/Foundations.xml 2010-04-15
10:43:53 UTC (rev 2652)
@@ -1,733 +0,0 @@
-<?xml version='1.0' encoding='utf-8' ?>
-<!DOCTYPE chapter 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-Foundations">
-
- <title>Foundations</title>
- <section id="sect-Reference_Guide-Foundations-Kernel">
- <title>GateIn Kernel</title>
- <para>
- &PRODUCT; is built as a set of services on top of a dependency injection
kernel. The kernel provides configuration, lifecycle handling, component scopes, and some
core services.
- </para>
- <para>
- Service components exist in two scopes. First scope is represented by
<emphasis role="bold">RootContainer</emphasis> - it contains
services that exist independently of any portal, and can be
- accessed by all portals.
- </para>
- <para>
- Second scope is portal-private in the form of <emphasis
role="bold">PortalContainer</emphasis>. Each portal lives in an
instance of PortalContainer.
- This scope contains services that are common for a set of portals, and services
which should not be shared by all portals.
- </para>
- <para>
- <mediaobject>
- <imageobject role="html">
- <imagedata
fileref="images/PortalDevelopment/Foundations/PortalContainers.png"
format="PNG" align="center" scale="100" />
- </imageobject>
- <imageobject role="fo">
- <imagedata
fileref="images/PortalDevelopment/Foundations/PortalContainers.png"
format="PNG" align="center" contentwidth="150mm" />
- </imageobject>
- </mediaobject>
- </para>
- <para>
- Whenever a specific service is looked up through PortalContainer, and the
service is not available, the lookup is
- delegated further up to RootContainer. We can therefore have default instance of
a certain component in
- RootContainer, and portal specific instances in some or all PortalContainers,
that override the default
- instance.
- </para>
- <para>
- Whenever your portal application has to be integrated more closely with GateIn
services, the way to do it is by
- looking up these services through PortalContainer. Be careful though - only
officially documented services
- should be accessed this way, and used according to documentation, as most of the
services are an implementation
- detail of GateIn, and subject to change without notice.
- </para>
- </section>
-
- <section id="sect-Reference_Guide-Foundations-Configuring_services">
- <title>Configuring services</title>
-
- <para>GateIn Kernel uses dependency injection to create services based on
<emphasis role="bold">configuration.xml</emphasis> configuration
files.
- The location of the configuration files determines if services are placed into
RootContainer scope, or into PortalContainer scope.
- All configuration.xml files located at <emphasis
role="bold">conf/configuration.xml</emphasis> in the classpath (any
directory, or any jar in the classpath) will have their
- services configured at RootContainer scope.
- All configuration.xml files located at <emphasis
role="bold">conf/portal/configuration.xml</emphasis> in the classpath
will have their services configured at PortalContainer scope.
- Additionally, <emphasis role="bold">portal
extensions</emphasis> can contain configuration in <emphasis
role="bold">WEB-INF/conf/configuration.xml</emphasis>, and will also
have their services configured at PortalContainer scope.
- </para>
- <note>
- <para>Portal extensions are described later on.</para>
- </note>
-
- </section>
-
- <section id="sect-Reference_Guide-Foundations-Configuration_syntax">
- <title>Configuration syntax</title>
-
- <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Component">
- <title>Components</title>
- <para>A service component is defined in <emphasis
role="bold">configuration.xml</emphasis> by using <emphasis
role="bold"><component></emphasis> element.</para>
- <para>There is only one required information when defining a service - the
service implementation class, specified using <emphasis
role="bold"><type></emphasis></para>
- <para>Every component has a <emphasis
role="bold"><key></emphasis> that identifies it. If not
explicitly set, a key defaults to the value of <type>.
- If key can be loaded as a class, a Class object is used as a key, otherwise a
String is used.</para>
- <para>The usual approach is to specify an interface as a
key.</para>
-
- <example>
- <title>Example of service component configuration:</title>
- <programlisting role="XML"><![CDATA[
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<configuration
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
-
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
-
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
- <component>
- <key>org.exoplatform.services.database.HibernateService</key>
-
<type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
-
- ...
-
- </component>
-</configuration>
- ]]></programlisting>
- </example>
- </section>
- <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-External_plugins">
- <title>External Plugins</title>
- <para>GateIn Kernel supports non-component objects that can be configured,
instantiated, and injected into registered components, using method calls.
- The mechanism is called 'plugins', and allows portal extensions to add
additional configurations to core services.</para>
- <para>External plugin is defined by using <emphasis
role="bold"><external-component-plugins></emphasis>
wrapper element which contains one or more
- <emphasis
role="bold"><component-plugin></emphasis> definitions.
<external-component-plugins> uses <emphasis
role="bold"><target-component></emphasis> to specify a
target service component that will receive injected objects.</para>
- <para>Every <component-plugin> defines an implementation
type, and a method on target component
- to use for injection (<emphasis
role="bold"><set-method></emphasis>). </para>
- <para>A plugin implementation class has to implement <emphasis
role="bold">org.exoplatform.container.component.
ComponentPlugin</emphasis> interface.</para>
- <para>In the following example <emphasis
role="bold">PortalContainerDefinitionPlugin</emphasis> implements
ComponentPlugin:</para>
- <example>
- <title>PortalContainerDefinitionPlugin</title>
- <programlisting role="XML"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
-
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
-
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
-
- <external-component-plugins>
-
<target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
- <component-plugin>
- <!-- The name of the plugin -->
- <name>Add PortalContainer Definitions</name>
-
- <!-- The name of the method to call on the PortalContainerConfig
- in order to register the PortalContainerDefinitions -->
- <set-method>registerPlugin</set-method>
-
- <!-- The fully qualified name of the PortalContainerDefinitionPlugin -->
-
<type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
-
- ...
-
- </component-plugin>
- </external-component-plugins>
-</configuration>
- ]]></programlisting>
- </example>
- </section>
-
- <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Includes">
- <title>Includes, and special URLs</title>
- <para>It is possible to break <emphasis
role="bold">configuration.xml</emphasis> file into many smaller files,
that are then included into a 'master' configuration file.
- The included files are complete configuration xml documents by themselves - they
are not fragments of text.</para>
- <para>An example configuration.xml that 'outsources' its content
into several files:</para>
- <programlisting role="XML"><![CDATA[
-<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
-
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
-
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
-
- <import>war:/conf/sample-ext/jcr/jcr-configuration.xml</import>
- <import>war:/conf/sample-ext/portal/portal-configuration.xml</import>
-
-</configuration>
- ]]></programlisting>
-
- <para>We see a special URL being used to reference another configuration
file.
- URL schema <emphasis
role="bold">'war:'</emphasis> means, that the path that follows
is resolved relative to current PortalContainer's servlet context resource path,
starting at <emphasis role="bold">WEB-INF</emphasis> as a
root.</para>
- <note>
- <para>Current PortalContainer is really a newly created
PortalContainer, as war: URLs only make sense for PortalContainer scoped
configuration.</para>
- </note>
- <para>Also, thanks to extension mechanism, the servlet context used for
resource loading is a <emphasis role="bold">unified servlet
context</emphasis> (as explaned in a later section).</para>
- <para>To have include path resolved relative to current classpath (context
classloader), use <emphasis role="bold">'jar:'</emphasis>
URL schema.</para>
- </section>
-
- <section
id="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars">
- <title>Special variables</title>
- <para>Configuration files may contain a <emphasis
role="bold">special variable</emphasis> reference
<emphasis>${container.name.suffix}</emphasis>. This variable resolves to the
name of the current portal container, prefixed by underscore (_).
- This facilitates reuse of configuration files in situations where portal
specific unique names need to be assigned to some resources
- (i.e. JNDI names, Database / DataSource names, JCR repository names, etc
...).</para>
- <para>This variable is only defined when there is a current
PortalContainer available - only for PortalContainer scoped services.</para>
- <para>A good example for this is <emphasis
role="bold">HibernateService</emphasis>:</para>
- <example
id="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars-Example">
- <title>HibernateService using variables</title>
- <programlisting role="XML"><![CDATA[
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<configuration
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
-
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
-
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
-
- <component>
- <key>org.exoplatform.services.database.HibernateService</key>
- <jmx-name>database:type=HibernateService</jmx-name>
-
<type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
- <init-params>
- <properties-param>
- <name>hibernate.properties</name>
- <description>Default Hibernate Service</description>
- <property name="hibernate.show_sql" value="false"
/>
- <property name="hibernate.cglib.use_reflection_optimizer"
value="true" />
- <property name="hibernate.connection.url"
-
value="jdbc:hsqldb:file:../temp/data/exodb${container.name.suffix}" />
- <property name="hibernate.connection.driver_class"
value="org.hsqldb.jdbcDriver" />
- <property name="hibernate.connection.autocommit"
value="true" />
- <property name="hibernate.connection.username"
value="sa" />
- <property name="hibernate.connection.password"
value="" />
- <property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect" />
- <property name="hibernate.c3p0.min_size" value="5"
/>
- <property name="hibernate.c3p0.max_size" value="20"
/>
- <property name="hibernate.c3p0.timeout" value="1800"
/>
- <property name="hibernate.c3p0.max_statements"
value="50" />
- </properties-param>
- </init-params>
- </component>
-</configuration>
- ]]></programlisting>
- </example>
-
- </section>
- </section>
-
-
- <section id="sect-Reference_Guide-Foundations-Init_params">
- <title>InitParams configuration object</title>
-
- <para>
- <literal>InitParams</literal> is a configuration object that is
essentially a map of key-value pairs,
- where key is always a <literal>String</literal>, and value can be
any type that can be described
- using kernel configuration xml.
- </para>
-
- <para>
- Service components that form the &PRODUCT; insfrastructure use
<literal>InitParams</literal> object to configure themselves.
- A component can have one instance of InitParams injected at most. If the service
component's constructor takes InitParams
- as any of the parameters it will automatically be injected at component
instantiation time. The xml configuration
- for a service component that expects InitParams object must include
<init-params> element (even if an empty one).
- </para>
-
- <para>
- Let's use an example to see how the kernel xml configuration syntax looks
for creating <literal>InitParams</literal> instances.
- </para>
-
- <example>
- <title>InitParams - properties-param</title>
- <programlisting role="XML"><![CDATA[
-<component>
- <key>org.exoplatform.services.naming.InitialContextInitializer</key>
- <type>org.exoplatform.services.naming.InitialContextInitializer</type>
- <init-params>
- <properties-param>
- <name>default-properties</name>
- <description>Default initial context properties</description>
- <property name="java.naming.factory.initial"
- value="org.exoplatform.services.naming.SimpleContextFactory"
/>
- </properties-param>
- </init-params>
-</component>
- ]]></programlisting>
- </example>
-
- <para>
- InitParams object description begins with <init-params> element.
It can have zero or more children elements
- each of which is one of <value-param>,
<values-param>, <properties-param>, or
<object-param>.
- Each of these child elements takes a <name> that serves as a map
entry key, and an optional <description>.
- It also takes a type-specific value specification.
- </para>
-
- <para>
- For <properties-param> the value specification is in the form of
one or more <property> elements,
- each of which specifies two strings - a property name, and a property value.
Each <properties-params>
- defines one <literal>java.util.Properties</literal> instance. Also
see
- <xref
linkend="sect-Reference_Guide-Foundations-Configuration_syntax-Special_vars-Example"/>
for an example.
- </para>
-
- <example>
- <title>InitParams - value-param</title>
- <programlisting role="XML"><![CDATA[
-<component>
- <key>org.exoplatform.services.transaction.TransactionService</key>
-
<type>org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl</type>
- <init-params>
- <value-param>
- <name>timeout</name>
- <value>5</value>
- </value-param>
- </init-params>
-</component>
- ]]></programlisting>
- </example>
-
- <para>
- For <value-param> the value specification is in the form of
<value> element, which defines
- one <literal>String</literal> instance.
- </para>
-
- <example>
- <title>InitParams - values-param</title>
- <programlisting role="XML"><![CDATA[
-<component>
- <key>org.exoplatform.services.resources.ResourceBundleService</key>
-
<type>org.exoplatform.services.resources.impl.SimpleResourceBundleService</type>
- <init-params>
- <values-param>
- <name>classpath.resources</name>
- <description>The resources that start with the following package name
should be load from file system</description>
- <value>locale.portlet</value>
- </values-param>
-
- <values-param>
- <name>init.resources</name>
- <description>Store the following resources into the db for the first
launch </description>
- <value>locale.test.resources.test</value>
- </values-param>
-
- <values-param>
- <name>portal.resource.names</name>
- <description>The properties files of the portal , those file will be
merged
- into one ResourceBundle properties </description>
- <value>local.portal.portal</value>
- <value>local.portal.custom</value>
- </values-param>
- </init-params>
-</component>
- ]]></programlisting>
- </example>
-
- <para>
- For <values-param> the value specification is in the form of one or
more <value> elements,
- each of which represents one <literal>String</literal> instance,
where all the <literal>String</literal> values
- are then collected into a <literal>java.util.List</literal>
instance.
- </para>
-
- <example>
- <title>InitParams - object-param</title>
- <programlisting role="XML"><![CDATA[
-<component>
- <key>org.exoplatform.services.cache.CacheService</key>
- <jmx-name>cache:type=CacheService</jmx-name>
- <type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
- <init-params>
- <object-param>
- <name>cache.config.default</name>
- <description>The default cache configuration</description>
- <object type="org.exoplatform.services.cache.ExoCacheConfig">
- <field name="name">
- <string>default</string>
- </field>
- <field name="maxSize">
- <int>300</int>
- </field>
- <field name="liveTime">
- <long>300</long>
- </field>
- <field name="distributed">
- <boolean>false</boolean>
- </field>
- <field name="implementation">
-
<string>org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache</string>
- </field>
- </object>
- </object-param>
- </init-params>
-</component>
- ]]></programlisting>
- </example>
-
- <para>
- For <object-param> in our case, the value specification comes in a
form of <object> element, which is
- used for POJO style object specification (you specify an implementation class -
<type>, and property values - <field>).
- </para>
-
- <para>
- Also see <xref
linkend="sect-Reference_Guide-Foundations-Configuring_portal_Container_declaration_example"
/>
- for an example of specifying a field of
<literal>Collection</literal> type.
- </para>
-
- <para>
- The <literal>InitParams</literal> structure - the names and types of
entries is specific for each service,
- as it is the code inside service components's class that decides what entry
names to look up and what types
- it expects to find.
- </para>
- </section>
-
-
- <section id="sect-Reference_Guide-Foundations-Configuring_portal">
- <title>Configuring a portal container</title>
-
- <para>
- A <emphasis role="bold">portal container</emphasis> is
defined by several attributes.
- </para>
-
- <para>
- First, there is a <emphasis role="bold">portal container
name</emphasis>, which is always equal to URL context to which the current portal is
bound.
- </para>
-
- <para>
- Second, there is a <emphasis role="bold">REST context
name</emphasis>, which is used for REST access to portal application - every portal
has
- exactly one (unique) REST context name.
- </para>
-
- <para>
- Then, there is a <emphasis role="bold">realm
name</emphasis> which is the name of security realm used for authentication when
users log into the
- portal.
- </para>
-
- <para>
- Finally, there is a list of <emphasis
role="bold">Dependencies</emphasis> - other web applications, whose
resources are visible to current
- portal (via extension mechanism described later), and are searched in the
specified order.
- </para>
-
- <example
id="sect-Reference_Guide-Foundations-Configuring_portal_Container_declaration_example">
- <title>Portal container declaration example</title>
- <programlisting role="XML"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
-
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
-
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
-
- <external-component-plugins>
- <!-- The full qualified name of the PortalContainerConfig -->
-
<target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
-
- <component-plugin>
- <!-- The name of the plugin -->
- <name>Add PortalContainer Definitions</name>
-
- <!-- The name of the method to call on the PortalContainerConfig
- in order to register the PortalContainerDefinitions -->
- <set-method>registerPlugin</set-method>
-
- <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
-
<type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
-
- <init-params>
- <object-param>
- <name>portal</name>
- <object
type="org.exoplatform.container.definition.PortalContainerDefinition">
- <!-- The name of the portal container -->
- <field
name="name"><string>portal</string></field>
-
- <!-- The name of the context name of the rest web application
-->
- <field
name="restContextName"><string>rest</string></field>
-
- <!-- The name of the realm -->
- <field
name="realmName"><string>exo-domain</string></field>
-
- <!-- All the dependencies of the portal container ordered by loading
priority -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>eXoResources</string>
- </value>
- <value>
- <string>portal</string>
- </value>
- <value>
- <string>dashboard</string>
- </value>
- <value>
- <string>exoadmin</string>
- </value>
- <value>
- <string>eXoGadgets</string>
- </value>
- <value>
- <string>eXoGadgetServer</string>
- </value>
- <value>
- <string>rest</string>
- </value>
- <value>
- <string>web</string>
- </value>
- <value>
- <string>wsrp-producer</string>
- </value>
- <!-- The sample-ext has been added at the end of the
dependency list
- in order to have the highest priority -->
- <value>
- <string>sample-ext</string>
- </value>
- </collection>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
- </external-component-plugins>
-</configuration>
- ]]>
-</programlisting>
- </example>
-
-
- <note>
- <para>Dependencies are part of the extension mechanism.</para>
- </note>
-
- <para>
- Every <emphasis role="bold">portal container</emphasis> is
represented by a <emphasis role="bold">PortalContainer
instance</emphasis>, which contains:
- <itemizedlist>
- <listitem>
- <para>associated <emphasis
role="bold">ExoContainerContext</emphasis>, which contains information
about the portal</para>
- </listitem>
- <listitem>
- <para><emphasis role="bold">unified servlet
context</emphasis>, for web-archive-relative resource loading</para>
- </listitem>
- <listitem>
- <para><emphasis role="bold">unified
classloader</emphasis>, for classpath based resource loading</para>
- </listitem>
- <listitem>
- <para>methods for retrieving services</para>
- </listitem>
- </itemizedlist>
- </para>
-
- <para>
- <emphasis role="bold">Unified servlet context</emphasis>,
and <emphasis role="bold">unified classloader</emphasis> are part of
the <emphasis role="bold">extension mechanism</emphasis> (explained
in next section),
- and provide standard API (ServletContext, ClassLoader) with specific resource
loading behavior - visibility into associated web application archives,
- configured with Dependencies property of PortalContainerDefinition. Resources
from other web applications are queried in the order specified by Dependencies.
- The later entries in the list override the previous ones.
- </para>
- </section>
-
- <section id="sect-Reference_Guide-Foundations-Extension_mechanism">
- <title>GateIn Extension Mechanism, and Portal Extensions</title>
-
- <para>
- <emphasis role="bold">Extension mechanism</emphasis> is a
functionality that makes it possible to override portal resources in an almost
- plug-and-play fashion - just drop in a .war archive with the resources, and
configure its position on the portal's
- classpath.
- This way any customizations of the portal don't have to involve unpacking
and repacking the original portal
- .war archives. Instead, you create your own .war archive with changed resources,
that override the resources in
- the original archive.
- </para>
-
- <para>
- A web archive packaged in a way to be used through extension mechanism is called
<emphasis role="bold">portal extension</emphasis>.
- </para>
- <para>
- There are two steps necessary to create a portal extension.
- </para>
- <para>
- First, declare <emphasis
role="bold">PortalConfigOwner</emphasis> servlet context listener in
web.xml of your web application.
- </para>
- <example><title>Example of a portal extension called
sample-ext:</title>
-
- <programlisting role="XML"><![CDATA[
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-<!DOCTYPE web-app PUBLIC -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN
-
http://java.sun.com/dtd/web-app_2_3.dtd>
-<web-app>
-
- <display-name>sample-ext</display-name>
-
- <listener>
-
<listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
- </listener>
-
- ...
-
-</web-app>
- ]]></programlisting>
- </example>
- <para>
- Then, add the servlet context name of this web application in proper place in
the list of Dependencies of the PortalContainerDefinition
- of all the portal containers that you want to have access to its resources.
- </para>
- <para>
- After this step your web archive will be on portal's unified classpath, and
unified servlet context resource path.
- The later in the Dependencies list your application is, the higher priority it
has when resources are loaded by portal.
- </para>
-
- <note>
- <para>See 'Configuring a portal' section for example of
PortalContainerDefinition, that has sample-ext at the end of its list of
Dependencies.</para>
- </note>
-
- </section>
-
-
- <section id="sect-Reference_Guide-Foundations-Multiple_portals">
- <title>Running Multiple Portals</title>
-
- <para>
- It is possible to run several independent portal containers - each bound to a
different URL context - within
- the same JVM instance. This kind of setup is very efficient from administration
and resource consumption
- aspect. The most elegant way to <emphasis
role="bold">reuse</emphasis> configuration for different coexisting
portals is by way of extension
- mechanism - by <emphasis role="bold">inheriting</emphasis>
resources and configuration from existing web archives, and just <emphasis
role="bold">adding</emphasis> extra resources to it,
- and <emphasis role="bold">overriding</emphasis> those that
need to be changed by including modified copies.
- </para>
-
- <para>
- In order for a portal application to correctly function when deployed in
multiple portals, the application may
- have to dynamically query the information about the current portal container.
The application should not make
- any assumptions about the name, and other information of the current portal, as
there are now multiple different portals in play.
- </para>
-
- <para>
- At any point during request processing, or lifecycle event processing, your
application can retrieve this
- information through <emphasis
role="bold">org.exoplatform.container. ExoContainerContext</emphasis>.
- Sometimes your application needs to make sure that the proper <emphasis
role="bold">PortalContainer</emphasis>
- - the source of <emphasis
role="bold">ExoContainerContext</emphasis> - is associated with the
current call.
- </para>
-
- <para>
- If you ship servlets or servlet filters as part of your portal application, and
if you need to access portal
- specific resources at any time during the processing of the servlet or filter
request, then you need to make
- sure the servlet/filter is associated with the current container.
- </para>
- <para>
- The proper way to do that is to make your servlet extend <emphasis
role="bold">org.exoplatform.container.web.
AbstractHttpServlet</emphasis>
- class.
- This will not only properly initialize current <emphasis
role="bold">PortalContainer</emphasis> for you, but will also set the
current thread's
- context classloader to one that looks for resources in associated web
applications in the order specified by
- <emphasis role="bold">Dependencies</emphasis>
configuration (as explained in Extension mechanism section).
- </para>
- <para>
- Similarly for filters, make sure your filter class extends <emphasis
role="bold">org.exoplatform.container.web. AbstractFilter</emphasis>.
- Both <emphasis role="bold">AbstractHttpServlet</emphasis>,
and <emphasis role="bold">AbstractFilter</emphasis> have a method
<emphasis role="bold">getContainer()</emphasis>,
- which returns the current <emphasis
role="bold">PortalContainer</emphasis>.
-
- If your servlet handles the requests by implementing a <emphasis
role="bold">service()</emphasis> method, you need to rename that method
to match
- the following signature:</para>
- <programlisting role="JAVA"><![CDATA[
-/**
- * Use this method instead of Servlet.service()
- */
-protected void onService(ExoContainer container, HttpServletRequest req,
- HttpServletResponse res) throws ServletException, IOException;
- ]]></programlisting>
- <note>
- <para>
- The reason is that AbstractHttpServlet implements service() to perform its
interception, and you don't want to
- overwrite (by overriding) this functionality.
- </para>
- </note>
- <para>
- You may also need to access portal information within your <emphasis
role="bold">HttpSessionListener</emphasis>. Again, make sure to extend
the
- provided abstract class - <emphasis
role="bold">org.exoplatform.container.web.
AbstractHttpSessionListener</emphasis>.
- Also, modify your method signatures as follows:</para>
- <programlisting role="JAVA"><![CDATA[
-/**
- * Use this method instead of HttpSessionListener.sessionCreated()
- */
-protected void onSessionCreated(ExoContainer container, HttpSessionEvent event);
-
-/**
- * Use this method instead of HttpSessionListener.sessionDestroyed()
- */
-protected void onSessionDestroyed(ExoContainer container, HttpSessionEvent event);
- ]]></programlisting>
- <para>
- There is another method you have to implement in this case:</para>
- <programlisting role="JAVA"><![CDATA[
-/**
- * Method should return true if unified servlet context,
- * and unified classloader should be made available
- */
-protected boolean requirePortalEnvironment();
- ]]></programlisting>
- <para>
- If this method returns true, current thread's context classloader is set up
according to <emphasis role="bold">Dependencies</emphasis>
- configuration, and availability of the associated web applications. If it
returns false, the standard
- application separation rules are used for resource loading (effectively turning
off the
- extension mechanism). This method exists on <emphasis
role="bold">AbstractHttpServlet</emphasis> and <emphasis
role="bold">AbstractFilter</emphasis> as well, where there is a
- default implementation that automatically returns true, when it detects there is
a current PortalContainer
- present, otherwise it returns false.
-
- </para>
-
- <para>
- We still have to explain how to properly perform <emphasis
role="bold">ServletContextListener</emphasis> based initialization,
when you need
- access to current PortalContainer.
- </para>
-
- <para>
- GateIn has no direct control over the deployment of application archives (.war,
.ear files) - it is the
- application server that performs the deployment. For <emphasis
role="bold">extension mechanism</emphasis> to work properly, the
applications,
- associated with the portal via <emphasis
role="bold">Dependencies</emphasis> configuration, have to be deployed
before the portal, that depends
- on them, is initialized. On the other hand, these applications may require an
already initialized PortalContainer
- to properly initialize themselves - we have a recursive dependency problem. To
resolve this problem, a
- mechanism of <emphasis role="bold">initialization
tasks</emphasis>, and <emphasis role="bold">task
queues</emphasis>, was put in place. Web applications that depend on current
- PortalContainer for their initialization have to avoid performing their
initialization directly in some
- ServletContextListener executed during their deployment (before any
PortalContainer was initialized). Instead,
- a web application should package its initialization logic into an init task of
appropriate type, and only use
- ServletContextListener to insert the init task instance into the proper init
tasks queue.
- </para>
-
- <para>An example of this is Gadgets application which registers Google
gadgets with the current PortalContainer:
- </para>
-
- <programlisting role="JAVA"><![CDATA[
-public class GadgetRegister implements ServletContextListener
-{
- public void contextInitialized(ServletContextEvent event)
- {
- // Create a new post-init task
- final PortalContainerPostInitTask task = new PortalContainerPostInitTask() {
-
- public void execute(ServletContext context, PortalContainer portalContainer)
- {
- try
- {
- SourceStorage sourceStorage =
- (SourceStorage)
portalContainer.getComponentInstanceOfType(SourceStorage.class);
- ...
- }
- catch (RuntimeException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("Initialization failed: ", e);
- }
- }
- };
-
- // Add post-init task for execution on all the portal containers
- // that depend on the given ServletContext according to
- // PortalContainerDefinitions (via Dependencies configuration)
- PortalContainer.addInitTask(event.getServletContext(), task);
- }
-}
- ]]></programlisting>
-
- <para>
- The above example uses <emphasis
role="bold">PortalContainerPostInitTask</emphasis>, which gets executed
after the portal container has been
- initialized. In some situations you may want to execute initialization after
portal container was instantiated,
- but before it was initialized - use <emphasis
role="bold">PortalContainerPreInitTask</emphasis> in that case. Or, you
may want to execute
- initialization after all the post-init tasks have been executed - use
<emphasis role="bold">PortalContainerPostCreateTask</emphasis> in
that case.
- </para>
-
- <para>
- One more area that may need your attention are <emphasis
role="bold">LoginModules</emphasis>. If you use custom LoginModules,
that require
- current ExoContainer, make sure they extend <emphasis
role="bold">org.exoplatform.services.security.jaas.AbstractLoginModule</emphasis>
for
- proper initialization. AbstractLoginModule also takes care of the basic
configuration - it recognizes two
- initialization options - <emphasis
role="bold">portalContainerName</emphasis>, and <emphasis
role="bold">realmName</emphasis> whose values you can access via
protected fields of
- the same name.
- </para>
-
- </section>
-
-</section>
Modified: portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml
===================================================================
--- portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml 2010-04-15 10:32:55
UTC (rev 2651)
+++ portal/trunk/docs/reference-guide/en/modules/PortalDevelopment.xml 2010-04-15 10:43:53
UTC (rev 2652)
@@ -5,7 +5,6 @@
]>
<chapter id="chap-Reference_Guide-Development">
<title>Portal Development</title>
- <xi:include href="PortalDevelopment/Foundations.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/Skinning.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/PortalLifecycle.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="PortalDevelopment/DefaultPortalConfiguration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />