[exo-jcr-commits] exo-jcr SVN: r2879 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel.
do-not-reply at jboss.org
do-not-reply at jboss.org
Thu Aug 5 05:13:57 EDT 2010
Author: sergiykarpenko
Date: 2010-08-05 05:13:56 -0400 (Thu, 05 Aug 2010)
New Revision: 2879
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/kernel.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
Log:
EXOJCR-869: link fixes
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-05 08:52:15 UTC (rev 2878)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-05 09:13:56 UTC (rev 2879)
@@ -1,1837 +1,1837 @@
-<?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">
-<chapter id="Kernel.ContainerConfiguration">
- <?dbhtml filename="ch-kernel-container-configuration.html"?>
-
- <title>Container Configuration</title>
-
- <section>
- <title>Intro</title>
-
- <para>eXo Portal uses PicoContainer, which implements the Inversion of
- Control (IoC) design pattern. All eXo containers inherit from a
- PicoContainer. There are mainly two eXo containers used, each of them can
- provide one or several services. Each container service is delivered in a
- JAR file. This JAR file may contain a default configuration. The use of
- default configurations is recommended and most services provide it.</para>
-
- <para>When a Pico Container searches for services and its configurations,
- each configurable service may be reconfigured to override default values
- or set additional parameters. If the service is configured in two or more
- places the configuration override mechanism will be used.</para>
-
- <para>Confused? - You might be interested in the <link
- linkend="KernelServiceConfigurationforBeginners">Service Configuration for
- Beginners</link> article, which explains the basics.</para>
- </section>
-
- <section id="KernelConfigurationNamespace">
- <title>Kernel configuration namespace</title>
-
- <para>To be effective the namespace URI
- <uri>http://www.exoplaform.org/xml/ns/kernel_1_1.xsd</uri> must be target
- namespace of the XML configuration file.</para>
-
- <programlisting><xsd:schema
- targetNamespace="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
- xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified"
- version="1.0">
-
- ...
-</xsd:schema></programlisting>
- </section>
-
- <section>
- <title>Understanding How configuration files are loaded</title>
-
- <para>eXo Portal uses PicoContainer, which implements the Inversion of
- Control (IoC) design pattern. All eXo containers inherit from a
- PicoContainer. There are mainly two eXo containers used, each of them can
- provide one or several services. Each container service is delivered in a
- JAR file. This JAR file may contain a default configuration. The use of
- default configurations is recommended and most services provide it.</para>
-
- <para>When a Pico Container searches for services and its configurations,
- each configurable service may be reconfigured to override default values
- or set additional parameters. If the service is configured in two or more
- places the configuration override mechanism will be used.</para>
-
- <section>
- <title>Configuration Retrieval</title>
-
- <para>The container performs the following steps making eXo Container
- configuration retrieval depending on the container type.</para>
-
- <section>
- <title>Configuration retrieval order for the
- <envar>PortalContainer</envar></title>
-
- <para>The container is initialized by looking into different
- locations. This container is used by portal applications.
- Configurations are overloaded in the following lookup sequence:</para>
-
- <orderedlist>
- <listitem>
- <para>Services default <envar>RootContainer</envar> configurations
- from JAR files <emphasis>/conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>External <envar>RootContainer</envar> configuration, if will
- be found at
- <emphasis>$AS_HOME/exo-conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Services default <envar>PortalContainer</envar>
- configurations from JAR files
- <emphasis>/conf/portal/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Web applications configurations from WAR files
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>External configuration for services of named portal, if will
- be found at
- <emphasis>$AS_HOME/exo-conf/portal/$PORTAL_NAME/configuration.xml</emphasis></para>
- </listitem>
- </orderedlist>
- </section>
-
- <section>
- <title>Configuration retrieval for a
- <envar>StandaloneContainer</envar></title>
-
- <para>The container is initialized by looking into different
- locations. This container is used by non portal applications.
- Configurations are overloaded in the following lookup sequence:</para>
-
- <orderedlist>
- <listitem>
- <para>Services default <envar>RootContainer</envar> configurations
- from JAR files <emphasis>/conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>External <envar>RootContainer</envar> configuration, if will
- be found at
- <emphasis>$AS_HOME/exo-conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Services default <envar>StandaloneContainer</envar>
- configurations from JAR files
- <emphasis>/conf/portal/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Web applications configurations from WAR files
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Then depending on the <envar>StandaloneContainer</envar>
- configuration URL initialization:</para>
-
- <itemizedlist>
- <listitem>
- <para>if configuration URL was initialized to be added to
- services defaults, as below:<programlisting>// add configuration to the default services configurations from JARs/WARs
-StandaloneContainer.addConfigurationURL(containerConf);</programlisting></para>
-
- <para>Configuration from added URL
- <emphasis>containerConf</emphasis> will override only services
- configured in the file</para>
- </listitem>
-
- <listitem>
- <para>if configuration URL not initialized at all, it will be
- found at <emphasis>$AS_HOME/exo-configuration.xml</emphasis>.
- If <emphasis>$AS_HOME/exo-configuration.xml</emphasis> doesn't
- exist the container will try find it at
- <emphasis>$AS_HOME/exo-conf/exo-configuration.xml</emphasis>
- location and if it's still not found and the
- <envar>StandaloneContainer</envar> instance obtained with the
- dedicated configuration <envar>ClassLoader</envar> the
- container will try to retrieve the resource
- <emphasis>conf/exo-configuration.xml</emphasis> within the
- given <envar>ClassLoader</envar>.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </orderedlist>
- </section>
-
- <section>
- <title>General notes about the configuration retrieval</title>
-
- <note>
- <para><emphasis>$AS_HOME</emphasis> - application server home
- directory, or <emphasis>user.dir</emphasis> JVM system property
- value in case of Java Standalone application.</para>
- </note>
-
- <note>
- <para><emphasis>$PORTAL_NAME</emphasis> - portal web application
- name.</para>
- </note>
-
- <note>
- <para>External configuration location can be overridden with System
- property <emphasis>exo.conf.dir</emphasis>. If the property exists
- its value will be used as path to eXo configuration directory, i.e.
- to <emphasis>$AS_HOME/exo-conf</emphasis> alternative. E.g. put
- property in command line java
- <emphasis>-Dexo.conf.dir=/path/to/exo/conf</emphasis>. In this
- particular use case, you have no need to use any prefix to import
- other files. For instance, if your configuration file is
- <emphasis>$AS_HOME/exo-conf/portal/PORTAL_NAME/configuration.xml</emphasis>
- and you want to import the configuration file
- <emphasis>$AS_HOME/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.xml</emphasis>,
- you can do it by adding
- <emphasis><import>mySubConfDir/myConfig.xml</import></emphasis>
- to your configuration file.</para>
- </note>
-
- <note>
- <para>The name of the configuration folder that is by default
- <emphasis>"exo-conf"</emphasis>, can be changed thanks to the System
- property <emphasis>exo.conf.dir.name</emphasis>.</para>
- </note>
-
- <note>
- <para>Under JBoss application server <emphasis>exo-conf</emphasis>
- will be looked up in directory described by JBoss System property
- <emphasis>jboss.server.config.url</emphasis>. If the property is not
- found or empty <emphasis>$AS_HOME/exo-conf</emphasis> will be
- asked.</para>
- </note>
-
- <note>
- <para>The search looks for a configuration file in each JAR/WAR
- available from the classpath using the current thread context
- classloader. During the search these configurations are added to a
- set. If the service was configured previously and the current JAR
- contains a new configuration of that service the latest (from the
- current JAR/WAR) will replace the previous one. The last one will be
- applied to the service during the services start phase.</para>
- </note>
-
- <warning>
- <para>Take care to have no dependencies between configurations from
- JAR files (<emphasis>/conf/portal/configuration.xml</emphasis> and
- <emphasis>/conf/configuration.xml</emphasis>) since we have no way
- to know in advance the loading order of those configurations. In
- other words, if you want to overload some configuration located in
- the file <emphasis>/conf/portal/configuration.xml</emphasis> of a
- given JAR file, you must not do it from the file
- <emphasis>/conf/portal/configuration.xml</emphasis> of another JAR
- file but from another configuration file loaded after configurations
- from JAR files
- <emphasis>/conf/portal/configuration.xml.</emphasis></para>
- </warning>
-
- <para>After the processing of all configurations available in system
- the container will initialize it and start each service in order of
- the dependency injection (DI).</para>
-
- <para>The user/developer should be careful when configuring the same
- service in different configuration files. It's recommended to
- configure a service in its own JAR only. Or, in case of a portal
- configuration, strictly reconfigure the services in portal WAR files
- or in an external configuration.</para>
-
- <para>There are services that can be (or should be) configured more
- than one time. This depends on business logic of the service. A
- service may initialize the same resource (shared with other services)
- or may add a particular object to a set of objects (shared with other
- services too). In the first case it's critical who will be the last,
- i.e. whose configuration will be used. In the second case it's no
- matter who is the first and who is the last (if the parameter objects
- are independent).</para>
- </section>
-
- <section>
- <title>Configuration retrieval log</title>
-
- <para>In case of problems with service configuration it's important to
- know from which JAR/WAR it comes. For that purpose the JVM system
- property
- <emphasis>org.exoplatform.container.configuration.debug</emphasis> can
- be used.<programlisting>java -Dorg.exoplatform.container.configuration.debug ...</programlisting></para>
-
- <para>If the property is enabled the container configuration manager
- will log the configuration adding process at <emphasis>INFO</emphasis>
- level.<programlisting>......
- Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
- Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
- Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml
- import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
- import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml
- import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
- import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
- ......</programlisting></para>
- </section>
-
- <section>
- <title>Get the effective configuration at Runtime</title>
-
- <para>The effective configuration of the StandaloneContainer,
- RootContainer and/or PortalContainer can be known thanks to the method
- <emphasis>getConfigurationXML</emphasis>() that is exposed through JMX
- at the container's level. This method will give you the effective
- configuration in XML format that has been really interpreted by the
- kernel. This could be helpful to understand how a given component or
- plugin has been initialized.</para>
- </section>
- </section>
-
- <section>
- <title>Advanced concepts for the
- <emphasis>PortalContainers</emphasis></title>
-
- <para>Since eXo JCR 1.12, we added a set of new features that have been
- designed to extend portal applications such as GateIn.</para>
-
- <section>
- <title>Add new configuration files from a WAR file</title>
-
- <para>A <envar>ServletContextListener</envar> called
- <envar>org.exoplatform.container.web.PortalContainerConfigOwner</envar>
- has been added in order to notify the application that a given web
- application provides some configuration to the portal container, and
- this configuration file is the file
- <emphasis>WEB-INF/conf/configuration.xml</emphasis> available in the
- web application itself.</para>
-
- <para>If your war file contains some configuration to add to the
- <envar>PortalContainer</envar> simply add the following lines in your
- <emphasis>web.xml</emphasis> file.</para>
-
- <programlisting><?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>
-...
- <!-- ================================================================== -->
- <!-- LISTENER -->
- <!-- ================================================================== -->
- <listener>
- <listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
- </listener>
-...
-</web-app></programlisting>
- </section>
-
- <section>
- <title>Create your <emphasis>PortalContainers</emphasis> from a WAR
- file</title>
-
- <para>A <envar>ServletContextListener</envar> called
- <envar>org.exoplatform.container.web.PortalContainerCreator</envar>
- has been added in order to create the current portal containers that
- have been registered. We assume that all the web applications have
- already been loaded before calling
- <envar>PortalContainerCreator.contextInitialized<replaceable><optional>.</optional></replaceable></envar></para>
-
- <para><note>
- <para>In GateIn, the <envar>PortalContainerCreator</envar> is
- already managed by the file
- <emphasis>starter.war/ear.</emphasis></para>
- </note></para>
- </section>
-
- <section>
- <title>Define a <emphasis>PortalContainer</emphasis> with its
- dependencies and its settings</title>
-
- <para>Now we can define precisely a portal container and its
- dependencies and settings thanks to the
- <envar>PortalContainerDefinition</envar> that currently contains the
- name of the portal container, the name of the rest context, the name
- of the realm he web application dependencies ordered by loading
- priority (i.e. the first dependency must be loaded at first and so
- on..) and the settings.</para>
-
- <para>To be able to define a <envar>PortalContainerDefinition</envar>,
- we need to ensure first of all that a
- <envar>PortalContainerConfig</envar> has been defined at the
- <envar>RootContainer</envar> level, see below an example:</para>
-
- <programlisting> <component>
- <!-- The full qualified name of the PortalContainerConfig -->
- <type>org.exoplatform.container.definition.PortalContainerConfig</type>
- <init-params>
- <!-- The name of the default portal container -->
- <value-param>
- <name>default.portal.container</name>
- <value>myPortal</value>
- </value-param>
- <!-- The name of the default rest ServletContext -->
- <value-param>
- <name>default.rest.context</name>
- <value>myRest</value>
- </value-param>
- <!-- The name of the default realm -->
- <value-param>
- <name>default.realm.name</name>
- <value>my-exo-domain</value>
- </value-param>
- <!-- The default portal container definition -->
- <!-- It cans be used to avoid duplicating configuration -->
- <object-param>
- <name>default.portal.definition</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinition">
- <!-- All the dependencies of the portal container ordered by loading priority -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- <value>
- <string>foo2</string>
- </value>
- <value>
- <string>foo3</string>
- </value>
- </collection>
- </field>
- <!-- A map of settings tied to the default portal container -->
- <field name="settings">
- <map type="java.util.HashMap">
- <entry>
- <key>
- <string>foo5</string>
- </key>
- <value>
- <string>value</string>
- </value>
- </entry>
- <entry>
- <key>
- <string>string</string>
- </key>
- <value>
- <string>value0</string>
- </value>
- </entry>
- <entry>
- <key>
- <string>int</string>
- </key>
- <value>
- <int>100</int>
- </value>
- </entry>
- </map>
- </field>
- <!-- The path to the external properties file -->
- <field name="externalSettingsPath">
- <string>classpath:/org/exoplatform/container/definition/default-settings.properties</string>
- </field>
- </object>
- </object-param>
- </init-params>
- </component></programlisting>
-
- <table>
- <title>Descriptions of the fields of
- <envar>PortalContainerConfig</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>default.portal.container</entry>
-
- <entry>The name of the default portal container. This field is
- optional.</entry>
- </row>
-
- <row>
- <entry>default.rest.context</entry>
-
- <entry>The name of the default rest
- <envar>ServletContext</envar>. This field is optional.</entry>
- </row>
-
- <row>
- <entry>default.realm.name</entry>
-
- <entry>The name of the default realm. This field is
- optional.</entry>
- </row>
-
- <row>
- <entry>default.portal.definition</entry>
-
- <entry>The definition of the default portal container. This
- field is optional. The expected type is
- <envar>org.exoplatform.container.definition.PortalContainerDefinition</envar>
- that is described below. Allow the parameters defined in this
- default <envar>PortalContainerDefinition</envar> will be the
- default values.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>A new <envar>PortalContainerDefinition</envar> can be defined at
- the <envar>RootContainer</envar> level thanks to an external plugin,
- see below an example:<programlisting> <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>myPortal</string>
- </field>
- <!-- The name of the context name of the rest web application -->
- <field name="restContextName">
- <string>myRest</string>
- </field>
- <!-- The name of the realm -->
- <field name="realmName">
- <string>my-domain</string>
- </field>
- <!-- All the dependencies of the portal container ordered by loading priority -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- <value>
- <string>foo2</string>
- </value>
- <value>
- <string>foo3</string>
- </value>
- </collection>
- </field>
- <!-- A map of settings tied to the portal container -->
- <field name="settings">
- <map type="java.util.HashMap">
- <entry>
- <key>
- <string>foo</string>
- </key>
- <value>
- <string>value</string>
- </value>
- </entry>
- <entry>
- <key>
- <string>int</string>
- </key>
- <value>
- <int>10</int>
- </value>
- </entry>
- <entry>
- <key>
- <string>long</string>
- </key>
- <value>
- <long>10</long>
- </value>
- </entry>
- <entry>
- <key>
- <string>double</string>
- </key>
- <value>
- <double>10</double>
- </value>
- </entry>
- <entry>
- <key>
- <string>boolean</string>
- </key>
- <value>
- <boolean>true</boolean>
- </value>
- </entry>
- </map>
- </field>
- <!-- The path to the external properties file -->
- <field name="externalSettingsPath">
- <string>classpath:/org/exoplatform/container/definition/settings.properties</string>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
- </external-component-plugins></programlisting></para>
-
- <table>
- <title>Descriptions of the fields of a
- <envar>PortalContainerDefinition</envar> when it is used to define a
- new portal container</title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>name</entry>
-
- <entry>The name of the portal container. This field is
- mandatory .</entry>
- </row>
-
- <row>
- <entry>restContextName</entry>
-
- <entry>The name of the context name of the rest web
- application. This field is optional. The default value will
- the value define at the <envar>PortalContainerConfig</envar>
- level.</entry>
- </row>
-
- <row>
- <entry>realmName</entry>
-
- <entry>The name of the realm. This field is optional. The
- default value will the value define at the
- <envar>PortalContainerConfig</envar> level.</entry>
- </row>
-
- <row>
- <entry>dependencies</entry>
-
- <entry>All the dependencies of the portal container ordered by
- loading priority. This field is optional. The default value
- will the value define at the
- <envar>PortalContainerConfig</envar> level. The dependencies
- are in fact the list of the context names of the web
- applications from which the portal container depends. This
- field is optional. The dependency order is really crucial
- since it will be interpreted the same way by several
- components of the platform. All those components, will
- consider the 1st element in the list less important than the
- second element and so on. It is currently used
- to:<itemizedlist>
- <listitem>
- <para>Know the loading order of all the
- dependencies.</para>
- </listitem>
-
- <listitem>
- <para>If we have several
- <envar>PortalContainerConfigOwner</envar><itemizedlist>
- <listitem>
- <para>The <envar>ServletContext</envar> of all the
- <envar>PortalContainerConfigOwner</envar> will be
- unified, if we use the unified
- <envar>ServletContext</envar>
- (<emphasis>PortalContainer.getPortalContext()</emphasis>)
- to get a resource, it will try to get the resource
- in the <envar>ServletContext</envar> of the most
- important <envar>PortalContainerConfigOwner</envar>
- (i.e. last in the dependency list) and if it cans
- find it, it will try with the second most important
- <envar>PortalContainerConfigOwner</envar> and so
- on.</para>
- </listitem>
-
- <listitem>
- <para>The <envar>ClassLoader</envar> of all the
- <envar>PortalContainerConfigOwner</envar> will be
- unified, if we use the unified
- <envar>ClassLoader</envar>
- (<emphasis>PortalContainer.getPortalClassLoader()</emphasis>)
- to get a resource, it will try to get the resource
- in the <envar>ClassLoader</envar> of the most
- important <envar>PortalContainerConfigOwner</envar>
- (i.e. last in the dependency list) and if it cans
- find it, it will try with the second most important
- <envar>PortalContainerConfigOwner</envar> and so
- on.</para>
- </listitem>
- </itemizedlist></para>
- </listitem>
- </itemizedlist></entry>
- </row>
-
- <row>
- <entry>settings</entry>
-
- <entry>A <envar>java.util.Map</envar> of internal parameters
- that we would like to tie the portal container. Those
- parameters could have any type of value. This field is
- optional. If some internal settings are defined at the
- <envar>PortalContainerConfig</envar> level, the two maps of
- settings will be merged. If a setting with the same name is
- defined in both maps, it will keep the value defined at the
- <envar>PortalContainerDefinition</envar> level.</entry>
- </row>
-
- <row>
- <entry>externalSettingsPath</entry>
-
- <entry>The path of the external properties file to load as
- default settings to the portal container. This field is
- optional. If some external settings are defined at the
- <envar>PortalContainerConfig</envar> level, the two maps of
- settings will be merged. If a setting with the same name is
- defined in both maps, it will keep the value defined at the
- <envar>PortalContainerDefinition</envar> level. The external
- properties files can be either of type "properties" or of type
- "xml". The path will be interpreted as follows:<orderedlist>
- <listitem>
- <para>The path doesn't contain any prefix of type
- "classpath:", "jar:" or "file:", we assume that the file
- could be externalized so we apply the following
- rules:<orderedlist>
- <listitem>
- <para>A file exists at
- <emphasis>${exo-conf-dir}/portal/${portalContainerName}/${externalSettingsPath}</emphasis>,
- we will load this file.</para>
- </listitem>
-
- <listitem>
- <para>No file exists at the previous path, we then
- assume that the path cans be interpreted by the
- <envar>ConfigurationManager</envar>.</para>
- </listitem>
- </orderedlist></para>
- </listitem>
-
- <listitem>
- <para>The path contains a prefix, we then assume that
- the path cans be interpreted by the
- <envar>ConfigurationManager</envar>.</para>
- </listitem>
- </orderedlist></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table>
- <title>Descriptions of the fields of a
- <envar>PortalContainerDefinition</envar> when it is used to define
- the default portal container</title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>name</entry>
-
- <entry>The name of the portal container. This field is
- optional. The default portal name will be:<orderedlist>
- <listitem>
- <para>If this field is not empty, then the default value
- will be the value of this field.</para>
- </listitem>
-
- <listitem>
- <para>If this field is empty and the value of the
- parameter <emphasis>default.portal.container</emphasis>
- is not empty, then the default value will be the value
- of the parameter.</para>
- </listitem>
-
- <listitem>
- <para>If this field and the parameter
- <emphasis>default.portal.container</emphasis> are both
- empty, the default value will be
- <emphasis>"portal".</emphasis></para>
- </listitem>
- </orderedlist></entry>
- </row>
-
- <row>
- <entry>restContextName</entry>
-
- <entry>The name of the context name of the rest web
- application. This field is optional. The default value wil
- be:<orderedlist>
- <listitem>
- <para>If this field is not empty, then the default value
- will be the value of this field.</para>
- </listitem>
-
- <listitem>
- <para>f this field is empty and the value of the
- parameter <emphasis>default.rest.context</emphasis> is
- not empty, then the default value will be the value of
- the parameter.</para>
- </listitem>
-
- <listitem>
- <para>f this field and the parameter
- <emphasis>default.rest.context</emphasis> are both
- empty, the default value will be
- <emphasis>"rest".</emphasis></para>
- </listitem>
- </orderedlist></entry>
- </row>
-
- <row>
- <entry>realmName</entry>
-
- <entry>The name of the realm. This field is optional. The
- default value wil be:<orderedlist>
- <listitem>
- <para>If this field is not empty, then the default value
- will be the value of this field.</para>
- </listitem>
-
- <listitem>
- <para>f this field is empty and the value of the
- parameter <emphasis>default.realm.name</emphasis> is not
- empty, then the default value will be the value of the
- parameter.</para>
- </listitem>
-
- <listitem>
- <para>f this field and the parameter
- <emphasis>default.realm.name</emphasis> are both empty,
- the default value will be
- <emphasis>"exo-domain".</emphasis></para>
- </listitem>
- </orderedlist></entry>
- </row>
-
- <row>
- <entry>dependencies</entry>
-
- <entry>All the dependencies of the portal container ordered by
- loading priority. This field is optional. If this field has a
- non empty value, it will be the default list of
- dependencies.</entry>
- </row>
-
- <row>
- <entry>settings</entry>
-
- <entry>A <envar>java.util.Map</envar> of internal parameters
- that we would like to tie the default portal container. Those
- parameters could have any type of value. This field is
- optional.</entry>
- </row>
-
- <row>
- <entry>externalSettingsPath</entry>
-
- <entry>The path of the external properties file to load as
- default settings to the default portal container. This field
- is optional. The external properties files can be either of
- type "properties" or of type "xml". The path will be
- interpreted as follows:<orderedlist>
- <listitem>
- <para>The path doesn't contain any prefix of type
- "classpath:", "jar:" or "file:", we assume that the file
- could be externalized so we apply the following
- rules:<orderedlist>
- <listitem>
- <para>A file exists at
- <emphasis>${exo-conf-dir}/portal/${externalSettingsPath}</emphasis>,
- we will load this file.</para>
- </listitem>
-
- <listitem>
- <para>No file exists at the previous path, we then
- assume that the path cans be interpreted by the
- <envar>ConfigurationManager</envar>.</para>
- </listitem>
- </orderedlist></para>
- </listitem>
-
- <listitem>
- <para>The path contains a prefix, we then assume that
- the path cans be interpreted by the
- <envar>ConfigurationManager</envar>.</para>
- </listitem>
- </orderedlist></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>Internal and external settings are both optional, but if we give
- a non empty value for both the application will merge the settings. If
- the same setting name exists in both settings, we apply the following
- rules:</para>
-
- <orderedlist>
- <listitem>
- <para>The value of the external setting is
- <emphasis>null</emphasis>, we ignore the value.</para>
- </listitem>
-
- <listitem>
- <para>The value of the external setting is not
- <emphasis>null</emphasis> and the value of the internal setting is
- <emphasis>null</emphasis>, the final value will be the external
- setting value that is of type <envar>String</envar>.</para>
- </listitem>
-
- <listitem>
- <para>Both values are not <envar>null</envar>, we will have to
- convert the external setting value into the target type which is
- the type of the internal setting value, thanks to the static
- method <emphasis>valueOf(String)</emphasis>, the following
- sub-rules are then applied:</para>
-
- <orderedlist>
- <listitem>
- <para>The method cannot be found, the final value will be the
- external setting value that is of type
- <envar>String</envar>.</para>
- </listitem>
-
- <listitem>
- <para>The method can be found and the external setting value
- is an empty <envar>String</envar>, we ignore the external
- setting value.</para>
- </listitem>
-
- <listitem>
- <para>The method can be found and the external setting value
- is not an empty <envar>String</envar> but the method call
- fails, we ignore the external setting value.</para>
- </listitem>
-
- <listitem>
- <para>The method can be found and the external setting value
- is not an empty <envar>String</envar> and the method call
- succeeds, the final value will be the external setting value
- that is of type of the internal setting value.</para>
- </listitem>
- </orderedlist>
- </listitem>
- </orderedlist>
- </section>
-
- <section>
- <title><envar>PortalContainer</envar> settings</title>
-
- <para>We can inject the value of the portal container settings into
- the portal container configuration files thanks to the variables which
- name start with "<emphasis>portal.container.</emphasis>", so to get
- the value of a setting called "<emphasis>foo</emphasis>" just use the
- following syntax <emphasis>${portal.container.foo}</emphasis>. You can
- also use internal variables, such as:</para>
-
- <table>
- <title>Definition of the internal variables</title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>portal.container.name</entry>
-
- <entry>Gives the name of the current portal container.</entry>
- </row>
-
- <row>
- <entry>portal.container.rest</entry>
-
- <entry>Gives the context name of the rest web application of
- the current portal container.</entry>
- </row>
-
- <row>
- <entry>portal.container.realm</entry>
-
- <entry>Gives the realm name of the current portal
- container.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>You can find below an example of how to use the
- variables:<programlisting><configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
- xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">
- <component>
- <type>org.exoplatform.container.TestPortalContainer$MyComponent</type>
- <init-params>
- <!-- The name of the portal container -->
- <value-param>
- <name>portal</name>
- <value>${portal.container.name}</value>
- </value-param>
- <!-- The name of the rest ServletContext -->
- <value-param>
- <name>rest</name>
- <value>${portal.container.rest}</value>
- </value-param>
- <!-- The name of the realm -->
- <value-param>
- <name>realm</name>
- <value>${portal.container.realm}</value>
- </value-param>
- <value-param>
- <name>foo</name>
- <value>${portal.container.foo}</value>
- </value-param>
- <value-param>
- <name>before foo after</name>
- <value>before ${portal.container.foo} after</value>
- </value-param>
- </init-params>
- </component>
-</configuration></programlisting></para>
-
- <para>In the properties file corresponding to the external settings,
- you can reuse variables previously defined (in the external settings
- or in the internal settings) to create a new variable. In this case
- the prefix "<emphasis>portal.container.</emphasis>" is not needed, see
- an example below:<programlisting>my-var1=value 1
-my-var2=value 2
-complex-value=${my-var1}-${my-var2}</programlisting></para>
-
- <para>In the external and internal settings, you can also use create
- variables based on value of System paramaters. The System parameters
- can either be defined at launch time or thanks to the
- <envar>PropertyConfigurator</envar> (see next section for more
- details). See an example below:</para>
-
- <programlisting>temp-dir=${java.io.tmpdir}${file.separator}my-temp</programlisting>
-
- <para>However, for the internal settings you can use System parameters
- only to define settings of type
- <envar>java.lang.String</envar>.</para>
-
- <para>It cans be also very usefull to define a generic variable in the
- settings of the default portal container, the value of this variable
- will change according to the current portal container. See below an
- example:<programlisting>my-generic-var=value of the portal container "${name}"</programlisting></para>
-
- <para>If this variable is defined at the default portal container
- level, the value of this variable for a portal container called
- <emphasis>"foo"</emphasis> will be <emphasis>value of the portal
- container "foo"</emphasis>.</para>
- </section>
-
- <section>
- <title>Add dynamically settings and/or dependencies to a
- <envar>PortalContainer</envar></title>
-
- <para>It is possible to use <envar>component-plugin</envar> elements
- in order to dynamically change a PortalContainerDefinition. In the
- example below, we add the dependency <envar>foo</envar> to the default
- portal container and to the portal containers called
- <envar>foo1</envar> and <envar>foo2</envar>:</para>
-
- <programlisting><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>Change PortalContainer Definitions</name>
- <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
- <set-method>registerChangePlugin</set-method>
- <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
- <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
- <init-params>
- <value-param>
- <name>apply.default</name>
- <value>true</value>
- </value-param>
- <values-param>
- <name>apply.specific</name>
- <value>foo1</value>
- <value>foo2</value>
- </values-param>
- <object-param>
- <name>change</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
- <!-- The list of name of the dependencies to add -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- </collection>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
-
- <table>
- <title>Descriptions of the fields of a
- <envar>PortalContainerDefinitionChangePlugin</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>apply.all</entry>
-
- <entry>Indicates whether the changes have to be applied to all
- the portal containers or not. The default value of this field
- is <envar>false</envar>. This field is a
- <envar>ValueParam</envar> and is not mandatory.</entry>
- </row>
-
- <row>
- <entry>apply.default</entry>
-
- <entry>Indicates whether the changes have to be applied to the
- default portal container or not. The default value of this
- field is <envar>false</envar>. This field is a
- <envar>ValueParam</envar> and is not mandatory.</entry>
- </row>
-
- <row>
- <entry>apply.specific</entry>
-
- <entry>A set of specific portal container names to which we
- want to apply the changes. This field is a
- <envar>ValuesParam</envar> and is not mandatory.</entry>
- </row>
-
- <row>
- <entry><envar>Rest of the expected parameters </envar></entry>
-
- <entry>The rest of the expected paramaters are
- <envar>ObjectParam</envar> of type
- <envar>PortalContainerDefinitionChange</envar>. Those
- parameters are in fact the list of changes that we want to
- apply to one or several portal containers. If the list of
- changes is empty, the component plugin will be ignored. The
- supported implementations of PortalContainerDefinitionChange
- are described later in this section.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>To identify the portal containers to which the changes have to
- be applied, we use the follwing algorithm:</para>
-
- <orderedlist>
- <listitem>
- <para>The parameter <envar>apply.all</envar> has been set to
- <envar>true</envar>. The corresponding changes will be applied to
- all the portal containers. The other parameters will be
- ignored.</para>
- </listitem>
-
- <listitem>
- <para>The parameter <envar>apply.default</envar> has been set to
- <envar>true</envar> and the parameter
- <envar>apply.specific</envar> is <envar>null</envar>. The
- corresponding changes will be applied to the default portal
- container only.</para>
- </listitem>
-
- <listitem>
- <para>The parameter <envar>apply.default</envar> has been set to
- <envar>true</envar> and the parameter
- <envar>apply.specific</envar> is not <envar>null</envar>. The
- corresponding changes will be applied to the default portal
- container and the given list of specific portal containers.</para>
- </listitem>
-
- <listitem>
- <para>The parameter <envar>apply.default</envar> has been set to
- <envar>false</envar> or has not been set and the parameter
- <envar>apply.specific</envar> is <envar>null</envar>. The
- corresponding changes will be applied to the default portal
- container only.</para>
- </listitem>
-
- <listitem>
- <para>The parameter <envar>apply.default</envar> has been set to
- <envar>false</envar> or has not been set and the parameter
- <envar>apply.specific</envar> is not <envar>null</envar>. The
- corresponding changes will be applied to the given list of
- specific portal containers.</para>
- </listitem>
- </orderedlist>
-
- <section>
- <title>The existing implementations of
- <envar>PortalContainerDefinitionChange</envar></title>
-
- <para>The modifications that can be applied to a
- <envar>PortalContainerDefinition</envar> must be a class of type
- <envar>PortalContainerDefinitionChange</envar>. The product proposes
- out of the box some implementations that we describe in the next sub
- sections.</para>
-
- <section>
- <title><envar>AddDependencies</envar></title>
-
- <para>This modification adds a list of dependencies at the end of
- the list of dependencies defined into the
- <envar>PortalContainerDefinition</envar>. The full qualified name
- is
- <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies</emphasis>.</para>
-
- <table>
- <title>Descriptions of the fields of an
- <envar>AddDependencies</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>dependencies</entry>
-
- <entry>A list of <emphasis>String</emphasis> corresponding
- to the list of name of the dependencies to add. If the
- value of this field is empty, the change will be
- ignored.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>See an example below, that will add <envar>foo</envar> at
- the end of the dependency list of the default portal
- container:</para>
-
- <programlisting><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>Change PortalContainer Definitions</name>
- <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
- <set-method>registerChangePlugin</set-method>
- <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
- <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
- <init-params>
- <value-param>
- <name>apply.default</name>
- <value>true</value>
- </value-param>
- <object-param>
- <name>change</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
- <!-- The list of name of the dependencies to add -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- </collection>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
- </section>
-
- <section>
- <title><envar>AddDependenciesBefore</envar></title>
-
- <para>This modification adds a list of dependencies before a given
- target dependency defined into the list of dependencies of the
- <envar>PortalContainerDefinition</envar>. The full qualified name
- is
- <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore</emphasis>.</para>
-
- <table>
- <title>Descriptions of the fields of an
- <envar>AddDependenciesBefore</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>dependencies</entry>
-
- <entry>A list of <emphasis>String</emphasis> corresponding
- to the list of name of the dependencies to add. If the
- value of this field is empty, the change will be
- ignored.</entry>
- </row>
-
- <row>
- <entry>target</entry>
-
- <entry>The name of the dependency before which we would
- like to add the new dependencies. If this field is
- <envar>null</envar> or the target dependency cannot be
- found in the list of dependencies defined into the
- <envar>PortalContainerDefinition</envar>, the new
- dependencies will be added in first position to the
- list.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>See an example below, that will add <envar>foo</envar>
- before <envar>foo2</envar> in the dependency list of the default
- portal container:</para>
-
- <programlisting><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>Change PortalContainer Definitions</name>
- <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
- <set-method>registerChangePlugin</set-method>
- <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
- <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
- <init-params>
- <value-param>
- <name>apply.default</name>
- <value>true</value>
- </value-param>
- <object-param>
- <name>change</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore">
- <!-- The list of name of the dependencies to add -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- </collection>
- </field>
- <!-- The name of the target dependency -->
- <field name="target">
- <string>foo2</string>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
- </section>
-
- <section>
- <title><envar>AddDependenciesAfter</envar></title>
-
- <para>This modification adds a list of dependencies before a given
- target dependency defined into the list of dependencies of the
- <envar>PortalContainerDefinition</envar>. The full qualified name
- is
- <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter</emphasis>.</para>
-
- <table>
- <title>Descriptions of the fields of an
- <envar>AddDependenciesAfter</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>dependencies</entry>
-
- <entry>A list of <emphasis>String</emphasis> corresponding
- to the list of name of the dependencies to add. If the
- value of this field is empty, the change will be
- ignored.</entry>
- </row>
-
- <row>
- <entry>target</entry>
-
- <entry>The name of the dependency after which we would
- like to add the new dependencies. If this field is
- <envar>null</envar> or the target dependency cannot be
- found in the list of dependencies defined into the
- <envar>PortalContainerDefinition</envar>, the new
- dependencies will be added in last position to the
- list.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>See an example below, that will add <envar>foo</envar> after
- <envar>foo2</envar> in the dependency list of the default portal
- container:</para>
-
- <programlisting><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>Change PortalContainer Definitions</name>
- <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
- <set-method>registerChangePlugin</set-method>
- <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
- <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
- <init-params>
- <value-param>
- <name>apply.default</name>
- <value>true</value>
- </value-param>
- <object-param>
- <name>change</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter">
- <!-- The list of name of the dependencies to add -->
- <field name="dependencies">
- <collection type="java.util.ArrayList">
- <value>
- <string>foo</string>
- </value>
- </collection>
- </field>
- <!-- The name of the target dependency -->
- <field name="target">
- <string>foo2</string>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
- </section>
-
- <section>
- <title><envar>AddSettings</envar></title>
-
- <para>This modification adds new settings to a
- <envar>PortalContainerDefinition</envar>. The full qualified name
- is
- <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings</emphasis>.</para>
-
- <table>
- <title>Descriptions of the fields of an
- <envar>AddSettings</envar></title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>settings</entry>
-
- <entry>A map of <emphasis><String,
- Object></emphasis> corresponding to the settings to
- add. If the value of this field is empty, the change will
- be ignored.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>See an example below, that will add the settings
- <envar>string</envar> and <envar>stringX</envar> to the settings
- of the default portal container:</para>
-
- <programlisting><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>Change PortalContainer Definitions</name>
- <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
- <set-method>registerChangePlugin</set-method>
- <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
- <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
- <init-params>
- <value-param>
- <name>apply.default</name>
- <value>true</value>
- </value-param>
- <object-param>
- <name>change</name>
- <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings">
- <!-- The settings to add to the to the portal containers -->
- <field name="settings">
- <map type="java.util.HashMap">
- <entry>
- <key>
- <string>string</string>
- </key>
- <value>
- <string>value1</string>
- </value>
- </entry>
- <entry>
- <key>
- <string>stringX</string>
- </key>
- <value>
- <string>value1</string>
- </value>
- </entry>
- </map>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
- </section>
- </section>
- </section>
- </section>
- </section>
-
- <section>
- <title>System property configuration</title>
-
- <para>A new property configurator service has been developed for taking
- care of configuring system properties from the inline kernel configuration
- or from specified property files.</para>
-
- <para>The services is scoped at the root container level because it is
- used by all the services in the different portal containers in the
- application runtime.</para>
-
- <section>
- <title>Properties init param</title>
-
- <para>The properties init param takes a property declared to configure
- various properties.</para>
-
- <programlisting><component>
- <key>PropertyManagerConfigurator</key>
- <type>org.exoplatform.container.PropertyConfigurator</type>
- <init-params>
- <properties-param>
- <name>properties</name>
- <property name="foo" value="bar"/>
- </properties-param>
- </init-params>
-</component></programlisting>
- </section>
-
- <section>
- <title>Properties URL init param</title>
-
- <para>The properties URL init param allow to load an external file by
- specifying its URL. Both property and XML format are supported, see the
- javadoc of the <emphasis><envar>java.util.Properties</envar></emphasis>
- class for more information. When a property file is loaded the various
- property declarations are loaded in the order in which the properties
- are declared sequentially in the file.</para>
-
- <programlisting><component>
- <key>PropertyManagerConfigurator</key>
- <type>org.exoplatform.container.PropertyConfigurator</type>
- <init-params>
- <value-param>
- <name>properties.url</name>
- <value>classpath:configuration.properties</value>
- </value-param>
- </init-params>
-</component></programlisting>
-
- <para>In the properties file corresponding to the external properties,
- you can reuse variables previously defined to create a new variable. In
- this case the prefix "<emphasis>portal.container.</emphasis>" is not
- needed, see an example below:<programlisting>my-var1=value 1
-my-var2=value 2
-complex-value=${my-var1}-${my-var2}</programlisting></para>
- </section>
-
- <section>
- <title>System Property configuration of the properties URL</title>
-
- <para>It is possible to replace the properties URL init param by a
- system property that overwrites it. The name of that property is
- <emphasis>exo.properties.url</emphasis>.</para>
- </section>
- </section>
-
- <section>
- <title>Runtime configuration profiles</title>
-
- <para>The kernel configuration is able to handle configuration profiles at
- runtime (as opposed to packaging time).</para>
-
- <section>
- <title>Profiles activation</title>
-
- <para>An active profile list is obtained during the boot of the root
- container and is composed of the system property
- <emphasis>exo.profiles</emphasis> sliced according the "," delimiter and
- also a server specific profile value (tomcat for tomcat, jboss for
- jboss, etc...).</para>
-
- <programlisting># runs GateIn on Tomcat with the profiles tomcat and foo
-sh gatein.sh -Dexo.profiles=foo
-
-# runs GateIn on JBoss with the profiles jboss, foo and bar
-sh run.sh -Dexo.profiles=foo,bar</programlisting>
- </section>
-
- <section>
- <title>Profiles configuration</title>
-
- <para>Profiles are configured in the configuration files of the eXo
- kernel.</para>
-
- <section>
- <title>Profiles definition</title>
-
- <para>Profile activation occurs at XML to configuration object
- unmarshalling time. It is based on an "profile" attribute that is
- present on some of the XML element of the configuration files. To
- enable this the kernel configuration schema has been upgraded to
- kernel_1_1.xsd. The configuration is based on the following
- rules:</para>
-
- <orderedlist>
- <listitem>
- <para>Any kernel element with the no <emphasis>profiles</emphasis>
- attribute will create a configuration object</para>
- </listitem>
-
- <listitem>
- <para>Any kernel element having a <emphasis>profiles</emphasis>
- attribute containing at least one of the active profiles will
- create a configuration object</para>
- </listitem>
-
- <listitem>
- <para>Any kernel element having a <emphasis>profiles</emphasis>
- attribute matching none of the active profile will not create a
- configuration object</para>
- </listitem>
-
- <listitem>
- <para>Resolution of duplicates (such as two components with same
- type) is left up to the kernel</para>
- </listitem>
- </orderedlist>
- </section>
-
- <section>
- <title>Profiles capable configuration elements</title>
-
- <para>A configuration element is <emphasis>profiles</emphasis> capable
- when it carries a profiles element.</para>
-
- <section>
- <title>Component element</title>
-
- <para>The component element declares a component when activated. It
- will shadow any element with the same key declared before in the
- same configuration file:</para>
-
- <programlisting><component>
- <key>Component</key>
- <type>Component</type>
-</component>
-
-<component profiles="foo">
- <key>Component</key>
- <type>FooComponent</type>
-</component></programlisting>
- </section>
-
- <section>
- <title>Component plugin element</title>
-
- <para>The component-plugin element is used to dynamically extend the
- configuration of a given component. Thanks to the profiles the
- component-plugins could be enabled or disabled:</para>
-
- <programlisting><external-component-plugins>
- <target-component>Component</target-component>
- <component-plugin profiles="foo">
- <name>foo</name>
- <set-method>addPlugin</set-method>
- <type>type</type>
- <init-params>
- <value-param>
- <name>param</name>
- <value>empty</value>
- </value-param>
- </init-params>
- </component-plugin>
-</external-component-plugins></programlisting>
- </section>
-
- <section>
- <title>Import element</title>
-
- <para>The import element imports a referenced configuration file
- when activated:</para>
-
- <programlisting><import>empty</import>
-<import profiles="foo">foo</import>
-<import profiles="bar">bar</import></programlisting>
- </section>
-
- <section>
- <title>Init param element</title>
-
- <para>The init param element configures the parameter argument of
- the construction of a component service:</para>
-
- <programlisting><component>
- <key>Component</key>
- <type>ComponentImpl</type>
- <init-params>
- <value-param>
- <name>param</name>
- <value>empty</value>
- </value-param>
- <value-param profiles="foo">
- <name>param</name>
- <value>foo</value>
- </value-param>
- <value-param profiles="bar">
- <name>param</name>
- <value>bar</value>
- </value-param>
- </init-params>
-</component></programlisting>
- </section>
-
- <section>
- <title>Value collection element</title>
-
- <para>The value collection element configures one of the value of
- collection data:</para>
-
- <programlisting><object type="org.exoplatform.container.configuration.ConfigParam">
- <field name="role">
- <collection type="java.util.ArrayList">
- <value><string>manager</string></value>
- <value profiles="foo"><string>foo_manager</string></value>
- <value profiles="foo,bar"><string>foo_bar_manager</string></value>
- </collection>
- </field>
-</object></programlisting>
- </section>
-
- <section>
- <title>Field configuration element</title>
-
- <para>The field configuration element configures the field of an
- object:</para>
-
- <programlisting><object-param>
- <name>test.configuration</name>
- <object type="org.exoplatform.container.configuration.ConfigParam">
- <field name="role">
- <collection type="java.util.ArrayList">
- <value><string>manager</string></value>
- </collection>
- </field>
- <field name="role" profiles="foo,bar">
- <collection type="java.util.ArrayList">
- <value><string>foo_bar_manager</string></value>
- </collection>
- </field>
- <field name="role" profiles="foo">
- <collection type="java.util.ArrayList">
- <value><string>foo_manager</string></value>
- </collection>
- </field>
- </object>
-</object-param></programlisting>
- </section>
- </section>
- </section>
- </section>
-
- <section>
- <title>Component request life cycle</title>
-
- <section>
- <title>Component request life cycle contract</title>
-
- <para>The component request life cycle is an interface that defines a
- contract for a component for being involved into a
- request:<programlisting>public interface ComponentRequestLifecycle
-{
- /**
- * Start a request.
- * @param container the related container
- */
- void startRequest(ExoContainer container);
-
- /**
- * Ends a request.
- * @param container the related container
- */
- void endRequest(ExoContainer container);
-}</programlisting></para>
-
- <para>The container passed is the container to which the component is
- related. This contract is often used to setup a thread local based
- context that will be demarcated by a request.</para>
-
- <para>For instance in the GateIn portal context, a component request
- life cycle is triggered for user requests. Another example is the
- initial data import in GateIn that demarcates using callbacks made to
- that interface.</para>
- </section>
-
- <section>
- <title>Request life cycle</title>
-
- <para>The <envar>RequestLifeCycle</envar> class has several statics
- methods that are used to schedule the component request life cycle of
- components. Its main responsability is to perform scheduling while
- respecting the constraint to execute the request life cycle of a
- component only once even if it can be scheduled several times.</para>
-
- <section>
- <title>Scheduling a component request life cycle</title>
-
- <programlisting>RequestLifeCycle.begin(component);
-try
-{
- // Do something
-}
-finally
-{
- RequestLifeCycle.end();
-}</programlisting>
- </section>
-
- <section>
- <title>Scheduling a container request life cycle</title>
-
- <para>Scheduling a container triggers the component request life cyle
- of all the components that implement the interface
- <envar>ComponentRequestLifeCycle</envar>. If one of the component has
- already been scheduled before then that component will not be
- scheduled again. When the local value is true then the looked
- components will be those of the container, when it is false then the
- scheduler will also look at the components in the ancestor
- containers.<programlisting>RequestLifeCycle.begin(container, local);
-try
-{
- // Do something
-}
-finally
-{
- RequestLifeCycle.end();
-}</programlisting></para>
- </section>
- </section>
-
- <section>
- <title>When request life cycle is triggered</title>
-
- <section>
- <title>Portal request life cycle</title>
-
- <para>Each portal request triggers the life cycle of the associated
- portal container.</para>
- </section>
-
- <section>
- <title>JMX request Life Cycle</title>
-
- <para>When a JMX bean is invoked, the request life cycle of the
- container to which it belongs it scheduled. Indeed JMX is an entry
- point of the system that may need component to have a request life
- cycle triggered.</para>
- </section>
- </section>
- </section>
-</chapter>
+<?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">
+<chapter id="Kernel.ContainerConfiguration">
+ <?dbhtml filename="ch-kernel-container-configuration.html"?>
+
+ <title>Container Configuration</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>eXo Portal uses PicoContainer, which implements the Inversion of
+ Control (IoC) design pattern. All eXo containers inherit from a
+ PicoContainer. There are mainly two eXo containers used, each of them can
+ provide one or several services. Each container service is delivered in a
+ JAR file. This JAR file may contain a default configuration. The use of
+ default configurations is recommended and most services provide it.</para>
+
+ <para>When a Pico Container searches for services and its configurations,
+ each configurable service may be reconfigured to override default values
+ or set additional parameters. If the service is configured in two or more
+ places the configuration override mechanism will be used.</para>
+
+ <para>Confused? - You might be interested in the <link
+ linkend="KernelServiceConfigurationforBeginners">Service Configuration for
+ Beginners</link> article, which explains the basics.</para>
+ </section>
+
+ <section id="Kernel.ContainerConfiguration.ConfigurationNamespace">
+ <title>Kernel configuration namespace</title>
+
+ <para>To be effective the namespace URI
+ <uri>http://www.exoplaform.org/xml/ns/kernel_1_1.xsd</uri> must be target
+ namespace of the XML configuration file.</para>
+
+ <programlisting><xsd:schema
+ targetNamespace="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ ...
+</xsd:schema></programlisting>
+ </section>
+
+ <section>
+ <title>Understanding How configuration files are loaded</title>
+
+ <para>eXo Portal uses PicoContainer, which implements the Inversion of
+ Control (IoC) design pattern. All eXo containers inherit from a
+ PicoContainer. There are mainly two eXo containers used, each of them can
+ provide one or several services. Each container service is delivered in a
+ JAR file. This JAR file may contain a default configuration. The use of
+ default configurations is recommended and most services provide it.</para>
+
+ <para>When a Pico Container searches for services and its configurations,
+ each configurable service may be reconfigured to override default values
+ or set additional parameters. If the service is configured in two or more
+ places the configuration override mechanism will be used.</para>
+
+ <section>
+ <title>Configuration Retrieval</title>
+
+ <para>The container performs the following steps making eXo Container
+ configuration retrieval depending on the container type.</para>
+
+ <section>
+ <title>Configuration retrieval order for the
+ <envar>PortalContainer</envar></title>
+
+ <para>The container is initialized by looking into different
+ locations. This container is used by portal applications.
+ Configurations are overloaded in the following lookup sequence:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Services default <envar>RootContainer</envar> configurations
+ from JAR files <emphasis>/conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>External <envar>RootContainer</envar> configuration, if will
+ be found at
+ <emphasis>$AS_HOME/exo-conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Services default <envar>PortalContainer</envar>
+ configurations from JAR files
+ <emphasis>/conf/portal/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Web applications configurations from WAR files
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>External configuration for services of named portal, if will
+ be found at
+ <emphasis>$AS_HOME/exo-conf/portal/$PORTAL_NAME/configuration.xml</emphasis></para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>Configuration retrieval for a
+ <envar>StandaloneContainer</envar></title>
+
+ <para>The container is initialized by looking into different
+ locations. This container is used by non portal applications.
+ Configurations are overloaded in the following lookup sequence:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Services default <envar>RootContainer</envar> configurations
+ from JAR files <emphasis>/conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>External <envar>RootContainer</envar> configuration, if will
+ be found at
+ <emphasis>$AS_HOME/exo-conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Services default <envar>StandaloneContainer</envar>
+ configurations from JAR files
+ <emphasis>/conf/portal/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Web applications configurations from WAR files
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Then depending on the <envar>StandaloneContainer</envar>
+ configuration URL initialization:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>if configuration URL was initialized to be added to
+ services defaults, as below:<programlisting>// add configuration to the default services configurations from JARs/WARs
+StandaloneContainer.addConfigurationURL(containerConf);</programlisting></para>
+
+ <para>Configuration from added URL
+ <emphasis>containerConf</emphasis> will override only services
+ configured in the file</para>
+ </listitem>
+
+ <listitem>
+ <para>if configuration URL not initialized at all, it will be
+ found at <emphasis>$AS_HOME/exo-configuration.xml</emphasis>.
+ If <emphasis>$AS_HOME/exo-configuration.xml</emphasis> doesn't
+ exist the container will try find it at
+ <emphasis>$AS_HOME/exo-conf/exo-configuration.xml</emphasis>
+ location and if it's still not found and the
+ <envar>StandaloneContainer</envar> instance obtained with the
+ dedicated configuration <envar>ClassLoader</envar> the
+ container will try to retrieve the resource
+ <emphasis>conf/exo-configuration.xml</emphasis> within the
+ given <envar>ClassLoader</envar>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>General notes about the configuration retrieval</title>
+
+ <note>
+ <para><emphasis>$AS_HOME</emphasis> - application server home
+ directory, or <emphasis>user.dir</emphasis> JVM system property
+ value in case of Java Standalone application.</para>
+ </note>
+
+ <note>
+ <para><emphasis>$PORTAL_NAME</emphasis> - portal web application
+ name.</para>
+ </note>
+
+ <note>
+ <para>External configuration location can be overridden with System
+ property <emphasis>exo.conf.dir</emphasis>. If the property exists
+ its value will be used as path to eXo configuration directory, i.e.
+ to <emphasis>$AS_HOME/exo-conf</emphasis> alternative. E.g. put
+ property in command line java
+ <emphasis>-Dexo.conf.dir=/path/to/exo/conf</emphasis>. In this
+ particular use case, you have no need to use any prefix to import
+ other files. For instance, if your configuration file is
+ <emphasis>$AS_HOME/exo-conf/portal/PORTAL_NAME/configuration.xml</emphasis>
+ and you want to import the configuration file
+ <emphasis>$AS_HOME/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.xml</emphasis>,
+ you can do it by adding
+ <emphasis><import>mySubConfDir/myConfig.xml</import></emphasis>
+ to your configuration file.</para>
+ </note>
+
+ <note>
+ <para>The name of the configuration folder that is by default
+ <emphasis>"exo-conf"</emphasis>, can be changed thanks to the System
+ property <emphasis>exo.conf.dir.name</emphasis>.</para>
+ </note>
+
+ <note>
+ <para>Under JBoss application server <emphasis>exo-conf</emphasis>
+ will be looked up in directory described by JBoss System property
+ <emphasis>jboss.server.config.url</emphasis>. If the property is not
+ found or empty <emphasis>$AS_HOME/exo-conf</emphasis> will be
+ asked.</para>
+ </note>
+
+ <note>
+ <para>The search looks for a configuration file in each JAR/WAR
+ available from the classpath using the current thread context
+ classloader. During the search these configurations are added to a
+ set. If the service was configured previously and the current JAR
+ contains a new configuration of that service the latest (from the
+ current JAR/WAR) will replace the previous one. The last one will be
+ applied to the service during the services start phase.</para>
+ </note>
+
+ <warning>
+ <para>Take care to have no dependencies between configurations from
+ JAR files (<emphasis>/conf/portal/configuration.xml</emphasis> and
+ <emphasis>/conf/configuration.xml</emphasis>) since we have no way
+ to know in advance the loading order of those configurations. In
+ other words, if you want to overload some configuration located in
+ the file <emphasis>/conf/portal/configuration.xml</emphasis> of a
+ given JAR file, you must not do it from the file
+ <emphasis>/conf/portal/configuration.xml</emphasis> of another JAR
+ file but from another configuration file loaded after configurations
+ from JAR files
+ <emphasis>/conf/portal/configuration.xml.</emphasis></para>
+ </warning>
+
+ <para>After the processing of all configurations available in system
+ the container will initialize it and start each service in order of
+ the dependency injection (DI).</para>
+
+ <para>The user/developer should be careful when configuring the same
+ service in different configuration files. It's recommended to
+ configure a service in its own JAR only. Or, in case of a portal
+ configuration, strictly reconfigure the services in portal WAR files
+ or in an external configuration.</para>
+
+ <para>There are services that can be (or should be) configured more
+ than one time. This depends on business logic of the service. A
+ service may initialize the same resource (shared with other services)
+ or may add a particular object to a set of objects (shared with other
+ services too). In the first case it's critical who will be the last,
+ i.e. whose configuration will be used. In the second case it's no
+ matter who is the first and who is the last (if the parameter objects
+ are independent).</para>
+ </section>
+
+ <section>
+ <title>Configuration retrieval log</title>
+
+ <para>In case of problems with service configuration it's important to
+ know from which JAR/WAR it comes. For that purpose the JVM system
+ property
+ <emphasis>org.exoplatform.container.configuration.debug</emphasis> can
+ be used.<programlisting>java -Dorg.exoplatform.container.configuration.debug ...</programlisting></para>
+
+ <para>If the property is enabled the container configuration manager
+ will log the configuration adding process at <emphasis>INFO</emphasis>
+ level.<programlisting>......
+ Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
+ Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
+ Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml
+ import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
+ import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml
+ import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
+ import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
+ ......</programlisting></para>
+ </section>
+
+ <section>
+ <title>Get the effective configuration at Runtime</title>
+
+ <para>The effective configuration of the StandaloneContainer,
+ RootContainer and/or PortalContainer can be known thanks to the method
+ <emphasis>getConfigurationXML</emphasis>() that is exposed through JMX
+ at the container's level. This method will give you the effective
+ configuration in XML format that has been really interpreted by the
+ kernel. This could be helpful to understand how a given component or
+ plugin has been initialized.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Advanced concepts for the
+ <emphasis>PortalContainers</emphasis></title>
+
+ <para>Since eXo JCR 1.12, we added a set of new features that have been
+ designed to extend portal applications such as GateIn.</para>
+
+ <section>
+ <title>Add new configuration files from a WAR file</title>
+
+ <para>A <envar>ServletContextListener</envar> called
+ <envar>org.exoplatform.container.web.PortalContainerConfigOwner</envar>
+ has been added in order to notify the application that a given web
+ application provides some configuration to the portal container, and
+ this configuration file is the file
+ <emphasis>WEB-INF/conf/configuration.xml</emphasis> available in the
+ web application itself.</para>
+
+ <para>If your war file contains some configuration to add to the
+ <envar>PortalContainer</envar> simply add the following lines in your
+ <emphasis>web.xml</emphasis> file.</para>
+
+ <programlisting><?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>
+...
+ <!-- ================================================================== -->
+ <!-- LISTENER -->
+ <!-- ================================================================== -->
+ <listener>
+ <listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
+ </listener>
+...
+</web-app></programlisting>
+ </section>
+
+ <section>
+ <title>Create your <emphasis>PortalContainers</emphasis> from a WAR
+ file</title>
+
+ <para>A <envar>ServletContextListener</envar> called
+ <envar>org.exoplatform.container.web.PortalContainerCreator</envar>
+ has been added in order to create the current portal containers that
+ have been registered. We assume that all the web applications have
+ already been loaded before calling
+ <envar>PortalContainerCreator.contextInitialized<replaceable><optional>.</optional></replaceable></envar></para>
+
+ <para><note>
+ <para>In GateIn, the <envar>PortalContainerCreator</envar> is
+ already managed by the file
+ <emphasis>starter.war/ear.</emphasis></para>
+ </note></para>
+ </section>
+
+ <section>
+ <title>Define a <emphasis>PortalContainer</emphasis> with its
+ dependencies and its settings</title>
+
+ <para>Now we can define precisely a portal container and its
+ dependencies and settings thanks to the
+ <envar>PortalContainerDefinition</envar> that currently contains the
+ name of the portal container, the name of the rest context, the name
+ of the realm he web application dependencies ordered by loading
+ priority (i.e. the first dependency must be loaded at first and so
+ on..) and the settings.</para>
+
+ <para>To be able to define a <envar>PortalContainerDefinition</envar>,
+ we need to ensure first of all that a
+ <envar>PortalContainerConfig</envar> has been defined at the
+ <envar>RootContainer</envar> level, see below an example:</para>
+
+ <programlisting> <component>
+ <!-- The full qualified name of the PortalContainerConfig -->
+ <type>org.exoplatform.container.definition.PortalContainerConfig</type>
+ <init-params>
+ <!-- The name of the default portal container -->
+ <value-param>
+ <name>default.portal.container</name>
+ <value>myPortal</value>
+ </value-param>
+ <!-- The name of the default rest ServletContext -->
+ <value-param>
+ <name>default.rest.context</name>
+ <value>myRest</value>
+ </value-param>
+ <!-- The name of the default realm -->
+ <value-param>
+ <name>default.realm.name</name>
+ <value>my-exo-domain</value>
+ </value-param>
+ <!-- The default portal container definition -->
+ <!-- It cans be used to avoid duplicating configuration -->
+ <object-param>
+ <name>default.portal.definition</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinition">
+ <!-- All the dependencies of the portal container ordered by loading priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ <value>
+ <string>foo2</string>
+ </value>
+ <value>
+ <string>foo3</string>
+ </value>
+ </collection>
+ </field>
+ <!-- A map of settings tied to the default portal container -->
+ <field name="settings">
+ <map type="java.util.HashMap">
+ <entry>
+ <key>
+ <string>foo5</string>
+ </key>
+ <value>
+ <string>value</string>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>string</string>
+ </key>
+ <value>
+ <string>value0</string>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>int</string>
+ </key>
+ <value>
+ <int>100</int>
+ </value>
+ </entry>
+ </map>
+ </field>
+ <!-- The path to the external properties file -->
+ <field name="externalSettingsPath">
+ <string>classpath:/org/exoplatform/container/definition/default-settings.properties</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component></programlisting>
+
+ <table>
+ <title>Descriptions of the fields of
+ <envar>PortalContainerConfig</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>default.portal.container</entry>
+
+ <entry>The name of the default portal container. This field is
+ optional.</entry>
+ </row>
+
+ <row>
+ <entry>default.rest.context</entry>
+
+ <entry>The name of the default rest
+ <envar>ServletContext</envar>. This field is optional.</entry>
+ </row>
+
+ <row>
+ <entry>default.realm.name</entry>
+
+ <entry>The name of the default realm. This field is
+ optional.</entry>
+ </row>
+
+ <row>
+ <entry>default.portal.definition</entry>
+
+ <entry>The definition of the default portal container. This
+ field is optional. The expected type is
+ <envar>org.exoplatform.container.definition.PortalContainerDefinition</envar>
+ that is described below. Allow the parameters defined in this
+ default <envar>PortalContainerDefinition</envar> will be the
+ default values.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>A new <envar>PortalContainerDefinition</envar> can be defined at
+ the <envar>RootContainer</envar> level thanks to an external plugin,
+ see below an example:<programlisting> <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>myPortal</string>
+ </field>
+ <!-- The name of the context name of the rest web application -->
+ <field name="restContextName">
+ <string>myRest</string>
+ </field>
+ <!-- The name of the realm -->
+ <field name="realmName">
+ <string>my-domain</string>
+ </field>
+ <!-- All the dependencies of the portal container ordered by loading priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ <value>
+ <string>foo2</string>
+ </value>
+ <value>
+ <string>foo3</string>
+ </value>
+ </collection>
+ </field>
+ <!-- A map of settings tied to the portal container -->
+ <field name="settings">
+ <map type="java.util.HashMap">
+ <entry>
+ <key>
+ <string>foo</string>
+ </key>
+ <value>
+ <string>value</string>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>int</string>
+ </key>
+ <value>
+ <int>10</int>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>long</string>
+ </key>
+ <value>
+ <long>10</long>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>double</string>
+ </key>
+ <value>
+ <double>10</double>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>boolean</string>
+ </key>
+ <value>
+ <boolean>true</boolean>
+ </value>
+ </entry>
+ </map>
+ </field>
+ <!-- The path to the external properties file -->
+ <field name="externalSettingsPath">
+ <string>classpath:/org/exoplatform/container/definition/settings.properties</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins></programlisting></para>
+
+ <table>
+ <title>Descriptions of the fields of a
+ <envar>PortalContainerDefinition</envar> when it is used to define a
+ new portal container</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>name</entry>
+
+ <entry>The name of the portal container. This field is
+ mandatory .</entry>
+ </row>
+
+ <row>
+ <entry>restContextName</entry>
+
+ <entry>The name of the context name of the rest web
+ application. This field is optional. The default value will
+ the value define at the <envar>PortalContainerConfig</envar>
+ level.</entry>
+ </row>
+
+ <row>
+ <entry>realmName</entry>
+
+ <entry>The name of the realm. This field is optional. The
+ default value will the value define at the
+ <envar>PortalContainerConfig</envar> level.</entry>
+ </row>
+
+ <row>
+ <entry>dependencies</entry>
+
+ <entry>All the dependencies of the portal container ordered by
+ loading priority. This field is optional. The default value
+ will the value define at the
+ <envar>PortalContainerConfig</envar> level. The dependencies
+ are in fact the list of the context names of the web
+ applications from which the portal container depends. This
+ field is optional. The dependency order is really crucial
+ since it will be interpreted the same way by several
+ components of the platform. All those components, will
+ consider the 1st element in the list less important than the
+ second element and so on. It is currently used
+ to:<itemizedlist>
+ <listitem>
+ <para>Know the loading order of all the
+ dependencies.</para>
+ </listitem>
+
+ <listitem>
+ <para>If we have several
+ <envar>PortalContainerConfigOwner</envar><itemizedlist>
+ <listitem>
+ <para>The <envar>ServletContext</envar> of all the
+ <envar>PortalContainerConfigOwner</envar> will be
+ unified, if we use the unified
+ <envar>ServletContext</envar>
+ (<emphasis>PortalContainer.getPortalContext()</emphasis>)
+ to get a resource, it will try to get the resource
+ in the <envar>ServletContext</envar> of the most
+ important <envar>PortalContainerConfigOwner</envar>
+ (i.e. last in the dependency list) and if it cans
+ find it, it will try with the second most important
+ <envar>PortalContainerConfigOwner</envar> and so
+ on.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <envar>ClassLoader</envar> of all the
+ <envar>PortalContainerConfigOwner</envar> will be
+ unified, if we use the unified
+ <envar>ClassLoader</envar>
+ (<emphasis>PortalContainer.getPortalClassLoader()</emphasis>)
+ to get a resource, it will try to get the resource
+ in the <envar>ClassLoader</envar> of the most
+ important <envar>PortalContainerConfigOwner</envar>
+ (i.e. last in the dependency list) and if it cans
+ find it, it will try with the second most important
+ <envar>PortalContainerConfigOwner</envar> and so
+ on.</para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></entry>
+ </row>
+
+ <row>
+ <entry>settings</entry>
+
+ <entry>A <envar>java.util.Map</envar> of internal parameters
+ that we would like to tie the portal container. Those
+ parameters could have any type of value. This field is
+ optional. If some internal settings are defined at the
+ <envar>PortalContainerConfig</envar> level, the two maps of
+ settings will be merged. If a setting with the same name is
+ defined in both maps, it will keep the value defined at the
+ <envar>PortalContainerDefinition</envar> level.</entry>
+ </row>
+
+ <row>
+ <entry>externalSettingsPath</entry>
+
+ <entry>The path of the external properties file to load as
+ default settings to the portal container. This field is
+ optional. If some external settings are defined at the
+ <envar>PortalContainerConfig</envar> level, the two maps of
+ settings will be merged. If a setting with the same name is
+ defined in both maps, it will keep the value defined at the
+ <envar>PortalContainerDefinition</envar> level. The external
+ properties files can be either of type "properties" or of type
+ "xml". The path will be interpreted as follows:<orderedlist>
+ <listitem>
+ <para>The path doesn't contain any prefix of type
+ "classpath:", "jar:" or "file:", we assume that the file
+ could be externalized so we apply the following
+ rules:<orderedlist>
+ <listitem>
+ <para>A file exists at
+ <emphasis>${exo-conf-dir}/portal/${portalContainerName}/${externalSettingsPath}</emphasis>,
+ we will load this file.</para>
+ </listitem>
+
+ <listitem>
+ <para>No file exists at the previous path, we then
+ assume that the path cans be interpreted by the
+ <envar>ConfigurationManager</envar>.</para>
+ </listitem>
+ </orderedlist></para>
+ </listitem>
+
+ <listitem>
+ <para>The path contains a prefix, we then assume that
+ the path cans be interpreted by the
+ <envar>ConfigurationManager</envar>.</para>
+ </listitem>
+ </orderedlist></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Descriptions of the fields of a
+ <envar>PortalContainerDefinition</envar> when it is used to define
+ the default portal container</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>name</entry>
+
+ <entry>The name of the portal container. This field is
+ optional. The default portal name will be:<orderedlist>
+ <listitem>
+ <para>If this field is not empty, then the default value
+ will be the value of this field.</para>
+ </listitem>
+
+ <listitem>
+ <para>If this field is empty and the value of the
+ parameter <emphasis>default.portal.container</emphasis>
+ is not empty, then the default value will be the value
+ of the parameter.</para>
+ </listitem>
+
+ <listitem>
+ <para>If this field and the parameter
+ <emphasis>default.portal.container</emphasis> are both
+ empty, the default value will be
+ <emphasis>"portal".</emphasis></para>
+ </listitem>
+ </orderedlist></entry>
+ </row>
+
+ <row>
+ <entry>restContextName</entry>
+
+ <entry>The name of the context name of the rest web
+ application. This field is optional. The default value wil
+ be:<orderedlist>
+ <listitem>
+ <para>If this field is not empty, then the default value
+ will be the value of this field.</para>
+ </listitem>
+
+ <listitem>
+ <para>f this field is empty and the value of the
+ parameter <emphasis>default.rest.context</emphasis> is
+ not empty, then the default value will be the value of
+ the parameter.</para>
+ </listitem>
+
+ <listitem>
+ <para>f this field and the parameter
+ <emphasis>default.rest.context</emphasis> are both
+ empty, the default value will be
+ <emphasis>"rest".</emphasis></para>
+ </listitem>
+ </orderedlist></entry>
+ </row>
+
+ <row>
+ <entry>realmName</entry>
+
+ <entry>The name of the realm. This field is optional. The
+ default value wil be:<orderedlist>
+ <listitem>
+ <para>If this field is not empty, then the default value
+ will be the value of this field.</para>
+ </listitem>
+
+ <listitem>
+ <para>f this field is empty and the value of the
+ parameter <emphasis>default.realm.name</emphasis> is not
+ empty, then the default value will be the value of the
+ parameter.</para>
+ </listitem>
+
+ <listitem>
+ <para>f this field and the parameter
+ <emphasis>default.realm.name</emphasis> are both empty,
+ the default value will be
+ <emphasis>"exo-domain".</emphasis></para>
+ </listitem>
+ </orderedlist></entry>
+ </row>
+
+ <row>
+ <entry>dependencies</entry>
+
+ <entry>All the dependencies of the portal container ordered by
+ loading priority. This field is optional. If this field has a
+ non empty value, it will be the default list of
+ dependencies.</entry>
+ </row>
+
+ <row>
+ <entry>settings</entry>
+
+ <entry>A <envar>java.util.Map</envar> of internal parameters
+ that we would like to tie the default portal container. Those
+ parameters could have any type of value. This field is
+ optional.</entry>
+ </row>
+
+ <row>
+ <entry>externalSettingsPath</entry>
+
+ <entry>The path of the external properties file to load as
+ default settings to the default portal container. This field
+ is optional. The external properties files can be either of
+ type "properties" or of type "xml". The path will be
+ interpreted as follows:<orderedlist>
+ <listitem>
+ <para>The path doesn't contain any prefix of type
+ "classpath:", "jar:" or "file:", we assume that the file
+ could be externalized so we apply the following
+ rules:<orderedlist>
+ <listitem>
+ <para>A file exists at
+ <emphasis>${exo-conf-dir}/portal/${externalSettingsPath}</emphasis>,
+ we will load this file.</para>
+ </listitem>
+
+ <listitem>
+ <para>No file exists at the previous path, we then
+ assume that the path cans be interpreted by the
+ <envar>ConfigurationManager</envar>.</para>
+ </listitem>
+ </orderedlist></para>
+ </listitem>
+
+ <listitem>
+ <para>The path contains a prefix, we then assume that
+ the path cans be interpreted by the
+ <envar>ConfigurationManager</envar>.</para>
+ </listitem>
+ </orderedlist></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Internal and external settings are both optional, but if we give
+ a non empty value for both the application will merge the settings. If
+ the same setting name exists in both settings, we apply the following
+ rules:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The value of the external setting is
+ <emphasis>null</emphasis>, we ignore the value.</para>
+ </listitem>
+
+ <listitem>
+ <para>The value of the external setting is not
+ <emphasis>null</emphasis> and the value of the internal setting is
+ <emphasis>null</emphasis>, the final value will be the external
+ setting value that is of type <envar>String</envar>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Both values are not <envar>null</envar>, we will have to
+ convert the external setting value into the target type which is
+ the type of the internal setting value, thanks to the static
+ method <emphasis>valueOf(String)</emphasis>, the following
+ sub-rules are then applied:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The method cannot be found, the final value will be the
+ external setting value that is of type
+ <envar>String</envar>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The method can be found and the external setting value
+ is an empty <envar>String</envar>, we ignore the external
+ setting value.</para>
+ </listitem>
+
+ <listitem>
+ <para>The method can be found and the external setting value
+ is not an empty <envar>String</envar> but the method call
+ fails, we ignore the external setting value.</para>
+ </listitem>
+
+ <listitem>
+ <para>The method can be found and the external setting value
+ is not an empty <envar>String</envar> and the method call
+ succeeds, the final value will be the external setting value
+ that is of type of the internal setting value.</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title><envar>PortalContainer</envar> settings</title>
+
+ <para>We can inject the value of the portal container settings into
+ the portal container configuration files thanks to the variables which
+ name start with "<emphasis>portal.container.</emphasis>", so to get
+ the value of a setting called "<emphasis>foo</emphasis>" just use the
+ following syntax <emphasis>${portal.container.foo}</emphasis>. You can
+ also use internal variables, such as:</para>
+
+ <table>
+ <title>Definition of the internal variables</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>portal.container.name</entry>
+
+ <entry>Gives the name of the current portal container.</entry>
+ </row>
+
+ <row>
+ <entry>portal.container.rest</entry>
+
+ <entry>Gives the context name of the rest web application of
+ the current portal container.</entry>
+ </row>
+
+ <row>
+ <entry>portal.container.realm</entry>
+
+ <entry>Gives the realm name of the current portal
+ container.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>You can find below an example of how to use the
+ variables:<programlisting><configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">
+ <component>
+ <type>org.exoplatform.container.TestPortalContainer$MyComponent</type>
+ <init-params>
+ <!-- The name of the portal container -->
+ <value-param>
+ <name>portal</name>
+ <value>${portal.container.name}</value>
+ </value-param>
+ <!-- The name of the rest ServletContext -->
+ <value-param>
+ <name>rest</name>
+ <value>${portal.container.rest}</value>
+ </value-param>
+ <!-- The name of the realm -->
+ <value-param>
+ <name>realm</name>
+ <value>${portal.container.realm}</value>
+ </value-param>
+ <value-param>
+ <name>foo</name>
+ <value>${portal.container.foo}</value>
+ </value-param>
+ <value-param>
+ <name>before foo after</name>
+ <value>before ${portal.container.foo} after</value>
+ </value-param>
+ </init-params>
+ </component>
+</configuration></programlisting></para>
+
+ <para>In the properties file corresponding to the external settings,
+ you can reuse variables previously defined (in the external settings
+ or in the internal settings) to create a new variable. In this case
+ the prefix "<emphasis>portal.container.</emphasis>" is not needed, see
+ an example below:<programlisting>my-var1=value 1
+my-var2=value 2
+complex-value=${my-var1}-${my-var2}</programlisting></para>
+
+ <para>In the external and internal settings, you can also use create
+ variables based on value of System paramaters. The System parameters
+ can either be defined at launch time or thanks to the
+ <envar>PropertyConfigurator</envar> (see next section for more
+ details). See an example below:</para>
+
+ <programlisting>temp-dir=${java.io.tmpdir}${file.separator}my-temp</programlisting>
+
+ <para>However, for the internal settings you can use System parameters
+ only to define settings of type
+ <envar>java.lang.String</envar>.</para>
+
+ <para>It cans be also very usefull to define a generic variable in the
+ settings of the default portal container, the value of this variable
+ will change according to the current portal container. See below an
+ example:<programlisting>my-generic-var=value of the portal container "${name}"</programlisting></para>
+
+ <para>If this variable is defined at the default portal container
+ level, the value of this variable for a portal container called
+ <emphasis>"foo"</emphasis> will be <emphasis>value of the portal
+ container "foo"</emphasis>.</para>
+ </section>
+
+ <section>
+ <title>Add dynamically settings and/or dependencies to a
+ <envar>PortalContainer</envar></title>
+
+ <para>It is possible to use <envar>component-plugin</envar> elements
+ in order to dynamically change a PortalContainerDefinition. In the
+ example below, we add the dependency <envar>foo</envar> to the default
+ portal container and to the portal containers called
+ <envar>foo1</envar> and <envar>foo2</envar>:</para>
+
+ <programlisting><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>Change PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
+ <set-method>registerChangePlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
+ <init-params>
+ <value-param>
+ <name>apply.default</name>
+ <value>true</value>
+ </value-param>
+ <values-param>
+ <name>apply.specific</name>
+ <value>foo1</value>
+ <value>foo2</value>
+ </values-param>
+ <object-param>
+ <name>change</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
+ <!-- The list of name of the dependencies to add -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+
+ <table>
+ <title>Descriptions of the fields of a
+ <envar>PortalContainerDefinitionChangePlugin</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>apply.all</entry>
+
+ <entry>Indicates whether the changes have to be applied to all
+ the portal containers or not. The default value of this field
+ is <envar>false</envar>. This field is a
+ <envar>ValueParam</envar> and is not mandatory.</entry>
+ </row>
+
+ <row>
+ <entry>apply.default</entry>
+
+ <entry>Indicates whether the changes have to be applied to the
+ default portal container or not. The default value of this
+ field is <envar>false</envar>. This field is a
+ <envar>ValueParam</envar> and is not mandatory.</entry>
+ </row>
+
+ <row>
+ <entry>apply.specific</entry>
+
+ <entry>A set of specific portal container names to which we
+ want to apply the changes. This field is a
+ <envar>ValuesParam</envar> and is not mandatory.</entry>
+ </row>
+
+ <row>
+ <entry><envar>Rest of the expected parameters </envar></entry>
+
+ <entry>The rest of the expected paramaters are
+ <envar>ObjectParam</envar> of type
+ <envar>PortalContainerDefinitionChange</envar>. Those
+ parameters are in fact the list of changes that we want to
+ apply to one or several portal containers. If the list of
+ changes is empty, the component plugin will be ignored. The
+ supported implementations of PortalContainerDefinitionChange
+ are described later in this section.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>To identify the portal containers to which the changes have to
+ be applied, we use the follwing algorithm:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The parameter <envar>apply.all</envar> has been set to
+ <envar>true</envar>. The corresponding changes will be applied to
+ all the portal containers. The other parameters will be
+ ignored.</para>
+ </listitem>
+
+ <listitem>
+ <para>The parameter <envar>apply.default</envar> has been set to
+ <envar>true</envar> and the parameter
+ <envar>apply.specific</envar> is <envar>null</envar>. The
+ corresponding changes will be applied to the default portal
+ container only.</para>
+ </listitem>
+
+ <listitem>
+ <para>The parameter <envar>apply.default</envar> has been set to
+ <envar>true</envar> and the parameter
+ <envar>apply.specific</envar> is not <envar>null</envar>. The
+ corresponding changes will be applied to the default portal
+ container and the given list of specific portal containers.</para>
+ </listitem>
+
+ <listitem>
+ <para>The parameter <envar>apply.default</envar> has been set to
+ <envar>false</envar> or has not been set and the parameter
+ <envar>apply.specific</envar> is <envar>null</envar>. The
+ corresponding changes will be applied to the default portal
+ container only.</para>
+ </listitem>
+
+ <listitem>
+ <para>The parameter <envar>apply.default</envar> has been set to
+ <envar>false</envar> or has not been set and the parameter
+ <envar>apply.specific</envar> is not <envar>null</envar>. The
+ corresponding changes will be applied to the given list of
+ specific portal containers.</para>
+ </listitem>
+ </orderedlist>
+
+ <section>
+ <title>The existing implementations of
+ <envar>PortalContainerDefinitionChange</envar></title>
+
+ <para>The modifications that can be applied to a
+ <envar>PortalContainerDefinition</envar> must be a class of type
+ <envar>PortalContainerDefinitionChange</envar>. The product proposes
+ out of the box some implementations that we describe in the next sub
+ sections.</para>
+
+ <section>
+ <title><envar>AddDependencies</envar></title>
+
+ <para>This modification adds a list of dependencies at the end of
+ the list of dependencies defined into the
+ <envar>PortalContainerDefinition</envar>. The full qualified name
+ is
+ <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies</emphasis>.</para>
+
+ <table>
+ <title>Descriptions of the fields of an
+ <envar>AddDependencies</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>dependencies</entry>
+
+ <entry>A list of <emphasis>String</emphasis> corresponding
+ to the list of name of the dependencies to add. If the
+ value of this field is empty, the change will be
+ ignored.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>See an example below, that will add <envar>foo</envar> at
+ the end of the dependency list of the default portal
+ container:</para>
+
+ <programlisting><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>Change PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
+ <set-method>registerChangePlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
+ <init-params>
+ <value-param>
+ <name>apply.default</name>
+ <value>true</value>
+ </value-param>
+ <object-param>
+ <name>change</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
+ <!-- The list of name of the dependencies to add -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+ </section>
+
+ <section>
+ <title><envar>AddDependenciesBefore</envar></title>
+
+ <para>This modification adds a list of dependencies before a given
+ target dependency defined into the list of dependencies of the
+ <envar>PortalContainerDefinition</envar>. The full qualified name
+ is
+ <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore</emphasis>.</para>
+
+ <table>
+ <title>Descriptions of the fields of an
+ <envar>AddDependenciesBefore</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>dependencies</entry>
+
+ <entry>A list of <emphasis>String</emphasis> corresponding
+ to the list of name of the dependencies to add. If the
+ value of this field is empty, the change will be
+ ignored.</entry>
+ </row>
+
+ <row>
+ <entry>target</entry>
+
+ <entry>The name of the dependency before which we would
+ like to add the new dependencies. If this field is
+ <envar>null</envar> or the target dependency cannot be
+ found in the list of dependencies defined into the
+ <envar>PortalContainerDefinition</envar>, the new
+ dependencies will be added in first position to the
+ list.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>See an example below, that will add <envar>foo</envar>
+ before <envar>foo2</envar> in the dependency list of the default
+ portal container:</para>
+
+ <programlisting><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>Change PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
+ <set-method>registerChangePlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
+ <init-params>
+ <value-param>
+ <name>apply.default</name>
+ <value>true</value>
+ </value-param>
+ <object-param>
+ <name>change</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore">
+ <!-- The list of name of the dependencies to add -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ </collection>
+ </field>
+ <!-- The name of the target dependency -->
+ <field name="target">
+ <string>foo2</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+ </section>
+
+ <section>
+ <title><envar>AddDependenciesAfter</envar></title>
+
+ <para>This modification adds a list of dependencies before a given
+ target dependency defined into the list of dependencies of the
+ <envar>PortalContainerDefinition</envar>. The full qualified name
+ is
+ <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter</emphasis>.</para>
+
+ <table>
+ <title>Descriptions of the fields of an
+ <envar>AddDependenciesAfter</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>dependencies</entry>
+
+ <entry>A list of <emphasis>String</emphasis> corresponding
+ to the list of name of the dependencies to add. If the
+ value of this field is empty, the change will be
+ ignored.</entry>
+ </row>
+
+ <row>
+ <entry>target</entry>
+
+ <entry>The name of the dependency after which we would
+ like to add the new dependencies. If this field is
+ <envar>null</envar> or the target dependency cannot be
+ found in the list of dependencies defined into the
+ <envar>PortalContainerDefinition</envar>, the new
+ dependencies will be added in last position to the
+ list.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>See an example below, that will add <envar>foo</envar> after
+ <envar>foo2</envar> in the dependency list of the default portal
+ container:</para>
+
+ <programlisting><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>Change PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
+ <set-method>registerChangePlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
+ <init-params>
+ <value-param>
+ <name>apply.default</name>
+ <value>true</value>
+ </value-param>
+ <object-param>
+ <name>change</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter">
+ <!-- The list of name of the dependencies to add -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>foo</string>
+ </value>
+ </collection>
+ </field>
+ <!-- The name of the target dependency -->
+ <field name="target">
+ <string>foo2</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+ </section>
+
+ <section>
+ <title><envar>AddSettings</envar></title>
+
+ <para>This modification adds new settings to a
+ <envar>PortalContainerDefinition</envar>. The full qualified name
+ is
+ <emphasis>org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings</emphasis>.</para>
+
+ <table>
+ <title>Descriptions of the fields of an
+ <envar>AddSettings</envar></title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>settings</entry>
+
+ <entry>A map of <emphasis><String,
+ Object></emphasis> corresponding to the settings to
+ add. If the value of this field is empty, the change will
+ be ignored.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>See an example below, that will add the settings
+ <envar>string</envar> and <envar>stringX</envar> to the settings
+ of the default portal container:</para>
+
+ <programlisting><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>Change PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
+ <set-method>registerChangePlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
+ <init-params>
+ <value-param>
+ <name>apply.default</name>
+ <value>true</value>
+ </value-param>
+ <object-param>
+ <name>change</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings">
+ <!-- The settings to add to the to the portal containers -->
+ <field name="settings">
+ <map type="java.util.HashMap">
+ <entry>
+ <key>
+ <string>string</string>
+ </key>
+ <value>
+ <string>value1</string>
+ </value>
+ </entry>
+ <entry>
+ <key>
+ <string>stringX</string>
+ </key>
+ <value>
+ <string>value1</string>
+ </value>
+ </entry>
+ </map>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+ </section>
+ </section>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>System property configuration</title>
+
+ <para>A new property configurator service has been developed for taking
+ care of configuring system properties from the inline kernel configuration
+ or from specified property files.</para>
+
+ <para>The services is scoped at the root container level because it is
+ used by all the services in the different portal containers in the
+ application runtime.</para>
+
+ <section>
+ <title>Properties init param</title>
+
+ <para>The properties init param takes a property declared to configure
+ various properties.</para>
+
+ <programlisting><component>
+ <key>PropertyManagerConfigurator</key>
+ <type>org.exoplatform.container.PropertyConfigurator</type>
+ <init-params>
+ <properties-param>
+ <name>properties</name>
+ <property name="foo" value="bar"/>
+ </properties-param>
+ </init-params>
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>Properties URL init param</title>
+
+ <para>The properties URL init param allow to load an external file by
+ specifying its URL. Both property and XML format are supported, see the
+ javadoc of the <emphasis><envar>java.util.Properties</envar></emphasis>
+ class for more information. When a property file is loaded the various
+ property declarations are loaded in the order in which the properties
+ are declared sequentially in the file.</para>
+
+ <programlisting><component>
+ <key>PropertyManagerConfigurator</key>
+ <type>org.exoplatform.container.PropertyConfigurator</type>
+ <init-params>
+ <value-param>
+ <name>properties.url</name>
+ <value>classpath:configuration.properties</value>
+ </value-param>
+ </init-params>
+</component></programlisting>
+
+ <para>In the properties file corresponding to the external properties,
+ you can reuse variables previously defined to create a new variable. In
+ this case the prefix "<emphasis>portal.container.</emphasis>" is not
+ needed, see an example below:<programlisting>my-var1=value 1
+my-var2=value 2
+complex-value=${my-var1}-${my-var2}</programlisting></para>
+ </section>
+
+ <section>
+ <title>System Property configuration of the properties URL</title>
+
+ <para>It is possible to replace the properties URL init param by a
+ system property that overwrites it. The name of that property is
+ <emphasis>exo.properties.url</emphasis>.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Runtime configuration profiles</title>
+
+ <para>The kernel configuration is able to handle configuration profiles at
+ runtime (as opposed to packaging time).</para>
+
+ <section>
+ <title>Profiles activation</title>
+
+ <para>An active profile list is obtained during the boot of the root
+ container and is composed of the system property
+ <emphasis>exo.profiles</emphasis> sliced according the "," delimiter and
+ also a server specific profile value (tomcat for tomcat, jboss for
+ jboss, etc...).</para>
+
+ <programlisting># runs GateIn on Tomcat with the profiles tomcat and foo
+sh gatein.sh -Dexo.profiles=foo
+
+# runs GateIn on JBoss with the profiles jboss, foo and bar
+sh run.sh -Dexo.profiles=foo,bar</programlisting>
+ </section>
+
+ <section>
+ <title>Profiles configuration</title>
+
+ <para>Profiles are configured in the configuration files of the eXo
+ kernel.</para>
+
+ <section>
+ <title>Profiles definition</title>
+
+ <para>Profile activation occurs at XML to configuration object
+ unmarshalling time. It is based on an "profile" attribute that is
+ present on some of the XML element of the configuration files. To
+ enable this the kernel configuration schema has been upgraded to
+ kernel_1_1.xsd. The configuration is based on the following
+ rules:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Any kernel element with the no <emphasis>profiles</emphasis>
+ attribute will create a configuration object</para>
+ </listitem>
+
+ <listitem>
+ <para>Any kernel element having a <emphasis>profiles</emphasis>
+ attribute containing at least one of the active profiles will
+ create a configuration object</para>
+ </listitem>
+
+ <listitem>
+ <para>Any kernel element having a <emphasis>profiles</emphasis>
+ attribute matching none of the active profile will not create a
+ configuration object</para>
+ </listitem>
+
+ <listitem>
+ <para>Resolution of duplicates (such as two components with same
+ type) is left up to the kernel</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>Profiles capable configuration elements</title>
+
+ <para>A configuration element is <emphasis>profiles</emphasis> capable
+ when it carries a profiles element.</para>
+
+ <section>
+ <title>Component element</title>
+
+ <para>The component element declares a component when activated. It
+ will shadow any element with the same key declared before in the
+ same configuration file:</para>
+
+ <programlisting><component>
+ <key>Component</key>
+ <type>Component</type>
+</component>
+
+<component profiles="foo">
+ <key>Component</key>
+ <type>FooComponent</type>
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>Component plugin element</title>
+
+ <para>The component-plugin element is used to dynamically extend the
+ configuration of a given component. Thanks to the profiles the
+ component-plugins could be enabled or disabled:</para>
+
+ <programlisting><external-component-plugins>
+ <target-component>Component</target-component>
+ <component-plugin profiles="foo">
+ <name>foo</name>
+ <set-method>addPlugin</set-method>
+ <type>type</type>
+ <init-params>
+ <value-param>
+ <name>param</name>
+ <value>empty</value>
+ </value-param>
+ </init-params>
+ </component-plugin>
+</external-component-plugins></programlisting>
+ </section>
+
+ <section>
+ <title>Import element</title>
+
+ <para>The import element imports a referenced configuration file
+ when activated:</para>
+
+ <programlisting><import>empty</import>
+<import profiles="foo">foo</import>
+<import profiles="bar">bar</import></programlisting>
+ </section>
+
+ <section>
+ <title>Init param element</title>
+
+ <para>The init param element configures the parameter argument of
+ the construction of a component service:</para>
+
+ <programlisting><component>
+ <key>Component</key>
+ <type>ComponentImpl</type>
+ <init-params>
+ <value-param>
+ <name>param</name>
+ <value>empty</value>
+ </value-param>
+ <value-param profiles="foo">
+ <name>param</name>
+ <value>foo</value>
+ </value-param>
+ <value-param profiles="bar">
+ <name>param</name>
+ <value>bar</value>
+ </value-param>
+ </init-params>
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>Value collection element</title>
+
+ <para>The value collection element configures one of the value of
+ collection data:</para>
+
+ <programlisting><object type="org.exoplatform.container.configuration.ConfigParam">
+ <field name="role">
+ <collection type="java.util.ArrayList">
+ <value><string>manager</string></value>
+ <value profiles="foo"><string>foo_manager</string></value>
+ <value profiles="foo,bar"><string>foo_bar_manager</string></value>
+ </collection>
+ </field>
+</object></programlisting>
+ </section>
+
+ <section>
+ <title>Field configuration element</title>
+
+ <para>The field configuration element configures the field of an
+ object:</para>
+
+ <programlisting><object-param>
+ <name>test.configuration</name>
+ <object type="org.exoplatform.container.configuration.ConfigParam">
+ <field name="role">
+ <collection type="java.util.ArrayList">
+ <value><string>manager</string></value>
+ </collection>
+ </field>
+ <field name="role" profiles="foo,bar">
+ <collection type="java.util.ArrayList">
+ <value><string>foo_bar_manager</string></value>
+ </collection>
+ </field>
+ <field name="role" profiles="foo">
+ <collection type="java.util.ArrayList">
+ <value><string>foo_manager</string></value>
+ </collection>
+ </field>
+ </object>
+</object-param></programlisting>
+ </section>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Component request life cycle</title>
+
+ <section>
+ <title>Component request life cycle contract</title>
+
+ <para>The component request life cycle is an interface that defines a
+ contract for a component for being involved into a
+ request:<programlisting>public interface ComponentRequestLifecycle
+{
+ /**
+ * Start a request.
+ * @param container the related container
+ */
+ void startRequest(ExoContainer container);
+
+ /**
+ * Ends a request.
+ * @param container the related container
+ */
+ void endRequest(ExoContainer container);
+}</programlisting></para>
+
+ <para>The container passed is the container to which the component is
+ related. This contract is often used to setup a thread local based
+ context that will be demarcated by a request.</para>
+
+ <para>For instance in the GateIn portal context, a component request
+ life cycle is triggered for user requests. Another example is the
+ initial data import in GateIn that demarcates using callbacks made to
+ that interface.</para>
+ </section>
+
+ <section>
+ <title>Request life cycle</title>
+
+ <para>The <envar>RequestLifeCycle</envar> class has several statics
+ methods that are used to schedule the component request life cycle of
+ components. Its main responsability is to perform scheduling while
+ respecting the constraint to execute the request life cycle of a
+ component only once even if it can be scheduled several times.</para>
+
+ <section>
+ <title>Scheduling a component request life cycle</title>
+
+ <programlisting>RequestLifeCycle.begin(component);
+try
+{
+ // Do something
+}
+finally
+{
+ RequestLifeCycle.end();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Scheduling a container request life cycle</title>
+
+ <para>Scheduling a container triggers the component request life cyle
+ of all the components that implement the interface
+ <envar>ComponentRequestLifeCycle</envar>. If one of the component has
+ already been scheduled before then that component will not be
+ scheduled again. When the local value is true then the looked
+ components will be those of the container, when it is false then the
+ scheduler will also look at the components in the ancestor
+ containers.<programlisting>RequestLifeCycle.begin(container, local);
+try
+{
+ // Do something
+}
+finally
+{
+ RequestLifeCycle.end();
+}</programlisting></para>
+ </section>
+ </section>
+
+ <section>
+ <title>When request life cycle is triggered</title>
+
+ <section>
+ <title>Portal request life cycle</title>
+
+ <para>Each portal request triggers the life cycle of the associated
+ portal container.</para>
+ </section>
+
+ <section>
+ <title>JMX request Life Cycle</title>
+
+ <para>When a JMX bean is invoked, the request life cycle of the
+ container to which it belongs it scheduled. Indeed JMX is an entry
+ point of the system that may need component to have a request life
+ cycle triggered.</para>
+ </section>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/kernel.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/kernel.xml 2010-08-05 08:52:15 UTC (rev 2878)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/kernel.xml 2010-08-05 09:13:56 UTC (rev 2879)
@@ -20,8 +20,5 @@
<para>The Kernel module also contains a set of very low level
services.</para>
-
- <para><ulink url="http://wiki.exoplatform.org/xwiki/bin/view/Kernel/">Find
- more on eXo site</ulink></para>
</section>
</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml 2010-08-05 08:52:15 UTC (rev 2878)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml 2010-08-05 09:13:56 UTC (rev 2879)
@@ -1,767 +1,767 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="Kernel.ServiceConfigurationforBeginners">
- <?dbhtml filename="ch-service-configuration-for-beginners.html"?>
-
- <title>Service Configuration for Beginners</title>
-
- <para><emphasis role="bold">Related documents</emphasis></para>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="KernelServiceConfigurationinDetail">Service
- Configuration in Detail</link></para>
- </listitem>
-
- <listitem>
- <para><link endterm="KernelServicesWiring.Title"
- linkend="KernelServicesWiring">ServicesWiring</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="KernelContainerConfiguration">Container
- Configuration</link></para>
- </listitem>
- </itemizedlist>
-
- <section>
- <title>Objective</title>
-
- <para>We are going to talk about service configuration. You will learn
- about modes, services and containers, you will find out where the service
- configuration files have to be placed and you will also see the overriding
- mechanism of configurations. Finally you will understand how the container
- creates the services one after the other and what <emphasis>Inversion of
- Control</emphasis> really means.</para>
- </section>
-
- <section>
- <title>Requirements</title>
-
- <para>By reading this article you are already glancing at the heart of eXo
- Kernel. </para>
-
- <para>Even you will read in this article to open the directory
- "exo-tomcat", you may have installed eXo Portal on any application server,
- just replace "exo-tomcat" by your folder name.</para>
-
- <note>
- <para>If you only installed the all-in-one package for the eXo Portal,
- the folder paths are a slightly different. You have to replace
- <emphasis>exo-tomcat</emphasis> by
- <emphasis>exo-eXoPortal-2.5.1-tomcat</emphasis> (obviously depending on
- your version). Furthermore the webapps are delivered as war
- files.</para>
- </note>
-
- <para>You certainly already discovered eXo's fisheye URL (eXo is open
- source!) - <ulink
- url="https://anonsvn.jboss.org/repos/exo-jcr/">https://anonsvn.jboss.org/repos/exo-jcr/</ulink>
- - which allows you to surf in the source code of all classes, if you wish
- to do so.</para>
- </section>
-
- <section>
- <title>Services</title>
-
- <para>Nearly everything could be considered a service! To get a better
- idea, let's look into the <emphasis>exo-tomcat/lib</emphasis> folder where
- you find all deployed jar files.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/TomcatLibFolder.png" />
- </imageobject>
- </mediaobject>
-
- <para>For example you find services for databases, caching, ldap and
- ftp:</para>
-
- <itemizedlist>
- <listitem>
- <para>exo.core.component.database-2.1.3.jar</para>
- </listitem>
-
- <listitem>
- <para>exo.kernel.component.cache-2.0.5.jar</para>
- </listitem>
-
- <listitem>
- <para>exo.core.component.organization.ldap-2.1.3.jar</para>
- </listitem>
-
- <listitem>
- <para>exo.jcr.component.ftp-1.10.1.jar</para>
- </listitem>
- </itemizedlist>
-
- <para>Of course, there are many more services, in fact a lot of these jar
- files are services. To find out you have to open the jar file and then
- look into its <emphasis>/conf</emphasis> or
- <emphasis>/conf/portal</emphasis> directory. Only if there is a file named
- <emphasis>configuration.xml</emphasis>, you are sure to have found a
- service.</para>
-
- <note>
- <para>Why are there 2 different places to look for the
- configuration.xml? Because the <emphasis>/conf</emphasis> directory is
- used by the <classname>RootContainer</classname> and the
- /<emphasis>conf/portal</emphasis> directory is used by the
- <classname>PortalContainer</classname>. Later you will see more details
- about these containers.</para>
- </note>
-
- <para><emphasis role="bold">Interface - Implementation</emphasis> It's
- important to get the idea that you separate the interface and
- implementation for a service. That is a good concept to reduce
- dependencies on specific implementations. This concept is well known for
- JDBC. If you use standard JDBC (=interface), you can connect any database
- (=implementation) to your application. In a similar way any service in eXo
- is defined by a java interface and may have many different
- implementations. The service implementation is then
- <emphasis>injected</emphasis> by a <emphasis>container</emphasis> into the
- application.</para>
-
- <para><emphasis role="bold">Singleton</emphasis> Each service has to be
- implemented as a <ulink
- url="http://en.wikipedia.org/wiki/Singleton_pattern">singleton</ulink>,
- which means that each service is created only once - in one single
- instance.</para>
-
- <para><emphasis role="bold">Service = Component</emphasis> You always read
- about services, and you imagine a service as a large application which
- does big things, but that's not true, a service can be just a little
- <emphasis>component</emphasis> that reads or transforms a document,
- therefore the term component is often used instead of service - so bear in
- mind: <emphasis>a service and a component can safely be considered to be
- the same thing</emphasis>.</para>
- </section>
-
- <section>
- <title>Configuration File</title>
-
- <para>The jar file of a service should contain a default configuration,
- you find this configuration in the configuration.xml file which comes with
- the jar. A configuration file can specify several services, as well as
- there can be several services in one jar file.</para>
-
- <para>For example open the
- <package>exo.kernel.component.cache-2.0.5.jar</package> file and inside
- this jar open /conf/portal/configuration.xml. You will see:</para>
-
- <programlisting>
-<component>
-<key>org.exoplatform.services.cache.CacheService</key>
-<type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
-...</programlisting>
-
- <para>Here you will note that a service is specified between the
- <parameter><component></parameter> tags. Each service has got a key,
- which defines the kind of service. As you imagine the content of the
- <parameter><key></parameter> tag matches the <emphasis>qualified
- java interface name</emphasis>
- (<classname>org.exoplatform.services.cache.CacheService</classname>) of
- the service. The specific implementation class of the
- <classname>CacheService</classname> is defined in the
- <parameter><type></parameter> tag.</para>
-
- <para><emphasis role="bold">Parameters</emphasis> You have already opened
- some configuration files and seen that there are more than just
- <parameter><key></parameter> and <parameter><type></parameter>
- tags. You can provide your service with init parameters. The parameters
- can be simple parameters, properties, or object-params. There are also
- <emphasis>plugins</emphasis> and they are special because the container
- calls the setters of your service in order to <emphasis>inject</emphasis>
- your plugin in your service (called <emphasis>setter injection</emphasis>)
- see <link linkend="KernelServiceConfigurationinDetail">Service
- Configuration in Detail</link>. In general your service is free to use
- init parameters, they are not required.</para>
-
- <para>If you ever need to create your own service, the minimum is to
- create an empty interface, an empty class and a constructor for your class
- - that's all. Ok, you also should put your class and the interface in a
- jar file and add a default configuration file.</para>
- </section>
-
- <section id="Kernel.ServiceConfigurationinDetail.ExecutionModes">
- <title>Execution Modes</title>
-
- <para>One important thing to understand concerns execution modes. There
- are only two modes:</para>
-
- <itemizedlist>
- <listitem>
- <para>Portal mode: The service runs embedded in the eXo Portal. In
- this mode a <classname>PortalContainer</classname> is used.</para>
- </listitem>
-
- <listitem>
- <para>Standalone mode: The service runs without the portal. For
- example, the JCR service can run standalone, and also the eXo Portlet
- Container. This mode is used by eXo developers for unit tests. As the
- name suggests a <classname>StandaloneContainer</classname> is
- used.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Containers</title>
-
- <para>In order to access to a service you need to use a Container. Just
- open <ulink
- url="https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container">https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container</ulink>.</para>
-
- <para>Among the classes you see in this directory, you only will be
- interested in these three container types:</para>
-
- <itemizedlist>
- <listitem>
- <para>RootContainer: This is a base container. This container plays an
- important role during startup, but you should not use it
- directly.</para>
- </listitem>
-
- <listitem>
- <para>PortalContainer: Created at the startup of the portal web
- application (in the init() method of the PortalController
- servlet)</para>
- </listitem>
-
- <listitem>
- <para>StandaloneContainer: A context independent eXo Container. The
- <classname>StandaloneContainer</classname> is also used for unit
- tests.</para>
- </listitem>
- </itemizedlist>
-
- <para><emphasis role="bold">Use only one container</emphasis> Even if
- there are several container types you always use exactly one. The
- RootContainer is never directly used and it depends on the execution mode
- if you use the PortalContainer or the StandaloneContainer. You will ask
- how to find out the execution mode in my application and how to manage
- these two modes. It's easy, you don't have to worry about it because the
- ExoContainerContext class provides a static method that allows you to get
- the right container from anywhere (see info box).</para>
-
- <para><emphasis role="bold">PicoContainer</emphasis> All containers
- inherit from the ExoContainer class which itself inherits from a
- <classname>PicoContainer</classname>. <ulink
- url="http://www.picocontainer.org/">PicoContainer</ulink> is a framework
- which allows eXo to apply the IoC (<link
- linkend="KernelInversionOfControl">Inversion of Control</link>)
- principles. The precise implementations of any service is unknown at
- compile time. Various implementations can be used, eXo supplies different
- implementations but they also may be delivered by other vendors. The
- decision which service to use during runtime is made in configuration
- files.</para>
-
- <para>These configuration files are read by the container, the container
- adds all services to a list or more exactly a java HashTable. It's
- completely correct to suppose that the configuration.xml you already saw
- plays an important role. But there are more places where a configuration
- for a service can be defined as you see in the next chapter.</para>
-
- <note>
- <para>"In your java code you have to use <programlisting>ExoContainer myContainer = ExoContainerContext.getCurrentContainer()</programlisting>
- in order to access to the current container. It doesn't greatly matter
- to your application if the current container is a
- <classname>PortalContainer</classname> or a
- <classname>StandaloneContainer</classname>. Once you have your container
- you may access to any service registered in this container using
- <programlisting>MyService myService = (MyService) myContainer.getComponentInstance(MyService.class)</programlisting>
- You easily realize that <classname>MyService.class</classname> is the
- name of the service interface.</para>
- </note>
- </section>
-
- <section>
- <title>Configuration Retrieval</title>
-
- <para>The configuration you find inside the jar file is considered as the
- default configuration. If you want to override this default configuration
- you can do it in different places outside the jar. When the container
- finds several configurations for the same service, the configuration which
- is found later replaces completely the one found previously. Let's call
- this the <emphasis>configuration override mechanism</emphasis>.</para>
-
- <section id="RootContainer">
- <title>RootContainer</title>
-
- <para>As both containers, PortalContainer and StandaloneContainer,
- depend on the RootContainer, we will start by looking into this
- one.</para>
-
- <para>The retrieval sequence in short:</para>
-
- <orderedlist>
- <listitem>
- <para>Services default <classname>RootContainer</classname>
- configurations from JAR files
- <emphasis>/conf/configuration.xml</emphasis></para>
- </listitem>
-
- <listitem>
- <para>External <classname>RootContainer</classname> configuration,
- to be found at
- <emphasis>exo-tomcat/exo-conf/configuration.xml</emphasis></para>
- </listitem>
- </orderedlist>
-
- <note>
- <para>Naturally you always have to replace
- <parameter>exo-tomcat</parameter> by your own folder name. In case of
- a Java Standalone application you have to use the
- <parameter>user.dir</parameter> JVM system property value.</para>
- </note>
-
- <para><emphasis role="bold">HashTable</emphasis> The
- <classname>RootContainer</classname> creates a java
- <classname>HashTable</classname> which contains key-value pairs for the
- services. The qualified interface name of each service is used as key
- for the hashtable. Hopefully you still remember that the
- <parameter><key></parameter> tag of the configuration file
- contains the interface name? The value of each hashtable pair is an
- object that contains the service configuration (yes, this means the
- whole structure between the <parameter><component></parameter>
- tags of your <filename>configuration.xml</filename> file).</para>
-
- <para>The <classname>RootContainer</classname> runs over all jar files
- you find in <emphasis>exo-tomcat/lib</emphasis> and looks if there is a
- configuration file at <emphasis>/conf/configuration.xml</emphasis>, the
- services configured in this file are added to the hashtable. That way -
- at the end of this process - the default configurations for all services
- are stored in the hashtable.</para>
-
- <note>
- <para>What happens if the same service - recognized by the same
- qualified interface name - is configured in different jars? As the
- service only can exist one time the configuration of the jar found
- later overrides the previous configuration. You know that the loading
- <emphasis role="bold">order of the jars is unpredictable</emphasis>
- you <emphasis role="bold">must not depend on this</emphasis>.</para>
- </note>
-
- <para>If you wish to provide your own configurations for one or several
- services, you can do it in a general configuration file that has to be
- placed at <emphasis>exo-tomcat/exo-conf/configuration.xml</emphasis>. Do
- not search for such a file on your computer - you won't find one,
- because this option is not used in the default installation. Here again
- the same rule applies: <emphasis>The posterior configuration replaces
- the previous one</emphasis>.</para>
-
- <para>The further configuration retrieval depends on the container
- type.</para>
- </section>
-
- <section>
- <title>PortalContainer</title>
-
- <para>The PortalContainer takes the hashtable filled by the
- RootContainer and continues to look in some more places. Here you get
- the opportunity to replace RootContainer configurations by those which
- are specific to your portal. Again, the configurations are overridden
- whenever necessary.</para>
-
- <para>In short PortalContainer configurations are retrieved in the
- following lookup sequence :</para>
-
- <orderedlist>
- <listitem>
- <para>Take over the configurations of the RootContainer</para>
- </listitem>
-
- <listitem>
- <para>Default PortalContainer configurations from all JAR files
- (folder <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>Web application configurations from the portal.war file - or
- the <emphasis>portal</emphasis> weppapp (folder
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>External configuration for services of a named portal, it will
- be found at
- <emphasis>exo-tomcat/exo-conf/portal/$portal_name/configuration.xml</emphasis>
- (as of Portal 2.5)</para>
- </listitem>
- </orderedlist>
-
- <para>You see, here the
- <emphasis>/conf/portal/configuration.xml</emphasis> file of each jar
- enters the game, they are searched at first. Next, there is nearly
- always a configuration.xml in the portal.war file (or in the portal
- webapp folder), you find this file at
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis>. If you open it,
- you will find a lot of import statements that point to other
- configuration files in the same portal.war (or portal webapp).</para>
-
- <para><emphasis role="bold">Multiple Portals</emphasis> Be aware that
- you might set up several different portals ("admin", "mexico", etc.),
- and each of these portals will use a different PortalContainer. And each
- of these PortalContainers can be configured separately. As of eXo Portal
- 2.5 you also will be able to provide configurations from outside the
- jars and wars or webapps. Put a configuration file in
- <emphasis>exo-tomcat/exo-conf/portal/$portal_name/configuration.xml</emphasis>
- where <parameter>$portal_name</parameter> is the name of the portal you
- want to configure for . But normally you only have one portal which is
- called "portal" so you use
- <emphasis>exo-tomcat/exo-conf/portal/portal/configuration.xml</emphasis>.</para>
-
- <note>
- <para>As of eXo Portal 2.5 you can override the external configuration
- location with the system property <emphasis>exo.conf.dir</emphasis>.
- If the property exists its value will be used as path to the eXo
- configuration directory, that means this is an alternative to
- <emphasis>exo-tomcat/exo-conf</emphasis>. Just put this property in
- the command line: <emphasis>java
- -Dexo.conf.dir=/path/to/exo/conf</emphasis> or use eXo.bat or eXo.sh.
- In this particular use case, you have no need to use any prefixes in
- your configuration file to import other files. For example, if your
- configuration file is
- <emphasis>exo-tomcat/exo-conf/portal/PORTAL_NAME/configuration.xml</emphasis>
- and you want to import the configuration file
- <emphasis>exo-tomcat/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.xml</emphasis>,
- you can do it by adding
- <emphasis><import>mySubConfDir/myConfig.xml</import></emphasis>
- to your configuration file.</para>
- </note>
-
- <note>
- <para>Under <emphasis role="bold">JBoss</emphasis> application server
- <emphasis>exo-conf</emphasis> will be looked up in directory described
- by JBoss System property <emphasis>jboss.server.config.url</emphasis>.
- If the property is not found or empty
- <emphasis>exo-jboss/exo-conf</emphasis> will be asked (since kernel
- 2.0.4).</para>
- </note>
- </section>
-
- <section>
- <title>StandaloneContainer</title>
-
- <para>In the same way as the PortalContainer the StandaloneContainer
- <emphasis>takes over the configuration of the RootContainer</emphasis>.
- After that our configuration gets a little bit more tricky because
- standalone containers can be initialized using an URL. This URL contains
- a link to an external configuration. As you probably never need a
- standalone configuration you can safely jump over the remaining
- confusing words of this chapter.</para>
-
- <para>After taking over RootContainer's configuration, there are three
- cases which depend on the URL initialization, :</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">Independent configuration by
- URL</emphasis> No other configuration file is taken in
- consideration. The configuration provided by the URL is used without
- any default configs. That means that the container creates a new
- empty hashtable and not any bit of previous configuration is used.
- Apply the following code to do this:</para>
-
- <programlisting>StandaloneContainer.setConfigurationURL(containerConf);</programlisting>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">Additional configuration by
- URL</emphasis> The StandaloneContainer is initialized very similar
- to the PortalContainer, but the last step is slightly different. A
- configuration file that is provided by the URL is used to replace
- some of the service configurations.The code looks like this:</para>
-
- <programlisting>StandaloneContainer.addConfigurationURL(containerConf);</programlisting>
-
- <orderedlist>
- <listitem>
- <para>Take over the configurations of the RootContainer</para>
- </listitem>
-
- <listitem>
- <para>Default <emphasis>StandaloneContainer</emphasis>
- configurations from JAR files (folder
- <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>Web application configurations from WAR files (folder
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>Configuration from added URL
- <emphasis>containerConf</emphasis> overrides only services
- configured in the file</para>
- </listitem>
- </orderedlist>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">File based configuration</emphasis> No
- URL is involved, in this case the sequence is:</para>
-
- <orderedlist>
- <listitem>
- <para>Take over the configurations of the RootContainer</para>
- </listitem>
-
- <listitem>
- <para>Default <emphasis>StandaloneContainer</emphasis>
- configurations from JAR files (folder
- <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>Web applications configurations from WAR files (folder
- <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
- </listitem>
-
- <listitem>
- <para>External configuration for
- <emphasis>StandaloneContainer</emphasis> services, it will be
- found at <emphasis>$user_home/exo-configuration.xml</emphasis>.
- If <emphasis>$user_home/exo-configuration.xml</emphasis> doesn't
- exist and the <emphasis>StandaloneContainer</emphasis> instance
- obtained with the dedicated configuration classloader the
- container will try to retrieve the resource
- <emphasis>conf/exo-configuration.xml</emphasis> within the given
- classloader (user_home is your home directory like "C:/Documents
- and Settings/Smith").</para>
- </listitem>
- </orderedlist>
- </listitem>
- </itemizedlist>
- </section>
- </section>
-
- <section>
- <title>Service instantiation</title>
-
- <para>As you have already learned the services are all singletons, so that
- the container creates only one single instance of each container. The
- services are created by calling the constructors (called
- <emphasis>constructor injection</emphasis>). If there are only
- zero-arguments constructors (<code>Foo public Foo(){}</code>) there are no
- problems to be expected. That's easy.</para>
-
- <para>But now look at <ulink
- url="https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/jdbc/OrganizationServiceImpl.java">https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/jdbc/OrganizationServiceImpl.java</ulink></para>
-
- <para>This JDBC implementation of BaseOrganizationService interface has
- only one constructor:</para>
-
- <para><programlisting>public OrganizationServiceImpl(ListenerService listenerService, DatabaseService dbService)</programlisting></para>
-
- <para>You see this service depends on two other services. In order to be
- able to call this constructor the container first needs a
- <classname>ListenerService</classname> and a
- <classname>DatabaseService</classname>. Therefore these services must be
- instantiated before <classname>BaseOrganizationService</classname>,
- because <classname>BaseOrganizationService</classname> depends on
- them.</para>
-
- <para>For this purpose the container first looks at the constructors of
- all services and creates a matrix of service dependencies in order to call
- the services in a proper order. If for any reason there are
- interdependencies or circular dependencies you will get a java
- <classname>Exception</classname>. <emphasis>In this way the dependencies
- are injected by the container</emphasis>.</para>
-
- <note>
- <para>What happens if one service has more than one constructor? The
- container always tries first to use the constructor with a maximum of
- arguments, if this is not possible the container continues step by step
- with constructors that have less arguments until arriving at the
- zero-argument constructor (if there is one).</para>
- </note>
- </section>
-
- <section>
- <title>Miscellaneous</title>
-
- <section id="Startableinterface">
- <title>Startable interface</title>
-
- <para>Your service can implement the <emphasis>startable</emphasis>
- interface which defines a <emphasis>start()</emphasis> and a
- <emphasis>stop()</emphasis> method. These methods are called by the
- container at the beginning and the end of the container's lifecycle.
- This way the lifecycle of your service is managed by the
- container.</para>
- </section>
-
- <section>
- <title>Inversion of Control</title>
-
- <para><emphasis role="bold">Retrospection</emphasis> Do you remember
- your last project where you had some small components and several larger
- services? How was this organized? Some services had their own
- configuration files, others had static values in the source code. Most
- components were probably tightly coupled to the main application, or you
- called static methods whenever you needed a service in your java class.
- Presumably you even copied the source code of an earlier project in
- order to adapt the implementation to your needs. In short:</para>
-
- <itemizedlist>
- <listitem>
- <para>Each of your service had a proprietary configuration
- mechanism.</para>
- </listitem>
-
- <listitem>
- <para>The service lifecycles were managed inside of each service or
- were arbitrary.</para>
- </listitem>
-
- <listitem>
- <para>The dependencies between your services were
- implementation-dependent and tightly coupled in your source
- code.</para>
- </listitem>
- </itemizedlist>
-
- <para><emphasis role="bold">New Approach</emphasis> You have seen that
- eXo uses the <emphasis>Inversion of Control</emphasis> (IoC) pattern
- which means that the control of the services is given to an independent
- outside entity, in this case a <emphasis>container</emphasis>. Now the
- container takes care of everything:</para>
-
- <itemizedlist>
- <listitem>
- <para>The <emphasis>configuration is injected</emphasis> by external
- configuration files.</para>
- </listitem>
-
- <listitem>
- <para>The <emphasis>lifecycle is managed from outside</emphasis>,
- because the constructors are called by the container. You can
- achieve an even finer lifecycle management if you use the startable
- interface.</para>
- </listitem>
-
- <listitem>
- <para>The <emphasis>dependencies are injected</emphasis> by the
- service instantiation process.</para>
- </listitem>
- </itemizedlist>
-
- <para><emphasis role="bold">Dependency Injection</emphasis> You also saw
- two types of dependency injections:</para>
-
- <itemizedlist>
- <listitem>
- <para>Constructor injection: The constructor is called by the
- container.</para>
- </listitem>
-
- <listitem>
- <para>Setter injection: Whenever you use
- <emphasis>external-plugins</emphasis> to provide your service with
- plugins (see <link
- linkend="KernelServiceConfigurationinDetail">Service Configuration
- in Detail</link>.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>More Containers</title>
-
- <para>There are two more Containers called
- <classname>RepositoryContainer</classname> and
- <classname>WorkspaceContainer</classname>. These are specificities of
- eXo JCR, for the sake of simplicity. You don't need them.</para>
- </section>
-
- <section>
- <title>Single Implementation Services</title>
-
- <para>In some case the developer of a service does not expect that there
- will be several implementations for his service. Therefore he does not
- create an interface. In this case the configuration looks like
- this:</para>
-
- <programlisting><key>org.exoplatform.services.database.jdbc.DBSchemaCreator</key>
-<type>org.exoplatform.services.database.jdbc.DBSchemaCreator</type></programlisting>
-
- <para>The key and type tags contain equally the qualified class
- name.</para>
- </section>
-
- <section>
- <title>Configuration properties</title>
-
- <para>Since kernel 2.0.7 and 2.1, it is possible to use system
- properties in literal values of component configuration meta data. Thus
- it is possible to resolve properties at runtime instead of providing a
- value at packaging time.</para>
-
- <programlisting><component>
- ...
- <init-params>
- <value-param>
- <name>simple_param</name>
- <value>${simple_param_value}</value>
- </value-param>
- <properties-param>
- <name>properties_param</name>
- <property name="value_1" value="properties_param_value_1"/>
- <property name="value_2" value="${properties_param_value_2}"/>
- </properties-param>
- <object-param>
- <name>object_param</name>
- <object type="org.exoplatform.xml.test.Person">
- <field name="address"><string>${person_address}</string></field>
- <field name="male"><boolean>${person_male}</boolean></field>
- <field name="age"><int>${age_value}</int></field>
- <field name="size"><double>${size_value}</double></field>
- </object>
- </object-param>
- </init-params>
-</component></programlisting>
- </section>
-
- <section>
- <title>Configuration Logging</title>
-
- <para>In case you need to solve problems with your service
- configuration, you have to know from which JAR/WAR causes your troubles.
- Add the JVM system property
- <parameter>org.exoplatform.container.configuration.debug</parameter> to
- your eXo.bat or eXo.sh file (exo-tomcat/bin/).</para>
-
- <programlisting>set EXO_CONFIG_OPTS="-Dorg.exoplatform.container.configuration.debug"</programlisting>
-
- <para>If this property is set the container configuration manager
- reports during startup the configuration retrieval process to the
- standard output (System.out).</para>
-
- <programlisting>......
-Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
-Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
-Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
-import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
-import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
-......</programlisting>
- </section>
- </section>
-
- <section>
- <title>Further Reading</title>
-
- <para>Do you feel an expert now? Not yet. Get a deeper look and read this
- <link linkend="KernelServicesWiring">Services Wiring</link> article. You
- read so much about configuration, that you should wonder what the <link
- linkend="KernelConfigurationNamespace">XML Schema of the configuration
- file</link> looks like. </para>
-
- <para>If you wish to see a examples of service configurations you should
- study the <link linkend="Core">Core.</link> Where you find descriptions of
- some eXo's core services. Finally you might wish to read more about <ulink
- url="http://www.picocontainer.org/">PicoContainer</ulink>.</para>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="Kernel.ServiceConfigurationforBeginners">
+ <?dbhtml filename="ch-service-configuration-for-beginners.html"?>
+
+ <title>Service Configuration for Beginners</title>
+
+ <para><emphasis role="bold">Related documents</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="Kernel.ServiceConfigurationinDetail">Service
+ Configuration in Detail</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link endterm="KernelServicesWiring.Title"
+ linkend="Kernel.ServicesWiring">Services Wiring</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="Kernel.ContainerConfiguration">Container
+ Configuration</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <section>
+ <title>Objective</title>
+
+ <para>We are going to talk about service configuration. You will learn
+ about modes, services and containers, you will find out where the service
+ configuration files have to be placed and you will also see the overriding
+ mechanism of configurations. Finally you will understand how the container
+ creates the services one after the other and what <emphasis>Inversion of
+ Control</emphasis> really means.</para>
+ </section>
+
+ <section>
+ <title>Requirements</title>
+
+ <para>By reading this article you are already glancing at the heart of eXo
+ Kernel.</para>
+
+ <para>Even you will read in this article to open the directory
+ "exo-tomcat", you may have installed eXo Portal on any application server,
+ just replace "exo-tomcat" by your folder name.</para>
+
+ <note>
+ <para>If you only installed the all-in-one package for the eXo Portal,
+ the folder paths are a slightly different. You have to replace
+ <emphasis>exo-tomcat</emphasis> by
+ <emphasis>exo-eXoPortal-2.5.1-tomcat</emphasis> (obviously depending on
+ your version). Furthermore the webapps are delivered as war
+ files.</para>
+ </note>
+
+ <para>You certainly already discovered eXo's fisheye URL (eXo is open
+ source!) - <ulink
+ url="https://anonsvn.jboss.org/repos/exo-jcr/">https://anonsvn.jboss.org/repos/exo-jcr/</ulink>
+ - which allows you to surf in the source code of all classes, if you wish
+ to do so.</para>
+ </section>
+
+ <section>
+ <title>Services</title>
+
+ <para>Nearly everything could be considered a service! To get a better
+ idea, let's look into the <emphasis>exo-tomcat/lib</emphasis> folder where
+ you find all deployed jar files.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/TomcatLibFolder.png" />
+ </imageobject>
+ </mediaobject>
+
+ <para>For example you find services for databases, caching, ldap and
+ ftp:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>exo.core.component.database-2.1.3.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>exo.kernel.component.cache-2.0.5.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>exo.core.component.organization.ldap-2.1.3.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>exo.jcr.component.ftp-1.10.1.jar</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Of course, there are many more services, in fact a lot of these jar
+ files are services. To find out you have to open the jar file and then
+ look into its <emphasis>/conf</emphasis> or
+ <emphasis>/conf/portal</emphasis> directory. Only if there is a file named
+ <emphasis>configuration.xml</emphasis>, you are sure to have found a
+ service.</para>
+
+ <note>
+ <para>Why are there 2 different places to look for the
+ configuration.xml? Because the <emphasis>/conf</emphasis> directory is
+ used by the <classname>RootContainer</classname> and the
+ /<emphasis>conf/portal</emphasis> directory is used by the
+ <classname>PortalContainer</classname>. Later you will see more details
+ about these containers.</para>
+ </note>
+
+ <para><emphasis role="bold">Interface - Implementation</emphasis> It's
+ important to get the idea that you separate the interface and
+ implementation for a service. That is a good concept to reduce
+ dependencies on specific implementations. This concept is well known for
+ JDBC. If you use standard JDBC (=interface), you can connect any database
+ (=implementation) to your application. In a similar way any service in eXo
+ is defined by a java interface and may have many different
+ implementations. The service implementation is then
+ <emphasis>injected</emphasis> by a <emphasis>container</emphasis> into the
+ application.</para>
+
+ <para><emphasis role="bold">Singleton</emphasis> Each service has to be
+ implemented as a <ulink
+ url="http://en.wikipedia.org/wiki/Singleton_pattern">singleton</ulink>,
+ which means that each service is created only once - in one single
+ instance.</para>
+
+ <para><emphasis role="bold">Service = Component</emphasis> You always read
+ about services, and you imagine a service as a large application which
+ does big things, but that's not true, a service can be just a little
+ <emphasis>component</emphasis> that reads or transforms a document,
+ therefore the term component is often used instead of service - so bear in
+ mind: <emphasis>a service and a component can safely be considered to be
+ the same thing</emphasis>.</para>
+ </section>
+
+ <section>
+ <title>Configuration File</title>
+
+ <para>The jar file of a service should contain a default configuration,
+ you find this configuration in the configuration.xml file which comes with
+ the jar. A configuration file can specify several services, as well as
+ there can be several services in one jar file.</para>
+
+ <para>For example open the
+ <package>exo.kernel.component.cache-2.0.5.jar</package> file and inside
+ this jar open /conf/portal/configuration.xml. You will see:</para>
+
+ <programlisting>
+<component>
+<key>org.exoplatform.services.cache.CacheService</key>
+<type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
+...</programlisting>
+
+ <para>Here you will note that a service is specified between the
+ <parameter><component></parameter> tags. Each service has got a key,
+ which defines the kind of service. As you imagine the content of the
+ <parameter><key></parameter> tag matches the <emphasis>qualified
+ java interface name</emphasis>
+ (<classname>org.exoplatform.services.cache.CacheService</classname>) of
+ the service. The specific implementation class of the
+ <classname>CacheService</classname> is defined in the
+ <parameter><type></parameter> tag.</para>
+
+ <para><emphasis role="bold">Parameters</emphasis> You have already opened
+ some configuration files and seen that there are more than just
+ <parameter><key></parameter> and <parameter><type></parameter>
+ tags. You can provide your service with init parameters. The parameters
+ can be simple parameters, properties, or object-params. There are also
+ <emphasis>plugins</emphasis> and they are special because the container
+ calls the setters of your service in order to <emphasis>inject</emphasis>
+ your plugin in your service (called <emphasis>setter injection</emphasis>)
+ see <link linkend="Kernel.ServiceConfigurationinDetail">Service
+ Configuration in Detail</link>. In general your service is free to use
+ init parameters, they are not required.</para>
+
+ <para>If you ever need to create your own service, the minimum is to
+ create an empty interface, an empty class and a constructor for your class
+ - that's all. Ok, you also should put your class and the interface in a
+ jar file and add a default configuration file.</para>
+ </section>
+
+ <section id="Kernel.ServiceConfigurationinDetail.ExecutionModes">
+ <title>Execution Modes</title>
+
+ <para>One important thing to understand concerns execution modes. There
+ are only two modes:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Portal mode: The service runs embedded in the eXo Portal. In
+ this mode a <classname>PortalContainer</classname> is used.</para>
+ </listitem>
+
+ <listitem>
+ <para>Standalone mode: The service runs without the portal. For
+ example, the JCR service can run standalone, and also the eXo Portlet
+ Container. This mode is used by eXo developers for unit tests. As the
+ name suggests a <classname>StandaloneContainer</classname> is
+ used.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Containers</title>
+
+ <para>In order to access to a service you need to use a Container. Just
+ open <ulink
+ url="https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container">https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container</ulink>.</para>
+
+ <para>Among the classes you see in this directory, you only will be
+ interested in these three container types:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>RootContainer: This is a base container. This container plays an
+ important role during startup, but you should not use it
+ directly.</para>
+ </listitem>
+
+ <listitem>
+ <para>PortalContainer: Created at the startup of the portal web
+ application (in the init() method of the PortalController
+ servlet)</para>
+ </listitem>
+
+ <listitem>
+ <para>StandaloneContainer: A context independent eXo Container. The
+ <classname>StandaloneContainer</classname> is also used for unit
+ tests.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">Use only one container</emphasis> Even if
+ there are several container types you always use exactly one. The
+ RootContainer is never directly used and it depends on the execution mode
+ if you use the PortalContainer or the StandaloneContainer. You will ask
+ how to find out the execution mode in my application and how to manage
+ these two modes. It's easy, you don't have to worry about it because the
+ ExoContainerContext class provides a static method that allows you to get
+ the right container from anywhere (see info box).</para>
+
+ <para><emphasis role="bold">PicoContainer</emphasis> All containers
+ inherit from the ExoContainer class which itself inherits from a
+ <classname>PicoContainer</classname>. <ulink
+ url="http://www.picocontainer.org/">PicoContainer</ulink> is a framework
+ which allows eXo to apply the IoC (<link
+ linkend="Kernel.InversionOfControl">Inversion of Control</link>)
+ principles. The precise implementations of any service is unknown at
+ compile time. Various implementations can be used, eXo supplies different
+ implementations but they also may be delivered by other vendors. The
+ decision which service to use during runtime is made in configuration
+ files.</para>
+
+ <para>These configuration files are read by the container, the container
+ adds all services to a list or more exactly a java HashTable. It's
+ completely correct to suppose that the configuration.xml you already saw
+ plays an important role. But there are more places where a configuration
+ for a service can be defined as you see in the next chapter.</para>
+
+ <note>
+ <para>"In your java code you have to use <programlisting>ExoContainer myContainer = ExoContainerContext.getCurrentContainer()</programlisting>
+ in order to access to the current container. It doesn't greatly matter
+ to your application if the current container is a
+ <classname>PortalContainer</classname> or a
+ <classname>StandaloneContainer</classname>. Once you have your container
+ you may access to any service registered in this container using
+ <programlisting>MyService myService = (MyService) myContainer.getComponentInstance(MyService.class)</programlisting>
+ You easily realize that <classname>MyService.class</classname> is the
+ name of the service interface.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Configuration Retrieval</title>
+
+ <para>The configuration you find inside the jar file is considered as the
+ default configuration. If you want to override this default configuration
+ you can do it in different places outside the jar. When the container
+ finds several configurations for the same service, the configuration which
+ is found later replaces completely the one found previously. Let's call
+ this the <emphasis>configuration override mechanism</emphasis>.</para>
+
+ <section id="RootContainer">
+ <title>RootContainer</title>
+
+ <para>As both containers, PortalContainer and StandaloneContainer,
+ depend on the RootContainer, we will start by looking into this
+ one.</para>
+
+ <para>The retrieval sequence in short:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Services default <classname>RootContainer</classname>
+ configurations from JAR files
+ <emphasis>/conf/configuration.xml</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>External <classname>RootContainer</classname> configuration,
+ to be found at
+ <emphasis>exo-tomcat/exo-conf/configuration.xml</emphasis></para>
+ </listitem>
+ </orderedlist>
+
+ <note>
+ <para>Naturally you always have to replace
+ <parameter>exo-tomcat</parameter> by your own folder name. In case of
+ a Java Standalone application you have to use the
+ <parameter>user.dir</parameter> JVM system property value.</para>
+ </note>
+
+ <para><emphasis role="bold">HashTable</emphasis> The
+ <classname>RootContainer</classname> creates a java
+ <classname>HashTable</classname> which contains key-value pairs for the
+ services. The qualified interface name of each service is used as key
+ for the hashtable. Hopefully you still remember that the
+ <parameter><key></parameter> tag of the configuration file
+ contains the interface name? The value of each hashtable pair is an
+ object that contains the service configuration (yes, this means the
+ whole structure between the <parameter><component></parameter>
+ tags of your <filename>configuration.xml</filename> file).</para>
+
+ <para>The <classname>RootContainer</classname> runs over all jar files
+ you find in <emphasis>exo-tomcat/lib</emphasis> and looks if there is a
+ configuration file at <emphasis>/conf/configuration.xml</emphasis>, the
+ services configured in this file are added to the hashtable. That way -
+ at the end of this process - the default configurations for all services
+ are stored in the hashtable.</para>
+
+ <note>
+ <para>What happens if the same service - recognized by the same
+ qualified interface name - is configured in different jars? As the
+ service only can exist one time the configuration of the jar found
+ later overrides the previous configuration. You know that the loading
+ <emphasis role="bold">order of the jars is unpredictable</emphasis>
+ you <emphasis role="bold">must not depend on this</emphasis>.</para>
+ </note>
+
+ <para>If you wish to provide your own configurations for one or several
+ services, you can do it in a general configuration file that has to be
+ placed at <emphasis>exo-tomcat/exo-conf/configuration.xml</emphasis>. Do
+ not search for such a file on your computer - you won't find one,
+ because this option is not used in the default installation. Here again
+ the same rule applies: <emphasis>The posterior configuration replaces
+ the previous one</emphasis>.</para>
+
+ <para>The further configuration retrieval depends on the container
+ type.</para>
+ </section>
+
+ <section>
+ <title>PortalContainer</title>
+
+ <para>The PortalContainer takes the hashtable filled by the
+ RootContainer and continues to look in some more places. Here you get
+ the opportunity to replace RootContainer configurations by those which
+ are specific to your portal. Again, the configurations are overridden
+ whenever necessary.</para>
+
+ <para>In short PortalContainer configurations are retrieved in the
+ following lookup sequence :</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Take over the configurations of the RootContainer</para>
+ </listitem>
+
+ <listitem>
+ <para>Default PortalContainer configurations from all JAR files
+ (folder <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Web application configurations from the portal.war file - or
+ the <emphasis>portal</emphasis> weppapp (folder
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>External configuration for services of a named portal, it will
+ be found at
+ <emphasis>exo-tomcat/exo-conf/portal/$portal_name/configuration.xml</emphasis>
+ (as of Portal 2.5)</para>
+ </listitem>
+ </orderedlist>
+
+ <para>You see, here the
+ <emphasis>/conf/portal/configuration.xml</emphasis> file of each jar
+ enters the game, they are searched at first. Next, there is nearly
+ always a configuration.xml in the portal.war file (or in the portal
+ webapp folder), you find this file at
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis>. If you open it,
+ you will find a lot of import statements that point to other
+ configuration files in the same portal.war (or portal webapp).</para>
+
+ <para><emphasis role="bold">Multiple Portals</emphasis> Be aware that
+ you might set up several different portals ("admin", "mexico", etc.),
+ and each of these portals will use a different PortalContainer. And each
+ of these PortalContainers can be configured separately. As of eXo Portal
+ 2.5 you also will be able to provide configurations from outside the
+ jars and wars or webapps. Put a configuration file in
+ <emphasis>exo-tomcat/exo-conf/portal/$portal_name/configuration.xml</emphasis>
+ where <parameter>$portal_name</parameter> is the name of the portal you
+ want to configure for . But normally you only have one portal which is
+ called "portal" so you use
+ <emphasis>exo-tomcat/exo-conf/portal/portal/configuration.xml</emphasis>.</para>
+
+ <note>
+ <para>As of eXo Portal 2.5 you can override the external configuration
+ location with the system property <emphasis>exo.conf.dir</emphasis>.
+ If the property exists its value will be used as path to the eXo
+ configuration directory, that means this is an alternative to
+ <emphasis>exo-tomcat/exo-conf</emphasis>. Just put this property in
+ the command line: <emphasis>java
+ -Dexo.conf.dir=/path/to/exo/conf</emphasis> or use eXo.bat or eXo.sh.
+ In this particular use case, you have no need to use any prefixes in
+ your configuration file to import other files. For example, if your
+ configuration file is
+ <emphasis>exo-tomcat/exo-conf/portal/PORTAL_NAME/configuration.xml</emphasis>
+ and you want to import the configuration file
+ <emphasis>exo-tomcat/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.xml</emphasis>,
+ you can do it by adding
+ <emphasis><import>mySubConfDir/myConfig.xml</import></emphasis>
+ to your configuration file.</para>
+ </note>
+
+ <note>
+ <para>Under <emphasis role="bold">JBoss</emphasis> application server
+ <emphasis>exo-conf</emphasis> will be looked up in directory described
+ by JBoss System property <emphasis>jboss.server.config.url</emphasis>.
+ If the property is not found or empty
+ <emphasis>exo-jboss/exo-conf</emphasis> will be asked (since kernel
+ 2.0.4).</para>
+ </note>
+ </section>
+
+ <section>
+ <title>StandaloneContainer</title>
+
+ <para>In the same way as the PortalContainer the StandaloneContainer
+ <emphasis>takes over the configuration of the RootContainer</emphasis>.
+ After that our configuration gets a little bit more tricky because
+ standalone containers can be initialized using an URL. This URL contains
+ a link to an external configuration. As you probably never need a
+ standalone configuration you can safely jump over the remaining
+ confusing words of this chapter.</para>
+
+ <para>After taking over RootContainer's configuration, there are three
+ cases which depend on the URL initialization, :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Independent configuration by
+ URL</emphasis> No other configuration file is taken in
+ consideration. The configuration provided by the URL is used without
+ any default configs. That means that the container creates a new
+ empty hashtable and not any bit of previous configuration is used.
+ Apply the following code to do this:</para>
+
+ <programlisting>StandaloneContainer.setConfigurationURL(containerConf);</programlisting>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Additional configuration by
+ URL</emphasis> The StandaloneContainer is initialized very similar
+ to the PortalContainer, but the last step is slightly different. A
+ configuration file that is provided by the URL is used to replace
+ some of the service configurations.The code looks like this:</para>
+
+ <programlisting>StandaloneContainer.addConfigurationURL(containerConf);</programlisting>
+
+ <orderedlist>
+ <listitem>
+ <para>Take over the configurations of the RootContainer</para>
+ </listitem>
+
+ <listitem>
+ <para>Default <emphasis>StandaloneContainer</emphasis>
+ configurations from JAR files (folder
+ <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Web application configurations from WAR files (folder
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Configuration from added URL
+ <emphasis>containerConf</emphasis> overrides only services
+ configured in the file</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">File based configuration</emphasis> No
+ URL is involved, in this case the sequence is:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Take over the configurations of the RootContainer</para>
+ </listitem>
+
+ <listitem>
+ <para>Default <emphasis>StandaloneContainer</emphasis>
+ configurations from JAR files (folder
+ <emphasis>/conf/portal/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Web applications configurations from WAR files (folder
+ <emphasis>/WEB-INF/conf/configuration.xml</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>External configuration for
+ <emphasis>StandaloneContainer</emphasis> services, it will be
+ found at <emphasis>$user_home/exo-configuration.xml</emphasis>.
+ If <emphasis>$user_home/exo-configuration.xml</emphasis> doesn't
+ exist and the <emphasis>StandaloneContainer</emphasis> instance
+ obtained with the dedicated configuration classloader the
+ container will try to retrieve the resource
+ <emphasis>conf/exo-configuration.xml</emphasis> within the given
+ classloader (user_home is your home directory like "C:/Documents
+ and Settings/Smith").</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>Service instantiation</title>
+
+ <para>As you have already learned the services are all singletons, so that
+ the container creates only one single instance of each container. The
+ services are created by calling the constructors (called
+ <emphasis>constructor injection</emphasis>). If there are only
+ zero-arguments constructors (<code>Foo public Foo(){}</code>) there are no
+ problems to be expected. That's easy.</para>
+
+ <para>But now look at <ulink
+ url="https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/jdbc/OrganizationServiceImpl.java">https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/jdbc/OrganizationServiceImpl.java</ulink></para>
+
+ <para>This JDBC implementation of BaseOrganizationService interface has
+ only one constructor:</para>
+
+ <para><programlisting>public OrganizationServiceImpl(ListenerService listenerService, DatabaseService dbService)</programlisting></para>
+
+ <para>You see this service depends on two other services. In order to be
+ able to call this constructor the container first needs a
+ <classname>ListenerService</classname> and a
+ <classname>DatabaseService</classname>. Therefore these services must be
+ instantiated before <classname>BaseOrganizationService</classname>,
+ because <classname>BaseOrganizationService</classname> depends on
+ them.</para>
+
+ <para>For this purpose the container first looks at the constructors of
+ all services and creates a matrix of service dependencies in order to call
+ the services in a proper order. If for any reason there are
+ interdependencies or circular dependencies you will get a java
+ <classname>Exception</classname>. <emphasis>In this way the dependencies
+ are injected by the container</emphasis>.</para>
+
+ <note>
+ <para>What happens if one service has more than one constructor? The
+ container always tries first to use the constructor with a maximum of
+ arguments, if this is not possible the container continues step by step
+ with constructors that have less arguments until arriving at the
+ zero-argument constructor (if there is one).</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Miscellaneous</title>
+
+ <section id="Startableinterface">
+ <title>Startable interface</title>
+
+ <para>Your service can implement the <emphasis>startable</emphasis>
+ interface which defines a <emphasis>start()</emphasis> and a
+ <emphasis>stop()</emphasis> method. These methods are called by the
+ container at the beginning and the end of the container's lifecycle.
+ This way the lifecycle of your service is managed by the
+ container.</para>
+ </section>
+
+ <section>
+ <title>Inversion of Control</title>
+
+ <para><emphasis role="bold">Retrospection</emphasis> Do you remember
+ your last project where you had some small components and several larger
+ services? How was this organized? Some services had their own
+ configuration files, others had static values in the source code. Most
+ components were probably tightly coupled to the main application, or you
+ called static methods whenever you needed a service in your java class.
+ Presumably you even copied the source code of an earlier project in
+ order to adapt the implementation to your needs. In short:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Each of your service had a proprietary configuration
+ mechanism.</para>
+ </listitem>
+
+ <listitem>
+ <para>The service lifecycles were managed inside of each service or
+ were arbitrary.</para>
+ </listitem>
+
+ <listitem>
+ <para>The dependencies between your services were
+ implementation-dependent and tightly coupled in your source
+ code.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">New Approach</emphasis> You have seen that
+ eXo uses the <emphasis>Inversion of Control</emphasis> (IoC) pattern
+ which means that the control of the services is given to an independent
+ outside entity, in this case a <emphasis>container</emphasis>. Now the
+ container takes care of everything:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <emphasis>configuration is injected</emphasis> by external
+ configuration files.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>lifecycle is managed from outside</emphasis>,
+ because the constructors are called by the container. You can
+ achieve an even finer lifecycle management if you use the startable
+ interface.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>dependencies are injected</emphasis> by the
+ service instantiation process.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">Dependency Injection</emphasis> You also saw
+ two types of dependency injections:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Constructor injection: The constructor is called by the
+ container.</para>
+ </listitem>
+
+ <listitem>
+ <para>Setter injection: Whenever you use
+ <emphasis>external-plugins</emphasis> to provide your service with
+ plugins (see <link
+ linkend="Kernel.ServiceConfigurationinDetail">Service Configuration
+ in Detail</link>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>More Containers</title>
+
+ <para>There are two more Containers called
+ <classname>RepositoryContainer</classname> and
+ <classname>WorkspaceContainer</classname>. These are specificities of
+ eXo JCR, for the sake of simplicity. You don't need them.</para>
+ </section>
+
+ <section>
+ <title>Single Implementation Services</title>
+
+ <para>In some case the developer of a service does not expect that there
+ will be several implementations for his service. Therefore he does not
+ create an interface. In this case the configuration looks like
+ this:</para>
+
+ <programlisting><key>org.exoplatform.services.database.jdbc.DBSchemaCreator</key>
+<type>org.exoplatform.services.database.jdbc.DBSchemaCreator</type></programlisting>
+
+ <para>The key and type tags contain equally the qualified class
+ name.</para>
+ </section>
+
+ <section>
+ <title>Configuration properties</title>
+
+ <para>Since kernel 2.0.7 and 2.1, it is possible to use system
+ properties in literal values of component configuration meta data. Thus
+ it is possible to resolve properties at runtime instead of providing a
+ value at packaging time.</para>
+
+ <programlisting><component>
+ ...
+ <init-params>
+ <value-param>
+ <name>simple_param</name>
+ <value>${simple_param_value}</value>
+ </value-param>
+ <properties-param>
+ <name>properties_param</name>
+ <property name="value_1" value="properties_param_value_1"/>
+ <property name="value_2" value="${properties_param_value_2}"/>
+ </properties-param>
+ <object-param>
+ <name>object_param</name>
+ <object type="org.exoplatform.xml.test.Person">
+ <field name="address"><string>${person_address}</string></field>
+ <field name="male"><boolean>${person_male}</boolean></field>
+ <field name="age"><int>${age_value}</int></field>
+ <field name="size"><double>${size_value}</double></field>
+ </object>
+ </object-param>
+ </init-params>
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>Configuration Logging</title>
+
+ <para>In case you need to solve problems with your service
+ configuration, you have to know from which JAR/WAR causes your troubles.
+ Add the JVM system property
+ <parameter>org.exoplatform.container.configuration.debug</parameter> to
+ your eXo.bat or eXo.sh file (exo-tomcat/bin/).</para>
+
+ <programlisting>set EXO_CONFIG_OPTS="-Dorg.exoplatform.container.configuration.debug"</programlisting>
+
+ <para>If this property is set the container configuration manager
+ reports during startup the configuration retrieval process to the
+ standard output (System.out).</para>
+
+ <programlisting>......
+Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
+Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
+Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
+import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
+import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
+......</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Further Reading</title>
+
+ <para>Do you feel an expert now? Not yet. Get a deeper look and read this
+ <link linkend="Kernel.ServicesWiring">Services Wiring</link> article. You
+ read so much about configuration, that you should wonder what the <link
+ linkend="Kernel.ContainerConfiguration.ConfigurationNamespace">XML Schema
+ of the configuration file</link> looks like.</para>
+
+ <para>If you wish to see a examples of service configurations you should
+ study the <link linkend="Core">Core.</link> Where you find descriptions of
+ some eXo's core services. Finally you might wish to read more about <ulink
+ url="http://www.picocontainer.org/">PicoContainer</ulink>.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-05 08:52:15 UTC (rev 2878)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-05 09:13:56 UTC (rev 2879)
@@ -10,17 +10,19 @@
<itemizedlist>
<listitem>
- <para><link linkend="KernelServiceConfigurationforBeginners">Service
+ <para><link linkend="Kernel.ServiceConfigurationforBeginners">Service
Configuration for Beginners</link></para>
</listitem>
<listitem>
- <para><link linkend="KernelServicesWiring">Services Wiring</link></para>
+ <para><link linkend="Kernel.ServicesWiring">Services
+ Wiring</link></para>
</listitem>
<listitem>
- <para><link linkend="KernelConfigurationNamespace">Kernel Configuration
- File</link></para>
+ <para><link
+ linkend="Kernel.ContainerConfiguration.ConfigurationNamespace">Kernel
+ Configuration File</link></para>
</listitem>
</itemizedlist>
@@ -41,12 +43,12 @@
<title>Requirements</title>
<para>You should have read and understood <link
- linkend="KernelServiceConfigurationforBeginners">Service Configuration for
- Beginners</link>. Obviously you should know java and xml. We are working
- with examples that are created for teaching reasons only and you will see
- extracts from the eXo Products default installation. When reading do not
- forget that the terms service and component are interchangeable in eXo
- Products.</para>
+ linkend="Kernel.ServiceConfigurationforBeginners">Service Configuration
+ for Beginners</link>. Obviously you should know java and xml. We are
+ working with examples that are created for teaching reasons only and you
+ will see extracts from the eXo Products default installation. When reading
+ do not forget that the terms service and component are interchangeable in
+ eXo Products.</para>
</section>
<section id="SampleService">
@@ -357,8 +359,7 @@
<para>Let's have a look at the configuration of the LDAPService. It's
not important to know LDAP, we only discuss the parameters.</para>
- <programlisting>
-<component>
+ <programlisting><component>
<key>org.exoplatform.services.ldap.LDAPService</key>
<type>org.exoplatform.services.ldap.impl.LDAPServiceImpl</type>
<init-params>
@@ -524,12 +525,12 @@
fly.</para>
<para>As you have carefully read <link
- linkend="KernelServiceConfigurationforBeginners">Service Configuration for
- Beginners</link> you know that <emphasis role="bold">normally</emphasis>
- newer configurations always <emphasis role="bold">replaces</emphasis>
- previous configurations. An external plugin allows you to <emphasis
- role="bold">add</emphasis> configuration without replacing previous
- configurations.</para>
+ linkend="Kernel.ServiceConfigurationforBeginners">Service Configuration
+ for Beginners</link> you know that <emphasis
+ role="bold">normally</emphasis> newer configurations always <emphasis
+ role="bold">replaces</emphasis> previous configurations. An external
+ plugin allows you to <emphasis role="bold">add</emphasis> configuration
+ without replacing previous configurations.</para>
<para>That can be interesting if you adapt a service configuration for
your project-specific needs (country, language, branch, project,
More information about the exo-jcr-commits
mailing list