exo-jcr SVN: r2882 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules: ws and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-05 06:29:53 -0400 (Thu, 05 Aug 2010)
New Revision: 2882
Removed:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0-1.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws.xml
Log:
EXOJCR-870 Release notes removed from reference
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0-1.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0-1.xml 2010-08-05 10:25:35 UTC (rev 2881)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0-1.xml 2010-08-05 10:29:53 UTC (rev 2882)
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id = "WS.2.0.1">
- <?dbhtml filename="ch-exo-ws-2-0-1.html"?>
-
- <title>eXo WS 2.0.1 Release Notes (released on 2009.04.16)</title>
-
- <section>
- <title>Notable Changes</title>
-
- <para>Add supports for javax.ws.rs.core.Application. It is back compatible
- feature.</para>
- </section>
-
- <section>
- <title>API changes</title>
-
- <para>None.</para>
- </section>
-
- <section>
- <title>Dependencies changed</title>
-
- <para>Use eXo Kernel version 2.1.1</para>
-
- <para>Use eXo Core version 2.2.1</para>
- </section>
-
- <section>
- <title>How to upgrade</title>
-
- <para>It depends on kernel 2.1.1, core 2.2.1.</para>
- </section>
-
- <section>
- <title>System Requirements</title>
-
- <para>JVM: version 1.5.x</para>
-
- <para>Building Tools: Maven 2.0.6 and up</para>
- </section>
-
- <section>
- <title>Detailed Changelog</title>
-
- <para>Complete list of issues fixed in eXo-Ws Version 2.0.1 . Find details
- on JIRA <link
- linkend="???">http://jira.exoplatform.org/secure/ReleaseNote.jspa?version=10631&sty...</link>.</para>
-
- <programlisting>Bug
-* [WS-125] - net.oauth wrong artifact id declared in maven dependencies
-* [WS-137] - Error of processing the request with encoded in UTF-8 content by gadgets.io
-* [WS-146] - In HierarchicalProperty class missing check QName.getPrefix() for length is 0
-* [WS-159] - Need add charSet for Reader and Writer in JSON transformers, problem come in in Windows OS.
-* [WS-165] - Incorrect maven dependency on net.oauth:net.oauth.core:20080229
-* [WS-166] - Generated files commited in svn
-* [WS-177] - Connection problem with NTLM when trying to connect two users in same time
-* [WS-183] - Use parent pom 1.1.1 in trunk
-
-Improvement
-* [WS-138] - Add supports for javax.ws.rs.core.Application in RESTful framework
-
-New Feature
-* [WS-176] - Create filter for URL rewriting
-* [WS-182] - Create new simple Deploy Service method with JaxWsProxyFactoryBean
-
-Task
-* [WS-168] - Change URL format of groovy services to "/{command}/{repostory}/{workspace}/{path}"
-* [WS-170] - oAuth in gadgets. Get protected resource from gadgets.
-* [WS-171] - Migrate module configuration to use kernel_1_0.xsd
-* [WS-172] - Remove unnecessary configuration from all the JARs' configuration.xml
-* [WS-184] - Release WS-2.0.1</programlisting>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0.xml 2010-08-05 10:25:35 UTC (rev 2881)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/exo-ws-2-0.xml 2010-08-05 10:29:53 UTC (rev 2882)
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id = "WS.2.0">
- <?dbhtml filename="ch-exo-ws-2-0.html"?>
-
- <title>eXo WS 2.0 Release Notes (released on 2009.02.07)</title>
-
- <section>
- <title>Notable Changes</title>
-
- <para>REST framework based on JSR-311 specification including:</para>
-
- <itemizedlist>
- <listitem>
- <para>Support of JSR-311 annotations</para>
- </listitem>
-
- <listitem>
- <para>Support all media types specified in section 4.2.4 Standard
- Entity Providers of jaxrs-1.0-final specification. Additional support
- for 'multipart/*' and 'application/json' media types.</para>
- </listitem>
-
- <listitem>
- <para>WADL generation on receipt an OPTIONS request</para>
- </listitem>
-
- <listitem>
- <para>Addition feature request and response filters. Filters is
- similar to servlet filter and gives possibility to modify request and
- response</para>
- </listitem>
-
- <listitem>
- <para>Support for RESTful services that made in Groovy.</para>
- </listitem>
- </itemizedlist>
-
- <para>OAuth implementation able to use persistent storage for
- 'tickets'</para>
- </section>
-
- <section>
- <title>API changes</title>
-
- <para>RESTful services MUST use JAX-RS annotations..</para>
- </section>
-
- <section>
- <title>Dependencies changed</title>
-
- <para>Use eXo Kernel version 2.1</para>
-
- <para>Use eXo Core version 2.2</para>
-
- <para>Use maven-ant-run-plugin version 1.3 instead 1.2-SNAPSHOT</para>
-
- <para>Use jcifs version 1.2.19 instead 1.2.17</para>
- </section>
-
- <section>
- <title>How to upgrade</title>
-
- <para>See REST Migration to jsr311</para>
- </section>
-
- <section>
- <title>System Requirements</title>
-
- <para>JVM: version 1.5.x</para>
-
- <para>Building Tools: Maven 2.0.6 and up</para>
- </section>
-
- <section>
- <title>Detailed Changelog</title>
-
- <para>Complete list of issues fixed in eXo-Ws Version 2.0. Find details on
- <link
- linkend="???">http://jira.exoplatform.org/secure/ReleaseNote.jspa?version=10432&sty...</link></para>
-
- <programlisting>Bug
-* [WS-124] - Usage of SNAPSHOT in maven dependencies
-* [WS-126] - jcifs 1.2.17 is not available in public maven repo, but 1.2.19 is.
-* [WS-127] - wrong groupId for catalina dependency declaration
-
-
-Improvement
-* [WS-69] - oAuth should be able to use with annotation JSR250.
-* [WS-74] - Add possibility transfer large data (files) via org.exoplatform.services.rest.impl.provider.MultipartFormDataEntityProvider
-* [WS-77] - Check if the class org.exoplatform.ws.rest.ejbconnector30.RestEJBConnector can better handle the Portal Container to be compatible with multiple portal instance
-* [WS-78] - Check if the class org.exoplatform.ws.rest.ejbconnector21.RestEJBConnectorBean can better handle the Portal Container to be compatible with multiple portal instance
-* [WS-97] - Add support for X-HTTP-Method-Override header
-* [WS-98] - Use URI pattern for request and response filters.
-
-
-Task
-* [WS-57] - Refactor eXo REST engine to compatibility with JSR-311.
-* [WS-68] - Refactor REST EJB conector according to new implementation of REST engine (JSR-311). See WS-57.
-* [WS-75] - Add WADL generation for request with OPTIONS HTTP method.
-* [WS-81] - Change cometd service for JSR-311
-* [WS-92] - Pre-release testing plan for QA team
-* [WS-93] - Move webdav methods to the package org.exoplatform.services.rest.ext.method.webdav
-* [WS-94] - More description of classes' purpose in rest.ext sources
-* [WS-95] - Remove StandaloneContainerInitializedListener from JCR (one from WS has to be used everywhere), move PortalContainerInitializedFilter from JCR to WS
-* [WS-117] - jsr-311 capability tests
-
-Sub-task
-* [WS-101] - Create service for administration groovy scripts for REST via HTTP.
-* [WS-116] - Merge code to the branches/2.0</programlisting>
- </section>
-
- <section>
- <title>Download</title>
-
- <para>Sources: <link
- linkend="???">http://download.forge.objectweb.org/exoplatform/exo-ws-2.0-src.zip</link></para>
-
- <para>Demo: <link
- linkend="???">http://download.forge.objectweb.org/exoplatform/exo-ws-2.0-tomcat.zip</link></para>
- </section>
-</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws.xml 2010-08-05 10:25:35 UTC (rev 2881)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws.xml 2010-08-05 10:29:53 UTC (rev 2882)
@@ -8,53 +8,47 @@
<xi:include href="ws/ws.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/introduction-to-rest.xml"
+
+ <xi:include href="ws/introduction-to-rest.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-service-tutorial.xml"
+
+ <xi:include href="ws/rest-service-tutorial.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-migration-to-jsr311.xml"
+
+ <xi:include href="ws/rest-migration-to-jsr311.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/groovy-scripts-as-rest-services.xml"
+
+ <xi:include href="ws/groovy-scripts-as-rest-services.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-framework.xml"
+
+ <xi:include href="ws/rest-framework.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/soap-service-tutorial.xml"
+
+ <xi:include href="ws/soap-service-tutorial.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/central-authentication-service-configuration.xml"
+
+ <xi:include href="ws/central-authentication-service-configuration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/kerberos-sso-on-active-directory.xml"
+
+ <xi:include href="ws/kerberos-sso-on-active-directory.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/oauth.xml"
+
+ <xi:include href="ws/oauth.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd.xml"
+
+ <xi:include href="ws/cometd.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd-cluster.xml"
+
+ <xi:include href="ws/cometd-cluster.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/framework-for-cross-domain-ajax.xml"
+
+ <xi:include href="ws/framework-for-cross-domain-ajax.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd-cluster-bench.xml"
+
+ <xi:include href="ws/cometd-cluster-bench.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/javascript-webdav-library.xml"
+
+ <xi:include href="ws/javascript-webdav-library.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/exo-ws-2-0.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/exo-ws-2-0-1.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+
</part>
15 years, 11 months
exo-jcr SVN: r2881 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-05 06:25:35 -0400 (Thu, 05 Aug 2010)
New Revision: 2881
Removed:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml
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/services-wiring.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml
Log:
EXOJCR-869: link fixes
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml 2010-08-05 09:16:13 UTC (rev 2880)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml 2010-08-05 10:25:35 UTC (rev 2881)
@@ -1,1817 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id = "Kernel.Configuration">
- <?dbhtml filename="ch-configuration.html"?>
-
- <title>Configuration</title>
-
- <section>
- <title>Kernel configuration namespace</title>
-
- <para>To be effective the namespace URI <link
- linkend="???">http://www.exoplaform.org/xml/ns/kernel_1_1.xsd</link> 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/container-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-05 09:16:13 UTC (rev 2880)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-05 10:25:35 UTC (rev 2881)
@@ -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="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>
+<?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="Kernel.ServiceConfigurationforBeginners">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/services-wiring.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml 2010-08-05 09:16:13 UTC (rev 2880)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml 2010-08-05 10:25:35 UTC (rev 2881)
@@ -43,7 +43,7 @@
important to be able to configure the loaded services per instance.
Therefore all the default configuration files located in the service impl
jar can be overridden from the portal war. For more information refer to
- <link linkend="KernelServiceConfigurationforBeginners">Service
+ <link linkend="Kernel.ServiceConfigurationforBeginners">Service
Configuration for Beginners</link>.</para>
</section>
@@ -145,7 +145,7 @@
<title>JMX auto wiring</title>
<para>For JMX wiring please refer to <link
- linkend="KernelJMXMBeanServer">JMX MBean Server</link>.</para>
+ linkend="Kernel.JMXMBeanServer">JMX MBean Server</link>.</para>
</section>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml 2010-08-05 09:16:13 UTC (rev 2880)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml 2010-08-05 10:25:35 UTC (rev 2881)
@@ -10,17 +10,17 @@
<itemizedlist>
<listitem>
- <para><link linkend="KernelServiceConfigurationforBeginners">Service
+ <para><link linkend="Kernel.ServiceConfigurationforBeginners">Service
Configuration for Beginners</link></para>
</listitem>
<listitem>
- <para><link linkend="KernelServiceConfigurationinDetail">Service
+ <para><link linkend="Kernel.ServiceConfigurationinDetail">Service
Configuration in Detail</link></para>
</listitem>
<listitem>
- <para><link linkend="KernelContainerConfiguration">Container
+ <para><link linkend="Kernel.ContainerConfiguration">Container
Configuration</link></para>
</listitem>
</itemizedlist>
15 years, 11 months
exo-jcr SVN: r2880 - in jcr/branches/1.12.x/docs/reference/en: src/main/docbook/en-US and 2 other directories.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-05 05:16:13 -0400 (Thu, 05 Aug 2010)
New Revision: 2880
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq/jcr-faq.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/pom.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/master.xml
Log:
EXOJCR-625 JCR FAQ ported to docbook format
Modified: jcr/branches/1.12.x/docs/reference/en/pom.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/pom.xml 2010-08-05 09:13:56 UTC (rev 2879)
+++ jcr/branches/1.12.x/docs/reference/en/pom.xml 2010-08-05 09:16:13 UTC (rev 2880)
@@ -99,11 +99,11 @@
<stylesheetResource>classpath:/xslt/org/exojcr/xhtml-single.xsl</stylesheetResource>
<finalName>index.html</finalName>
</format>
- <!-- format>
+ <!--format>
<formatName>pdf</formatName>
<stylesheetResource>classpath://xslt/org/exojcr/pdf.xsl</stylesheetResource>
<finalName>${pom.name}.pdf</finalName>
- </format -->
+ </format-->
<!-- format>
<formatName>eclipse</formatName>
<stylesheetResource>classpath:/xslt/org/exojcr/eclipse.xsl</stylesheetResource>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/master.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/master.xml 2010-08-05 09:13:56 UTC (rev 2879)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/master.xml 2010-08-05 09:16:13 UTC (rev 2880)
@@ -66,9 +66,9 @@
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/ws.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="modules/faq.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-
-
</book>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq/jcr-faq.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq/jcr-faq.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq/jcr-faq.xml 2010-08-05 09:16:13 UTC (rev 2880)
@@ -0,0 +1,714 @@
+<?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="JCR.FAQ">
+ <?dbhtml filename="ch-jcr-faq.html"?>
+
+ <title>JCR FAQ</title>
+
+ <para>It's the draft for a future FAQ of JCR usage.</para>
+
+ <section>
+ <title>Kernel</title>
+
+ <section>
+ <title>What is the best, standardized way to get the instance of a
+ service ?</title>
+
+ <programlisting>container.getComponentInstanceOfType(ServiceName.class);</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>JCR</title>
+
+ <section>
+ <title>JCR core</title>
+
+ <section>
+ <title>Is it better to use Session.getNodeByUUID or
+ Session.getItem?</title>
+
+ <para>Session.getNodeByUUID() about 2.5 times faster of
+ Session.getItem(String) and only 25% faster of Node.getNode(String).
+ See the daily tests results for such comparisons, e.g.</para>
+
+ <para><ulink
+ url="http://tests.exoplatform.org/JCR/1.12.2-GA/rev.2442/daily-performance-tes...">http://tests.exoplatform.org/JCR/1.12.2-GA/rev.2442/daily-performance-tes...</ulink></para>
+ </section>
+
+ <section>
+ <title>Does it make sense to have all the node referencable to use
+ getNodeByUUID all the time?</title>
+
+ <para>Until it's applicable for a business logic it can be. But take
+ in account the paths are human readable and lets you think in
+ hierarchy. If it's important a location based approach is
+ preferable.</para>
+ </section>
+
+ <section>
+ <title>What should I use to check if an Item exists before getting the
+ Value?</title>
+
+ <para>Use Session.itemExists(String absPath), Node.hasNode(String
+ relPath) or Property.hasProperty(String name). It's also is possible
+ to check Node.hasNodes() and Node.hasProprties().</para>
+ </section>
+
+ <section>
+ <title>How to use Observation properly?</title>
+
+ <para>JCR Observation it's a way to listen on persistence changes of a
+ Repository. It provides several options to configure the listener for
+ an interesting only changes. For proper use it's important to
+ understand concept of events filtering for a registered EventListener
+ (8.3.3 Observation Manager). An often confusing part it's the
+ <emphasis role="bold">absPath</emphasis>, it's an associated parent of
+ a location you want to observe events on. I.e. it's a parent of child
+ node(s) or this parent property(ies); if <emphasis
+ role="bold">isDeep</emphasis> is true then you'll get events of all
+ the subtree of child nodes also. Same actual for <emphasis
+ role="bold">uuid</emphasis> and <emphasis
+ role="bold">nodeTypeName</emphasis> parameters of
+ ObservationManager.addEventListener() method.</para>
+ </section>
+
+ <section>
+ <title>Is it better to use queries that to access the data by the JCR
+ API?</title>
+
+ <para>No, direct access to items via JCR API is more efficient. Search
+ will consume additional resources for index querying and only then
+ return the items.</para>
+ </section>
+
+ <section>
+ <title>What is default query ordering?</title>
+
+ <para>By default (if query do not contains any ordering statements)
+ result nodes is sorted by document order.</para>
+ </section>
+
+ <section>
+ <title>Is ordering by jcr:path or Item name supported?</title>
+
+ <para>No it does not supported There is two ways to ordering results,
+ when path may be used as criteria:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>order by property with value type NAME or PATH (jcr supports
+ it)</para>
+ </listitem>
+
+ <listitem>
+ <para>order by jcr:path - sort by exact path of node (jcr do not
+ supports it)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Order by jcr:path</para>
+
+ <para>If no order specification is supplied in the query statement,
+ implementations may support document order on the result nodes (see
+ 6.6.4.2 Document Order). And its sorted by order number.</para>
+
+ <para>By default (if query do not contains any ordering statements)
+ result nodes is sorted by document order.</para>
+
+ <programlisting>SELECT * FROM nt:unstructured WHERE jcr:path LIKE 'testRoot/%'</programlisting>
+
+ <para>For specified jcr:path ordering there is different proceeding in
+ XPath and SQL:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL no matter ascending or descending - query returns result
+ nodes in random order: {code}SELECT * FROM nt:unstructured WHERE
+ jcr:path LIKE 'testRoot/%' ORDER BY jcr:path{code}</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>XPath - jcr:path order construction is ignored (so result is
+ not sorted according path); {code}/testRoot/* <ulink
+ url="@jcr:primaryType='nt:unstructured'">@jcr:primaryType='nt:unstructured'</ulink>
+ order by jcr:path{code}</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How eXo JCR indexer uses content encoding?</title>
+
+ <para>1. Indexer uses jcr:encoding property of nt:resource node (used
+ as jcr:content child node of nt:file) 2. if no jcr:encoding property
+ set the Document Service will use the one configured in the service
+ (defaultEncoding) 3. if has nothing configured a JVM default encoding
+ will be used</para>
+ </section>
+
+ <section>
+ <title>Which database server is better for eXo JCR?</title>
+
+ <para>If question is a performance it's difficult question, as each
+ database can be configured to be more (and more) faster for each
+ special case. MySQL with MyISAM engine will be faster. But MySQL has
+ limitations for indexes for multilingual columns (Item names
+ actually). So, with long Item names (larger ofOracle or PostgreSQL
+ also are good for performance. DB2 and MSSQL slower in default
+ configurations. Default configuration of Sybase leader of slowness.
+ But in this question take the database server maintenance in account.
+ MySQL and PostgreSQL are simple in installation and can works even on
+ limited hardware. Oracle, DB2, MSSQL or Sybase need more efforts. Same
+ actual for maintenance during the work. Note for Sybase:
+ "check-sns-new-connection" data container configuration parameter
+ should be set to "true". For testing or embedded use HSQLDB is the
+ best. Apache Derby and H2 also supported. But H2 surprisingly needs
+ "beta" feature enabled - MVCC=TRUE in JDBC url.</para>
+ </section>
+
+ <section>
+ <title>How to setup eXo JCR for mutilingial content on MySQL?</title>
+
+ <para>MySQL database should be configured to use single-byte encoding,
+ e.g. "latin1". eXo JCR application (e.g. GateIn) should use JCR
+ dialect "MySQL-UTF8".</para>
+
+ <para>In other words: MySQL database default encoding and JCR dialect
+ cannot be UTF8 both. Use single-byte encoding (e.g. "latin1") for
+ database and "mysql-utf8" dialect for eXo JCR.</para>
+
+ <para>Notice: "MySQL-UTF8" dialect cannot be auto-detected, it should
+ be set explicitly in configuration.</para>
+ </section>
+
+ <section>
+ <title>Does MySQL has limitation affecting eXo JCR features?</title>
+
+ <para>Index's key length of JCR_SITEM (JCR_MITEM) table for mysql-utf8
+ dialect is reduced to 765 bytes (or 255 chars).</para>
+ </section>
+
+ <section>
+ <title>Does use of Sybase database needs special options in eXo JCR
+ configuration?</title>
+
+ <para>For properly work JCR with Sybase need for each workspace data
+ container add new property "check-sns-new-connection" with false value
+ like this:</para>
+
+ <programlisting><container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="auto" />
+ <property name="multi-db" value="true" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ <property name="check-sns-new-connection" value="false" />
+ </properties></programlisting>
+ </section>
+
+ <section>
+ <title>How to open and close a session properly to avoid memory
+ leaks?</title>
+
+ <programlisting>Session session = repository.login(credentials);
+try
+{
+// here your code
+}
+finally
+{
+session.logout();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Can I use Session after logout?</title>
+
+ <para>No. Any instance of Session or Node (acquired through session)
+ shouldn't be used after logout anymore. At least it is highly
+ recommended not to use.</para>
+ </section>
+
+ <section>
+ <title>How to configure jcr for cluster ?</title>
+
+ <para>So we have configured JCR in standalone mode and want to
+ reconfigure it for clustered environment. First of all let's check
+ whether all requirements are satisfied:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Dedicated RDBMS anyone like MySQL, Postges, Oracle and etc.
+ but just not HSSQL;</para>
+ </listitem>
+
+ <listitem>
+ <para>Shared storage. The simples thing is to use shared FS like
+ NFS or SMB mounted in operation system, but they are rather slow.
+ The best thing is to use SAN (Storage Area Network);</para>
+ </listitem>
+
+ <listitem>
+ <para>Fast network between JCR nodes.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>So now, need to configure Container a bit. Check
+ exo-configuration.xml to be sure You are using JBossTS Transaction
+ Service and JBossCache Transaction Manager, as shown below.</para>
+
+ <programlisting><component>
+ <key>org.jboss.cache.transaction.TransactionManagerLookup</key>
+ <type>org.jboss.cache.GenericTransactionManagerLookup</type>
+</component>
+
+<component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>300</value>
+ </value-param>
+ </init-params>
+</component></programlisting>
+
+ <para>Next stage is actually the JCR configuration. We need JBossCache
+ configuration templates for : data-cache, indexer-cache and
+ lock-manager-cache. Later they will be used configuring JCR's core
+ components. There are pre-bundled templates in EAR or JAR in
+ conf/standalone/cluster. They can be used as is or re-written if
+ needed. And now time to re-configure a bit each workspace. Actually
+ need to change few parameters of <cache>, <query-handler>
+ and <lock-manager>.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><cache> configuration should looks like this:</para>
+
+ <programlisting><cache enabled="true"
+ class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="test-jbosscache-data.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-db1-ws" />
+ </properties>
+</cache></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>"jbosscache-configuration" is the path to configuration
+ template;</para>
+ </listitem>
+
+ <listitem>
+ <para>"jgroups-configuration" is path to JGroups configuration
+ is multiplexer stack is used (default). This file is also
+ pre-bundled with templates and is recommended for use;</para>
+ </listitem>
+
+ <listitem>
+ <para>"jgroups-multiplexer-stack" just simply "true". Strongly
+ recommended;</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cluster-name" is the name of cluster group.
+ Should be different for each workspace and each workspace
+ component. I.e.:
+ <repository_name>-<ws_name>-<component(cache\|lock\|index)></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para><query-handler> configuration</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>You must replace or add in <query-handler> block
+ the "changesfilter-class" parameter equals with:</para>
+
+ <programlisting><property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter"/></programlisting>
+ </listitem>
+
+ <listitem>
+ <para>add JBossCache-oriented configuration:</para>
+
+ <programlisting><property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
+<property name="jgroups-configuration" value="udp-mux.xml" />
+<property name="jgroups-multiplexer-stack" value="true" />
+<property name="jbosscache-cluster-name" value="JCR-cluster-indexer-db1-ws" />
+<property name="max-volatile-time" value="60" /></programlisting>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>Those properties have the same meaning and restrictions as in
+ previous block. Last property "max-volatile-time" is not mandatory but
+ recommended. This notifies that latest changes in index will be
+ visible for each cluster node not later than in 60s.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><lock-manager> configuration</para>
+
+ <para>Maybe this is the hardest element to configure, because we
+ have to define access to DB where locks will be stored. Replace
+ exsiting lock-manager configuration with shown below.</para>
+
+ <programlisting>
+<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-locks-db1-ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1_ws_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ </properties>
+</lock-manager>
+
+</programlisting>
+
+ <para>First few properties are the same as in previous components,
+ but here you can see some strange "jbosscache-cl-cache.jdbc.*"
+ properties. They define access parameters for database where lock
+ are persisted.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.table.create" - whether to
+ create it or not. Usually "true";</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.table.drop" - whether to drop
+ on a start or not. Use "false";</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.table.primarykey" - name of
+ column with pk;</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.fqn.column" - name of one more
+ column, use as in example if not sure (if much interested,
+ please refer to JBossCache JDBCCacheLoader
+ documentation)</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.node.column" - name of one
+ more column, use as in example if not sure (if much
+ interested, please refer to JBossCache JDBCCacheLoader
+ documentation)</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.parent.column" - name of one
+ more column, use as in example if not sure (if much
+ interested, please refer to JBossCache JDBCCacheLoader
+ documentation)</para>
+ </listitem>
+
+ <listitem>
+ <para>"jbosscache-cl-cache.jdbc.datasource" - name of
+ configured in Container datasource, where you want to store
+ locks. Bets idea is to use the same as used for
+ workspace.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>That's all. JCR is ready for running in a cluster.</para>
+ </section>
+
+ <section>
+ <title>Is JCR suitable for remote sites\* synchronization</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>understand remote site as different buildings separated by a
+ WAN network.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How to use lucene spellchecker?</title>
+
+ <para>There is few steps:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>enable lucene spellchecker in jcr QueryHandler
+ configuration:</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
+ ...
+ </properties>
+</query-handler></programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>execute query with rep:spellcheck function and word that is
+ checked:</para>
+
+ <programlisting>Query query = qm.createQuery("select rep:spellcheck() from nt:base where " + "jcr:path = '/' and spellcheck('word that is checked')", Query.SQL);
+RowIterator rows = query.execute().getRows();</programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>fetch a result:</para>
+
+ <programlisting>Row r = rows.nextRow();
+Value v = r.getValue("rep:spellcheck()");</programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>If there is no any results, that means there is no suggestion,
+ so word is correct or spellcheckers dictionary do not contain any word
+ looking like checked word.</para>
+ </section>
+
+ <section>
+ <title>How can I affect to spellchecker results?</title>
+
+ <para>There is two parameters in jcr QueryHandler
+ configuration:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>minimal distance between checked word and proposed
+ suggestion;</para>
+ </listitem>
+
+ <listitem>
+ <para>search for more popular suggestions;</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
+ <property name="spellchecker-more-popular" value="false" />
+ <property name="spellchecker-min-distance" value="0.55" />
+ ...
+ </properties>
+</query-handler></programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>Minimal distance is counted as Levenshtein distance between
+ checked word and spellchecker suggestion.</para>
+
+ <para>MorePopular paramter affects in next way: If "morePopular"
+ disabled:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>if the proposed word exist in the directory - no suggestion
+ given;</para>
+ </listitem>
+
+ <listitem>
+ <para>if the proposed word doesn't exist in the directory -
+ propose the closed word;</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If "morePopular" enabled:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>no matter word exist or not, checker will propose the closed
+ word that is the most popular than checked word.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>JCR extensions</title>
+
+ <section>
+ <title>How to restore repository to existing repository ?</title>
+
+ <orderedlist>
+ <listitem>
+ <para>Remove existing repository, use :</para>
+
+ <programlisting>RepositoryService.removeRepository(String repositoryName)</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Restore repository, use</para>
+
+ <programlisting>BackupManager.restore(RepositoryBackupChainLog log, RepositoryEntry repositoryEntry, boolean asynchronous)</programlisting>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>How to restore workspace to existing worksapce ?</title>
+
+ <orderedlist>
+ <listitem>
+ <para>Remove existing workspace, use :</para>
+
+ <programlisting>ManageableRepository.removeWorkspace(String workspaceName)</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Restore workspace, use :</para>
+
+ <programlisting>BackupManager.restore(BackupChainLog log, String repositoryName, WorkspaceEntry workspaceEntry, boolean asynchronous)</programlisting>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>Does JCR support hot backup ?</title>
+
+ <para>Yes, JCR is support hot backup. Will use
+ org.exoplatform.services.jcr.ext.backup.BackupManager.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>WebDAV</title>
+
+ <section>
+ <title>I uploaded a file to WebDAV server using Mac OS Finder, but the
+ file size is '0', what is wrong ?</title>
+
+ <para>This is a known finder bug started from Mac OS v.10.5.3 and not
+ yet fixed, .</para>
+
+ <para>for more details follow:&nbsp; <ulink
+ url="http://discussions.apple.com/thread.jspa?threadID=1538882&start=0&...">Apple
+ Disscussion thread.</ulink></para>
+ </section>
+
+ <section>
+ <title>Can I manage 'cache-control' value for different media-types
+ from server configuration ?</title>
+
+ <para>Use "cache-control" configuration parameter.</para>
+
+ <para>The value of this parameter must contain colon-separated pairs
+ "MediaType:cache-control value"</para>
+
+ <para>For example if you need to cache all text/xml and text/plain
+ files for 5 minutes (300 sec.) and other text/\* files for 10 minutes
+ (600 sec.) use the next configuration:</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.jcr.webdav.WebDavServiceImpl</type>
+ <init-params>
+ <value-param>
+ <name>cache-control</name>
+ <value>text/xml,text/plain:max-age=300;text/*:max-age=600;</value>
+ </value-param>
+ <init-params>
+<component>
+</programlisting>
+ </section>
+
+ <section>
+ <title>How to perform WebDAV requests using curl ?</title>
+
+ <para>Simple Requests</para>
+
+ <para>For simple request such as: GET, HEAD, MKCOL, COPY, MOVE,
+ DELETE, CHECKIN, CHECKOUT, UNCHECKOUT, LOCK, UNLOCK, VERSIONCONTROL,
+ OPTIONS</para>
+
+ <para>perform:</para>
+
+ <programlisting>curl -i -u 'user:pass' -X 'METHOD_NAME' 'resource_url'</programlisting>
+
+ <para>for example to create a folder named test perform:</para>
+
+ <programlisting>curl -i -u 'root:exo' -X MKCOL 'http://localhost:8080/rest/jcr/repository/production/test</programlisting>
+
+ <para>to PUT a test.txt file from your current folder to "test "folder
+ on server perform:</para>
+
+ <programlisting>curl -i -u 'root:exo' -X PUT 'http://localhost:8080/rest/jcr/repository/production/test/test.txt' -d @test.txt</programlisting>
+
+ <para>Requests with XML body</para>
+
+ <para>For requests which contains xml body such as: ORDER, PROPFIND,
+ PROPPATCH, REPORT, SEARCH</para>
+
+ <para>add <emphasis role="bold">-d 'xml_body text'</emphasis> or
+ <emphasis role="bold">-d @body.xml</emphasis></para>
+
+ <para>(body.xml must contain a valid xml request bidy.) to you
+ curl-command:</para>
+
+ <programlisting>curl -i -u 'user:pass' -X 'METHOD_NAME' -H 'Headers' 'resource_url' -d 'xml_body text'</programlisting>
+
+ <para>for example to find all files containing "test" perform:</para>
+
+ <programlisting>curl -i -u "root:exo" -X "SEARCH" "http://192.168.0.7:8080/rest/jcr/repository/production/" -d
+"<?xml version='1.0' encoding='UTF-8' ?>
+ <D:searchrequest xmlns:D='DAV:'>
+ <D:sql>SELECT * FROM nt:base WHERE contains(*, 'text')</D:sql>
+</D:searchrequest>"</programlisting>
+
+ <para>if you need to add some headers to your request use \-H
+ key.</para>
+
+ <para>More information about methods parameters you can find in <ulink
+ url="http://www.ietf.org/rfc/rfc2518.txt">HTTP Extensions for
+ Distributed Authoring</ulink> specification.</para>
+ </section>
+
+ <section>
+ <title>How eXo JCR WebDAV server treats content encoding?</title>
+
+ <para>OS client (Windows, Linux etc) doesn't set an encoding in a
+ request. But eXo JCR WebDAV server looks for an encoding in a
+ Content-Type header and set it to jcr:encoding. See <ulink
+ url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,</ulink>
+ 14.17 Content-Type. e.g. Content-Type: text/html; charset=ISO-8859-4
+ So, if a client will set Content-Type header, e.g. JS code from a
+ page, it will works for a text file as expected.</para>
+
+ <para>If WebDAV request doesn't contain a content encoding it's
+ possible to write a dedicated action in a customer application. The
+ action will set jcr:encoding using its own logic, e.g. based on IP or
+ user preferences.</para>
+ </section>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/faq.xml 2010-08-05 09:16:13 UTC (rev 2880)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<part>
+ <?dbhtml filename="part-faq.html"?>
+
+ <title>Frequently Asked Question</title>
+
+ <xi:include href="faq/jcr-faq.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+</part>
15 years, 11 months
exo-jcr SVN: r2879 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel.
by do-not-reply@jboss.org
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...">https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.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.org...">https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.org...</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...">https://anonsvn.jboss.org/repos/exo-jcr/kernel/trunk/exo.kernel.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.org...">https://anonsvn.jboss.org/repos/exo-jcr/core/trunk/exo.core.component.org...</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,
15 years, 11 months
exo-jcr SVN: r2878 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr: backup and 2 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-05 04:52:15 -0400 (Thu, 05 Aug 2010)
New Revision: 2878
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/statistics.xml
Log:
EXOJCR-869: link fixes
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -1,480 +1,477 @@
-<?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="JCR.BackupService">
- <?dbhtml filename="ch-exojcr-backup-service.html"?>
-
- <title>eXo JCR Backup Service</title>
-
- <section id="Concept">
- <title>Concept</title>
-
- <para>The main purpose of that feature is to restore data in case of
- system faults and repository crashes. Also the backup results may be used
- as a content history.</para>
-
- <para>The eXo JCR backup service was developed from the JCR 1.8
- implementation. It's an independent service available as an eXo JCR
- Extensions project.</para>
-
- <para>The concept is based on the export of a workspace unit in the Full,
- or Full + Incrementals model. A repository workspace can be backup and
- restored using a combination of these modes. In all cases, at least one
- Full (initial) backup must be executed to mark a starting point of the
- backup history. An Incremental backup is not a complete image of the
- workspace. It contains only changes for some period. So it is not possible
- to perform an Incremental backup without an initial Full backup.</para>
-
- <para>The Backup service may operate as a hot-backup process at runtime on
- an in-use workspace. It's a case when the Full + Incrementals model should
- be used to have a guaranty of data consistency during restoration. An
- Incremental will be run starting from the start point of the Full backup
- and will contain changes that have occured during the Full backup
- too.</para>
-
- <para>A <emphasis role="bold">restore</emphasis> operation is a mirror of
- a backup one. At least one Full backup should be restored to obtain a
- workspace corresponding to some point in time. On the other hand,
- Incrementals may be restored in the order of creation to reach a required
- state of a content. If the Incremental contains the same data as the Full
- backup (hot-backup), the changes will be applied again as if they were
- made in a normal way via API calls.</para>
-
- <para>According to the model there are several modes for backup
- logic:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">Full backup only</emphasis> : single
- operation, runs once</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">Full + Incrementals</emphasis> : Start
- with an initial Full backup and then keep incrementals changes in one
- file. Runs until it is stopped.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">Full + Incrementals(periodic)</emphasis> :
- Start with an initial Full backup and then keep incrementals with
- periodic result file rotation. Runs until it is stopped.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>How it works</title>
-
- <section>
- <title>Implementation details</title>
-
- <para>Full backup/restore is implemented using the JCR SysView
- Export/Import. Workspace data will be exported into Sysview XML data
- from root node.</para>
-
- <para>Restore is implemented using the special eXo JCR API feature: a
- dynamic workspace creation. Restoring of the workspace Full backup will
- create one new workspace in the repository. Then the SysView XML data
- will be imported as the root node.</para>
-
- <para>Incremental backup is implemented using the eXo JCR ChangesLog
- API. This API allows to record each JCR API call as atomic entries in a
- changelog. Hence, the Incremental backup uses a listener that collects
- these logs and stores them in a file.</para>
-
- <para>Restoring an incremental backup consists in applying the collected
- set of ChangesLogs to a workspace in the correct order.</para>
- </section>
-
- <section>
- <title>Work basics</title>
-
- <para>The work of Backup is based on the BackupConfig configuration and
- the BackupChain logical unit.</para>
-
- <para>BackupConfig describes the backup operation chain that will be
- performed by the service. When you intend to work with it, the
- configuration should be prepared before the backup is started.</para>
-
- <para>The configuration contains such values as:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">types of full and incremental
- backup</emphasis> ? (fullBackupType, incrementalBackupType) Strings
- with full names of classes which will cover the type
- functional.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">incremental period</emphasis> - a period
- after that a current backup will be stopped and a new one will be
- started, in seconds (long).</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">target repository and workspace
- names</emphasis> ? Strings with described names</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">destination directory</emphasis> for
- result files ? String with a path to a folder where operation result
- files will be stored.</para>
- </listitem>
- </itemizedlist>
-
- <para>BackupChain is a unit performing the backup process and it covers
- the principle of initial Full backup execution and manages Incrementals
- operations. BackupChain is used as a key object for accessing current
- backups during runtime via BackupManager. Each BackupJob performs a
- single atomic operation ? a Full or Incremental process. The result of
- that operation is data for a Restore. BackupChain can contain one or
- more BackupJobs. But at least the initial Full job is always there. Each
- BackupJobs has its own unique number which means its Job order in the
- chain, the initial Full job always has the number 0.</para>
-
- <para><emphasis role="bold">Backup process, result data and file
- location</emphasis></para>
-
- <para>To start the backup process it's necessary to create the
- BackupConfig and call the BackupManager.startBackup(BackupConfig)
- method. This method will return BackupChain created according to the
- configuration. At the same time the chain creates a BackupChainLog which
- persists BackupConfig content and BackupChain operation states to the
- file in the service working directory (see Configuration).</para>
-
- <para>When the chain starts the work and the initial BackupJob starts,
- the job will create a result data file using the destination directory
- path from BackupConfig. The destination directory will contain a
- directory with an automatically created name using the pattern
- repository_workspace-timestamp where timestamp is current time in the
- format of yyyyMMdd_hhmmss (E.g. db1_ws1-20080306_055404). The directory
- will contain the results of all Jobs configured for execution. Each Job
- stores the backup result in its own file with the name
- repository_workspace-timestamp.jobNumber. BackupChain saves each state
- (STARTING, WAITING, WORKING, FINISHED) of its Jobs in the
- BackupChainLog, which has a current result full file path.</para>
-
- <para>BackupChain log file and job result files are a whole and
- consistent unit, that is a source for a Restore.</para>
-
- <note>
- <para>BackupChain log contains absolute paths to job result files.
- Don't move these files to another location.</para>
- </note>
-
- <para><emphasis role="bold">Restore requirements</emphasis></para>
-
- <para>As mentioned before a Restore operation is a mirror of a Backup.
- The process is a Full restore of a root node with restoring an
- additional Incremental backup to reach a desired workspace state.
- Restoring of the workspace Full backup will create a new workspace in
- the repository using given RepositoyEntry of existing repository and
- given (preconfigured) WorkspaceEntry for a new target workspace. A
- Restore process will restore a root node there from the SysView XML
- data.</para>
-
- <note>
- <para>The target workspace should not be in the repository. Otherwise
- a BackupConfigurationException exception will be thrown.</para>
- </note>
-
- <para>For creation and manipulation with Workspaces check the article
- <link linkend="TODO">Repository and Workspace management</link>.</para>
-
- <para>Finally we may say that a Restore is a process of a new Workspace
- creation and filling it with a Backup content. In case you already have
- a target Workspace (with the same name) in a Repository, you have to
- configure a new name for it. If no target workspace exists in the
- Repository you may use the same name as the Backup one.</para>
- </section>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <para>As an optional extension, the Backup service is not enabled by
- default. <emphasis role="bold">You need to enable it via
- configuration</emphasis>.</para>
-
- <para>Below is an example configuration compatible with JCR 1.9.3 and
- later :</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
- <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
- <init-params>
- <properties-param>
- <name>backup-properties</name>
- <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
- <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
- <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
- <property name="backup-dir" value="target/backup" />
- </properties-param>
- </init-params>
-</component></programlisting>
-
- <para>Where:<itemizedlist>
- <listitem>
- <para><emphasis role="bold">incremental-backup-type</emphasis>
- (since 1.9.3) : the FQN of incremental job class. Must implement
- org.exoplatform.services.jcr.ext.backup.BackupJob</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">full-backup-type</emphasis> (since
- 1.9.3) : the FQN of the full backup job class; Must implement
- org.exoplatform.services.jcr.ext.backup.BackupJob</para>
- </listitem>
-
- <listitem>
- <para><emphasis
- role="bold">default-incremental-job-period</emphasis> (since 1.9.3)
- :the period between incremetal flushes (in seconds)</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">backup-dir</emphasis> : the path to a
- working directory where the service will store internal files and
- chain logs.</para>
- </listitem>
- </itemizedlist></para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <section>
- <title>Perform a Backup</title>
-
- <para>In following example we create a BackupConfig bean for the Full +
- Incrementals mode, then we ask the BackupManager to start the backup
- process.</para>
-
- <programlisting>// Obtaining the backup service from the eXo container.
-BackupManager backup = (BackupManager) container.getComponentInstanceOfType(BackupManager.class);
-
-// And prepare the BackupConfig instance with custom parameters.
-// full backup & incremental
-File backDir = new File("/backup/ws1"); // the destination path for result files
-backDir.mkdirs();
-
-BackupConfig config = new BackupConfig();
-config.setRepository(repository.getName());
-config.setWorkspace("ws1");
-config.setBackupDir(backDir);
-
-// Before 1.9.3, you also need to indicate the backupjobs class FDNs
-// config.setFullBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob");
-// config.setIncrementalBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob");
-
-// start backup using the service manager
-BackupChain chain = backup.startBackup(config);</programlisting>
-
- <para>To stop the backup operation you have to use the BackupChain
- instance.</para>
-
- <programlisting>// stop backup
-backup.stopBackup(chain);</programlisting>
- </section>
-
- <section>
- <title>Perform a Restore</title>
-
- <para>Restoration involves the reloading the backup file into a
- BackupChainLog and applying appropriate workspace initialization. The
- following snippet shows the typical sequence for restoring a workspace
- :</para>
-
- <programlisting>// find BackupChain using the repository and workspace names (return null if not found)
-BackupChain chain = backup.findBackup("db1", "ws1");
-
-// Get the RepositoryEntry and WorkspaceEntry
-ManageableRepository repo = repositoryService.getRepository(repository);
-RepositoryEntry repoconf = repo.getConfiguration();
-List<WorkspaceEntry> entries = repoconf.getWorkspaceEntries();
-WorkspaceEntry = getNewEntry(entries, workspace); // create a copy entry from an existing one
-
-// restore backup log using ready RepositoryEntry and WorkspaceEntry
-File backLog = new File(chain.getLogFilePath());
-BackupChainLog bchLog = new BackupChainLog(backLog);
-
-// initialize the workspace
-repository.configWorkspace(workspaceEntry);
-
-// run restoration
-backup.restore(bchLog, repositoryEntry, workspaceEntry);</programlisting>
-
- <section>
- <title>Restoring into an existing workspace</title>
-
- <note>
- <para>These instructions only applies to regular workspace. Special
- instructions are provided for System workspace below.</para>
- </note>
-
- <para>To restore a backup over an existing workspace, you are required
- to clear its data. Your backup process should follow these steps :
- <itemizedlist>
- <listitem>
- <para>remove workspace<programlisting>ManageableRepository repo = repositoryService.getRepository(repository);
-repo.removeWorkspace(workspace);</programlisting></para>
- </listitem>
-
- <listitem>
- <para>clean database, value storage, index</para>
- </listitem>
-
- <listitem>
- <para>restore (see snippet above)</para>
- </listitem>
- </itemizedlist></para>
- </section>
-
- <section>
- <title>System workspace</title>
-
- <note>
- <para>The BackupWorkspaceInitializer is available in JCR 1.9 and
- later.</para>
- </note>
-
- <para>Restoring the JCR System workspace requires to shutdown the
- system and use of a special initializer.</para>
-
- <para>Follow these steps (this will also work for normal workspaces) :
- <itemizedlist>
- <listitem>
- <para>Stop repository (or portal)</para>
- </listitem>
-
- <listitem>
- <para>clean database, value storage, index; </para>
- </listitem>
-
- <listitem>
- <para>In configuration the workspace set
- BackupWorkspaceInitializer to reference your backup.</para>
-
- <para>For example :<programlisting><workspaces>
- <workspace name="production" ... >
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- ...
- </container>
- <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
- <properties>
- <property name="restore-path" value="D:\java\exo-working\backup\repository_production-20090527_030434"/>
- </properties>
- </initializer>
- ...
-</workspace></programlisting></para>
- </listitem>
-
- <listitem>
- <para>Start repository (or portal).</para>
- </listitem>
- </itemizedlist></para>
- </section>
- </section>
- </section>
-
- <section>
- <title>Scheduling (experimental)</title>
-
- <para>The Backup service has an additional feature that can be useful for
- a production level backup implementation. When you need to organize a
- backup of a repository it's necessary to have a tool which will be able to
- create and manage a cycle of Full and Incremental backups in periodic
- manner.</para>
-
- <para>The service has internal BackupScheduler which can run a
- configurable cycle of BackupChains as if they have been executed by a user
- during some period of time. I.e. BackupScheduler is a user-like daemon
- which asks the BackupManager to start or stop backup operations.</para>
-
- <para>For that purpose BackupScheduler has the method</para>
-
- <para>BackupScheduler.schedule(backupConfig, startDate, stopDate,
- chainPeriod, incrementalPeriod)</para>
-
- <para>where</para>
-
- <itemizedlist>
- <listitem>
- <para>backupConfig - a ready configuration which will be given to the
- BackupManager.startBackup() method</para>
- </listitem>
-
- <listitem>
- <para>startDate - a date and time of the backup start</para>
- </listitem>
-
- <listitem>
- <para>stopDate - a date and time of the backup stop</para>
- </listitem>
-
- <listitem>
- <para>chainPeriod - a period after which a current BackupChain will be
- stopped and a new one will be started, in seconds</para>
- </listitem>
-
- <listitem>
- <para>incrementalPeriod - if it is greater than 0 it will be used to
- override the same value in backupConfig.</para>
- </listitem>
- </itemizedlist>
-
- <programlisting>// geting the scheduler from the BackupManager
- BackupScheduler scheduler = backup.getScheduler();
-
-// schedule backup using a ready configuration (Full + Incrementals) to run from startTime
-// to stopTime. Full backuop will be performed every 24 hours (BackupChain lifecycle),
-// incremental will rotate result files every 3 hours.
- scheduler.schedule(config, startTime, stopTime, 3600 * 24, 3600 * 3);
-
-// it's possible to run the scheduler for an uncertain period of time (i.e. without stop time).
-// schedule backup to run from startTime till it will be stopped manually
-// also there, the incremental will rotate result files as it configured in BackupConfig
- scheduler.schedule(config, startTime, null, 3600 * 24, 0);
-
-// to unschedule backup simply call the scheduler with the configuration describing the
-// already planned backup cycle.
-// the scheduler will search in internal tasks list for task with repository and
-// workspace name from the configuration and will stop that task.
- scheduler.unschedule(config);</programlisting>
-
- <para>When the BackupScheduler starts the scheduling, it uses the internal
- Timer with startDate for the first (or just once) execution. If
- chainPeriod is greater than 0 then the task is repeated with this value
- used as a period starting from startDate. Otherwise the task will be
- executed once at startDate time. If the scheduler has stopDate it will
- stop the task ( the chain cycle) after stopDate. And the last parameter
- incrementalPeriod will be used instead of the same from BackupConfig if
- its values are greater than 0.</para>
-
- <para>Starting each task (BackupScheduler.schedule(...)), the scheduler
- creates a task file in the service working directory (see <emphasis
- role="bold">Configuration</emphasis>, backup-dir) which describes the task
- backup configuration and periodic values. These files will be used at the
- backup service start (JVM start) to reinitialize BackupScheduler for
- continuous task scheduling. Only tasks that don't have a stopDate or a
- stopDate not expired will be reinitialized.</para>
-
- <para>There is one notice about BackupScheduler task reinitialization in
- the current implementation. It comes from the BackupScheduler nature and
- its implemented behaviour. As the scheduler is just a virtual user which
- asks the BackupManager to start or stop backup operations, it isn't able
- to reinitialize each existing BackupChain before the service (JVM) is
- stopped. But it's possible to start a new operation with the same
- configuration via BackupManager (that was configured before and stored in
- a task file).</para>
-
- <para>This is a main detail of the BackupScheduler which should be taken
- into suggestion of a backup operation design now. In case of
- reinitialization the task will have new time values for the backup
- operation cycle as the chainPeriod and incrementalPeriod will be applied
- again. That behaviour may be changed in the future.</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="JCR.BackupService">
+ <?dbhtml filename="ch-exojcr-backup-service.html"?>
+
+ <title>eXo JCR Backup Service</title>
+
+ <section id="Concept">
+ <title>Concept</title>
+
+ <para>The main purpose of that feature is to restore data in case of
+ system faults and repository crashes. Also the backup results may be used
+ as a content history.</para>
+
+ <para>The eXo JCR backup service was developed from the JCR 1.8
+ implementation. It's an independent service available as an eXo JCR
+ Extensions project.</para>
+
+ <para>The concept is based on the export of a workspace unit in the Full,
+ or Full + Incrementals model. A repository workspace can be backup and
+ restored using a combination of these modes. In all cases, at least one
+ Full (initial) backup must be executed to mark a starting point of the
+ backup history. An Incremental backup is not a complete image of the
+ workspace. It contains only changes for some period. So it is not possible
+ to perform an Incremental backup without an initial Full backup.</para>
+
+ <para>The Backup service may operate as a hot-backup process at runtime on
+ an in-use workspace. It's a case when the Full + Incrementals model should
+ be used to have a guaranty of data consistency during restoration. An
+ Incremental will be run starting from the start point of the Full backup
+ and will contain changes that have occured during the Full backup
+ too.</para>
+
+ <para>A <emphasis role="bold">restore</emphasis> operation is a mirror of
+ a backup one. At least one Full backup should be restored to obtain a
+ workspace corresponding to some point in time. On the other hand,
+ Incrementals may be restored in the order of creation to reach a required
+ state of a content. If the Incremental contains the same data as the Full
+ backup (hot-backup), the changes will be applied again as if they were
+ made in a normal way via API calls.</para>
+
+ <para>According to the model there are several modes for backup
+ logic:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Full backup only</emphasis> : single
+ operation, runs once</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals</emphasis> : Start
+ with an initial Full backup and then keep incrementals changes in one
+ file. Runs until it is stopped.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals(periodic)</emphasis> :
+ Start with an initial Full backup and then keep incrementals with
+ periodic result file rotation. Runs until it is stopped.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How it works</title>
+
+ <section>
+ <title>Implementation details</title>
+
+ <para>Full backup/restore is implemented using the JCR SysView
+ Export/Import. Workspace data will be exported into Sysview XML data
+ from root node.</para>
+
+ <para>Restore is implemented using the special eXo JCR API feature: a
+ dynamic workspace creation. Restoring of the workspace Full backup will
+ create one new workspace in the repository. Then the SysView XML data
+ will be imported as the root node.</para>
+
+ <para>Incremental backup is implemented using the eXo JCR ChangesLog
+ API. This API allows to record each JCR API call as atomic entries in a
+ changelog. Hence, the Incremental backup uses a listener that collects
+ these logs and stores them in a file.</para>
+
+ <para>Restoring an incremental backup consists in applying the collected
+ set of ChangesLogs to a workspace in the correct order.</para>
+ </section>
+
+ <section>
+ <title>Work basics</title>
+
+ <para>The work of Backup is based on the BackupConfig configuration and
+ the BackupChain logical unit.</para>
+
+ <para>BackupConfig describes the backup operation chain that will be
+ performed by the service. When you intend to work with it, the
+ configuration should be prepared before the backup is started.</para>
+
+ <para>The configuration contains such values as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">types of full and incremental
+ backup</emphasis> - (fullBackupType, incrementalBackupType) Strings
+ with full names of classes which will cover the type
+ functional.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">incremental period</emphasis> - a period
+ after that a current backup will be stopped and a new one will be
+ started, in seconds (long).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">target repository and workspace
+ names</emphasis> - Strings with described names</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">destination directory</emphasis> for
+ result files - String with a path to a folder where operation result
+ files will be stored.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>BackupChain is a unit performing the backup process and it covers
+ the principle of initial Full backup execution and manages Incrementals
+ operations. BackupChain is used as a key object for accessing current
+ backups during runtime via BackupManager. Each BackupJob performs a
+ single atomic operation - a Full or Incremental process. The result of
+ that operation is data for a Restore. BackupChain can contain one or
+ more BackupJobs. But at least the initial Full job is always there. Each
+ BackupJobs has its own unique number which means its Job order in the
+ chain, the initial Full job always has the number 0.</para>
+
+ <para><emphasis role="bold">Backup process, result data and file
+ location</emphasis></para>
+
+ <para>To start the backup process it's necessary to create the
+ BackupConfig and call the BackupManager.startBackup(BackupConfig)
+ method. This method will return BackupChain created according to the
+ configuration. At the same time the chain creates a BackupChainLog which
+ persists BackupConfig content and BackupChain operation states to the
+ file in the service working directory (see Configuration).</para>
+
+ <para>When the chain starts the work and the initial BackupJob starts,
+ the job will create a result data file using the destination directory
+ path from BackupConfig. The destination directory will contain a
+ directory with an automatically created name using the pattern
+ repository_workspace-timestamp where timestamp is current time in the
+ format of yyyyMMdd_hhmmss (E.g. db1_ws1-20080306_055404). The directory
+ will contain the results of all Jobs configured for execution. Each Job
+ stores the backup result in its own file with the name
+ repository_workspace-timestamp.jobNumber. BackupChain saves each state
+ (STARTING, WAITING, WORKING, FINISHED) of its Jobs in the
+ BackupChainLog, which has a current result full file path.</para>
+
+ <para>BackupChain log file and job result files are a whole and
+ consistent unit, that is a source for a Restore.</para>
+
+ <note>
+ <para>BackupChain log contains absolute paths to job result files.
+ Don't move these files to another location.</para>
+ </note>
+
+ <para><emphasis role="bold">Restore requirements</emphasis></para>
+
+ <para>As mentioned before a Restore operation is a mirror of a Backup.
+ The process is a Full restore of a root node with restoring an
+ additional Incremental backup to reach a desired workspace state.
+ Restoring of the workspace Full backup will create a new workspace in
+ the repository using given RepositoyEntry of existing repository and
+ given (preconfigured) WorkspaceEntry for a new target workspace. A
+ Restore process will restore a root node there from the SysView XML
+ data.</para>
+
+ <note>
+ <para>The target workspace should not be in the repository. Otherwise
+ a BackupConfigurationException exception will be thrown.</para>
+ </note>
+
+ <para>Finally we may say that a Restore is a process of a new Workspace
+ creation and filling it with a Backup content. In case you already have
+ a target Workspace (with the same name) in a Repository, you have to
+ configure a new name for it. If no target workspace exists in the
+ Repository you may use the same name as the Backup one.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>As an optional extension, the Backup service is not enabled by
+ default. <emphasis role="bold">You need to enable it via
+ configuration</emphasis>.</para>
+
+ <para>Below is an example configuration compatible with JCR 1.9.3 and
+ later :</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
+ <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
+ <init-params>
+ <properties-param>
+ <name>backup-properties</name>
+ <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
+ <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
+ <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
+ <property name="backup-dir" value="target/backup" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para>Where:<itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">incremental-backup-type</emphasis>
+ (since 1.9.3) : the FQN of incremental job class. Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">full-backup-type</emphasis> (since
+ 1.9.3) : the FQN of the full backup job class; Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis
+ role="bold">default-incremental-job-period</emphasis> (since 1.9.3)
+ :the period between incremetal flushes (in seconds)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">backup-dir</emphasis> : the path to a
+ working directory where the service will store internal files and
+ chain logs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <section>
+ <title>Perform a Backup</title>
+
+ <para>In following example we create a BackupConfig bean for the Full +
+ Incrementals mode, then we ask the BackupManager to start the backup
+ process.</para>
+
+ <programlisting>// Obtaining the backup service from the eXo container.
+BackupManager backup = (BackupManager) container.getComponentInstanceOfType(BackupManager.class);
+
+// And prepare the BackupConfig instance with custom parameters.
+// full backup & incremental
+File backDir = new File("/backup/ws1"); // the destination path for result files
+backDir.mkdirs();
+
+BackupConfig config = new BackupConfig();
+config.setRepository(repository.getName());
+config.setWorkspace("ws1");
+config.setBackupDir(backDir);
+
+// Before 1.9.3, you also need to indicate the backupjobs class FDNs
+// config.setFullBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob");
+// config.setIncrementalBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob");
+
+// start backup using the service manager
+BackupChain chain = backup.startBackup(config);</programlisting>
+
+ <para>To stop the backup operation you have to use the BackupChain
+ instance.</para>
+
+ <programlisting>// stop backup
+backup.stopBackup(chain);</programlisting>
+ </section>
+
+ <section>
+ <title>Perform a Restore</title>
+
+ <para>Restoration involves the reloading the backup file into a
+ BackupChainLog and applying appropriate workspace initialization. The
+ following snippet shows the typical sequence for restoring a workspace
+ :</para>
+
+ <programlisting>// find BackupChain using the repository and workspace names (return null if not found)
+BackupChain chain = backup.findBackup("db1", "ws1");
+
+// Get the RepositoryEntry and WorkspaceEntry
+ManageableRepository repo = repositoryService.getRepository(repository);
+RepositoryEntry repoconf = repo.getConfiguration();
+List<WorkspaceEntry> entries = repoconf.getWorkspaceEntries();
+WorkspaceEntry = getNewEntry(entries, workspace); // create a copy entry from an existing one
+
+// restore backup log using ready RepositoryEntry and WorkspaceEntry
+File backLog = new File(chain.getLogFilePath());
+BackupChainLog bchLog = new BackupChainLog(backLog);
+
+// initialize the workspace
+repository.configWorkspace(workspaceEntry);
+
+// run restoration
+backup.restore(bchLog, repositoryEntry, workspaceEntry);</programlisting>
+
+ <section>
+ <title>Restoring into an existing workspace</title>
+
+ <note>
+ <para>These instructions only applies to regular workspace. Special
+ instructions are provided for System workspace below.</para>
+ </note>
+
+ <para>To restore a backup over an existing workspace, you are required
+ to clear its data. Your backup process should follow these steps :
+ <itemizedlist>
+ <listitem>
+ <para>remove workspace<programlisting>ManageableRepository repo = repositoryService.getRepository(repository);
+repo.removeWorkspace(workspace);</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index</para>
+ </listitem>
+
+ <listitem>
+ <para>restore (see snippet above)</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>System workspace</title>
+
+ <note>
+ <para>The BackupWorkspaceInitializer is available in JCR 1.9 and
+ later.</para>
+ </note>
+
+ <para>Restoring the JCR System workspace requires to shutdown the
+ system and use of a special initializer.</para>
+
+ <para>Follow these steps (this will also work for normal workspaces) :
+ <itemizedlist>
+ <listitem>
+ <para>Stop repository (or portal)</para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index;</para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration the workspace set
+ BackupWorkspaceInitializer to reference your backup.</para>
+
+ <para>For example :<programlisting><workspaces>
+ <workspace name="production" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_production-20090527_030434"/>
+ </properties>
+ </initializer>
+ ...
+</workspace></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository (or portal).</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Scheduling (experimental)</title>
+
+ <para>The Backup service has an additional feature that can be useful for
+ a production level backup implementation. When you need to organize a
+ backup of a repository it's necessary to have a tool which will be able to
+ create and manage a cycle of Full and Incremental backups in periodic
+ manner.</para>
+
+ <para>The service has internal BackupScheduler which can run a
+ configurable cycle of BackupChains as if they have been executed by a user
+ during some period of time. I.e. BackupScheduler is a user-like daemon
+ which asks the BackupManager to start or stop backup operations.</para>
+
+ <para>For that purpose BackupScheduler has the method</para>
+
+ <para>BackupScheduler.schedule(backupConfig, startDate, stopDate,
+ chainPeriod, incrementalPeriod)</para>
+
+ <para>where</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>backupConfig - a ready configuration which will be given to the
+ BackupManager.startBackup() method</para>
+ </listitem>
+
+ <listitem>
+ <para>startDate - a date and time of the backup start</para>
+ </listitem>
+
+ <listitem>
+ <para>stopDate - a date and time of the backup stop</para>
+ </listitem>
+
+ <listitem>
+ <para>chainPeriod - a period after which a current BackupChain will be
+ stopped and a new one will be started, in seconds</para>
+ </listitem>
+
+ <listitem>
+ <para>incrementalPeriod - if it is greater than 0 it will be used to
+ override the same value in backupConfig.</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>// geting the scheduler from the BackupManager
+ BackupScheduler scheduler = backup.getScheduler();
+
+// schedule backup using a ready configuration (Full + Incrementals) to run from startTime
+// to stopTime. Full backuop will be performed every 24 hours (BackupChain lifecycle),
+// incremental will rotate result files every 3 hours.
+ scheduler.schedule(config, startTime, stopTime, 3600 * 24, 3600 * 3);
+
+// it's possible to run the scheduler for an uncertain period of time (i.e. without stop time).
+// schedule backup to run from startTime till it will be stopped manually
+// also there, the incremental will rotate result files as it configured in BackupConfig
+ scheduler.schedule(config, startTime, null, 3600 * 24, 0);
+
+// to unschedule backup simply call the scheduler with the configuration describing the
+// already planned backup cycle.
+// the scheduler will search in internal tasks list for task with repository and
+// workspace name from the configuration and will stop that task.
+ scheduler.unschedule(config);</programlisting>
+
+ <para>When the BackupScheduler starts the scheduling, it uses the internal
+ Timer with startDate for the first (or just once) execution. If
+ chainPeriod is greater than 0 then the task is repeated with this value
+ used as a period starting from startDate. Otherwise the task will be
+ executed once at startDate time. If the scheduler has stopDate it will
+ stop the task ( the chain cycle) after stopDate. And the last parameter
+ incrementalPeriod will be used instead of the same from BackupConfig if
+ its values are greater than 0.</para>
+
+ <para>Starting each task (BackupScheduler.schedule(...)), the scheduler
+ creates a task file in the service working directory (see <emphasis
+ role="bold">Configuration</emphasis>, backup-dir) which describes the task
+ backup configuration and periodic values. These files will be used at the
+ backup service start (JVM start) to reinitialize BackupScheduler for
+ continuous task scheduling. Only tasks that don't have a stopDate or a
+ stopDate not expired will be reinitialized.</para>
+
+ <para>There is one notice about BackupScheduler task reinitialization in
+ the current implementation. It comes from the BackupScheduler nature and
+ its implemented behaviour. As the scheduler is just a virtual user which
+ asks the BackupManager to start or stop backup operations, it isn't able
+ to reinitialize each existing BackupChain before the service (JVM) is
+ stopped. But it's possible to start a new operation with the same
+ configuration via BackupManager (that was configured before and stored in
+ a task file).</para>
+
+ <para>This is a main detail of the BackupScheduler which should be taken
+ into suggestion of a backup operation design now. In case of
+ reinitialization the task will have new time values for the backup
+ operation cycle as the chainPeriod and incrementalPeriod will be applied
+ again. That behaviour may be changed in the future.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -1,112 +1,159 @@
-<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
- <chapter id="JCR.HowToImplementWorkspaceDataContainer">
- <title>How-to implement Workspace Data Container</title>
- <?dbhtml filename="ch-data-container-howto.html"?>
- <section id="ShortintrointoWorkspacedatacontainerimplementationpractices">
- <title>Short intro into Workspace data container implementation practices:</title>
- <orderedlist>
- <listitem>
- <para>Read a bit about the <link linkend="JCRWorkspaceDataContainerarchitecturecontract">contract</link>.</para>
- </listitem>
- <listitem>
- <para>Start new implementation project pom.xml with org.exoplatform.jcr parent. (optional, but will makes the development easy)</para>
- </listitem>
- <listitem>
- <para>Update sources of JCR Core and read JavaDoc on
- <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceDataContainer</emphasis> and
- <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceStorageConnection</emphasis> interfaces. This two are main part for the implemenation.
- </para>
- </listitem>
- <listitem>
- <para>Look at
- <emphasis role="bold">org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager</emphasis> sourcecode, check how data meneger uses container and its connections (see in save() method)
- </para>
- </listitem>
- <listitem>
- <para>Create
- <emphasis role="bold">WorkspaceStorageConnection</emphasis> dummy implementation class. It's freeform class, but to be close to the eXo JCR, check how implemented JDBC or SimpleDB containers (
- <emphasis role="bold">org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection</emphasis> and
- <emphasis role="bold">org.exoplatform.services.jcr.aws.storage.sdb.SDBWorkspaceStorageConnection</emphasis>). Take in account usage of
- <emphasis role="bold">ValueStoragePluginProvider</emphasis> in both implementations.Value storage is an useful option for production versions. But leave it to the end of implementation work.
- </para>
- </listitem>
- <listitem>
- <para>Create the connection implementation unit tests to play TTD. (optional, but takes many benefits for the process)</para>
- </listitem>
- <listitem>
- <para>Implement CRUD starting from the read to write etc. Test the methods using external to the implementation ways of data read/write in your backend.</para>
- </listitem>
- <listitem>
- <para>When all methods of the connection done start
- <emphasis role="bold">WorkspaceDataContainer</emphasis>. Container class very simple, it's like a factory for the connections only.
- </para>
- </listitem>
- <listitem>
- <para>Care about container reuseConnection(WorkspaceStorageConnection) method logic. For some backends it cab be same as openConnection(), but for some others it's important to reuse physical backend connection, e.g. to be in same transaction - see JDBC container.</para>
- </listitem>
- <listitem>
- <para>It's almost ready for use in data manager. Start another test and go on.</para>
- </listitem>
- </orderedlist>
- <para>When the container will be ready for run as JCR persistence storage (e.g. for this level testing) it should be configured in Repository configuration.</para>
- <para>Assuming that our new implementation class name is
- <emphasis role="bold">org.project.jcr.impl.storage.MyWorkspaceDataContainer</emphasis>.
- </para>
- <programlisting> <repository-service default-repository="repository">
- <repositories>
- <repository name="repository" system-workspace="production" default-workspace="production">
- .............
- <workspaces>
- <workspace name="production">
- <container class="org.project.jcr.impl.storage.MyWorkspaceDataContainer">
- <properties>
- <property name="propertyName1" value="propertyValue1" />
- <property name="propertyName2" value="propertyValue2" />
- .......
- <property name="propertyNameN" value="propertyValueN" />
- </properties>
- <value-storages>
- .......
- </value-storages>
- </container>
-
-</programlisting>
- <para>Container can be configured using set properties.</para>
- </section>
- <section id="Valuestorageusagenotes">
- <title>Value storage usage notes:</title>
- <para>Value storages pluggable to the container but if it used the container implementation should respect set of interfaces and external storage usage principles.</para>
- <para>If the container have
- <emphasis role="bold">ValueStoragePluginProvider</emphasis> (e.g. via constructor) it's just few methods to manipulate external Values data.
- </para>
- <programlisting>// get channel for ValueData write (add or update)
-ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data, i);
-if (channel == null) {
- // write
- channel.write(data.getIdentifier(), vd);
- // obtain storage id, id can be used for linkage of external ValueData and PropertyData in main backend
- String storageId = channel.getStorageId();
-}
-
-....
-
-// delete all Property Values in external storage
-ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
-channel.delete(propertyData.getIdentifier());
-
-....
-
-// read ValueData from external storage
-ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
-ValueData vdata = channel.read(propertyData.getIdentifier(), orderNumber, maxBufferSize);
-
-</programlisting>
- <important>
- <title>Important</title>
- <para>After a sequence of write and/or delete operations on the storage channel, the channel should be committed (or rolled back on an error). See
- <emphasis role="bold">ValueIOChannel.commit()</emphasis> and
- <emphasis role="bold">ValueIOChannel.rollback()</emphasis> and how those methods used in JDBC container.
- </para>
- </important>
- </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="JCR.HowToImplementWorkspaceDataContainer">
+ <title>How-to implement Workspace Data Container</title>
+
+ <?dbhtml filename="ch-data-container-howto.html"?>
+
+ <section id="ShortintrointoWorkspacedatacontainerimplementationpractices">
+ <title>Short intro into Workspace data container implementation
+ practices:</title>
+
+ <orderedlist>
+ <listitem>
+ <para>Read a bit about the <link
+ linkend="JCR.WorkspaceDataContainer">contract</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Start new implementation project pom.xml with
+ org.exoplatform.jcr parent. (optional, but will makes the development
+ easy)</para>
+ </listitem>
+
+ <listitem>
+ <para>Update sources of JCR Core and read JavaDoc on <emphasis
+ role="bold">org.exoplatform.services.jcr.storage.WorkspaceDataContainer</emphasis>
+ and <emphasis
+ role="bold">org.exoplatform.services.jcr.storage.WorkspaceStorageConnection</emphasis>
+ interfaces. This two are main part for the implemenation.</para>
+ </listitem>
+
+ <listitem>
+ <para>Look at <emphasis
+ role="bold">org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager</emphasis>
+ sourcecode, check how data meneger uses container and its connections
+ (see in save() method)</para>
+ </listitem>
+
+ <listitem>
+ <para>Create <emphasis
+ role="bold">WorkspaceStorageConnection</emphasis> dummy implementation
+ class. It's freeform class, but to be close to the eXo JCR, check how
+ implemented JDBC or SimpleDB containers ( <emphasis
+ role="bold">org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection</emphasis>
+ and <emphasis
+ role="bold">org.exoplatform.services.jcr.aws.storage.sdb.SDBWorkspaceStorageConnection</emphasis>).
+ Take in account usage of <emphasis
+ role="bold">ValueStoragePluginProvider</emphasis> in both
+ implementations.Value storage is an useful option for production
+ versions. But leave it to the end of implementation work.</para>
+ </listitem>
+
+ <listitem>
+ <para>Create the connection implementation unit tests to play TTD.
+ (optional, but takes many benefits for the process)</para>
+ </listitem>
+
+ <listitem>
+ <para>Implement CRUD starting from the read to write etc. Test the
+ methods using external to the implementation ways of data read/write
+ in your backend.</para>
+ </listitem>
+
+ <listitem>
+ <para>When all methods of the connection done start <emphasis
+ role="bold">WorkspaceDataContainer</emphasis>. Container class very
+ simple, it's like a factory for the connections only.</para>
+ </listitem>
+
+ <listitem>
+ <para>Care about container reuseConnection(WorkspaceStorageConnection)
+ method logic. For some backends it cab be same as openConnection(),
+ but for some others it's important to reuse physical backend
+ connection, e.g. to be in same transaction - see JDBC
+ container.</para>
+ </listitem>
+
+ <listitem>
+ <para>It's almost ready for use in data manager. Start another test
+ and go on.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>When the container will be ready for run as JCR persistence storage
+ (e.g. for this level testing) it should be configured in Repository
+ configuration.</para>
+
+ <para>Assuming that our new implementation class name is <emphasis
+ role="bold">org.project.jcr.impl.storage.MyWorkspaceDataContainer</emphasis>.</para>
+
+ <programlisting> <repository-service default-repository="repository">
+ <repositories>
+ <repository name="repository" system-workspace="production" default-workspace="production">
+ .............
+ <workspaces>
+ <workspace name="production">
+ <container class="org.project.jcr.impl.storage.MyWorkspaceDataContainer">
+ <properties>
+ <property name="propertyName1" value="propertyValue1" />
+ <property name="propertyName2" value="propertyValue2" />
+ .......
+ <property name="propertyNameN" value="propertyValueN" />
+ </properties>
+ <value-storages>
+ .......
+ </value-storages>
+ </container>
+
+</programlisting>
+
+ <para>Container can be configured using set properties.</para>
+ </section>
+
+ <section id="Valuestorageusagenotes">
+ <title>Value storage usage notes:</title>
+
+ <para>Value storages pluggable to the container but if it used the
+ container implementation should respect set of interfaces and external
+ storage usage principles.</para>
+
+ <para>If the container have <emphasis
+ role="bold">ValueStoragePluginProvider</emphasis> (e.g. via constructor)
+ it's just few methods to manipulate external Values data.</para>
+
+ <programlisting>// get channel for ValueData write (add or update)
+ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data, i);
+if (channel == null) {
+ // write
+ channel.write(data.getIdentifier(), vd);
+ // obtain storage id, id can be used for linkage of external ValueData and PropertyData in main backend
+ String storageId = channel.getStorageId();
+}
+
+....
+
+// delete all Property Values in external storage
+ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+channel.delete(propertyData.getIdentifier());
+
+....
+
+// read ValueData from external storage
+ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+ValueData vdata = channel.read(propertyData.getIdentifier(), orderNumber, maxBufferSize);
+
+</programlisting>
+
+ <important>
+ <title>Important</title>
+
+ <para>After a sequence of write and/or delete operations on the storage
+ channel, the channel should be committed (or rolled back on an error).
+ See <emphasis role="bold">ValueIOChannel.commit()</emphasis> and
+ <emphasis role="bold">ValueIOChannel.rollback()</emphasis> and how those
+ methods used in JDBC container.</para>
+ </important>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,31 +3,46 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.AccessControlExtension">
<?dbhtml filename="ch-acl-ext.html"?>
+
<title>Access Control Extension</title>
<section>
<title>Prerequisites</title>
<para>This is an extension of eXo JCR Access Control features. Please read
- <ulink url="Access Control">Access Control</ulink> and <ulink
- url="JCR Extensions">JCR Extensions</ulink> topics before.</para>
+ <link linkend="JCR.AccessControl">Access Control</link> and <link
+ linkend="JCR.Extensions">JCR Extensions</link> topics before.</para>
</section>
<section>
<title>Overview</title>
- <para>An extended Access Control system consists of: * Specifically
- configured custom <emphasis role="bold">Extended Access Manager</emphasis>
- which is called by eXo JCR internals to check if some user's Session
- (user) has some privilege to perform some operation * The <emphasis
- role="bold">Action</emphasis> which sets the thread local <emphasis
- role="bold">Invocation Context</emphasis> at runtime. This invocation
- context is used by the Extended Access Manager to make a decision about
- the current Session's permission * <emphasis role="bold">Invocation
- Context</emphasis> is a collection of properties which reflect the state
- of a current Session. For the time being it contains: the type of the
- current operation on Session (event), current Item (javax.jcr.Item) on
- which this operation is performed and the current eXo Container</para>
+ <para>An extended Access Control system consists of:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Specifically configured custom <emphasis role="bold">Extended
+ Access Manager</emphasis> which is called by eXo JCR internals to
+ check if some user's Session (user) has some privilege to perform some
+ operation</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis role="bold">Action</emphasis> which sets the
+ thread local <emphasis role="bold">Invocation Context</emphasis> at
+ runtime. This invocation context is used by the Extended Access
+ Manager to make a decision about the current Session's
+ permission</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Invocation Context</emphasis> is a
+ collection of properties which reflect the state of a current Session.
+ For the time being it contains: the type of the current operation on
+ Session (event), current Item (javax.jcr.Item) on which this operation
+ is performed and the current eXo Container</para>
+ </listitem>
+ </itemizedlist>
</section>
<section>
@@ -148,7 +163,6 @@
return false;
}
}
-}
-</programlisting>
+}</programlisting>
</section>
</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,13 +3,14 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.AccessControl">
<?dbhtml filename="ch-acl.html"?>
+
<title>Access Control</title>
<para>eXo JCR is a complete implementation of the standard JSR 170: <ulink
- url="Content Repository for Java TM Technology API > http://jcp.org/en/jsr/detail?id=170">Content
- Repository for Java TM Technology API</ulink>, including <emphasis
- role="bold">Level 1, Level 2 and Additional Features</emphasis> as is
- specified in the JCR Specification.</para>
+ url="http://jcp.org/en/jsr/detail?id=170">Content Repository for Java TM
+ Technology API</ulink>, including <emphasis role="bold">Level 1, Level 2 and
+ Additional Features</emphasis> as is specified in the JCR
+ Specification.</para>
<section>
<title>Standard Action Permissions</title>
@@ -282,8 +283,8 @@
repository to auto-create <emphasis
role="bold">exo:privilegeable</emphasis> or/and <emphasis
role="bold">exo:owneable</emphasis> thanks to eXo's JCR interceptors
- extension (see <ulink
- url="http://wiki.exoplatform.org/xwiki/bin/view/JCR/JCR+Extensions">http://wiki.exoplatform.org/xwiki/bin/view/JCR/JCR+Extensions</ulink>)</para>
+ extension (see <link linkend="JCR.Extensions">JCR
+ Extensions</link>)</para>
<para><emphasis role="bold">OR-based Privilege Inheritance</emphasis>
Note, that eXo's Access Control implementation supports an privilege
@@ -304,10 +305,12 @@
<para>In the following example, you see a node named "Politics" which
contains two nodes named "Cats" and "Dogs".</para>
- <para>#info("These examples are exported from eXo DMS using the
- \"document view\" representation of JCR. Each value of a multivalue
- property is separated by a whitespace, each whitespace is escaped by
- <emphasis>x0020</emphasis>.")</para>
+ <note>
+ <para>These examples are exported from eXo DMS using the \"document
+ view\" representation of JCR. Each value of a multivalue property is
+ separated by a whitespace, each whitespace is escaped by
+ <emphasis>x0020</emphasis>.</para>
+ </note>
<programlisting><Politics jcr:primaryType="nt:unstructured" jcr:mixinTypes="exo:owneable exo:datetime exo:privilegeable" exo:dateCreated="2009-10-08T18:02:43.687+02:00"
exo:dateModified="2009-10-08T18:02:43.703+02:00"
@@ -374,7 +377,7 @@
<mediaobject>
<imageobject>
- <imagedata fileref="images/other.acl.gif" />
+ <imagedata fileref="images/other/acl.gif" />
</imageobject>
</mediaobject>
</section>
@@ -387,19 +390,69 @@
interface provides additional methods for Access Control
management.</para>
- <para>{table} Method signature |Description void
- setPermissions(Map\<String, String\ <ulink url="\">\</ulink>\>
- permissions)| Assigns a set of Permissions to a node void
- setPermission(String identity, String\ <ulink url="\">\</ulink>
- permission)| Assigns some Identity's Permission to a node void
- removePermission(String identity)| Remove Identity's Permission void
- removePermission(String identity, String permission)|Remove the
- specified permission for a particular identity void clearACL()| Clears
- the current ACL so it becomes default AccessControlList getACL()|
- Returns the current ACL void checkPermission(String actions)| Checks
- Permission (AccessDeniedException will be thrown if denied)
- {table}</para>
+ <table>
+ <title>Additional methods</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Method signature</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>void setPermissions(Map<String, String[]>
+ permissions)</entry>
+
+ <entry>Assigns a set of Permissions to a node</entry>
+ </row>
+
+ <row>
+ <entry>void setPermission(String identity, String[]
+ permission)</entry>
+
+ <entry>Assigns some Identity's Permission to a node</entry>
+ </row>
+
+ <row>
+ <entry>void removePermission(String identity)</entry>
+
+ <entry>Remove Identity's Permission</entry>
+ </row>
+
+ <row>
+ <entry>void removePermission(String identity, String
+ permission)</entry>
+
+ <entry>Remove the specified permission for a particular
+ identity</entry>
+ </row>
+
+ <row>
+ <entry>void clearACL()</entry>
+
+ <entry>Clears the current ACL so it becomes default</entry>
+ </row>
+
+ <row>
+ <entry>AccessControlList getACL()</entry>
+
+ <entry>Returns the current ACL</entry>
+ </row>
+
+ <row>
+ <entry>void checkPermission(String actions)</entry>
+
+ <entry>Checks Permission (AccessDeniedException will be thrown
+ if denied)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
<para>The "identity" parameter is the user or group name. The
permissions are the literal strings of the standard action permissions
(add_node, set_property, remove, read.</para>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.BinaryValuesProcessing">
<?dbhtml filename="ch-binary-values-processing.html"?>
+
<title>Binary Values Processing</title>
<section>
@@ -28,17 +29,15 @@
<note>
<para>eXo JCR Repository service configuration basics is discussed in
- <ulink
- url="Configuration>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Configura...">Configuration</ulink></para>
+ <link linkend="JCR.eXoJCRconfiguration">Configuration</link></para>
<para>Database and workspace persistence storage configuration is
- discussed in <ulink
- url="http://wiki.exoplatform.com/xwiki/bin/view/JCR/JDBC+Data+Container+config">JDBC
- Data Container config</ulink></para>
+ discussed in <link linkend="JCR.JDBCDataContainerConfig">JDBC Data
+ Container config</link></para>
- <para>Configuration details for <ulink
- url="http://wiki.exoplatform.com/xwiki/bin/view/JCR/External+Value+Storages">External
- Value Storages</ulink>.</para>
+ <para>Configuration details for <link
+ linkend="JCR.ExternalValueStorages">External Value
+ Storages</link>.</para>
</note>
</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.Organizationservice">
<?dbhtml filename="ch-jcr-organization-service.html"?>
+
<title>JCR Organization service</title>
<para>This is an implementation of the exo.core.component.organization.api
@@ -59,7 +60,7 @@
storage will be created<br> storage-path - the relative path to the
stored data<br></para>
- <para>You should also read how to use the <ulink
- url="Core.Organization Service Initializer">Core.Organization Service
- Initializer</ulink>.</para>
+ <para>You should also read how to use the <link
+ linkend="Core.OrganizationServiceInitializer">Organization Service
+ Initializer</link>.</para>
</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.LinkProducerService">
<?dbhtml filename="ch-link-producer.html"?>
+
<title>Link Producer Service</title>
<para>Link Producer Service - a simple service, which generates an .lnk
@@ -19,17 +20,15 @@
</component></programlisting>
<para>When using JCR the resource can be addressed by WebDav reference
- (href) like <emphasis role="bold"> <ulink
- url="http://host:port/rest/jcr/repository/workspace/somenode/somefile.extention">http://host:port/rest/jcr/repository/workspace/somenode/somefile.extention</ulink>
- </emphasis>, the link servlet must be called for this resource by several
- hrefs, like <emphasis role="bold"> <ulink
- url="http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...">http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...</ulink>
- </emphasis></para>
+ (href) like
+ <uri>http://host:port/rest/jcr/repository/workspace/somenode/somefile.extention</uri>
+ , the link servlet must be called for this resource by several hrefs, like
+ <uri>http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...</uri>
+ </para>
<para>Please note, that when using the portal mode the REST servlet is
- available using a reference (href) like <emphasis role="bold"> <ulink
- url="http://localhost:8080/portal/rest/">http://localhost:8080/portal/rest/</ulink>...
- </emphasis></para>
+ available using a reference (href) like
+ <uri>http://localhost:8080/portal/rest/...</uri></para>
<para>The name of the .lnk file can be any. But for the best compatibility
it must be the same as the name of the JCR resource.</para>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -3,13 +3,18 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.WebDAV">
<?dbhtml filename="ch-webdav.html"?>
+
<title>WebDAV</title>
<section>
<title>Related documents</title>
- <para>* Link Producer * Microsoft Office plugin * Open Office Add-On *
- WebDav Client Libraries</para>
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.LinkProducerService">Link
+ Producer</link></para>
+ </listitem>
+ </itemizedlist>
</section>
<section>
@@ -39,22 +44,20 @@
<para>Standalone mode:</para>
- <para><ulink
- url="http://host:port/rest/jcr/">http://host:port/rest/jcr/</ulink>{RepositoryName}/{WorkspaceName}/{Path}</para>
+ <para><uri>http://host:port/rest/jcr/{RepositoryName}/{WorkspaceName}/{Path}</uri></para>
<para>Portal mode:</para>
- <para><ulink
- url="http://host:port/portal/rest/private/jcr/">http://host:port/portal/rest/private/jcr/</ulink>{RepositoryName}/{WorkspaceName}/{Path}</para>
+ <para><uri>http://host:port/portal/rest/private/jcr/{RepositoryName}/{WorkspaceName}...</uri></para>
- <para>When accessing the WebDAV server - here URL is <ulink
- url="http://localhost:8080/rest/jcr/repository/production">http://localhost:8080/rest/jcr/repository/production</ulink>,
- you might also use "collaboration" (instead of "production") which is the
- default workspace in eXo products - the user will be asked to enter his
- login and password. Those will then be checked using the organization
- service (that can be implemented thanks to an Inmemory(dummy) module or DB
- module or LDAP one) and the JCR user session will be created with the
- correct JCR Credentials.</para>
+ <para>When accessing the WebDAV server - here URL is
+ <uri>http://localhost:8080/rest/jcr/repository/production</uri>, you might
+ also use "collaboration" (instead of "production") which is the default
+ workspace in eXo products - the user will be asked to enter his login and
+ password. Those will then be checked using the organization service (that
+ can be implemented thanks to an Inmemory(dummy) module or DB module or
+ LDAP one) and the JCR user session will be created with the correct JCR
+ Credentials.</para>
<para><emphasis role="bold">NOTE:</emphasis> If you try the "in ECM"
option, add "@ecm" to the user's password. Alternatively, you may modify
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/statistics.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/statistics.xml 2010-08-05 06:58:25 UTC (rev 2877)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/statistics.xml 2010-08-05 08:52:15 UTC (rev 2878)
@@ -229,24 +229,24 @@
<para><emphasis>exo.jcr.component.statistics-X.Y.Z</emphasis>.jar
corresponding to your eXo JCR version that you can get from the jboss
maven repository <ulink
- url="???"><uri>http://repository.jboss.com/maven2/org/exoplatform/jcr/exo.jcr.component....</uri></ulink>.</para>
+ url="http://repository.jboss.com/maven2/org/exoplatform/jcr/exo.jcr.component....">http://repository.jboss.com/maven2/org/exoplatform/jcr/exo.jcr.component....</ulink>.</para>
</listitem>
<listitem>
<para>aspectjrt-1.6.8.jar that you can get from the main maven
repository <ulink
- url="???"><uri>http://repo2.maven.org/maven2/org/aspectj/aspectjrt</uri></ulink>.</para>
+ url="http://repo2.maven.org/maven2/org/aspectj/aspectjrt"><uri>http://repo2.maven.org/maven2/org/aspectj/aspectjrt</uri></ulink>.</para>
</listitem>
</itemizedlist>
<para>You will also need to get aspectjweaver-1.6.8.jar from the main
maven repository <ulink
- url="???">http://repo2.maven.org/maven2/org/aspectj/aspectjweaver</ulink>.
+ url="http://repo2.maven.org/maven2/org/aspectj/aspectjweaver">http://repo2.maven.org/maven2/org/aspectj/aspectjweaver</ulink>.
At this stage, to enable the statistics on the JCR API accesses, you will
need to add the JVM parameter
<emphasis>-javaagent:${pathto}/aspectjweaver-1.6.8.jar</emphasis> to your
command line, for more details please refer to <ulink
- url="???">http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html</ulink>.</para>
+ url="http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html">http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html</ulink>.</para>
<para>By default, the configuration will collect statistcs on all the
methods of the internal interfaces
15 years, 11 months
exo-jcr SVN: r2877 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-05 02:58:25 -0400 (Thu, 05 Aug 2010)
New Revision: 2877
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/and-constraint.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-all-nodes.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
Log:
EXOJCR-869: link fixes
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/and-constraint.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/and-constraint.xml 2010-08-04 15:22:05 UTC (rev 2876)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/and-constraint.xml 2010-08-05 06:58:25 UTC (rev 2877)
@@ -11,7 +11,7 @@
whose "prop_pagecount" property value is less than 90.</para>
<note>
- <para>See also <link linkend="JCR.MultiValuePropertyComparison">Multivalue
+ <para>See also <link linkend="JCR.MultivaluePropertyComparison">Multivalue
Property Comparison</link>.</para>
</note>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-all-nodes.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-all-nodes.xml 2010-08-04 15:22:05 UTC (rev 2876)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-all-nodes.xml 2010-08-05 06:58:25 UTC (rev 2877)
@@ -5,8 +5,8 @@
<title>Find All Nodes</title>
<para>Find all nodes in the repository. Only those nodes are found to which
- the session has READ permission. See also <ulink
- url="JCR.AccessControl">Access Control</ulink>.</para>
+ the session has READ permission. See also <link
+ linkend="JCR.AccessControl">Access Control</link>.</para>
<section>
<title>Repository structure:</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-04 15:22:05 UTC (rev 2876)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-05 06:58:25 UTC (rev 2877)
@@ -1,414 +1,414 @@
-<?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="JCR.QueryUsecases">
- <?dbhtml filename="ch-jcr-query-usecases.html"?>
-
- <title>JCR Query Usecases</title>
-
- <section>
- <title>Intro</title>
-
- <para>JCR supports two query languages - JCR and XPath. A query, whether
- XPath or SQL, specifies a subset of nodes within a workspace, called the
- result set. The result set constitutes all the nodes in the workspace that
- meet the constraints stated in the query.</para>
- </section>
-
- <section>
- <title>Query Lifecycle</title>
-
- <section>
- <title>Query Creation and Execution</title>
-
- <para><emphasis role="bold">SQL</emphasis></para>
-
- <programlisting>// get QueryManager
-QueryManager queryManager = workspace.getQueryManager();
-// make SQL query
-Query query = queryManager.createQuery("SELECT * FROM nt:base ", Query.SQL);
-// execute query
-QueryResult result = query.execute();</programlisting>
-
- <para><emphasis role="bold">XPath</emphasis></para>
-
- <programlisting>// get QueryManager
-QueryManager queryManager = workspace.getQueryManager();
-// make XPath query
-Query query = queryManager.createQuery("//element(*,nt:base)", Query.XPATH);
-// execute query
-QueryResult result = query.execute();</programlisting>
- </section>
-
- <section>
- <title>Query Result Processing</title>
-
- <programlisting>// fetch query result
-QueryResult result = query.execute();</programlisting>
-
- <para>Now we can get result in an iterator of nodes:</para>
-
- <programlisting>NodeIterator it = result.getNodes();</programlisting>
-
- <para>or we get the result in a table:</para>
-
- <programlisting>// get column names
-String[] columnNames = result.getColumnNames();
-// get column rows
-RowIterator rowIterator = result.getRows();
-while(rowIterator.hasNext()){
- // get next row
- Row row = rowIterator.nextRow();
- // get all values of row
- Value[] values = row.getValues();
-}</programlisting>
- </section>
-
- <section>
- <title>Scoring</title>
-
- <para>The result returns a score for each row in the result set. The
- score contains a value that indicates a rating of how well the result
- node matches the query. A high value means a better matching than a low
- value. This score can be used for ordering the result.</para>
-
- <para>eXo JCR Scoring is a mapping of Lucene scoring. For a more
- in-depth understanding, please study <ulink
- url="http://lucene.apache.org/java/2_4_1/scoring.html">Lucene
- documentation</ulink>.</para>
-
- <para>jcr:score counted in next way - (lucene score)*1000f.</para>
-
- <para>Score may be increased for specified nodes, see <ulink
- url="Index Boost Value">Index Boost Value</ulink></para>
-
- <para>Also, see an example <link linkend="JCR.OrderByScore">Order by
- Score</link></para>
- </section>
- </section>
-
- <section>
- <title>Query result settings</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.SetOffsetandSetLimit">Set Offset And
- Limit</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Type Constraints</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.FindAllNodes">Find All Nodes</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesByPrimaryType">Find Nodes by Primary
- Type</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesByMixinType">Find Nodes by Mixin
- Type</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Property Constraints</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.PropertyComparison">Property
- Comparison</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.LIKEConstraint">LIKE Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.EscapinginLIKEStatements">Escaping in LIKE
- Statements</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.NOTConstraint">NOT Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ANDConstraint">AND Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ORConstraint">OR Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.PropertyExistenceConstraint">Property
- Existence Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesCaseInsensitive">Upper and Lower
- Case Constraints</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.DatePropertyComparison">Date Property
- Comparison</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.NodeNameConstraint">Node Name
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.MultivaluePropertyComparison">Multivalue
- Property Comparison</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Path Constraint</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.ExactPathConstraint">Exact Path
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ChildNodeConstraint">Child Node
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindAllDescendantNodes">Find All Descendant
- Nodes</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Ordering specifing</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.OrderByProperty">Order by
- Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByDescendant">Order by Descendant Node
- Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByScore">Order by Score</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByPathOrName">Order by Path or
- Name</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title><link linkend="JCR.FulltextSearchAndSettings">Fulltext
- Search</link></title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.FulltextSearchByProperty">Fulltext Search by
- Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FulltextSearchByAllProperties">Fulltext
- Search by All Properties</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.AggregationRule">Find nt:file document by
- content of child jcr:content node</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.IgnoreAccentSymbols">How to set new Analyzer.
- Accent symblos ignoring</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Indexing rules and additional features</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.AggregationRule">Aggregation
- rule</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.HiglightResultofFulltextSearch">Search Result
- Highlighting</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.IndexBoostRule">Index Boost
- Value</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.NodeScopeIndex">Exclusion from the Node Scope
- Index</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.RegexpIndexingRule">Regular expressions as
- property name in indexing rule</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.SynonimProvider">Synonim
- Provider</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.SpellChecker">Spell Checking</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindSimilarNodes">Find Similar
- Nodes</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Query Examples</title>
-
- <xi:include href="offset-and-limit.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-all-nodes.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-nodes-by-primary-type.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-nodes-by-mixin-type.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="property-comparison.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="like-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="escaping-like-statements.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="not-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="and-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="or-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="property-existance-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-nodes-case-insensitive.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="date-property-comparison.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="node-name-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="multivalue-property-comparison.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="exact-path-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="child-node-constraint.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-all-descendant-nodes.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="order-by-property.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="order-by-descendant.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="order-by-score.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="order-by-path-or-name.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="fulltext-search-by-property.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="fulltext-search-by-all-properties.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ignore-accent-symbols.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="aggregation-rule.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="index-boost-value.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="node-scope-index.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="regexp-indexing-rule.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="higlight.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="synonim-provider.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="regexp-indexing-rule.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="spell-checker.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="find-similar-nodes.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
- </section>
-
- <section>
- <title>Tips and tricks</title>
-
- <xi:include href="tip-nodename-with-number.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <!--itemizedlist>
- <listitem>
- <para><link linkend="JCR.TipNodeNameWithNumber">Xpath and numbers in
- node names</link></para>
- </listitem>
- </itemizedlist-->
- </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="JCR.QueryUsecases">
+ <?dbhtml filename="ch-jcr-query-usecases.html"?>
+
+ <title>JCR Query Usecases</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>JCR supports two query languages - JCR and XPath. A query, whether
+ XPath or SQL, specifies a subset of nodes within a workspace, called the
+ result set. The result set constitutes all the nodes in the workspace that
+ meet the constraints stated in the query.</para>
+ </section>
+
+ <section>
+ <title>Query Lifecycle</title>
+
+ <section>
+ <title>Query Creation and Execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make SQL query
+Query query = queryManager.createQuery("SELECT * FROM nt:base ", Query.SQL);
+// execute query
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make XPath query
+Query query = queryManager.createQuery("//element(*,nt:base)", Query.XPATH);
+// execute query
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Query Result Processing</title>
+
+ <programlisting>// fetch query result
+QueryResult result = query.execute();</programlisting>
+
+ <para>Now we can get result in an iterator of nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();</programlisting>
+
+ <para>or we get the result in a table:</para>
+
+ <programlisting>// get column names
+String[] columnNames = result.getColumnNames();
+// get column rows
+RowIterator rowIterator = result.getRows();
+while(rowIterator.hasNext()){
+ // get next row
+ Row row = rowIterator.nextRow();
+ // get all values of row
+ Value[] values = row.getValues();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Scoring</title>
+
+ <para>The result returns a score for each row in the result set. The
+ score contains a value that indicates a rating of how well the result
+ node matches the query. A high value means a better matching than a low
+ value. This score can be used for ordering the result.</para>
+
+ <para>eXo JCR Scoring is a mapping of Lucene scoring. For a more
+ in-depth understanding, please study <ulink
+ url="http://lucene.apache.org/java/2_4_1/scoring.html">Lucene
+ documentation</ulink>.</para>
+
+ <para>jcr:score counted in next way - (lucene score)*1000f.</para>
+
+ <para>Score may be increased for specified nodes, see <link
+ linkend="JCR.IndexBoostRule">Index Boost Value</link></para>
+
+ <para>Also, see an example <link linkend="JCR.OrderByScore">Order by
+ Score</link></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Query result settings</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.SetOffsetandSetLimit">Set Offset And
+ Limit</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Type Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.FindAllNodes">Find All Nodes</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesByPrimaryType">Find Nodes by Primary
+ Type</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesByMixinType">Find Nodes by Mixin
+ Type</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Property Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.PropertyComparison">Property
+ Comparison</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.LIKEConstraint">LIKE Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.EscapinginLIKEStatements">Escaping in LIKE
+ Statements</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NOTConstraint">NOT Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ANDConstraint">AND Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ORConstraint">OR Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.PropertyExistenceConstraint">Property
+ Existence Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesCaseInsensitive">Upper and Lower
+ Case Constraints</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.DatePropertyComparison">Date Property
+ Comparison</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NodeNameConstraint">Node Name
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.MultivaluePropertyComparison">Multivalue
+ Property Comparison</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Path Constraint</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.ExactPathConstraint">Exact Path
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ChildNodeConstraint">Child Node
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindAllDescendantNodes">Find All Descendant
+ Nodes</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Ordering specifing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.OrderByProperty">Order by
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByDescendant">Order by Descendant Node
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByScore">Order by Score</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByPathOrName">Order by Path or
+ Name</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title><link linkend="JCR.FulltextSearchAndSettings">Fulltext
+ Search</link></title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByProperty">Fulltext Search by
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByAllProperties">Fulltext
+ Search by All Properties</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.AggregationRule">Find nt:file document by
+ content of child jcr:content node</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.IgnoreAccentSymbols">How to set new Analyzer.
+ Accent symblos ignoring</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Indexing rules and additional features</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.AggregationRule">Aggregation
+ rule</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.HiglightResultofFulltextSearch">Search Result
+ Highlighting</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.IndexBoostRule">Index Boost
+ Value</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NodeScopeIndex">Exclusion from the Node Scope
+ Index</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.RegexpIndexingRule">Regular expressions as
+ property name in indexing rule</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SynonimProvider">Synonim
+ Provider</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SpellChecker">Spell Checking</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindSimilarNodes">Find Similar
+ Nodes</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query Examples</title>
+
+ <xi:include href="offset-and-limit.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-all-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-by-primary-type.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-by-mixin-type.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="like-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="escaping-like-statements.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="not-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="and-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="or-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="property-existance-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-case-insensitive.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="date-property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="node-name-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="multivalue-property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="exact-path-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="child-node-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-all-descendant-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-property.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-descendant.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-score.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-path-or-name.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="fulltext-search-by-property.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="fulltext-search-by-all-properties.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="ignore-accent-symbols.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="aggregation-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="index-boost-value.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="node-scope-index.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="regexp-indexing-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="higlight.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="synonim-provider.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="regexp-indexing-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="spell-checker.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-similar-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </section>
+
+ <section>
+ <title>Tips and tricks</title>
+
+ <xi:include href="tip-nodename-with-number.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!--itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.TipNodeNameWithNumber">Xpath and numbers in
+ node names</link></para>
+ </listitem>
+ </itemizedlist-->
+ </section>
+</chapter>
15 years, 11 months
exo-jcr SVN: r2876 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-04 11:22:05 -0400 (Wed, 04 Aug 2010)
New Revision: 2876
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbosscache-configuration-templates.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbossts-transaction-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/query-handler-config.xml
Log:
EXOJCR-869: link fixes
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml 2010-08-04 15:01:37 UTC (rev 2875)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml 2010-08-04 15:22:05 UTC (rev 2876)
@@ -1,270 +1,269 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.ClusterConfig">
- <?dbhtml filename="ch-cluster-config.html"?>
-
- <title>Configuring JBoss AS with eXo JCR in cluster</title>
-
- <section>
- <title>Launching Cluster</title>
-
- <section>
- <title>Deploying eXo JCR to JBoss As</title>
-
- <para>To deploy eXo JCR to JBoss As follow next steps:</para>
-
- <orderedlist>
- <listitem>
- <para>Dowload the latest version of eXo JCR ear distribution.</para>
- </listitem>
-
- <listitem>
- <para>Copy <jcr.ear> into
- <%jboss_home%/server/default/deploy></para>
- </listitem>
-
- <listitem>
- <para>Put exo-configuration.xml to the root
- <%jboss_home%/exo-configuration.xml></para>
- </listitem>
-
- <listitem>
- <para>Configure JAAS by inserting XML fragment shown below into
- <%jboss_home%/server/default/conf/login-config.xml></para>
-
- <programlisting><application-policy name="exo-domain">
- <authentication>
- <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required"></login-module>
- </authentication>
-</application-policy></programlisting>
- </listitem>
-
- <listitem>
- <para>Ensure that you use JBossTS <link
- linkend="ch_transaction_service">Transaction Service</link> and
- JBossCache <link
- linkend="ch-jbossts-tranasction-service">Transaction Manager</link>.
- Your exo-configuration.xml must contain such parts:</para>
-
- <programlisting><component>
- <key>org.jboss.cache.transaction.TransactionManagerLookup</key>
- <type>org.jboss.cache.GenericTransactionManagerLookup</type>^
-</component>
-
-<component>
- <key>org.exoplatform.services.transaction.TransactionService</key>
- <type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
- <init-params>
- <value-param>
- <name>timeout</name>
- <value>300</value>
- </value-param>
- </init-params>
-</component></programlisting>
- </listitem>
-
- <listitem>
- <para>Start server:</para>
-
- <itemizedlist>
- <listitem>
- <para>bin/run.sh for Unix</para>
- </listitem>
-
- <listitem>
- <para>bin/run.bat for Windows</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Try accessing <ulink
- url="http://localhost:8080/browser">http://localhost:8080/browser</ulink>
- with root/exo as login/password if you have done everything right,
- you'll get access to repository browser.</para>
- </listitem>
- </orderedlist>
- </section>
-
- <section id="JCR.ClusterConfig.JCRExternalConfig">
- <title>Configuring JCR to use external configuration</title>
-
- <itemizedlist>
- <listitem>
- <para>To manually configure repository create a new configuration
- file (f.e. exo-jcr-configuration.xml). For details see <ulink
- url="http://wiki.exoplatform.org/xwiki/bin/view/JCR/#HConfiguration">JCR
- Configuration</ulink>. Your configuration must look like:</para>
-
- <programlisting><repository-service default-repository="repository1">
- <repositories>
- <repository name="repository1" system-workspace="ws1" default-workspace="ws1">
- <security-domain>exo-domain</security-domain>
- <access-control>optional</access-control>
- <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
- <workspaces>
- <workspace name="ws1">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="oracle" />
- <property name="multi-db" value="false" />
- <property name="update-storage" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="../temp/swap/production" />
- </properties>
- <value-storages>
- see "<link linkend="conf_value_storage">Value storage configuration</link>" part.
- </value-storages>
- </container>
- <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
- <properties>
- <property name="root-nodetype" value="nt:unstructured" />
- </properties>
- </initializer>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
- see "<link linkend="conf_cache">Cache configuration</link>" part.
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- see "<link linkend="conf_indexer">Indexer configuration</link>" part.
- </query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- see "<link linkend="conf_lock_manager">Lock Manager configuration</link>" part.
- </lock-manager>
- </workspace>
- <workspace name="ws2">
- ...
- </workspace>
- <workspace name="wsN">
- ...
- </workspace>
- </workspaces>
- </repository>
- </repositories>
-</repository-service> </programlisting>
- </listitem>
-
- <listitem>
- <para>and update RepositoryServiceConfiguration configuration in
- exo-configuration.xml to use this file:<programlisting><component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR configuration file</description>
- <value>exo-jcr-configuration.xml</value>
- </value-param>
- </init-params>
-</component></programlisting></para>
- </listitem>
- </itemizedlist>
- </section>
- </section>
-
- <section>
- <title>Requirements</title>
-
- <section>
- <title>Enviorenment requirements</title>
-
- <itemizedlist>
- <listitem>
- <para>Every node of cluster MUST have the same mounted Network File
- System with read and write permissions on it.</para>
-
- <para>"/mnt/tornado" - path to the mounted Network File System (all
- cluster nodes must use the same NFS)</para>
- </listitem>
-
- <listitem>
- <para>Every node of cluster MUST use the same database</para>
- </listitem>
-
- <listitem>
- <para>Same Clusters on different nodes MUST have the same cluster
- names (f.e if Indexer cluster in workspace production on the first
- node has name "production_indexer_cluster", then indexer clusters in
- workspace production on all other nodes MUST have the same name
- "production_indexer_cluster" )</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Enviorenment requirements</title>
-
- <para>Configuration of every workspace in repository must contains of
- such parts:</para>
-
- <itemizedlist>
- <listitem id="conf_value_storage">
- <para>Value Storage configuration:</para>
-
- <programlisting><value-storages>
- <value-storage id="system" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="/mnt/tornado/temp/values/production" /> <!--path within NFS where ValueStorage will hold it's data-->
- </properties>
- <filters>
- <filter property-type="Binary" />
- </filters>
- </value-storage>
-</value-storages></programlisting>
- </listitem>
-
- <listitem id="conf_cache">
- <para>Cache configuration:</para>
-
- <programlisting><cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
- <properties>
- <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-data.xml" /> <!-- path to JBoss Cache configuration for data storage -->
- <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
- <property name="jbosscache-cluster-name" value="JCR_Cluster_cache_production" /> <!-- JBoss Cache data storage cluster name -->
- <property name="jgroups-multiplexer-stack" value="true" />
- </properties>
-</cache> </programlisting>
- </listitem>
-
- <listitem id="conf_indexer">
- <para>Indexer configuration:</para>
-
- <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
- <property name="index-dir" value="/mnt/tornado/temp/jcrlucenedb/production" /> <!-- path within NFS where ValueStorage will hold it's data -->
- <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-indexer.xml" /> <!-- path to JBoss Cache configuration for indexer -->
- <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
- <property name="jbosscache-cluster-name" value="JCR_Cluster_indexer_production" /> <!-- JBoss Cache indexer cluster name -->
- <property name="jgroups-multiplexer-stack" value="true" />
- </properties>
-</query-handler> </programlisting>
- </listitem>
-
- <listitem id="conf_lock_manager">
- <para>Lock Manager configuration:</para>
-
- <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- <properties>
- <property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-lock.xml" /> <!-- path to JBoss Cache configuration for lock manager -->
- <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
- <property name="jgroups-multiplexer-stack" value="true" />
- <property name="jbosscache-cluster-name" value="JCR_Cluster_lock_production" /> <!-- JBoss Cache locks cluster name -->
-
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_production"/> <!-- the name of the DB table where lock's data will be stored -->
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true"/>
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false"/>
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_production_pk"/>
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn"/>
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node"/>
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent"/>
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr"/>
- </properties>
-</lock-manager></programlisting>
- </listitem>
- </itemizedlist>
- </section>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.ClusterConfig">
+ <?dbhtml filename="ch-cluster-config.html"?>
+
+ <title>Configuring JBoss AS with eXo JCR in cluster</title>
+
+ <section>
+ <title>Launching Cluster</title>
+
+ <section>
+ <title>Deploying eXo JCR to JBoss As</title>
+
+ <para>To deploy eXo JCR to JBoss As follow next steps:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Dowload the latest version of eXo JCR ear distribution.</para>
+ </listitem>
+
+ <listitem>
+ <para>Copy <jcr.ear> into
+ <%jboss_home%/server/default/deploy></para>
+ </listitem>
+
+ <listitem>
+ <para>Put exo-configuration.xml to the root
+ <%jboss_home%/exo-configuration.xml></para>
+ </listitem>
+
+ <listitem>
+ <para>Configure JAAS by inserting XML fragment shown below into
+ <%jboss_home%/server/default/conf/login-config.xml></para>
+
+ <programlisting><application-policy name="exo-domain">
+ <authentication>
+ <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required"></login-module>
+ </authentication>
+</application-policy></programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Ensure that you use JBossTS <link
+ linkend="Kernel.TransactionService">Transaction Service</link> and
+ JBossCache <link linkend="JCR.JBossTransactionsService">Transaction
+ Manager</link>. Your exo-configuration.xml must contain such
+ parts:</para>
+
+ <programlisting><component>
+ <key>org.jboss.cache.transaction.TransactionManagerLookup</key>
+ <type>org.jboss.cache.GenericTransactionManagerLookup</type>^
+</component>
+
+<component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>300</value>
+ </value-param>
+ </init-params>
+</component></programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Start server:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>bin/run.sh for Unix</para>
+ </listitem>
+
+ <listitem>
+ <para>bin/run.bat for Windows</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Try accessing <uri>http://localhostu:8080/browser</uri> with
+ root/exo as login/password if you have done everything right, you'll
+ get access to repository browser.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section id="JCR.ClusterConfig.JCRExternalConfig">
+ <title>Configuring JCR to use external configuration</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>To manually configure repository create a new configuration
+ file (f.e. exo-jcr-configuration.xml). For details see <link
+ linkend="JCR.eXoJCRconfiguration">JCR Configuration</link>. Your
+ configuration must look like:</para>
+
+ <programlisting><repository-service default-repository="repository1">
+ <repositories>
+ <repository name="repository1" system-workspace="ws1" default-workspace="ws1">
+ <security-domain>exo-domain</security-domain>
+ <access-control>optional</access-control>
+ <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+ <workspaces>
+ <workspace name="ws1">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="oracle" />
+ <property name="multi-db" value="false" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="../temp/swap/production" />
+ </properties>
+ <value-storages>
+ see "<link linkend="conf_value_storage">Value storage configuration</link>" part.
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ see "<link linkend="conf_cache">Cache configuration</link>" part.
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ see "<link linkend="conf_indexer">Indexer configuration</link>" part.
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ see "<link linkend="conf_lock_manager">Lock Manager configuration</link>" part.
+ </lock-manager>
+ </workspace>
+ <workspace name="ws2">
+ ...
+ </workspace>
+ <workspace name="wsN">
+ ...
+ </workspace>
+ </workspaces>
+ </repository>
+ </repositories>
+</repository-service> </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>and update RepositoryServiceConfiguration configuration in
+ exo-configuration.xml to use this file:<programlisting><component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>exo-jcr-configuration.xml</value>
+ </value-param>
+ </init-params>
+</component></programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>Requirements</title>
+
+ <section>
+ <title>Enviorenment requirements</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Every node of cluster MUST have the same mounted Network File
+ System with read and write permissions on it.</para>
+
+ <para>"/mnt/tornado" - path to the mounted Network File System (all
+ cluster nodes must use the same NFS)</para>
+ </listitem>
+
+ <listitem>
+ <para>Every node of cluster MUST use the same database</para>
+ </listitem>
+
+ <listitem>
+ <para>Same Clusters on different nodes MUST have the same cluster
+ names (f.e if Indexer cluster in workspace production on the first
+ node has name "production_indexer_cluster", then indexer clusters in
+ workspace production on all other nodes MUST have the same name
+ "production_indexer_cluster" )</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Enviorenment requirements</title>
+
+ <para>Configuration of every workspace in repository must contains of
+ such parts:</para>
+
+ <itemizedlist>
+ <listitem id="conf_value_storage">
+ <para>Value Storage configuration:</para>
+
+ <programlisting><value-storages>
+ <value-storage id="system" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="/mnt/tornado/temp/values/production" /> <!--path within NFS where ValueStorage will hold it's data-->
+ </properties>
+ <filters>
+ <filter property-type="Binary" />
+ </filters>
+ </value-storage>
+</value-storages></programlisting>
+ </listitem>
+
+ <listitem id="conf_cache">
+ <para>Cache configuration:</para>
+
+ <programlisting><cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-data.xml" /> <!-- path to JBoss Cache configuration for data storage -->
+ <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
+ <property name="jbosscache-cluster-name" value="JCR_Cluster_cache_production" /> <!-- JBoss Cache data storage cluster name -->
+ <property name="jgroups-multiplexer-stack" value="true" />
+ </properties>
+</cache> </programlisting>
+ </listitem>
+
+ <listitem id="conf_indexer">
+ <para>Indexer configuration:</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ <property name="index-dir" value="/mnt/tornado/temp/jcrlucenedb/production" /> <!-- path within NFS where ValueStorage will hold it's data -->
+ <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-indexer.xml" /> <!-- path to JBoss Cache configuration for indexer -->
+ <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
+ <property name="jbosscache-cluster-name" value="JCR_Cluster_indexer_production" /> <!-- JBoss Cache indexer cluster name -->
+ <property name="jgroups-multiplexer-stack" value="true" />
+ </properties>
+</query-handler> </programlisting>
+ </listitem>
+
+ <listitem id="conf_lock_manager">
+ <para>Lock Manager configuration:</para>
+
+ <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="jar:/conf/portal/test-jbosscache-lock.xml" /> <!-- path to JBoss Cache configuration for lock manager -->
+ <property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /> <!-- path to JGroups configuration -->
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR_Cluster_lock_production" /> <!-- JBoss Cache locks cluster name -->
+
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_production"/> <!-- the name of the DB table where lock's data will be stored -->
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true"/>
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false"/>
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_production_pk"/>
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn"/>
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node"/>
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent"/>
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr"/>
+ </properties>
+</lock-manager></programlisting>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbosscache-configuration-templates.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbosscache-configuration-templates.xml 2010-08-04 15:01:37 UTC (rev 2875)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbosscache-configuration-templates.xml 2010-08-04 15:22:05 UTC (rev 2876)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.JBossCacheConfiguration">
+<chapter id="JCR.JBossCacheConfigurationTemplates">
<?dbhtml filename="ch-jbosscache-configuration-templates.html"?>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbossts-transaction-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbossts-transaction-service.xml 2010-08-04 15:01:37 UTC (rev 2875)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jbossts-transaction-service.xml 2010-08-04 15:22:05 UTC (rev 2876)
@@ -10,15 +10,15 @@
<title>Introduction</title>
<para>JBossTransactionsService implements eXo <link
- linkend="ch_transaction_service">TransactionService</link> and provides
+ linkend="Kernel.TransactionService">TransactionService</link> and provides
access to <ulink url="http://www.jboss.org/jbosstm/">JBoss Transaction
Service (JBossTS)</ulink> JTA implementation via eXo container
dependency.</para>
<para>TransactionService used in JCR cache
<emphasis>org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache</emphasis>
- implementaion. See <ulink url="cluster-config.html">Cluster
- configuration</ulink> for example.</para>
+ implementaion. See <link linkend="JCR.ClusterConfig">Cluster
+ configuration</link> for example.</para>
</section>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/query-handler-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/query-handler-config.xml 2010-08-04 15:01:37 UTC (rev 2875)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/query-handler-config.xml 2010-08-04 15:22:05 UTC (rev 2876)
@@ -1,194 +1,194 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.QueryHandlerConfiguration">
- <?dbhtml filename="ch-query-handler-config.html"?>
-
- <title>QueryHandler configuration</title>
-
- <section>
- <title>How does it work?</title>
-
- <para>Lets talk about indexing content in cluster.</para>
-
- <para>For couple of reasons, we can't replicate index. That's means, some
- data added and indexed on one cluster node, will be replicated to another
- cluster node, but will not be indexed on that node.</para>
-
- <para><citetitle>So, how do the indexing works in cluster
- environment?</citetitle></para>
-
- <para>As, we can not index same data on all nodes of cluster, we must
- index it on one node. Node, that can index data and do changes on lucene
- index, is called "coordinator". Coordinator-node is choosen automaticaly,
- so we do not need special configuration for coordinator.</para>
-
- <para>But, how can another nodes save their changes to lucene
- index?</para>
-
- <para>First of all, data is already saved and replicated to another
- cluster-nodes, so we need only deliver message like "we need to index this
- data" to coordinator. Thats why Jboss-cache is used.</para>
-
- <para>All nodes of cluster writes messages into JBoss-cache but only
- coordinator takes those messages and makes changes Lucene index.</para>
-
- <para><citetitle>How do the search works in cluster
- environment?</citetitle></para>
-
- <para>Search engine do not works with indexer, coordinator, etc. Search
- needs only lucene index. But only one cluster node can change lucene index
- - asking you. Yes - lucene index is shared. So, all cluster nodes must be
- configured to use lucene index from shared directory.</para>
-
- <para>A little bit about indexing process (no matter, cluster or not)
- Indexer do not writes changes to FS lucene index immediately. At first,
- Indexer writes changes to Volatile index. If Volatile index size become
- 1Mb or more it is flushed to FS. Also there is timer, that flushes
- volatile index by timeout. Volatile index timeout configured by
- "max-volatile-time" paremeter.</para>
-
- <para>See more about <link linkend="ch_search_configuration">Search
- Configuration</link>.</para>
-
- <para>Common scheme of Shared Index<mediaobject>
- <imageobject>
- <imagedata fileref="images/diagram-shared-index.png" />
- </imageobject>
- </mediaobject></para>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <section>
- <title>Common requirements</title>
-
- <para>Now, lets see what we need to run Search engine in cluster
- environment.<itemizedlist>
- <listitem>
- <para>shared directory for storing Lucene index (i.e. NFS);</para>
- </listitem>
-
- <listitem>
- <para>changes filter configured as
- org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter;</para>
-
- <note>
- <para>This filter ignore changes on non-coordinator nodes, and
- index changes on coordinator node.</para>
- </note>
- </listitem>
-
- <listitem>
- <para>configure JBoss-cache, course;</para>
- </listitem>
- </itemizedlist></para>
- </section>
-
- <section>
- <title>Query-handler configuration</title>
-
- <para>Configuration example:<programlisting><workspace name="ws">
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="shareddir/index/db1/ws" />
- <property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
- <property name="jbosscache-configuration" value="jbosscache-indexer.xml" />
- <property name="jgroups-configuration" value="udp-mux.xml" />
- <property name="jgroups-multiplexer-stack" value="true" />
- <property name="jbosscache-cluster-name" value="JCR-cluster-indexer-ws" />
- <property name="max-volatile-time" value="60" />
- </properties>
- </query-handler>
-</workspace></programlisting> <table>
- <title>Config properties description</title>
-
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Property name</entry>
-
- <entry>Description</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>index-dir</entry>
-
- <entry>path to index</entry>
- </row>
-
- <row>
- <entry>jbosscache-configuration</entry>
-
- <entry>template of JBoss-cache configuration for all
- query-handlers in repository</entry>
- </row>
-
- <row>
- <entry>jgroups-configuration</entry>
-
- <entry>jgroups-configuration is template configuration for all
- components (search, cache, locks) [Add link to document
- describing template configurations]</entry>
- </row>
-
- <row>
- <entry>jgroups-multiplexer-stack</entry>
-
- <entry>[TODO about jgroups-multiplexer-stack - add link to
- JBoss doc]</entry>
- </row>
-
- <row>
- <entry>jbosscache-cluster-name</entry>
-
- <entry>cluster name (must be unique)</entry>
- </row>
-
- <row>
- <entry>max-volatile-time</entry>
-
- <entry>max time to live for Volatile Index</entry>
- </row>
- </tbody>
- </tgroup>
- </table></para>
- </section>
-
- <section>
- <title>JBoss-Cache template configuration</title>
-
- <para>JBoss-Cache template configuration for query handler.</para>
-
- <para>jbosscache-indexer.xml<programlisting><?xml version="1.0" encoding="UTF-8"?>
-<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1">
-
- <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false"
- lockAcquisitionTimeout="20000" />
- <!-- Configure the TransactionManager -->
- <transaction transactionManagerLookupClass="org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup" />
-
- <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
- <stateRetrieval timeout="20000" fetchInMemoryState="false" />
- <jgroupsConfig multiplexerStack="jcr.stack" />
- <sync />
- </clustering>
- <!-- Eviction configuration -->
- <eviction wakeUpInterval="5000">
- <default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="1000000">
- <property name="maxNodes" value="10000" />
- <property name="minTimeToLive" value="60000" />
- </default>
- </eviction>
-
-</jbosscache></programlisting></para>
-
- <para>See more about template configurations <link
- linkend="ch_jbosscache_config_templates">here</link>.</para>
- </section>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.QueryHandlerConfiguration">
+ <?dbhtml filename="ch-query-handler-config.html"?>
+
+ <title>QueryHandler configuration</title>
+
+ <section>
+ <title>How does it work?</title>
+
+ <para>Lets talk about indexing content in cluster.</para>
+
+ <para>For couple of reasons, we can't replicate index. That's means, some
+ data added and indexed on one cluster node, will be replicated to another
+ cluster node, but will not be indexed on that node.</para>
+
+ <para><citetitle>So, how do the indexing works in cluster
+ environment?</citetitle></para>
+
+ <para>As, we can not index same data on all nodes of cluster, we must
+ index it on one node. Node, that can index data and do changes on lucene
+ index, is called "coordinator". Coordinator-node is choosen automaticaly,
+ so we do not need special configuration for coordinator.</para>
+
+ <para>But, how can another nodes save their changes to lucene
+ index?</para>
+
+ <para>First of all, data is already saved and replicated to another
+ cluster-nodes, so we need only deliver message like "we need to index this
+ data" to coordinator. Thats why Jboss-cache is used.</para>
+
+ <para>All nodes of cluster writes messages into JBoss-cache but only
+ coordinator takes those messages and makes changes Lucene index.</para>
+
+ <para><citetitle>How do the search works in cluster
+ environment?</citetitle></para>
+
+ <para>Search engine do not works with indexer, coordinator, etc. Search
+ needs only lucene index. But only one cluster node can change lucene index
+ - asking you. Yes - lucene index is shared. So, all cluster nodes must be
+ configured to use lucene index from shared directory.</para>
+
+ <para>A little bit about indexing process (no matter, cluster or not)
+ Indexer do not writes changes to FS lucene index immediately. At first,
+ Indexer writes changes to Volatile index. If Volatile index size become
+ 1Mb or more it is flushed to FS. Also there is timer, that flushes
+ volatile index by timeout. Volatile index timeout configured by
+ "max-volatile-time" paremeter.</para>
+
+ <para>See more about <link linkend="JCR.SearchConfiguration">Search
+ Configuration</link>.</para>
+
+ <para>Common scheme of Shared Index<mediaobject>
+ <imageobject>
+ <imagedata fileref="images/diagram-shared-index.png" />
+ </imageobject>
+ </mediaobject></para>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <section>
+ <title>Common requirements</title>
+
+ <para>Now, lets see what we need to run Search engine in cluster
+ environment.<itemizedlist>
+ <listitem>
+ <para>shared directory for storing Lucene index (i.e. NFS);</para>
+ </listitem>
+
+ <listitem>
+ <para>changes filter configured as
+ org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter;</para>
+
+ <note>
+ <para>This filter ignore changes on non-coordinator nodes, and
+ index changes on coordinator node.</para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>configure JBoss-cache, course;</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Query-handler configuration</title>
+
+ <para>Configuration example:<programlisting><workspace name="ws">
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="shareddir/index/db1/ws" />
+ <property name="changesfilter-class"
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ <property name="jbosscache-configuration" value="jbosscache-indexer.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-indexer-ws" />
+ <property name="max-volatile-time" value="60" />
+ </properties>
+ </query-handler>
+</workspace></programlisting> <table>
+ <title>Config properties description</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Property name</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>index-dir</entry>
+
+ <entry>path to index</entry>
+ </row>
+
+ <row>
+ <entry>jbosscache-configuration</entry>
+
+ <entry>template of JBoss-cache configuration for all
+ query-handlers in repository</entry>
+ </row>
+
+ <row>
+ <entry>jgroups-configuration</entry>
+
+ <entry>jgroups-configuration is template configuration for all
+ components (search, cache, locks) [Add link to document
+ describing template configurations]</entry>
+ </row>
+
+ <row>
+ <entry>jgroups-multiplexer-stack</entry>
+
+ <entry>[TODO about jgroups-multiplexer-stack - add link to
+ JBoss doc]</entry>
+ </row>
+
+ <row>
+ <entry>jbosscache-cluster-name</entry>
+
+ <entry>cluster name (must be unique)</entry>
+ </row>
+
+ <row>
+ <entry>max-volatile-time</entry>
+
+ <entry>max time to live for Volatile Index</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table></para>
+ </section>
+
+ <section>
+ <title>JBoss-Cache template configuration</title>
+
+ <para>JBoss-Cache template configuration for query handler.</para>
+
+ <para>jbosscache-indexer.xml<programlisting><?xml version="1.0" encoding="UTF-8"?>
+<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1">
+
+ <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false"
+ lockAcquisitionTimeout="20000" />
+ <!-- Configure the TransactionManager -->
+ <transaction transactionManagerLookupClass="org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup" />
+
+ <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
+ <stateRetrieval timeout="20000" fetchInMemoryState="false" />
+ <jgroupsConfig multiplexerStack="jcr.stack" />
+ <sync />
+ </clustering>
+ <!-- Eviction configuration -->
+ <eviction wakeUpInterval="5000">
+ <default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="1000000">
+ <property name="maxNodes" value="10000" />
+ <property name="minTimeToLive" value="60000" />
+ </default>
+ </eviction>
+
+</jbosscache></programlisting></para>
+
+ <para>See more about template configurations <link
+ linkend="JCR.JBossCacheConfigurationTemplates">here</link>.</para>
+ </section>
+ </section>
+</chapter>
15 years, 11 months
exo-jcr SVN: r2875 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr: concepts and 2 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-04 11:01:37 -0400 (Wed, 04 Aug 2010)
New Revision: 2875
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/lock-manager-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/fulltext-search-and-settings.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
Log:
EXOJCR-869: link fixes
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/cluster-config.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_cluster_config">
+<chapter id="JCR.ClusterConfig">
<?dbhtml filename="ch-cluster-config.html"?>
<title>Configuring JBoss AS with eXo JCR in cluster</title>
@@ -87,7 +87,7 @@
</orderedlist>
</section>
- <section id="sect_conf_cluster_jcr">
+ <section id="JCR.ClusterConfig.JCRExternalConfig">
<title>Configuring JCR to use external configuration</title>
<itemizedlist>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -358,9 +358,7 @@
<title>Node type registration</title>
<para>eXo JCR implementation supports various methods of the node-type
- registration. The most used is registration from <link
- linkend="JCR.NodeTypesandNamespaces">xml file</link> on JCR
- startup.</para>
+ registration. </para>
<section>
<title>Run time registration from xml file.</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -11,11 +11,10 @@
<para>Support of node types and namespaces is required by the JSR-170
specification. Beyond the methods required by the specification, eXo JCR
- has its own API extension for the <ulink
- url="JCR.NodeTypeRegistration"><link
- linkend="JCR.NodeTypeRegistration">Node type registration</link></ulink>
- as well as the ability to declaratively define node types in the
- Repository at the start-up time.</para>
+ has its own API extension for the <link
+ linkend="JCR.NodeTypeRegistration">Node type registration</link> as well
+ as the ability to declaratively define node types in the Repository at the
+ start-up time.</para>
</section>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,124 +1,125 @@
-<?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="JCR.ConfigurationPersister">
- <?dbhtml filename="ch-external-value-storages.html"?>
- <title>JCR Configuration persister</title>
-
- <section>
- <title>Idea</title>
-
- <para>JCR Repository Service uses
- <classname>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</classname>
- component to read its configuration.</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR configuration file</description>
- <value>/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- </init-params>
- </component></programlisting>
-
- <para>In the example Repository Service will read the configuration from
- the file <filename>/conf/standalone/exo-jcr-config.xml</filename>.</para>
-
- <para>But in some cases it's required to change the configuration on the
- fly. And know that the new one will be used. Additionally we wish not to
- modify the original file.</para>
-
- <para>In this case we have to use the configuration persister feature
- which allows to store the configuration in different locations.</para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <para>On startup <classname>RepositoryServiceConfiguration</classname>
- component checks if a configuration persister was configured. In that case
- it uses the provided <classname>ConfigurationPersister</classname>
- implementation class to instantiate the persister object.</para>
-
- <para>Configuration with persister:<programlisting><component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR configuration file</description>
- <value>/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- <properties-param>
- <name>working-conf</name>
- <description>working-conf</description>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="mysql" />
- <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
- </properties-param>
- </init-params>
- </component></programlisting></para>
-
- <para>Where:<itemizedlist>
- <listitem>
- <para><parameter>source-name</parameter> - JNDI source name
- configured in <classname>InitialContextInitializer</classname>
- component. (<parameter>sourceName</parameter> prior v.1.9.) Find
- more in <link linkend="ch_configuration">database
- configuration</link>.</para>
- </listitem>
-
- <listitem>
- <para><parameter>dialect</parameter> - SQL dialect which will be
- used with database from <parameter>source-name</parameter>. Find
- more in <link linkend="ch_configuration">database
- configuration</link>.</para>
- </listitem>
-
- <listitem>
- <para><parameter>persister-class-name</parameter> - class name of
- <classname>ConfigurationPersister</classname> interface
- implementation. (<parameter>persisterClassName</parameter> prior
- v.1.9.)</para>
- </listitem>
- </itemizedlist></para>
-
- <para>ConfigurationPersister interface:<programlisting>/**
- * Init persister.
- * Used by RepositoryServiceConfiguration on init.
- * @return - config data stream
- */
- void init(PropertiesParam params) throws RepositoryConfigurationException;
-
- /**
- * Read config data.
- * @return - config data stream
- */
- InputStream read() throws RepositoryConfigurationException;
-
- /**
- * Create table, write data.
- * @param confData - config data stream
- */
- void write(InputStream confData) throws RepositoryConfigurationException;
-
- /**
- * Tell if the config exists.
- * @return - flag
- */
- boolean hasConfig() throws RepositoryConfigurationException;</programlisting></para>
-
- <para>JCR Core implementation contains a persister which stores the
- repository configuration in the relational database using JDBC calls -
- <classname>org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister</classname>.</para>
-
- <para>The implementation will crate and use table JCR_CONFIG in the
- provided database.</para>
-
- <para>But the developer can implement his own persister for his particular
- usecase.</para>
- </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="JCR.ConfigurationPersister">
+ <?dbhtml filename="ch-jcr-configuration-persister.html"?>
+
+ <title>JCR Configuration persister</title>
+
+ <section>
+ <title>Idea</title>
+
+ <para>JCR Repository Service uses
+ <classname>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</classname>
+ component to read its configuration.</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ </init-params>
+ </component></programlisting>
+
+ <para>In the example Repository Service will read the configuration from
+ the file <filename>/conf/standalone/exo-jcr-config.xml</filename>.</para>
+
+ <para>But in some cases it's required to change the configuration on the
+ fly. And know that the new one will be used. Additionally we wish not to
+ modify the original file.</para>
+
+ <para>In this case we have to use the configuration persister feature
+ which allows to store the configuration in different locations.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>On startup <classname>RepositoryServiceConfiguration</classname>
+ component checks if a configuration persister was configured. In that case
+ it uses the provided <classname>ConfigurationPersister</classname>
+ implementation class to instantiate the persister object.</para>
+
+ <para>Configuration with persister:<programlisting><component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ <properties-param>
+ <name>working-conf</name>
+ <description>working-conf</description>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="mysql" />
+ <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
+ </properties-param>
+ </init-params>
+ </component></programlisting></para>
+
+ <para>Where:<itemizedlist>
+ <listitem>
+ <para><parameter>source-name</parameter> - JNDI source name
+ configured in <classname>InitialContextInitializer</classname>
+ component. (<parameter>sourceName</parameter> prior v.1.9.) Find
+ more in <link linkend="JCR.JDBCDataContainerConfig">database
+ configuration</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>dialect</parameter> - SQL dialect which will be
+ used with database from <parameter>source-name</parameter>. Find
+ more in <link linkend="JCR.JDBCDataContainerConfig">database
+ configuration</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>persister-class-name</parameter> - class name of
+ <classname>ConfigurationPersister</classname> interface
+ implementation. (<parameter>persisterClassName</parameter> prior
+ v.1.9.)</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>ConfigurationPersister interface:<programlisting>/**
+ * Init persister.
+ * Used by RepositoryServiceConfiguration on init.
+ * @return - config data stream
+ */
+ void init(PropertiesParam params) throws RepositoryConfigurationException;
+
+ /**
+ * Read config data.
+ * @return - config data stream
+ */
+ InputStream read() throws RepositoryConfigurationException;
+
+ /**
+ * Create table, write data.
+ * @param confData - config data stream
+ */
+ void write(InputStream confData) throws RepositoryConfigurationException;
+
+ /**
+ * Tell if the config exists.
+ * @return - flag
+ */
+ boolean hasConfig() throws RepositoryConfigurationException;</programlisting></para>
+
+ <para>JCR Core implementation contains a persister which stores the
+ repository configuration in the relational database using JDBC calls -
+ <classname>org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister</classname>.</para>
+
+ <para>The implementation will crate and use table JCR_CONFIG in the
+ provided database.</para>
+
+ <para>But the developer can implement his own persister for his particular
+ usecase.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -21,22 +21,19 @@
</listitem>
<listitem>
- <para><link linkend="ch_jdbc_data_container">JDBC Data Container
+ <para><link linkend="JCR.JDBCDataContainerConfig">JDBC Data Container
config</link></para>
</listitem>
<listitem>
- <para><link linkend="ch_external_value_storages">External Value
+ <para><link linkend="JCR.ExternalValueStorages">External Value
Storages</link></para>
</listitem>
<listitem>
- <para><link linkend="none">Workspace SimpleDB storage</link></para>
+ <para><link linkend="JCR.WorkspacePersistenceStorage">Workspace
+ Persistence Storage</link></para>
</listitem>
-
- <listitem>
- <para><link linkend="none">Workspace Persistence Storage</link></para>
- </listitem>
</itemizedlist>
</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -13,8 +13,7 @@
along with the JCR structure (i.e. Nodes and Properties). eXo JCR offers
an additional option of storing JCR Values separately from Workspace Data
container, which can be extremely helpful to keep Binary Large Objects
- (BLOBs) for example (see [TODO<link linkend="TODO"> Binary values
- processing</link>]).</para>
+ (BLOBs) for example.</para>
<para>Value storage configuration is a part of Repository configuration,
find more details <link
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -89,7 +89,7 @@
Repository Service and related serivces) and repository-configuration.xml
(repositories configuration).</para>
- <para>Read more about <link linkend="ch_configuration">Repository
+ <para>Read more about <link linkend="JCR.eXoJCRconfiguration">Repository
configuration</link>.</para>
</section>
@@ -320,9 +320,10 @@
in two different databases (ws in HSQLDB, ws1 in MySQL).</para>
<note>
- <para>Starting from v.1.9 <link linkend="ch_configuration">repository
- configuration</link> parameters supports human-readable formats of
- values (e.g. 200K - 200 Kbytes, 30m - 30 minutes etc)</para>
+ <para>Starting from v.1.9 <link
+ linkend="JCR.eXoJCRconfiguration">repository configuration</link>
+ parameters supports human-readable formats of values (e.g. 200K - 200
+ Kbytes, 30m - 30 minutes etc)</para>
</note>
</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -110,8 +110,7 @@
<title>MySQL</title>
<para>JCR MySQL-backend requires special dialect <ulink
- url="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html"><ulink
- url="http://jira.exoplatform.org/browse/JCR-375">MySQL-UTF8</ulink></ulink>
+ url="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html">MySQL-UTF8</ulink>
to be used for internationalization support. But the database default
charset should be latin1 to use limited index space effectively (1000
bytes for MyISAM engine, 767 for InnoDB). If database default charset is
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -805,31 +805,31 @@
<itemizedlist>
<listitem>
<para>Get a text excerpt with <emphasis role="bold">highlighted
- words</emphasis> that matches the query: <ulink
- url="ExcerptProvider>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searchi...">ExcerptProvider</ulink>.</para>
+ words</emphasis> that matches the query: <link
+ linkend="JCR.SearchingRepositoryContent.Highlighting">ExcerptProvider</link>.</para>
</listitem>
<listitem>
<para>Search for a term and its <emphasis
- role="bold">synonyms</emphasis>: <ulink
- url="SynonymSearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching...">SynonymSearch</ulink></para>
+ role="bold">synonyms</emphasis>: <link
+ linkend="JCR.SearchingRepositoryContent.SynonimProvider">SynonymSearch</link></para>
</listitem>
<listitem>
<para>Search for <emphasis role="bold">similar</emphasis> nodes:
- <ulink
- url="SimilaritySearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Search...">SimilaritySearch</ulink></para>
+ <link
+ linkend="JCR.SearchingRepositoryContent.Similarity">SimilaritySearch</link></para>
</listitem>
<listitem>
<para>Check <emphasis role="bold">spelling</emphasis> of a fulltext
- query statement: <ulink
- url="SpellChecker>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+...">SpellChecker</ulink></para>
+ query statement: <link
+ linkend="JCR.SearchingRepositoryContent.SpellChecker">SpellChecker</link></para>
</listitem>
<listitem>
<para>Define index <emphasis role="bold">aggregates and
- rules</emphasis>: IndexingConfiguration (see this article)</para>
+ rules</emphasis>: IndexingConfiguration.</para>
</listitem>
</itemizedlist>
</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,7 +1,7 @@
<?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="JCR.WorkspaceDataContainer">
+<chapter id="JCR.WorkspacePersistenceStorage">
<?dbhtml filename="ch-workspace-data-container.html"?>
<title>Workspace Data Container</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container-howto.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,112 +1,112 @@
-<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
- <chapter id="JCR.HowtoimplementWorkspaceDataContainer">
- <title>How-to implement Workspace Data Container</title>
- <?dbhtml filename="ch-data-container-howto.html"?>
- <section id="ShortintrointoWorkspacedatacontainerimplementationpractices">
- <title>Short intro into Workspace data container implementation practices:</title>
- <orderedlist>
- <listitem>
- <para>Read a bit about the <link linkend="JCRWorkspaceDataContainerarchitecturecontract">contract</link>.</para>
- </listitem>
- <listitem>
- <para>Start new implementation project pom.xml with org.exoplatform.jcr parent. (optional, but will makes the development easy)</para>
- </listitem>
- <listitem>
- <para>Update sources of JCR Core and read JavaDoc on
- <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceDataContainer</emphasis> and
- <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceStorageConnection</emphasis> interfaces. This two are main part for the implemenation.
- </para>
- </listitem>
- <listitem>
- <para>Look at
- <emphasis role="bold">org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager</emphasis> sourcecode, check how data meneger uses container and its connections (see in save() method)
- </para>
- </listitem>
- <listitem>
- <para>Create
- <emphasis role="bold">WorkspaceStorageConnection</emphasis> dummy implementation class. It's freeform class, but to be close to the eXo JCR, check how implemented JDBC or SimpleDB containers (
- <emphasis role="bold">org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection</emphasis> and
- <emphasis role="bold">org.exoplatform.services.jcr.aws.storage.sdb.SDBWorkspaceStorageConnection</emphasis>). Take in account usage of
- <emphasis role="bold">ValueStoragePluginProvider</emphasis> in both implementations.Value storage is an useful option for production versions. But leave it to the end of implementation work.
- </para>
- </listitem>
- <listitem>
- <para>Create the connection implementation unit tests to play TTD. (optional, but takes many benefits for the process)</para>
- </listitem>
- <listitem>
- <para>Implement CRUD starting from the read to write etc. Test the methods using external to the implementation ways of data read/write in your backend.</para>
- </listitem>
- <listitem>
- <para>When all methods of the connection done start
- <emphasis role="bold">WorkspaceDataContainer</emphasis>. Container class very simple, it's like a factory for the connections only.
- </para>
- </listitem>
- <listitem>
- <para>Care about container reuseConnection(WorkspaceStorageConnection) method logic. For some backends it cab be same as openConnection(), but for some others it's important to reuse physical backend connection, e.g. to be in same transaction - see JDBC container.</para>
- </listitem>
- <listitem>
- <para>It's almost ready for use in data manager. Start another test and go on.</para>
- </listitem>
- </orderedlist>
- <para>When the container will be ready for run as JCR persistence storage (e.g. for this level testing) it should be configured in Repository configuration.</para>
- <para>Assuming that our new implementation class name is
- <emphasis role="bold">org.project.jcr.impl.storage.MyWorkspaceDataContainer</emphasis>.
- </para>
- <programlisting> <repository-service default-repository="repository">
- <repositories>
- <repository name="repository" system-workspace="production" default-workspace="production">
- .............
- <workspaces>
- <workspace name="production">
- <container class="org.project.jcr.impl.storage.MyWorkspaceDataContainer">
- <properties>
- <property name="propertyName1" value="propertyValue1" />
- <property name="propertyName2" value="propertyValue2" />
- .......
- <property name="propertyNameN" value="propertyValueN" />
- </properties>
- <value-storages>
- .......
- </value-storages>
- </container>
-
-</programlisting>
- <para>Container can be configured using set properties.</para>
- </section>
- <section id="Valuestorageusagenotes">
- <title>Value storage usage notes:</title>
- <para>Value storages pluggable to the container but if it used the container implementation should respect set of interfaces and external storage usage principles.</para>
- <para>If the container have
- <emphasis role="bold">ValueStoragePluginProvider</emphasis> (e.g. via constructor) it's just few methods to manipulate external Values data.
- </para>
- <programlisting>// get channel for ValueData write (add or update)
-ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data, i);
-if (channel == null) {
- // write
- channel.write(data.getIdentifier(), vd);
- // obtain storage id, id can be used for linkage of external ValueData and PropertyData in main backend
- String storageId = channel.getStorageId();
-}
-
-....
-
-// delete all Property Values in external storage
-ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
-channel.delete(propertyData.getIdentifier());
-
-....
-
-// read ValueData from external storage
-ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
-ValueData vdata = channel.read(propertyData.getIdentifier(), orderNumber, maxBufferSize);
-
-</programlisting>
- <important>
- <title>Important</title>
- <para>After a sequence of write and/or delete operations on the storage channel, the channel should be committed (or rolled back on an error). See
- <emphasis role="bold">ValueIOChannel.commit()</emphasis> and
- <emphasis role="bold">ValueIOChannel.rollback()</emphasis> and how those methods used in JDBC container.
- </para>
- </important>
- </section>
- </chapter>
+<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+ <chapter id="JCR.HowToImplementWorkspaceDataContainer">
+ <title>How-to implement Workspace Data Container</title>
+ <?dbhtml filename="ch-data-container-howto.html"?>
+ <section id="ShortintrointoWorkspacedatacontainerimplementationpractices">
+ <title>Short intro into Workspace data container implementation practices:</title>
+ <orderedlist>
+ <listitem>
+ <para>Read a bit about the <link linkend="JCRWorkspaceDataContainerarchitecturecontract">contract</link>.</para>
+ </listitem>
+ <listitem>
+ <para>Start new implementation project pom.xml with org.exoplatform.jcr parent. (optional, but will makes the development easy)</para>
+ </listitem>
+ <listitem>
+ <para>Update sources of JCR Core and read JavaDoc on
+ <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceDataContainer</emphasis> and
+ <emphasis role="bold">org.exoplatform.services.jcr.storage.WorkspaceStorageConnection</emphasis> interfaces. This two are main part for the implemenation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Look at
+ <emphasis role="bold">org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager</emphasis> sourcecode, check how data meneger uses container and its connections (see in save() method)
+ </para>
+ </listitem>
+ <listitem>
+ <para>Create
+ <emphasis role="bold">WorkspaceStorageConnection</emphasis> dummy implementation class. It's freeform class, but to be close to the eXo JCR, check how implemented JDBC or SimpleDB containers (
+ <emphasis role="bold">org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection</emphasis> and
+ <emphasis role="bold">org.exoplatform.services.jcr.aws.storage.sdb.SDBWorkspaceStorageConnection</emphasis>). Take in account usage of
+ <emphasis role="bold">ValueStoragePluginProvider</emphasis> in both implementations.Value storage is an useful option for production versions. But leave it to the end of implementation work.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Create the connection implementation unit tests to play TTD. (optional, but takes many benefits for the process)</para>
+ </listitem>
+ <listitem>
+ <para>Implement CRUD starting from the read to write etc. Test the methods using external to the implementation ways of data read/write in your backend.</para>
+ </listitem>
+ <listitem>
+ <para>When all methods of the connection done start
+ <emphasis role="bold">WorkspaceDataContainer</emphasis>. Container class very simple, it's like a factory for the connections only.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Care about container reuseConnection(WorkspaceStorageConnection) method logic. For some backends it cab be same as openConnection(), but for some others it's important to reuse physical backend connection, e.g. to be in same transaction - see JDBC container.</para>
+ </listitem>
+ <listitem>
+ <para>It's almost ready for use in data manager. Start another test and go on.</para>
+ </listitem>
+ </orderedlist>
+ <para>When the container will be ready for run as JCR persistence storage (e.g. for this level testing) it should be configured in Repository configuration.</para>
+ <para>Assuming that our new implementation class name is
+ <emphasis role="bold">org.project.jcr.impl.storage.MyWorkspaceDataContainer</emphasis>.
+ </para>
+ <programlisting> <repository-service default-repository="repository">
+ <repositories>
+ <repository name="repository" system-workspace="production" default-workspace="production">
+ .............
+ <workspaces>
+ <workspace name="production">
+ <container class="org.project.jcr.impl.storage.MyWorkspaceDataContainer">
+ <properties>
+ <property name="propertyName1" value="propertyValue1" />
+ <property name="propertyName2" value="propertyValue2" />
+ .......
+ <property name="propertyNameN" value="propertyValueN" />
+ </properties>
+ <value-storages>
+ .......
+ </value-storages>
+ </container>
+
+</programlisting>
+ <para>Container can be configured using set properties.</para>
+ </section>
+ <section id="Valuestorageusagenotes">
+ <title>Value storage usage notes:</title>
+ <para>Value storages pluggable to the container but if it used the container implementation should respect set of interfaces and external storage usage principles.</para>
+ <para>If the container have
+ <emphasis role="bold">ValueStoragePluginProvider</emphasis> (e.g. via constructor) it's just few methods to manipulate external Values data.
+ </para>
+ <programlisting>// get channel for ValueData write (add or update)
+ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data, i);
+if (channel == null) {
+ // write
+ channel.write(data.getIdentifier(), vd);
+ // obtain storage id, id can be used for linkage of external ValueData and PropertyData in main backend
+ String storageId = channel.getStorageId();
+}
+
+....
+
+// delete all Property Values in external storage
+ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+channel.delete(propertyData.getIdentifier());
+
+....
+
+// read ValueData from external storage
+ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+ValueData vdata = channel.read(propertyData.getIdentifier(), orderNumber, maxBufferSize);
+
+</programlisting>
+ <important>
+ <title>Important</title>
+ <para>After a sequence of write and/or delete operations on the storage channel, the channel should be committed (or rolled back on an error). See
+ <emphasis role="bold">ValueIOChannel.commit()</emphasis> and
+ <emphasis role="bold">ValueIOChannel.rollback()</emphasis> and how those methods used in JDBC container.
+ </para>
+ </important>
+ </section>
+ </chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,392 +1,392 @@
-<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.WorkspaceDataContainerarchitecturecontract">
- <?dbhtml filename="ch-data-container.html"?>
- <title>JCR Workspace Data Container (architecture contract)</title>
- <section id="Goals">
- <title>Goals</title>
- <itemizedlist>
- <listitem>
- <para>Cover Workspace Data Container implementation requirements</para>
- </listitem>
- <listitem>
- <para>Describe container life cycle</para>
- </listitem>
- <listitem>
- <para>Describe relations between container and high-level DataManagers</para>
- </listitem>
- </itemizedlist>
- </section>
- <section id="Concepts">
- <title>Concepts</title>
- <section id="Containerandconnection">
- <title>Container and connection</title>
- <para>Workspace Data Container (container) serves Repository Workspace persistent storage.
- WorkspacePersistentDataManager (data manager) uses container to perform CRUD operation on the persistent
- storage.
- Access to the storage in data manager makes via storage connection obtained from the container (WorkspaceDataContainer
- interface implemenatiton). Each connection represents a transaction on the storage. Storage Connection
- (connection) should be an implementation of WorkspaceStorageConnection.</para>
- <itemizedlist>
- <listitem>
- <para>Container acts as a factory of a new storage connections. Usually this method is designed to be
- synchronized, to avoid possible concurrent issues.</para>
- </listitem>
- </itemizedlist>
- <programlisting>WorkspaceStorageConnection openConnection() throws RepositoryException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Open read-only WorkspaceStorageConnection. Read-only connections can be potentially a bit faster in
- some cases.</para>
- </listitem>
- </itemizedlist>
- <programlisting>WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException;
-</programlisting>
- <note>
- <title>*EXPERIMENTAL*</title>
- <para>Read-only WorkspaceStorageConnection is experimental feature and not currently handled in JCR.
- Actually such connections didn't prove their performance, so JCR Core doesn't use them.</para>
- </note>
- <itemizedlist>
- <listitem>
- <para>Storage connection might be reused also. Reuse of the connection means reuse of physical resource
- (e.g. JDBC Connection) allocated by one connection in another. This feature used in data manager for
- saving ordinary and system changes on the system Workspace. But the reuse is an optional feature and
- it works only if possible, otherwise the new connection opens.</para>
- </listitem>
- </itemizedlist>
- <programlisting>WorkspaceStorageConnection reuseConnection(WorkspaceStorageConnection original) throws RepositoryException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>When checking Same-Name Siblings (SNS) existence, JCR Core can use new connection or not. This is
- defined via Workspace Data Container configuration and retrieved using special method.</para>
- </listitem>
- </itemizedlist>
- <programlisting>boolean isCheckSNSNewConnection();
-</programlisting>
- <important>
- <title>New connection for SNS</title>
- <para> Sometimes there is a need of checking if there are some nodes with equal names. Usually new Workspace
- Storage Connection is used for purpose. The improvement came from JDBC Workspace Data Container, which
- shows better performance on Oracle RDBMS when using new connection for checking SNS existence. But later
- this led to deadlocks on Sybase RDBMS, so feature was made as an optional and configurable.</para>
- </important>
- <para>Container initialization based on a configuration only. After the container created it's not possible to
- change parameters. Configuration consists of implementation class and set of properties and Value Storages
- configuration.</para>
- </section>
- <section id="Valuestorages">
- <title>Value storages</title>
- <para>Container provides optional special mechanism for Value storing. It's possible to configure external
- Value Storages via container configuration (available only via configuration).
- Value Storage works as fully independent pluggable storage. All required parameters storage obtains from its
- configuration. Some storages are possible for one container.
- Configuration describes such parameters as ValueStoragePluginimplementation class, set of implementation specific properties and
- filters. The filters declares criteria for Value matching to the storage. Only matched Property Values will
- be stored. So, in common case, the storage might contains only the part of the Workspace content.
- Value Storages are very useful for BLOB storing. E.g. storing on the File System instead of a database.</para>
- <para>Container obtains Values Storages from ValueStoragePluginProvider component. Provider acts as a factory
- of Value channels (ValueIOChannel). Channel provides all CRUD operation for Value Storage respecting the
- transaction manner of work (how it can be possible due to implementation specifics of the storages).</para>
- </section>
- <section id="Lifecycle">
- <title>Lifecycle</title>
- <para>Container used by data manager for read and write operations.
- Read operations (getters) uses connection once and close it on the finally.
- Write operations performs in commit method as a sequence of create/update calls and final commit (or rollback on error).
- Writes uses one connection (or two - another for system workspace) per commit call. One connection
- guaranties transaction support for write operations.
- Commit or rollback should free/clean all resources consumed by the container (connection).</para>
- </section>
- <section id="Valuestoragelifecycle">
- <title>Value storage lifecycle</title>
- <para>Value storage used from the container inside. Reads are related to a container reads. Writes are commit
- related.
- Container (connection) implementation should use transaction capabilities of the storages in same way as for other
- operations.</para>
- </section>
- </section>
- <section id="Requirements">
- <title>Requirements</title>
- <para>Connection create and reuse should be a thread safe operation.
- Connection provides CRUD operations support on the storage.</para>
- <section id="Readoperations">
- <title>Read operations</title>
- <itemizedlist>
- <listitem>
- <para>Reads ItemData from the storage by item identifier.</para>
- </listitem>
- </itemizedlist>
- <programlisting>ItemData getItemData(String identifier) throws RepositoryException, IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Reads ItemData from the storage using item's parent and name relative the parent location.</para>
- </listitem>
- </itemizedlist>
- <programlisting>ItemData getItemData(NodeData parentData, QPathEntry name) throws RepositoryException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Reads List of NodeData from the storage using item's parent location.</para>
- </listitem>
- </itemizedlist>
- <programlisting>List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException, IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Reads List of PropertyData from the storage using item's parent location</para>
- </listitem>
- </itemizedlist>
- <programlisting>List<PropertyData> getChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Reads List of PropertyData with empty ValueData from the storage using item's parent location.</para>
- </listitem>
- </itemizedlist>
- <para>This methiod specially dedicated for non-content modification operations (e.g. Items delete).</para>
- <programlisting>List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Reads List of PropertyData from the storage using item's parent location.</para>
- </listitem>
- </itemizedlist>
- <para>It's REFERENCE type Properties referencing Node with given nodeIdentifier. See more in javax.jcr.Node.getReferences()</para>
- <programlisting>List<PropertyData> getReferencesData(String nodeIdentifier) throws RepositoryException,IllegalStateException,UnsupportedOperationException;
-</programlisting>
- </section>
- <section id="Writeoperations">
- <title>Write operations</title>
- <itemizedlist>
- <listitem>
- <para>Adds single NodeData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void add(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Adds single PropertyData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void add(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Updates NodeData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void update(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Updates PropertyData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void update(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Renames NodeData using Node identifier and new name and index from the data.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void rename(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Deletes NodeData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void delete(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Deletes PropertyData.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void delete(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Persist changes and closes connection. It can be database transaction commit for instance etc.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void commit() throws IllegalStateException, RepositoryException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Refuses persistent changes and closes connection. It can be database transaction rollback for instance etc.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void rollback() throws IllegalStateException, RepositoryException;
-</programlisting>
- <para>All methods throws IllegalStateException if connection is closed.
- UnsupportedOperationException if the method is not supported (e.g. JCR Level 1 implementation etc).
- RepositoryException if some error occurs during preparation, validation or persistence.</para>
- </section>
- <section id="Stateoperations">
- <title>State operations</title>
- <itemizedlist>
- <listitem>
- <para>Returns true if connection can be used.</para>
- </listitem>
- </itemizedlist>
- <programlisting>boolean isOpened();
-</programlisting>
- </section>
- <section id="Validationofwriteoperations">
- <title>Validation of write operations</title>
- <para>Container have to care about storage consistency (JCR constraints) on write operations:
- (InvalidItemStateException should be thrown according the spec)
- At least following checks should be performed:</para>
- <itemizedlist>
- <listitem>
- <para>On ADD errors</para>
- <itemizedlist>
- <listitem>
- <para>Parent not found. Condition: Parent ID (Item with ID is not exists).</para>
- </listitem>
- <listitem>
- <para>Item already exists. Condition: ID (Item with ID already exists).</para>
- </listitem>
- <listitem>
- <para>Item already exists. Condition: Parent ID, Name, Index (Item with parent ID, name and index already exists).</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- <itemizedlist>
- <listitem>
- <para>On DELETE errors</para>
- <itemizedlist>
- <listitem>
- <para>Item not found. Condition ID.</para>
- </listitem>
- <listitem>
- <para>Can not delete parent till children exists.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- <itemizedlist>
- <listitem>
- <para>On UPDATE errors</para>
- <itemizedlist>
- <listitem>
- <para>Item not found. Condition ID.</para>
- </listitem>
- <listitem>
- <para>Item already exists with higher Version. Condition: ID, Version (Some Session had updated Item with ID prior this update).</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </section>
- <section id="Consistencyofsave">
- <title>Consistency of save</title>
- <para>The container (connection) should implement consistency of Commit (Rollback) in
- <emphasis role="bold">transaction manner</emphasis>.
- I.e. if set of operations were performed
- <emphasis role="bold">before</emphasis> the future
- <emphasis role="bold">Commit</emphasis> and another next operation
- <emphasis role="bold">fails</emphasis>.
- <emphasis role="bold">It should be possible to</emphasis> rollback applied changes using
- <emphasis role="bold">Rollback</emphasis> command.
- </para>
- </section>
- </section>
- <section id="ValuestoragesAPI">
- <title>Value storages API</title>
- <section id="Storagesprovider">
- <title>Storages provider:</title>
- <para>Container implementation obtains Values Storages option via ValueStoragePluginProvider component. Provider acts as a factory of Value channels (ValueIOChannel) and has two methods for this purpose:</para>
- <itemizedlist>
- <listitem>
- <para>Return ValueIOChannel matched this property and valueOrderNumer. Null will be returned if no channel matches.</para>
- </listitem>
- </itemizedlist>
- <programlisting>ValueIOChannel getApplicableChannel(PropertyData property, int valueOrderNumer) throws IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Return ValueIOChannel associated with given storageId.</para>
- </listitem>
- </itemizedlist>
- <programlisting>ValueIOChannel getChannel(String storageId) throws IOException, ValueStorageNotFoundException;
-</programlisting>
- <para>There is also method for consistency check, but this method doesn't used anywhere and storage implementations has it empty.</para>
- </section>
- <section id="Valuestorageplugin">
- <title>Value storage plugin</title>
- <para>Provider implementation should use ValueStoragePlugin abstract class as a base for all storage implementations.
- Plugin provides support for provider implementation methods. Plugin's methods should be implemented:</para>
- <itemizedlist>
- <listitem>
- <para>Initialize this plugin. Used at start time in ValueStoragePluginProvider.</para>
- </listitem>
- </itemizedlist>
- <programlisting>public abstract void init(Properties props, ValueDataResourceHolder resources) throws RepositoryConfigurationException, IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Open ValueIOChannel.Used in ValueStoragePluginProvider.getApplicableChannel(PropertyData, int) and getChannel(String)</para>
- </listitem>
- </itemizedlist>
- <programlisting>public abstract ValueIOChannel openIOChannel() throws IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Return true if this storage has same storageId.</para>
- </listitem>
- </itemizedlist>
- <programlisting>public abstract boolean isSame(String valueDataDescriptor);
-</programlisting>
- </section>
- <section id="ValueIOchannel">
- <title>Value I/O channel</title>
- <para>Channel should implement ValueIOChannel interface. CRUD operation for Value Storage:</para>
- <itemizedlist>
- <listitem>
- <para>Read Property value.</para>
- </listitem>
- </itemizedlist>
- <programlisting>ValueData read(String propertyId, int orderNumber, int maxBufferSize) throws IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Add or update Property value.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void write(String propertyId, ValueData data) throws IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Delete Property all values.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void delete(String propertyId) throws IOException;
-</programlisting>
- </section>
- <section id="Transactionsupportviachannel">
- <title>Transaction support via channel</title>
- <para>Modification operations should be applied only on commit. Rollback is required for data created cleanup.</para>
- <itemizedlist>
- <listitem>
- <para>Commit channel changes.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void commit() throws IOException;
-</programlisting>
- <itemizedlist>
- <listitem>
- <para>Rollback channel changes.</para>
- </listitem>
- </itemizedlist>
- <programlisting>void rollback() throws IOException;
-</programlisting>
- </section>
- </section>
- </chapter>
+<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.WorkspaceDataContainer">
+ <?dbhtml filename="ch-data-container.html"?>
+ <title>JCR Workspace Data Container (architecture contract)</title>
+ <section id="Goals">
+ <title>Goals</title>
+ <itemizedlist>
+ <listitem>
+ <para>Cover Workspace Data Container implementation requirements</para>
+ </listitem>
+ <listitem>
+ <para>Describe container life cycle</para>
+ </listitem>
+ <listitem>
+ <para>Describe relations between container and high-level DataManagers</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="Concepts">
+ <title>Concepts</title>
+ <section id="Containerandconnection">
+ <title>Container and connection</title>
+ <para>Workspace Data Container (container) serves Repository Workspace persistent storage.
+ WorkspacePersistentDataManager (data manager) uses container to perform CRUD operation on the persistent
+ storage.
+ Access to the storage in data manager makes via storage connection obtained from the container (WorkspaceDataContainer
+ interface implemenatiton). Each connection represents a transaction on the storage. Storage Connection
+ (connection) should be an implementation of WorkspaceStorageConnection.</para>
+ <itemizedlist>
+ <listitem>
+ <para>Container acts as a factory of a new storage connections. Usually this method is designed to be
+ synchronized, to avoid possible concurrent issues.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>WorkspaceStorageConnection openConnection() throws RepositoryException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Open read-only WorkspaceStorageConnection. Read-only connections can be potentially a bit faster in
+ some cases.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException;
+</programlisting>
+ <note>
+ <title>*EXPERIMENTAL*</title>
+ <para>Read-only WorkspaceStorageConnection is experimental feature and not currently handled in JCR.
+ Actually such connections didn't prove their performance, so JCR Core doesn't use them.</para>
+ </note>
+ <itemizedlist>
+ <listitem>
+ <para>Storage connection might be reused also. Reuse of the connection means reuse of physical resource
+ (e.g. JDBC Connection) allocated by one connection in another. This feature used in data manager for
+ saving ordinary and system changes on the system Workspace. But the reuse is an optional feature and
+ it works only if possible, otherwise the new connection opens.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>WorkspaceStorageConnection reuseConnection(WorkspaceStorageConnection original) throws RepositoryException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>When checking Same-Name Siblings (SNS) existence, JCR Core can use new connection or not. This is
+ defined via Workspace Data Container configuration and retrieved using special method.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>boolean isCheckSNSNewConnection();
+</programlisting>
+ <important>
+ <title>New connection for SNS</title>
+ <para> Sometimes there is a need of checking if there are some nodes with equal names. Usually new Workspace
+ Storage Connection is used for purpose. The improvement came from JDBC Workspace Data Container, which
+ shows better performance on Oracle RDBMS when using new connection for checking SNS existence. But later
+ this led to deadlocks on Sybase RDBMS, so feature was made as an optional and configurable.</para>
+ </important>
+ <para>Container initialization based on a configuration only. After the container created it's not possible to
+ change parameters. Configuration consists of implementation class and set of properties and Value Storages
+ configuration.</para>
+ </section>
+ <section id="Valuestorages">
+ <title>Value storages</title>
+ <para>Container provides optional special mechanism for Value storing. It's possible to configure external
+ Value Storages via container configuration (available only via configuration).
+ Value Storage works as fully independent pluggable storage. All required parameters storage obtains from its
+ configuration. Some storages are possible for one container.
+ Configuration describes such parameters as ValueStoragePluginimplementation class, set of implementation specific properties and
+ filters. The filters declares criteria for Value matching to the storage. Only matched Property Values will
+ be stored. So, in common case, the storage might contains only the part of the Workspace content.
+ Value Storages are very useful for BLOB storing. E.g. storing on the File System instead of a database.</para>
+ <para>Container obtains Values Storages from ValueStoragePluginProvider component. Provider acts as a factory
+ of Value channels (ValueIOChannel). Channel provides all CRUD operation for Value Storage respecting the
+ transaction manner of work (how it can be possible due to implementation specifics of the storages).</para>
+ </section>
+ <section id="Lifecycle">
+ <title>Lifecycle</title>
+ <para>Container used by data manager for read and write operations.
+ Read operations (getters) uses connection once and close it on the finally.
+ Write operations performs in commit method as a sequence of create/update calls and final commit (or rollback on error).
+ Writes uses one connection (or two - another for system workspace) per commit call. One connection
+ guaranties transaction support for write operations.
+ Commit or rollback should free/clean all resources consumed by the container (connection).</para>
+ </section>
+ <section id="Valuestoragelifecycle">
+ <title>Value storage lifecycle</title>
+ <para>Value storage used from the container inside. Reads are related to a container reads. Writes are commit
+ related.
+ Container (connection) implementation should use transaction capabilities of the storages in same way as for other
+ operations.</para>
+ </section>
+ </section>
+ <section id="Requirements">
+ <title>Requirements</title>
+ <para>Connection create and reuse should be a thread safe operation.
+ Connection provides CRUD operations support on the storage.</para>
+ <section id="Readoperations">
+ <title>Read operations</title>
+ <itemizedlist>
+ <listitem>
+ <para>Reads ItemData from the storage by item identifier.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>ItemData getItemData(String identifier) throws RepositoryException, IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Reads ItemData from the storage using item's parent and name relative the parent location.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>ItemData getItemData(NodeData parentData, QPathEntry name) throws RepositoryException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Reads List of NodeData from the storage using item's parent location.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException, IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Reads List of PropertyData from the storage using item's parent location</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>List<PropertyData> getChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Reads List of PropertyData with empty ValueData from the storage using item's parent location.</para>
+ </listitem>
+ </itemizedlist>
+ <para>This methiod specially dedicated for non-content modification operations (e.g. Items delete).</para>
+ <programlisting>List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Reads List of PropertyData from the storage using item's parent location.</para>
+ </listitem>
+ </itemizedlist>
+ <para>It's REFERENCE type Properties referencing Node with given nodeIdentifier. See more in javax.jcr.Node.getReferences()</para>
+ <programlisting>List<PropertyData> getReferencesData(String nodeIdentifier) throws RepositoryException,IllegalStateException,UnsupportedOperationException;
+</programlisting>
+ </section>
+ <section id="Writeoperations">
+ <title>Write operations</title>
+ <itemizedlist>
+ <listitem>
+ <para>Adds single NodeData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void add(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Adds single PropertyData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void add(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Updates NodeData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void update(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Updates PropertyData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void update(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Renames NodeData using Node identifier and new name and index from the data.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void rename(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Deletes NodeData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void delete(NodeData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Deletes PropertyData.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void delete(PropertyData data) throws RepositoryException,UnsupportedOperationException,InvalidItemStateException,IllegalStateException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Persist changes and closes connection. It can be database transaction commit for instance etc.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void commit() throws IllegalStateException, RepositoryException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Refuses persistent changes and closes connection. It can be database transaction rollback for instance etc.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void rollback() throws IllegalStateException, RepositoryException;
+</programlisting>
+ <para>All methods throws IllegalStateException if connection is closed.
+ UnsupportedOperationException if the method is not supported (e.g. JCR Level 1 implementation etc).
+ RepositoryException if some error occurs during preparation, validation or persistence.</para>
+ </section>
+ <section id="Stateoperations">
+ <title>State operations</title>
+ <itemizedlist>
+ <listitem>
+ <para>Returns true if connection can be used.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>boolean isOpened();
+</programlisting>
+ </section>
+ <section id="Validationofwriteoperations">
+ <title>Validation of write operations</title>
+ <para>Container have to care about storage consistency (JCR constraints) on write operations:
+ (InvalidItemStateException should be thrown according the spec)
+ At least following checks should be performed:</para>
+ <itemizedlist>
+ <listitem>
+ <para>On ADD errors</para>
+ <itemizedlist>
+ <listitem>
+ <para>Parent not found. Condition: Parent ID (Item with ID is not exists).</para>
+ </listitem>
+ <listitem>
+ <para>Item already exists. Condition: ID (Item with ID already exists).</para>
+ </listitem>
+ <listitem>
+ <para>Item already exists. Condition: Parent ID, Name, Index (Item with parent ID, name and index already exists).</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>On DELETE errors</para>
+ <itemizedlist>
+ <listitem>
+ <para>Item not found. Condition ID.</para>
+ </listitem>
+ <listitem>
+ <para>Can not delete parent till children exists.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>On UPDATE errors</para>
+ <itemizedlist>
+ <listitem>
+ <para>Item not found. Condition ID.</para>
+ </listitem>
+ <listitem>
+ <para>Item already exists with higher Version. Condition: ID, Version (Some Session had updated Item with ID prior this update).</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="Consistencyofsave">
+ <title>Consistency of save</title>
+ <para>The container (connection) should implement consistency of Commit (Rollback) in
+ <emphasis role="bold">transaction manner</emphasis>.
+ I.e. if set of operations were performed
+ <emphasis role="bold">before</emphasis> the future
+ <emphasis role="bold">Commit</emphasis> and another next operation
+ <emphasis role="bold">fails</emphasis>.
+ <emphasis role="bold">It should be possible to</emphasis> rollback applied changes using
+ <emphasis role="bold">Rollback</emphasis> command.
+ </para>
+ </section>
+ </section>
+ <section id="ValuestoragesAPI">
+ <title>Value storages API</title>
+ <section id="Storagesprovider">
+ <title>Storages provider:</title>
+ <para>Container implementation obtains Values Storages option via ValueStoragePluginProvider component. Provider acts as a factory of Value channels (ValueIOChannel) and has two methods for this purpose:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Return ValueIOChannel matched this property and valueOrderNumer. Null will be returned if no channel matches.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>ValueIOChannel getApplicableChannel(PropertyData property, int valueOrderNumer) throws IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Return ValueIOChannel associated with given storageId.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>ValueIOChannel getChannel(String storageId) throws IOException, ValueStorageNotFoundException;
+</programlisting>
+ <para>There is also method for consistency check, but this method doesn't used anywhere and storage implementations has it empty.</para>
+ </section>
+ <section id="Valuestorageplugin">
+ <title>Value storage plugin</title>
+ <para>Provider implementation should use ValueStoragePlugin abstract class as a base for all storage implementations.
+ Plugin provides support for provider implementation methods. Plugin's methods should be implemented:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Initialize this plugin. Used at start time in ValueStoragePluginProvider.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>public abstract void init(Properties props, ValueDataResourceHolder resources) throws RepositoryConfigurationException, IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Open ValueIOChannel.Used in ValueStoragePluginProvider.getApplicableChannel(PropertyData, int) and getChannel(String)</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>public abstract ValueIOChannel openIOChannel() throws IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Return true if this storage has same storageId.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>public abstract boolean isSame(String valueDataDescriptor);
+</programlisting>
+ </section>
+ <section id="ValueIOchannel">
+ <title>Value I/O channel</title>
+ <para>Channel should implement ValueIOChannel interface. CRUD operation for Value Storage:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Read Property value.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>ValueData read(String propertyId, int orderNumber, int maxBufferSize) throws IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Add or update Property value.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void write(String propertyId, ValueData data) throws IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Delete Property all values.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void delete(String propertyId) throws IOException;
+</programlisting>
+ </section>
+ <section id="Transactionsupportviachannel">
+ <title>Transaction support via channel</title>
+ <para>Modification operations should be applied only on commit. Rollback is required for data created cleanup.</para>
+ <itemizedlist>
+ <listitem>
+ <para>Commit channel changes.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void commit() throws IOException;
+</programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Rollback channel changes.</para>
+ </listitem>
+ </itemizedlist>
+ <programlisting>void rollback() throws IOException;
+</programlisting>
+ </section>
+ </section>
+ </chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/lock-manager-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/lock-manager-config.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/lock-manager-config.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,442 +1,442 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.LockManagerConfiguration">
- <?dbhtml filename="ch-lock-manager-config.html"?>
-
- <title>LockManager configuration</title>
-
- <section>
- <title>Introduction</title>
-
- <para>What LockManager does?</para>
-
- <para>In common words, LockManager stores lock objects, so it can give
- Lock object or can release it, etc.</para>
-
- <para>Also LockManager is responsible for removing Locks that live too
- long. This parameter may be configured with "time-out" property.</para>
-
- <para>JCR provide two base implementation of LockManager:</para>
-
- <itemizedlist>
- <listitem>
- <para><classname>org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl</classname>;</para>
- </listitem>
-
- <listitem>
- <para><classname>org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl</classname>;</para>
- </listitem>
- </itemizedlist>
-
- <para>In this article we will talk mostly about
- CacheableLockManagerImpl.</para>
-
- <para>You can enable LockManager by adding lock-manager-configuration to
- workspace-configuration.</para>
-
- <para>For example:</para>
-
- <programlisting><workspace name="ws">
- ...
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- <properties>
- <property name="time-out" value="15m" />
- ...
- </properties>
- </lock-manager>
- ...
-</workspace></programlisting>
- </section>
-
- <section>
- <title>LockManagerImpl</title>
-
- <para>LockManagerImpl is simple implementation of LockManager, and also
- faster than CacheableLockManager. It stores Lock objects in HashMap and
- may also persist Locks if LockPersister is configured. LockManagerImpl do
- not support replication in any way.</para>
-
- <para>See more about LockManager Configuration <link
- linkend="ch_configuration">here</link>.</para>
- </section>
-
- <section>
- <title>CacheableLockManagerImpl</title>
-
- <para>CacheableLockManagerImpl stores Lock object in JBoss-cache, so Locks
- are replicable and affects on cluster, not only a single node. Also
- JBoss-cache has JDBCCacheLoader, so locks will be stored to
- database.</para>
-
- <para>Both implementation supports Expired Locks removing. There is
- LockRemover - separate thread, that periodically ask LockManager for Locks
- that lives to much and must be removed. So, timeout for LockRemover may be
- set as follows, default value is 30m.</para>
-
- <programlisting><properties>
- <property name="time-out" value="10m" />
- ...
-</properties></programlisting>
-
- <section>
- <title>Configuration</title>
-
- <para>Replication requirements are same as for Cache</para>
-
- <para>Full JCR configuration example you can see <link
- linkend="sect_conf_cluster_jcr">here</link>.</para>
-
- <para>Common tips:</para>
-
- <itemizedlist>
- <listitem>
- <para><parameter>clusterName</parameter> ("jbosscache-cluster-name")
- must be unique;</para>
- </listitem>
-
- <listitem>
- <para><parameter>cache.jdbc.table.name</parameter> must be unique
- per datasource;</para>
- </listitem>
-
- <listitem>
- <para><parameter>cache.jdbc.fqn.type</parameter> must and
- cache.jdbc.node.type must be configured according to used
- database;</para>
- </listitem>
- </itemizedlist>
-
- <para>There is few ways how to configure CacheableLockManagerImpl, and
- all of them configures JBoss-cache and JDBCCacheLoader.</para>
-
- <para>See <ulink
- url="http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader">http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader</ulink></para>
- </section>
-
- <section>
- <title>Simple JbossCache Configuraion</title>
-
- <para>First one is - put JbossCache configuraion file path to
- CacheableLockManagerImpl</para>
-
- <para><note>
- <para>This configuration is not so good, as you can think. Because
- repository may contain many workspaces, and each workspace must
- contain LockManager configuration, and LockManager config may
- contain JbossCache config file. So total configuration is growing
- up. But it is usefull if we want a single LockManager with special
- configuration.</para>
- </note></para>
-
- <para>Config is:</para>
-
- <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- <properties>
- <property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/cluster/test-jbosscache-lock-config.xml" />
- </properties>
-</lock-manager></programlisting>
-
- <para><filename>test-jbosscache-lock-config.xml</filename><programlisting><?xml version="1.0" encoding="UTF-8"?>
-<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">
-
- <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" />
-
- <clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_Name">
- <stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true" />
- <jgroupsConfig>
-
- <TCP bind_addr="127.0.0.1" start_port="9800" loopback="true" recv_buf_size="20000000" send_buf_size="640000" discard_incompatible_packets="true"
- max_bundle_size="64000" max_bundle_timeout="30" use_incoming_packet_handler="true" enable_bundling="false" use_send_queues="false" sock_conn_timeout="300"
- skip_suspected_members="true" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="1" thread_pool.max_threads="25"
- thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="false" thread_pool.queue_max_size="100" thread_pool.rejection_policy="run"
- oob_thread_pool.enabled="true" oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000"
- oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="run" />
- <MPING timeout="2000" num_initial_members="2" mcast_port="34540" bind_addr="127.0.0.1" mcast_addr="224.0.0.1" />
-
-
- <MERGE2 max_interval="30000" min_interval="10000" />
- <FD_SOCK />
- <FD max_tries="5" shun="true" timeout="10000" />
- <VERIFY_SUSPECT timeout="1500" />
- <pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800" use_mcast_xmit="false" />
- <UNICAST timeout="300,600,1200,2400,3600" />
- <pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000" />
- <pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000" view_bundling="true" />
- <FRAG2 frag_size="60000" />
- <pbcast.STREAMING_STATE_TRANSFER />
- <pbcast.FLUSH timeout="0" />
-
- </jgroupsConfig
-
- <sync />
- </clustering>
-
- <loaders passivation="false" shared="true">
- <preload>
- <node fqn="/" />
- </preload>
- <loader class="org.jboss.cache.loader.JDBCCacheLoader" async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
- <properties>
- cache.jdbc.table.name=jcrlocks_ws
- cache.jdbc.table.create=true
- cache.jdbc.table.drop=false
- cache.jdbc.table.primarykey=jcrlocks_ws_pk
- cache.jdbc.fqn.column=fqn
- cache.jdbc.fqn.type=VARCHAR(512)
- cache.jdbc.node.column=node
- cache.jdbc.node.type=<BLOB>
- cache.jdbc.parent.column=parent
- cache.jdbc.datasource=jdbcjcr
- </properties>
- </loader>
-
- </loaders>
-
-</jbosscache></programlisting></para>
-
- <para>Configuration requirements:</para>
-
- <itemizedlist>
- <listitem>
- <para><clustering mode="replication"
- clusterName="JBoss-Cache-Lock-Cluster_Name"> - cluster name must
- be unique;</para>
- </listitem>
-
- <listitem>
- <para><parameter>cache.jdbc.table.name</parameter> must be unique
- per datasource;</para>
- </listitem>
-
- <listitem>
- <para><parameter>cache.jdbc.node.type</parameter> and
- <parameter>cache.jdbc.fqn.type</parameter> must be configured
- according to using database. See <link endterm="datatypes.title"
- linkend="datatypes"></link> .</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Template JBossCache Configuration</title>
-
- <para>Second one is - use template JBoss-cache configuration for all
- LockManagers</para>
-
- <para><citetitle>Lock template configuration</citetitle></para>
-
- <para><filename>test-jbosscache-lock.xml</filename></para>
-
- <programlisting><?xml version="1.0" encoding="UTF-8"?>
-<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1">
-
- <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false"
- lockAcquisitionTimeout="20000" />
-
- <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
- <stateRetrieval timeout="20000" fetchInMemoryState="false" />
- <jgroupsConfig multiplexerStack="jcr.stack" />
- <sync />
- </clustering>
-
- <loaders passivation="false" shared="true">
- <!-- All the data of the JCR locks needs to be loaded at startup -->
- <preload>
- <node fqn="/" />
- </preload>
- <!--
- For another cache-loader class you should use another template with
- cache-loader specific parameters
- ->
- <loader class="org.jboss.cache.loader.JDBCCacheLoader" async=q"false" fetchPersistentState="false"
- ignoreModifications="false" purgeOnStartup="false">
- <properties>
- cache.jdbc.table.name=${jbosscache-cl-cache.jdbc.table.name}
- cache.jdbc.table.create=${jbosscache-cl-cache.jdbc.table.create}
- cache.jdbc.table.drop=${jbosscache-cl-cache.jdbc.table.drop}
- cache.jdbc.table.primarykey=${jbosscache-cl-cache.jdbc.table.primarykey}
- cache.jdbc.fqn.column=${jbosscache-cl-cache.jdbc.fqn.column}
- cache.jdbc.fqn.type=${jbosscache-cl-cache.jdbc.fqn.type}
- cache.jdbc.node.column=${jbosscache-cl-cache.jdbc.node.column}
- cache.jdbc.node.type=${jbosscache-cl-cache.jdbc.node.type}
- cache.jdbc.parent.column=${jbosscache-cl-cache.jdbc.parent.column}
- cache.jdbc.datasource=${jbosscache-cl-cache.jdbc.datasource}
- </properties>
- </loader>
- </loaders>
-</jbosscache></programlisting>
-
- <para>As you see, all configurable paramaters filled by templates and
- will be replaced by LockManagers conf parameters:</para>
-
- <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- <properties>
- <property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
- <property name="jgroups-configuration" value="udp-mux.xml" />
- <property name="jgroups-multiplexer-stack" value="true" />
- <property name="jbosscache-cluster-name" value="JCR-cluster-locks-ws" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_ws" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_ws_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.fqn.type" value="AUTO"/>
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.node.type" value="AUTO"/>
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
- </properties>
-</lock-manager></programlisting>
-
- <para>Configuration requirements:<itemizedlist>
- <listitem>
- <para><parameter>jbosscache-cl-cache.jdbc.fqn.column</parameter>
- and <parameter>jbosscache-cl-cache.jdbc.node.type</parameter> is
- nothing else as cache.jdbc.fqn.type and cache.jdbc.node.type in
- JBoss-Cache configuration. You can set those data types according
- to database type (See <link endterm="datatypes.title"
- linkend="datatypes"></link>) or set it as AUTO (or do not set at
- all) and data type will by detected automaticaly.</para>
- </listitem>
-
- <listitem>
- <para>as you see, jgroups-configuration moved to separate config
- file - udp-mux.xml; In our case udp-mux.xml is common JGroup
- config for all components (QueryHandler, cache, LockManager). But
- we, still, can create own config.</para>
- </listitem>
- </itemizedlist></para>
-
- <para><filename>our-udp-mux.xml</filename><programlisting><protocol_stacks>
- <stack name="jcr.stack">
- <config>
- <UDP mcast_addr="228.10.10.10" mcast_port="45588" tos="8" ucast_recv_buf_size="20000000"
- ucast_send_buf_size="640000" mcast_recv_buf_size="25000000" mcast_send_buf_size="640000" loopback="false"
- discard_incompatible_packets="true" max_bundle_size="64000" max_bundle_timeout="30"
- use_incoming_packet_handler="true" ip_ttl="2" enable_bundling="true" enable_diagnostics="true"
- thread_naming_pattern="cl" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="2"
- thread_pool.max_threads="8" thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="true"
- thread_pool.queue_max_size="1000" thread_pool.rejection_policy="discard" oob_thread_pool.enabled="true"
- oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000"
- oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="Run" />
-
- <PING timeout="2000" num_initial_members="3" />
- <MERGE2 max_interval="30000" min_interval="10000" />
- <FD_SOCK />
- <FD timeout="10000" max_tries="5" shun="true" />
- <VERIFY_SUSPECT timeout="1500" />
- <BARRIER />
- <pbcast.NAKACK use_stats_for_retransmission="false" exponential_backoff="150" use_mcast_xmit="true"
- gc_lag="0" retransmit_timeout="50,300,600,1200" discard_delivered_msgs="true" />
- <UNICAST timeout="300,600,1200" />
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="1000000" />
- <VIEW_SYNC avg_send_interval="60000" />
- <pbcast.GMS print_local_addr="true" join_timeout="3000" shun="false" view_bundling="true" />
- <FC max_credits="500000" min_threshold="0.20" />
- <FRAG2 frag_size="60000" />
- <!--pbcast.STREAMING_STATE_TRANSFER /-->
- <pbcast.STATE_TRANSFER />
- <!-- pbcast.FLUSH /-->
- </config>
- </stack>
-</protocol_stacks> </programlisting></para>
- </section>
-
- <section id="datatypes">
- <title id="datatypes.title">Data Types in Different Databases</title>
-
- <table>
- <title>Fqn type and node type in different databases</title>
-
- <tgroup cols="3">
- <thead>
- <row>
- <entry>DataBase name</entry>
-
- <entry>Node data type</entry>
-
- <entry>FQN data type</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>default</entry>
-
- <entry>BLOB</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>HSSQL</entry>
-
- <entry>OBJECT</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>MySQL</entry>
-
- <entry>LONGBLOB</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>ORACLE</entry>
-
- <entry>BLOB</entry>
-
- <entry>VARCHAR2(512)</entry>
- </row>
-
- <row>
- <entry>PostgreSQL</entry>
-
- <entry>bytea</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>MSSQL</entry>
-
- <entry>VARBINARY(MAX)</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>DB2</entry>
-
- <entry>BLOB</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>Sybase</entry>
-
- <entry>IMAGE</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
-
- <row>
- <entry>Ingres</entry>
-
- <entry>long byte</entry>
-
- <entry>VARCHAR(512)</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.LockManagerConfiguration">
+ <?dbhtml filename="ch-lock-manager-config.html"?>
+
+ <title>LockManager configuration</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>What LockManager does?</para>
+
+ <para>In common words, LockManager stores lock objects, so it can give
+ Lock object or can release it, etc.</para>
+
+ <para>Also LockManager is responsible for removing Locks that live too
+ long. This parameter may be configured with "time-out" property.</para>
+
+ <para>JCR provide two base implementation of LockManager:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><classname>org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl</classname>;</para>
+ </listitem>
+
+ <listitem>
+ <para><classname>org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl</classname>;</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In this article we will talk mostly about
+ CacheableLockManagerImpl.</para>
+
+ <para>You can enable LockManager by adding lock-manager-configuration to
+ workspace-configuration.</para>
+
+ <para>For example:</para>
+
+ <programlisting><workspace name="ws">
+ ...
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ ...
+ </properties>
+ </lock-manager>
+ ...
+</workspace></programlisting>
+ </section>
+
+ <section>
+ <title>LockManagerImpl</title>
+
+ <para>LockManagerImpl is simple implementation of LockManager, and also
+ faster than CacheableLockManager. It stores Lock objects in HashMap and
+ may also persist Locks if LockPersister is configured. LockManagerImpl do
+ not support replication in any way.</para>
+
+ <para>See more about LockManager Configuration <link
+ linkend="JCR.eXoJCRconfiguration">here</link>.</para>
+ </section>
+
+ <section>
+ <title>CacheableLockManagerImpl</title>
+
+ <para>CacheableLockManagerImpl stores Lock object in JBoss-cache, so Locks
+ are replicable and affects on cluster, not only a single node. Also
+ JBoss-cache has JDBCCacheLoader, so locks will be stored to
+ database.</para>
+
+ <para>Both implementation supports Expired Locks removing. There is
+ LockRemover - separate thread, that periodically ask LockManager for Locks
+ that lives to much and must be removed. So, timeout for LockRemover may be
+ set as follows, default value is 30m.</para>
+
+ <programlisting><properties>
+ <property name="time-out" value="10m" />
+ ...
+</properties></programlisting>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>Replication requirements are same as for Cache</para>
+
+ <para>Full JCR configuration example you can see <link
+ linkend="JCR.ClusterConfig.JCRExternalConfig">here</link>.</para>
+
+ <para>Common tips:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><parameter>clusterName</parameter> ("jbosscache-cluster-name")
+ must be unique;</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>cache.jdbc.table.name</parameter> must be unique
+ per datasource;</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>cache.jdbc.fqn.type</parameter> must and
+ cache.jdbc.node.type must be configured according to used
+ database;</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>There is few ways how to configure CacheableLockManagerImpl, and
+ all of them configures JBoss-cache and JDBCCacheLoader.</para>
+
+ <para>See <ulink
+ url="http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader">http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader</ulink></para>
+ </section>
+
+ <section>
+ <title>Simple JbossCache Configuraion</title>
+
+ <para>First one is - put JbossCache configuraion file path to
+ CacheableLockManagerImpl</para>
+
+ <para><note>
+ <para>This configuration is not so good, as you can think. Because
+ repository may contain many workspaces, and each workspace must
+ contain LockManager configuration, and LockManager config may
+ contain JbossCache config file. So total configuration is growing
+ up. But it is usefull if we want a single LockManager with special
+ configuration.</para>
+ </note></para>
+
+ <para>Config is:</para>
+
+ <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="conf/standalone/cluster/test-jbosscache-lock-config.xml" />
+ </properties>
+</lock-manager></programlisting>
+
+ <para><filename>test-jbosscache-lock-config.xml</filename><programlisting><?xml version="1.0" encoding="UTF-8"?>
+<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">
+
+ <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" />
+
+ <clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_Name">
+ <stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true" />
+ <jgroupsConfig>
+
+ <TCP bind_addr="127.0.0.1" start_port="9800" loopback="true" recv_buf_size="20000000" send_buf_size="640000" discard_incompatible_packets="true"
+ max_bundle_size="64000" max_bundle_timeout="30" use_incoming_packet_handler="true" enable_bundling="false" use_send_queues="false" sock_conn_timeout="300"
+ skip_suspected_members="true" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="1" thread_pool.max_threads="25"
+ thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="false" thread_pool.queue_max_size="100" thread_pool.rejection_policy="run"
+ oob_thread_pool.enabled="true" oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="run" />
+ <MPING timeout="2000" num_initial_members="2" mcast_port="34540" bind_addr="127.0.0.1" mcast_addr="224.0.0.1" />
+
+
+ <MERGE2 max_interval="30000" min_interval="10000" />
+ <FD_SOCK />
+ <FD max_tries="5" shun="true" timeout="10000" />
+ <VERIFY_SUSPECT timeout="1500" />
+ <pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800" use_mcast_xmit="false" />
+ <UNICAST timeout="300,600,1200,2400,3600" />
+ <pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000" />
+ <pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000" view_bundling="true" />
+ <FRAG2 frag_size="60000" />
+ <pbcast.STREAMING_STATE_TRANSFER />
+ <pbcast.FLUSH timeout="0" />
+
+ </jgroupsConfig
+
+ <sync />
+ </clustering>
+
+ <loaders passivation="false" shared="true">
+ <preload>
+ <node fqn="/" />
+ </preload>
+ <loader class="org.jboss.cache.loader.JDBCCacheLoader" async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ cache.jdbc.table.name=jcrlocks_ws
+ cache.jdbc.table.create=true
+ cache.jdbc.table.drop=false
+ cache.jdbc.table.primarykey=jcrlocks_ws_pk
+ cache.jdbc.fqn.column=fqn
+ cache.jdbc.fqn.type=VARCHAR(512)
+ cache.jdbc.node.column=node
+ cache.jdbc.node.type=<BLOB>
+ cache.jdbc.parent.column=parent
+ cache.jdbc.datasource=jdbcjcr
+ </properties>
+ </loader>
+
+ </loaders>
+
+</jbosscache></programlisting></para>
+
+ <para>Configuration requirements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><clustering mode="replication"
+ clusterName="JBoss-Cache-Lock-Cluster_Name"> - cluster name must
+ be unique;</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>cache.jdbc.table.name</parameter> must be unique
+ per datasource;</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>cache.jdbc.node.type</parameter> and
+ <parameter>cache.jdbc.fqn.type</parameter> must be configured
+ according to using database. See <link endterm="datatypes.title"
+ linkend="datatypes"></link> .</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Template JBossCache Configuration</title>
+
+ <para>Second one is - use template JBoss-cache configuration for all
+ LockManagers</para>
+
+ <para><citetitle>Lock template configuration</citetitle></para>
+
+ <para><filename>test-jbosscache-lock.xml</filename></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1">
+
+ <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false"
+ lockAcquisitionTimeout="20000" />
+
+ <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
+ <stateRetrieval timeout="20000" fetchInMemoryState="false" />
+ <jgroupsConfig multiplexerStack="jcr.stack" />
+ <sync />
+ </clustering>
+
+ <loaders passivation="false" shared="true">
+ <!-- All the data of the JCR locks needs to be loaded at startup -->
+ <preload>
+ <node fqn="/" />
+ </preload>
+ <!--
+ For another cache-loader class you should use another template with
+ cache-loader specific parameters
+ ->
+ <loader class="org.jboss.cache.loader.JDBCCacheLoader" async=q"false" fetchPersistentState="false"
+ ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ cache.jdbc.table.name=${jbosscache-cl-cache.jdbc.table.name}
+ cache.jdbc.table.create=${jbosscache-cl-cache.jdbc.table.create}
+ cache.jdbc.table.drop=${jbosscache-cl-cache.jdbc.table.drop}
+ cache.jdbc.table.primarykey=${jbosscache-cl-cache.jdbc.table.primarykey}
+ cache.jdbc.fqn.column=${jbosscache-cl-cache.jdbc.fqn.column}
+ cache.jdbc.fqn.type=${jbosscache-cl-cache.jdbc.fqn.type}
+ cache.jdbc.node.column=${jbosscache-cl-cache.jdbc.node.column}
+ cache.jdbc.node.type=${jbosscache-cl-cache.jdbc.node.type}
+ cache.jdbc.parent.column=${jbosscache-cl-cache.jdbc.parent.column}
+ cache.jdbc.datasource=${jbosscache-cl-cache.jdbc.datasource}
+ </properties>
+ </loader>
+ </loaders>
+</jbosscache></programlisting>
+
+ <para>As you see, all configurable paramaters filled by templates and
+ will be replaced by LockManagers conf parameters:</para>
+
+ <programlisting><lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-locks-ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_ws_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.type" value="AUTO"/>
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.node.type" value="AUTO"/>
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ </properties>
+</lock-manager></programlisting>
+
+ <para>Configuration requirements:<itemizedlist>
+ <listitem>
+ <para><parameter>jbosscache-cl-cache.jdbc.fqn.column</parameter>
+ and <parameter>jbosscache-cl-cache.jdbc.node.type</parameter> is
+ nothing else as cache.jdbc.fqn.type and cache.jdbc.node.type in
+ JBoss-Cache configuration. You can set those data types according
+ to database type (See <link endterm="datatypes.title"
+ linkend="datatypes"></link>) or set it as AUTO (or do not set at
+ all) and data type will by detected automaticaly.</para>
+ </listitem>
+
+ <listitem>
+ <para>as you see, jgroups-configuration moved to separate config
+ file - udp-mux.xml; In our case udp-mux.xml is common JGroup
+ config for all components (QueryHandler, cache, LockManager). But
+ we, still, can create own config.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><filename>our-udp-mux.xml</filename><programlisting><protocol_stacks>
+ <stack name="jcr.stack">
+ <config>
+ <UDP mcast_addr="228.10.10.10" mcast_port="45588" tos="8" ucast_recv_buf_size="20000000"
+ ucast_send_buf_size="640000" mcast_recv_buf_size="25000000" mcast_send_buf_size="640000" loopback="false"
+ discard_incompatible_packets="true" max_bundle_size="64000" max_bundle_timeout="30"
+ use_incoming_packet_handler="true" ip_ttl="2" enable_bundling="true" enable_diagnostics="true"
+ thread_naming_pattern="cl" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="2"
+ thread_pool.max_threads="8" thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000" thread_pool.rejection_policy="discard" oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="Run" />
+
+ <PING timeout="2000" num_initial_members="3" />
+ <MERGE2 max_interval="30000" min_interval="10000" />
+ <FD_SOCK />
+ <FD timeout="10000" max_tries="5" shun="true" />
+ <VERIFY_SUSPECT timeout="1500" />
+ <BARRIER />
+ <pbcast.NAKACK use_stats_for_retransmission="false" exponential_backoff="150" use_mcast_xmit="true"
+ gc_lag="0" retransmit_timeout="50,300,600,1200" discard_delivered_msgs="true" />
+ <UNICAST timeout="300,600,1200" />
+ <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="1000000" />
+ <VIEW_SYNC avg_send_interval="60000" />
+ <pbcast.GMS print_local_addr="true" join_timeout="3000" shun="false" view_bundling="true" />
+ <FC max_credits="500000" min_threshold="0.20" />
+ <FRAG2 frag_size="60000" />
+ <!--pbcast.STREAMING_STATE_TRANSFER /-->
+ <pbcast.STATE_TRANSFER />
+ <!-- pbcast.FLUSH /-->
+ </config>
+ </stack>
+</protocol_stacks> </programlisting></para>
+ </section>
+
+ <section id="datatypes">
+ <title id="datatypes.title">Data Types in Different Databases</title>
+
+ <table>
+ <title>Fqn type and node type in different databases</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>DataBase name</entry>
+
+ <entry>Node data type</entry>
+
+ <entry>FQN data type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>default</entry>
+
+ <entry>BLOB</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>HSSQL</entry>
+
+ <entry>OBJECT</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>MySQL</entry>
+
+ <entry>LONGBLOB</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>ORACLE</entry>
+
+ <entry>BLOB</entry>
+
+ <entry>VARCHAR2(512)</entry>
+ </row>
+
+ <row>
+ <entry>PostgreSQL</entry>
+
+ <entry>bytea</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>MSSQL</entry>
+
+ <entry>VARBINARY(MAX)</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>DB2</entry>
+
+ <entry>BLOB</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>Sybase</entry>
+
+ <entry>IMAGE</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+
+ <row>
+ <entry>Ingres</entry>
+
+ <entry>long byte</entry>
+
+ <entry>VARCHAR(512)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/fulltext-search-and-settings.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/fulltext-search-and-settings.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/fulltext-search-and-settings.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,280 +1,281 @@
-<?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="JCR.FulltextSearchAndSettings">
- <title>Fulltext Search And Affecting Settings</title>
-
- <section>
- <title>Property content indexing</title>
-
- <para>Each property of a node (if it is indexable) is processed with
- Lucene analyzer and stored in Lucene index. That's called indexing of a
- property. After that we can perform a fulltext search among these indexed
- properties.</para>
- </section>
-
- <section>
- <title>Lucene Analyzers</title>
-
- <para>The sense of analyzers is to transform all strings stored in the
- index in a well-defined condition. The same analyzer(s) is/are used when
- searching in order to adapt the query string to the index reality.</para>
-
- <para>Therefore, performing the same query using different analyzers can
- return different results.</para>
-
- <para>Now, let's see how the same string is transformed by different
- analyzers.</para>
-
- <table>
- <title>"The quick brown fox jumped over the lazy dogs"</title>
-
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Analyzer</entry>
-
- <entry>Parsed</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>org.apache.lucene.analysis.WhitespaceAnalyzer</entry>
-
- <entry>[The] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
- [dogs]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.SimpleAnalyzer</entry>
-
- <entry>[the] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
- [dogs]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.StopAnalyzer</entry>
-
- <entry>[quick] [brown] [fox] [jumped] [over] [lazy] [dogs]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
-
- <entry>[quick] [brown] [fox] [jumped] [over] [lazy] [dogs]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.snowball.SnowballAnalyzer</entry>
-
- <entry>[quick] [brown] [fox] [jump] [over] [lazi] [dog]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer
- (configured without stop word - jcr default analyzer)</entry>
-
- <entry>[the] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
- [dogs]</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table>
- <title>"XY&Z Corporation - xyz(a)example.com"</title>
-
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Analyzer</entry>
-
- <entry>Parsed</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>org.apache.lucene.analysis.WhitespaceAnalyzer</entry>
-
- <entry>[XY&Z] [Corporation] [-] [xyz(a)example.com]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.SimpleAnalyzer</entry>
-
- <entry>[xy] [z] [corporation] [xyz] [example] [com]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.StopAnalyzer</entry>
-
- <entry>[xy] [z] [corporation] [xyz] [example] [com]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
-
- <entry>[xy&z] [corporation] [xyz@example] [com]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.snowball.SnowballAnalyzer</entry>
-
- <entry>[xy&z] [corpor] [xyz@exampl] [com]</entry>
- </row>
-
- <row>
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer
- (configured without stop word - jcr default analyzer)</entry>
-
- <entry>[xy&z] [corporation] [xyz@example] [com]</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <note>
- <para>StandardAnalyzer is the default analyzer in exo's jcr search
- engine. But we do not use stop words.</para>
- </note>
-
- <para>You can assign your analyzer as described in <link
- linkend="JCR.SearchConfiguration">Search Configuration</link></para>
- </section>
-
- <section>
- <title>How are different properties indexed?</title>
-
- <para>Different properties are indexed in different ways, this affect to
- can it be searched like fulltext by property or not.</para>
-
- <para>Only two property types are indexed as fulltext searcheable: STRING
- and BINARY.</para>
-
- <table>
- <title>Fulltext search by different properties</title>
-
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Property Type</entry>
-
- <entry>Fulltext search by all properties</entry>
-
- <entry>Fulltext search by exact property</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>STRING</entry>
-
- <entry>YES</entry>
-
- <entry>YES</entry>
- </row>
-
- <row>
- <entry>BINARY</entry>
-
- <entry>YES</entry>
-
- <entry>NO</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>For example. We have property jcr:data (it' BINARY). Its stored
- well. But you will newer find any string with query like:</para>
-
- <programlisting>SELECT * FROM nt:resource WHERE CONTAINS(jcr:data, 'some string')</programlisting>
-
- <para>Because, BINARY is not searchable by fulltext search on exact
- property.</para>
-
- <para>But, next query will return result (off course if node has searched
- data):</para>
-
- <programlisting>SELECT * FROM nt:resource WHERE CONTAINS( * , 'some string')</programlisting>
- </section>
-
- <section>
- <title>Fulltext search query examples</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.FulltextSearchByProperty">JCR.Fulltext Search
- by Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FulltextSearchByAllProperties">JCR.Fulltext
- Search by All Properties</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.AggregationRule">Find nt:file document by
- content of its child jcr:content node</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.IgnoreAccentSymbols">How to set a new
- analyzer. Accent symbols ignoring</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Different analyzers in action</title>
-
- <para>First of all, we will fill repository by nodes with mixin type
- 'mix:title' and different values of 'jcr:description' property.</para>
-
- <itemizedlist>
- <listitem>
- <para>root</para>
-
- <itemizedlist>
- <listitem>
- <para>document1 (mix:title) jcr:description = "The quick brown fox
- jumped over the lazy dogs"</para>
- </listitem>
-
- <listitem>
- <para>document2 (mix:title) jcr:description = "Brown fox live in
- forest."</para>
- </listitem>
-
- <listitem>
- <para>document3 (mix:title) jcr:description = "Fox is a nice
- animal."</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- <para>Lets see analyzers effect closer. In first case we use base jcr
- settings, so, as mentioned above, string "The quick brown fox jumped over
- the lazy dogs" will be transformed to set {[the] [quick] [brown] [fox]
- [jumped] [over] [the] [lazy] [dogs] }</para>
-
- <programlisting>// make SQL query
-QueryManager queryManager = workspace.getQueryManager();
-String sqlStatement = "SELECT * FROM mix:title WHERE CONTAINS(jcr:description, 'the')";
-// create query
-Query query = queryManager.createQuery(sqlStatement, Query.SQL);
-// execute query and fetch result
-QueryResult result = query.execute();</programlisting>
-
- <para>NodeIterator will return "document1".</para>
-
- <para>Now change default analyzer to
- org.apache.lucene.analysis.StopAnalyzer. Fill repository again (new
- Analyzer must process nodes properties) and run same query again. It will
- return nothing, because stop words like "the" will be excluded from parsed
- string set.</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="JCR.FulltextSearchAndSettings">
+ <?dbhtml filename="ch-jcr-fulltext-search-and-settings.html"?>
+ <title>Fulltext Search And Affecting Settings</title>
+
+ <section>
+ <title>Property content indexing</title>
+
+ <para>Each property of a node (if it is indexable) is processed with
+ Lucene analyzer and stored in Lucene index. That's called indexing of a
+ property. After that we can perform a fulltext search among these indexed
+ properties.</para>
+ </section>
+
+ <section>
+ <title>Lucene Analyzers</title>
+
+ <para>The sense of analyzers is to transform all strings stored in the
+ index in a well-defined condition. The same analyzer(s) is/are used when
+ searching in order to adapt the query string to the index reality.</para>
+
+ <para>Therefore, performing the same query using different analyzers can
+ return different results.</para>
+
+ <para>Now, let's see how the same string is transformed by different
+ analyzers.</para>
+
+ <table>
+ <title>"The quick brown fox jumped over the lazy dogs"</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Analyzer</entry>
+
+ <entry>Parsed</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.apache.lucene.analysis.WhitespaceAnalyzer</entry>
+
+ <entry>[The] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
+ [dogs]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.SimpleAnalyzer</entry>
+
+ <entry>[the] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
+ [dogs]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.StopAnalyzer</entry>
+
+ <entry>[quick] [brown] [fox] [jumped] [over] [lazy] [dogs]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
+
+ <entry>[quick] [brown] [fox] [jumped] [over] [lazy] [dogs]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.snowball.SnowballAnalyzer</entry>
+
+ <entry>[quick] [brown] [fox] [jump] [over] [lazi] [dog]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer
+ (configured without stop word - jcr default analyzer)</entry>
+
+ <entry>[the] [quick] [brown] [fox] [jumped] [over] [the] [lazy]
+ [dogs]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>"XY&Z Corporation - xyz(a)example.com"</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Analyzer</entry>
+
+ <entry>Parsed</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.apache.lucene.analysis.WhitespaceAnalyzer</entry>
+
+ <entry>[XY&Z] [Corporation] [-] [xyz(a)example.com]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.SimpleAnalyzer</entry>
+
+ <entry>[xy] [z] [corporation] [xyz] [example] [com]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.StopAnalyzer</entry>
+
+ <entry>[xy] [z] [corporation] [xyz] [example] [com]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
+
+ <entry>[xy&z] [corporation] [xyz@example] [com]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.snowball.SnowballAnalyzer</entry>
+
+ <entry>[xy&z] [corpor] [xyz@exampl] [com]</entry>
+ </row>
+
+ <row>
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer
+ (configured without stop word - jcr default analyzer)</entry>
+
+ <entry>[xy&z] [corporation] [xyz@example] [com]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>StandardAnalyzer is the default analyzer in exo's jcr search
+ engine. But we do not use stop words.</para>
+ </note>
+
+ <para>You can assign your analyzer as described in <link
+ linkend="JCR.SearchConfiguration">Search Configuration</link></para>
+ </section>
+
+ <section>
+ <title>How are different properties indexed?</title>
+
+ <para>Different properties are indexed in different ways, this affect to
+ can it be searched like fulltext by property or not.</para>
+
+ <para>Only two property types are indexed as fulltext searcheable: STRING
+ and BINARY.</para>
+
+ <table>
+ <title>Fulltext search by different properties</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Property Type</entry>
+
+ <entry>Fulltext search by all properties</entry>
+
+ <entry>Fulltext search by exact property</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>STRING</entry>
+
+ <entry>YES</entry>
+
+ <entry>YES</entry>
+ </row>
+
+ <row>
+ <entry>BINARY</entry>
+
+ <entry>YES</entry>
+
+ <entry>NO</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>For example. We have property jcr:data (it' BINARY). Its stored
+ well. But you will newer find any string with query like:</para>
+
+ <programlisting>SELECT * FROM nt:resource WHERE CONTAINS(jcr:data, 'some string')</programlisting>
+
+ <para>Because, BINARY is not searchable by fulltext search on exact
+ property.</para>
+
+ <para>But, next query will return result (off course if node has searched
+ data):</para>
+
+ <programlisting>SELECT * FROM nt:resource WHERE CONTAINS( * , 'some string')</programlisting>
+ </section>
+
+ <section>
+ <title>Fulltext search query examples</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByProperty">JCR.Fulltext Search
+ by Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByAllProperties">JCR.Fulltext
+ Search by All Properties</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.AggregationRule">Find nt:file document by
+ content of its child jcr:content node</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.IgnoreAccentSymbols">How to set a new
+ analyzer. Accent symbols ignoring</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Different analyzers in action</title>
+
+ <para>First of all, we will fill repository by nodes with mixin type
+ 'mix:title' and different values of 'jcr:description' property.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>document1 (mix:title) jcr:description = "The quick brown fox
+ jumped over the lazy dogs"</para>
+ </listitem>
+
+ <listitem>
+ <para>document2 (mix:title) jcr:description = "Brown fox live in
+ forest."</para>
+ </listitem>
+
+ <listitem>
+ <para>document3 (mix:title) jcr:description = "Fox is a nice
+ animal."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>Lets see analyzers effect closer. In first case we use base jcr
+ settings, so, as mentioned above, string "The quick brown fox jumped over
+ the lazy dogs" will be transformed to set {[the] [quick] [brown] [fox]
+ [jumped] [over] [the] [lazy] [dogs] }</para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+String sqlStatement = "SELECT * FROM mix:title WHERE CONTAINS(jcr:description, 'the')";
+// create query
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para>NodeIterator will return "document1".</para>
+
+ <para>Now change default analyzer to
+ org.apache.lucene.analysis.StopAnalyzer. Fill repository again (new
+ Analyzer must process nodes properties) and run same query again. It will
+ return nothing, because stop words like "the" will be excluded from parsed
+ string set.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml 2010-08-04 13:51:23 UTC (rev 2874)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml 2010-08-04 15:01:37 UTC (rev 2875)
@@ -1,374 +1,374 @@
-<?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="JCR.SearchingRepositoryContent">
- <?dbhtml filename="ch-jcr-searching-repository-conten.html"?>
-
- <title>Searching Repository Content</title>
-
- <section>
- <title>Introduction</title>
-
- <para>You can find the JCR configuration file here:
- .../portal/WEB-INF/conf/jcr/repository-configuration.xml. Please read also
- <link linkend="JCR.SearchConfiguration">Search Configuration</link> for
- more information about index configuration.</para>
- </section>
-
- <section>
- <title>Bi-directional RangeIterator (since 1.9)</title>
-
- <para>QueryResult.getNodes() will return bi-directional NodeIterator
- implementation.</para>
-
- <note>
- <para>Bi-directional NodeIterator is <emphasis role="bold">not
- supported</emphasis> in two cases:</para>
-
- <itemizedlist>
- <listitem>
- <para>SQL query: select * from nt:base</para>
- </listitem>
-
- <listitem>
- <para>XPath query: //* .</para>
- </listitem>
- </itemizedlist>
-
- <para>")</para>
- </note>
-
- <para>TwoWayRangeIterator interface:</para>
-
- <programlisting>/**
- * Skip a number of elements in the iterator.
- *
- * @param skipNum the non-negative number of elements to skip
- * @throws java.util.NoSuchElementException if skipped past the first element
- * in the iterator.
- */
-public void skipBack(long skipNum);</programlisting>
-
- <para>Usage:</para>
-
- <programlisting>NodeIterator iter = queryResult.getNodes();
-while (iter.hasNext()) {
- if (skipForward) {
- iter.skip(10); // Skip 10 nodes in forward direction
- } else if (skipBack) {
- TwoWayRangeIterator backIter = (TwoWayRangeIterator) iter;
- backIter.skipBack(10); // Skip 10 nodes back
- }
- .......
-}</programlisting>
- </section>
-
- <section>
- <title>Fuzzy Searches (since 1.0)</title>
-
- <para>JCR supports such features as Lucene Fuzzy Searches <ulink
- url="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Apache
- Lucene - Query Parser Syntax</ulink>.</para>
-
- <para>To use it you have to form a query like described below:</para>
-
- <programlisting>QueryManager qman = session.getWorkspace().getQueryManager();
-Query q = qman.createQuery("select * from nt:base where contains(field, 'ccccc~')", Query.SQL);
-QueryResult res = q.execute();</programlisting>
- </section>
-
- <section>
- <title>SynonymSearch (since 1.9)</title>
-
- <para>Searching with synonyms is integrated in the jcr:contains() function
- and uses the same syntax as synonym searches in Google. If a search term
- is prefixed by a tilde symbol ( ~ ) also synonyms of the search term are
- taken into consideration. Example:</para>
-
- <programlisting>SQL: select * from nt:resource where contains(., '~parameter')
-
-XPath: //element(*, nt:resource)[jcr:contains(., '~parameter')</programlisting>
-
- <para>This feature is disabled per default and you need to add a
- configuration parameter to the query-handler element in your jcr
- configuration file to enable it.</para>
-
- <programlisting><param name="synonymprovider-config-path" value="..you path to configuration file....."/>
-<param name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider"/></programlisting>
-
- <programlisting>/**
- * <code>SynonymProvider</code> defines an interface for a component that
- * returns synonyms for a given term.
- */
-public interface SynonymProvider {
-
- /**
- * Initializes the synonym provider and passes the file system resource to
- * the synonym provider configuration defined by the configuration value of
- * the <code>synonymProviderConfigPath</code> parameter. The resource may be
- * <code>null</code> if the configuration parameter is not set.
- *
- * @param fsr the file system resource to the synonym provider
- * configuration.
- * @throws IOException if an error occurs while initializing the synonym
- * provider.
- */
- public void initialize(InputStream fsr) throws IOException;
-
- /**
- * Returns an array of terms that are considered synonyms for the given
- * <code>term</code>.
- *
- * @param term a search term.
- * @return an array of synonyms for the given <code>term</code> or an empty
- * array if no synonyms are known.
- */
- public String[] getSynonyms(String term);
-}</programlisting>
- </section>
-
- <section id="JCR.SearchingRepositoryContent.Highlighting">
- <title>Highlighting (Since 1.9)</title>
-
- <para>An ExcerptProvider retrieves text excerpts for a node in the query
- result and marks up the words in the text that match the query
- terms.</para>
-
- <para>Per default highlighting words that matched the query is disabled
- because this feature requires that additional information is written to
- the search index. To enable this feature you need to add a configuration
- parameter to the query-handler element in your jcr configuration file to
- enable it.</para>
-
- <programlisting><param name="support-highlighting" value="true"/></programlisting>
-
- <para>Additionally there is a parameter that controls the format of the
- excerpt created. In JCR 1.9 the default is set to
- org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt.
- The configuration parameter for this setting is:</para>
-
- <programlisting><param name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultXMLExcerpt"/></programlisting>
-
- <section>
- <title>DefaultXMLExcerpt</title>
-
- <para>This excerpt provider creates an XML fragment of the following
- form:</para>
-
- <programlisting><excerpt>
- <fragment>
- <highlight>exoplatform</highlight> implements both the mandatory
- XPath and optional SQL <highlight>query</highlight> syntax.
- </fragment>
- <fragment>
- Before parsing the XPath <highlight>query</highlight> in
- <highlight>exoplatform</highlight>, the statement is surrounded
- </fragment>
-</excerpt></programlisting>
- </section>
-
- <section>
- <title>DefaultHTMLExcerpt</title>
-
- <para>This excerpt provider creates an HTML fragment of the following
- form:</para>
-
- <programlisting><div>
- <span>
- <strong>exoplatform</strong> implements both the mandatory XPath
- and optional SQL <strong>query</strong> syntax.
- </span>
- <span>
- Before parsing the XPath <strong>query</strong> in
- <strong>exoplatform</strong>, the statement is surrounded
- </span>
-</div></programlisting>
- </section>
-
- <section>
- <title>How to use it</title>
-
- <para>If you are using XPath you must use the rep:excerpt() function in
- the last location step, just like you would select properties:</para>
-
- <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
-Query q = qm.createQuery("//*[jcr:contains(., 'exoplatform')]/(@Title|rep:excerpt(.))", Query.XPATH);
-QueryResult result = q.execute();
-for (RowIterator it = result.getRows(); it.hasNext(); ) {
- Row r = it.nextRow();
- Value title = r.getValue("Title");
- Value excerpt = r.getValue("rep:excerpt(.)");
-}</programlisting>
-
- <para>The above code searches for nodes that contain the word
- exoplatform and then gets the value of the Title property and an excerpt
- for each result node.</para>
-
- <para>It is also possible to use a relative path in the call
- Row.getValue() while the query statement still remains the same. Also
- you may use a relative path to a string property. The returned value
- will then be an excerpt based on string value of the property.</para>
-
- <para>Both available excerpt provider will create fragments of about 150
- characters and up to 3 fragments.</para>
-
- <para>In SQL the function is called excerpt() without the rep prefix,
- but the column in the RowIterator will nonetheless be labled
- rep:excerpt(.)!</para>
-
- <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
-Query q = qm.createQuery("select excerpt(.) from nt:resource where contains(., 'exoplatform')", Query.SQL);
-QueryResult result = q.execute();
-for (RowIterator it = result.getRows(); it.hasNext(); ) {
- Row r = it.nextRow();
- Value excerpt = r.getValue("rep:excerpt(.)");
-}</programlisting>
- </section>
- </section>
-
- <section>
- <title>SpellChecker</title>
-
- <para>The lucene based query handler implementation supports a pluggable
- spell checker mechanism. Per default spell checking is not available and
- you have to configure it first. See parameter spellCheckerClass on page
- <link linkend="JCR.SearchConfiguration">Search Configuration</link> JCR
- currently provides an implementation class , which uses the <ulink
- url="http://wiki.apache.org/jakarta-lucene/SpellChecker">lucene-spellchecker</ulink>
- contrib . The dictionary is derived from the fulltext indexed content of
- the workspace and updated periodically. You can configure the refresh
- interval by picking one of the available inner classes of
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker:</para>
-
- <itemizedlist>
- <listitem>
- <para>OneMinuteRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>FiveMinutesRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>ThirtyMinutesRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>OneHourRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>SixHoursRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>TwelveHoursRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>OneDayRefreshInterval</para>
- </listitem>
- </itemizedlist>
-
- <para>E.g. if you want a refresh interval of six hours the class name is:
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$SixHoursRefreshInterval.
- If you use
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker
- the refresh interval will be one hour.</para>
-
- <para>The spell checker dictionary is stored as a lucene index under
- <emphasis role="bold">"index-dir"/spellchecker</emphasis>. If it does not
- exist, a background thread will create it on startup. Similarly the
- dictionary refresh is also done in a background thread to not block
- regular queries.</para>
-
- <section>
- <title>How do I use it?</title>
-
- <para>You can spell check a fulltext statement either with an XPath or a
- SQL query:</para>
-
- <programlisting>// rep:spellcheck('explatform') will always evaluate to true
-Query query = qm.createQuery("/jcr:root[rep:spellcheck('explatform')]/(rep:spellcheck())", Query.XPATH);
-RowIterator rows = query.execute().getRows();
-// the above query will always return the root node no matter what string we check
-Row r = rows.nextRow();
-// get the result of the spell checking
-Value v = r.getValue("rep:spellcheck()");
-if (v == null) {
- // no suggestion returned, the spelling is correct or the spell checker
- // does not know how to correct it.
-} else {
- String suggestion = v.getString();
-}</programlisting>
-
- <para>And the same using SQL:</para>
-
- <programlisting>// SPELLCHECK('exoplatform') will always evaluate to true
-Query query = qm.createQuery("SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('explatform')", Query.SQL);
-RowIterator rows = query.execute().getRows();
-// the above query will always return the root node no matter what string we check
-Row r = rows.nextRow();
-// get the result of the spell checking
-Value v = r.getValue("rep:spellcheck()");
-if (v == null) {
- // no suggestion returned, the spelling is correct or the spell checker
- // does not know how to correct it.
-} else {
- String suggestion = v.getString();
-}</programlisting>
- </section>
- </section>
-
- <section>
- <title>Similarity (Since 1.12)</title>
-
- <para>Starting with version, 1.12 JCR allows you to search for nodes that
- are similar to an existing node.</para>
-
- <para>Similarity is determined by looking up terms that are common to
- nodes. There are some conditions that must be met for a term to be
- considered. This is required to limit the number possibly relevant
- terms.</para>
-
- <itemizedlist>
- <listitem>
- <para>Only terms with at least 4 characters are considered.</para>
- </listitem>
-
- <listitem>
- <para>Only terms that occur at least 2 times in the source node are
- considered.</para>
- </listitem>
-
- <listitem>
- <para>Only terms that occur in at least 5 nodes are considered.</para>
- </listitem>
- </itemizedlist>
-
- <para>Note: The similarity functionality requires that the
- supportHightlighting is enabled. Please make sure that you have the
- following parameter set for the query handler in your
- workspace.xml.</para>
-
- <programlisting><param name="support-highlighting" value="true"/></programlisting>
-
- <para>The functions are called rep:similar() (in XPath) and similar() (in
- SQL) and have two arguments:</para>
-
- <para>relativePath: a relative path to a descendant node or . for the
- current node. absoluteStringPath: a string literal that contains the path
- to the node for which to find similar nodes.</para>
-
- <warning>
- <para>Relative path is not supported yet.</para>
- </warning>
-
- <para>Examples:</para>
-
- <programlisting>//element(*, nt:resource)[rep:similar(., '/parentnode/node.txt/jcr:content')]</programlisting>
-
- <para>Finds nt:resource nodes, which are similar to node by path
- /parentnode/node.txt/jcr:content.</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="JCR.SearchingRepositoryContent">
+ <?dbhtml filename="ch-jcr-searching-repository-conten.html"?>
+
+ <title>Searching Repository Content</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>You can find the JCR configuration file here:
+ .../portal/WEB-INF/conf/jcr/repository-configuration.xml. Please read also
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> for
+ more information about index configuration.</para>
+ </section>
+
+ <section>
+ <title>Bi-directional RangeIterator (since 1.9)</title>
+
+ <para>QueryResult.getNodes() will return bi-directional NodeIterator
+ implementation.</para>
+
+ <note>
+ <para>Bi-directional NodeIterator is <emphasis role="bold">not
+ supported</emphasis> in two cases:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL query: select * from nt:base</para>
+ </listitem>
+
+ <listitem>
+ <para>XPath query: //* .</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>")</para>
+ </note>
+
+ <para>TwoWayRangeIterator interface:</para>
+
+ <programlisting>/**
+ * Skip a number of elements in the iterator.
+ *
+ * @param skipNum the non-negative number of elements to skip
+ * @throws java.util.NoSuchElementException if skipped past the first element
+ * in the iterator.
+ */
+public void skipBack(long skipNum);</programlisting>
+
+ <para>Usage:</para>
+
+ <programlisting>NodeIterator iter = queryResult.getNodes();
+while (iter.hasNext()) {
+ if (skipForward) {
+ iter.skip(10); // Skip 10 nodes in forward direction
+ } else if (skipBack) {
+ TwoWayRangeIterator backIter = (TwoWayRangeIterator) iter;
+ backIter.skipBack(10); // Skip 10 nodes back
+ }
+ .......
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Fuzzy Searches (since 1.0)</title>
+
+ <para>JCR supports such features as Lucene Fuzzy Searches <ulink
+ url="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Apache
+ Lucene - Query Parser Syntax</ulink>.</para>
+
+ <para>To use it you have to form a query like described below:</para>
+
+ <programlisting>QueryManager qman = session.getWorkspace().getQueryManager();
+Query q = qman.createQuery("select * from nt:base where contains(field, 'ccccc~')", Query.SQL);
+QueryResult res = q.execute();</programlisting>
+ </section>
+
+ <section id="JCR.SearchingRepositoryContent.SynonimProvider">
+ <title>SynonymSearch (since 1.9)</title>
+
+ <para>Searching with synonyms is integrated in the jcr:contains() function
+ and uses the same syntax as synonym searches in Google. If a search term
+ is prefixed by a tilde symbol ( ~ ) also synonyms of the search term are
+ taken into consideration. Example:</para>
+
+ <programlisting>SQL: select * from nt:resource where contains(., '~parameter')
+
+XPath: //element(*, nt:resource)[jcr:contains(., '~parameter')</programlisting>
+
+ <para>This feature is disabled per default and you need to add a
+ configuration parameter to the query-handler element in your jcr
+ configuration file to enable it.</para>
+
+ <programlisting><param name="synonymprovider-config-path" value="..you path to configuration file....."/>
+<param name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider"/></programlisting>
+
+ <programlisting>/**
+ * <code>SynonymProvider</code> defines an interface for a component that
+ * returns synonyms for a given term.
+ */
+public interface SynonymProvider {
+
+ /**
+ * Initializes the synonym provider and passes the file system resource to
+ * the synonym provider configuration defined by the configuration value of
+ * the <code>synonymProviderConfigPath</code> parameter. The resource may be
+ * <code>null</code> if the configuration parameter is not set.
+ *
+ * @param fsr the file system resource to the synonym provider
+ * configuration.
+ * @throws IOException if an error occurs while initializing the synonym
+ * provider.
+ */
+ public void initialize(InputStream fsr) throws IOException;
+
+ /**
+ * Returns an array of terms that are considered synonyms for the given
+ * <code>term</code>.
+ *
+ * @param term a search term.
+ * @return an array of synonyms for the given <code>term</code> or an empty
+ * array if no synonyms are known.
+ */
+ public String[] getSynonyms(String term);
+}</programlisting>
+ </section>
+
+ <section id="JCR.SearchingRepositoryContent.Highlighting">
+ <title>Highlighting (Since 1.9)</title>
+
+ <para>An ExcerptProvider retrieves text excerpts for a node in the query
+ result and marks up the words in the text that match the query
+ terms.</para>
+
+ <para>Per default highlighting words that matched the query is disabled
+ because this feature requires that additional information is written to
+ the search index. To enable this feature you need to add a configuration
+ parameter to the query-handler element in your jcr configuration file to
+ enable it.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>Additionally there is a parameter that controls the format of the
+ excerpt created. In JCR 1.9 the default is set to
+ org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt.
+ The configuration parameter for this setting is:</para>
+
+ <programlisting><param name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultXMLExcerpt"/></programlisting>
+
+ <section>
+ <title>DefaultXMLExcerpt</title>
+
+ <para>This excerpt provider creates an XML fragment of the following
+ form:</para>
+
+ <programlisting><excerpt>
+ <fragment>
+ <highlight>exoplatform</highlight> implements both the mandatory
+ XPath and optional SQL <highlight>query</highlight> syntax.
+ </fragment>
+ <fragment>
+ Before parsing the XPath <highlight>query</highlight> in
+ <highlight>exoplatform</highlight>, the statement is surrounded
+ </fragment>
+</excerpt></programlisting>
+ </section>
+
+ <section>
+ <title>DefaultHTMLExcerpt</title>
+
+ <para>This excerpt provider creates an HTML fragment of the following
+ form:</para>
+
+ <programlisting><div>
+ <span>
+ <strong>exoplatform</strong> implements both the mandatory XPath
+ and optional SQL <strong>query</strong> syntax.
+ </span>
+ <span>
+ Before parsing the XPath <strong>query</strong> in
+ <strong>exoplatform</strong>, the statement is surrounded
+ </span>
+</div></programlisting>
+ </section>
+
+ <section>
+ <title>How to use it</title>
+
+ <para>If you are using XPath you must use the rep:excerpt() function in
+ the last location step, just like you would select properties:</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("//*[jcr:contains(., 'exoplatform')]/(@Title|rep:excerpt(.))", Query.XPATH);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value title = r.getValue("Title");
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+
+ <para>The above code searches for nodes that contain the word
+ exoplatform and then gets the value of the Title property and an excerpt
+ for each result node.</para>
+
+ <para>It is also possible to use a relative path in the call
+ Row.getValue() while the query statement still remains the same. Also
+ you may use a relative path to a string property. The returned value
+ will then be an excerpt based on string value of the property.</para>
+
+ <para>Both available excerpt provider will create fragments of about 150
+ characters and up to 3 fragments.</para>
+
+ <para>In SQL the function is called excerpt() without the rep prefix,
+ but the column in the RowIterator will nonetheless be labled
+ rep:excerpt(.)!</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("select excerpt(.) from nt:resource where contains(., 'exoplatform')", Query.SQL);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+ </section>
+ </section>
+
+ <section id="JCR.SearchingRepositoryContent.SpellChecker">
+ <title>SpellChecker</title>
+
+ <para>The lucene based query handler implementation supports a pluggable
+ spell checker mechanism. Per default spell checking is not available and
+ you have to configure it first. See parameter spellCheckerClass on page
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> JCR
+ currently provides an implementation class , which uses the <ulink
+ url="http://wiki.apache.org/jakarta-lucene/SpellChecker">lucene-spellchecker</ulink>
+ contrib . The dictionary is derived from the fulltext indexed content of
+ the workspace and updated periodically. You can configure the refresh
+ interval by picking one of the available inner classes of
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>OneMinuteRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>FiveMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>ThirtyMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneHourRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>SixHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>TwelveHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneDayRefreshInterval</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>E.g. if you want a refresh interval of six hours the class name is:
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$SixHoursRefreshInterval.
+ If you use
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker
+ the refresh interval will be one hour.</para>
+
+ <para>The spell checker dictionary is stored as a lucene index under
+ <emphasis role="bold">"index-dir"/spellchecker</emphasis>. If it does not
+ exist, a background thread will create it on startup. Similarly the
+ dictionary refresh is also done in a background thread to not block
+ regular queries.</para>
+
+ <section>
+ <title>How do I use it?</title>
+
+ <para>You can spell check a fulltext statement either with an XPath or a
+ SQL query:</para>
+
+ <programlisting>// rep:spellcheck('explatform') will always evaluate to true
+Query query = qm.createQuery("/jcr:root[rep:spellcheck('explatform')]/(rep:spellcheck())", Query.XPATH);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+
+ <para>And the same using SQL:</para>
+
+ <programlisting>// SPELLCHECK('exoplatform') will always evaluate to true
+Query query = qm.createQuery("SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('explatform')", Query.SQL);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+ </section>
+ </section>
+
+ <section id="JCR.SearchingRepositoryContent.Similarity">
+ <title>Similarity (Since 1.12)</title>
+
+ <para>Starting with version, 1.12 JCR allows you to search for nodes that
+ are similar to an existing node.</para>
+
+ <para>Similarity is determined by looking up terms that are common to
+ nodes. There are some conditions that must be met for a term to be
+ considered. This is required to limit the number possibly relevant
+ terms.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Only terms with at least 4 characters are considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur at least 2 times in the source node are
+ considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur in at least 5 nodes are considered.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note: The similarity functionality requires that the
+ supportHightlighting is enabled. Please make sure that you have the
+ following parameter set for the query handler in your
+ workspace.xml.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>The functions are called rep:similar() (in XPath) and similar() (in
+ SQL) and have two arguments:</para>
+
+ <para>relativePath: a relative path to a descendant node or . for the
+ current node. absoluteStringPath: a string literal that contains the path
+ to the node for which to find similar nodes.</para>
+
+ <warning>
+ <para>Relative path is not supported yet.</para>
+ </warning>
+
+ <para>Examples:</para>
+
+ <programlisting>//element(*, nt:resource)[rep:similar(., '/parentnode/node.txt/jcr:content')]</programlisting>
+
+ <para>Finds nt:resource nodes, which are similar to node by path
+ /parentnode/node.txt/jcr:content.</para>
+ </section>
+</chapter>
15 years, 11 months
exo-jcr SVN: r2874 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr: configuration and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-04 09:51:23 -0400 (Wed, 04 Aug 2010)
New Revision: 2874
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
Log:
EXOJCR-869 documentation updated
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.eXoJCRApplicationModel">
<?dbhtml filename="ch-jcr-applications.html"?>
+
<title>eXo JCR Application Model</title>
<para>A large picture of interaction between Applications and JCR looks as
@@ -34,8 +35,4 @@
specific Frameworks. It is possible to build a multi-layered (in framework
sense) JCR application, for example Web application uses Web framework that
uses Command framework underneath.</para>
-
- <para>To READ:</para>
-
- <para>Deployment JCR standalone (ver 1_5)</para>
</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.RegistryService">
<?dbhtml filename="ch-jcr-registry-service.html"?>
+
<title>Registry Service</title>
<section id="Concept">
@@ -27,8 +28,7 @@
<para>The proposed structure of the Registry Service storage.It is divided
into 3 logical groups: services, applications and users:</para>
- <programlisting>/
- exo:registry/ <-- registry "root" (exo:registry)
+ <programlisting> exo:registry/ <-- registry "root" (exo:registry)
exo:services/ <-- service data storage (exo:registryGroup)
service1/
Consumer data (exo:registryEntry)
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.NodeTypeRegistration">
<?dbhtml filename="ch-nodetype-registration.html"?>
+
<title>NodeType Registration</title>
<para>eXo JCR implementation supports two ways of Nodetypes
@@ -357,9 +358,9 @@
<title>Node type registration</title>
<para>eXo JCR implementation supports various methods of the node-type
- registration. The most used is registration from xml file <ulink
- url="on JCR startup>Node+types+and+Namespaces">on JCR
- startup>Node+types+and+Namespaces</ulink>.</para>
+ registration. The most used is registration from <link
+ linkend="JCR.NodeTypesandNamespaces">xml file</link> on JCR
+ startup.</para>
<section>
<title>Run time registration from xml file.</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="JCR.NodeTypesandNamespaces">
<?dbhtml filename="ch-nodetypes-and-namespaces.html"?>
+
<title>Node Types and Namespaces</title>
<section>
@@ -11,10 +12,10 @@
<para>Support of node types and namespaces is required by the JSR-170
specification. Beyond the methods required by the specification, eXo JCR
has its own API extension for the <ulink
- url="JCR.NodeTypeRegistration">Node type
- registration>NodeType+registration</ulink> as well as the ability to
- declaratively define node types in the Repository at the start-up
- time.</para>
+ url="JCR.NodeTypeRegistration"><link
+ linkend="JCR.NodeTypeRegistration">Node type registration</link></ulink>
+ as well as the ability to declaratively define node types in the
+ Repository at the start-up time.</para>
</section>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -1,415 +1,413 @@
-<?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="JCR.eXoJCRconfiguration">
- <?dbhtml filename="ch-exo-jcr-configuration.html"?>
- <title>eXo JCR configuration</title>
- <section>
- <title>Related documents</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.ConfigurationPersister">Configuration
- persister</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.SearchConfiguration">Search
- Configuration</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="ch_jdbc_data_container">JDBC Data Container
- config</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="ch_external_value_storages">External Value
- Storages</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="none">Workspace SimpleDB storage</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="none">Workspace Persistence Storage</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section id ="JCR.eXoJCRconfiguration.PortalAndStandaloneConfiguration">
- <title>Portal and Standalone configuration</title>
-
- <para>Like other eXo services eXo JCR can be configured and used in portal
- or embedded mode (as a service embedded in eXo Portal) and in standalone
- mode.</para>
-
- <para>In Embedded mode, JCR services are registered in the Portal
- container and the second option is to use a Standalone container. The main
- difference between these container types is that the first one is intended
- to be used in a Portal (Web) environment, while the second one can be used
- standalone (see the comprehensive page <link
- linkend="Kernel.ServiceConfigurationForBeginners">Service Configuration
- for Beginners</link> for more details).</para>
-
- <para>The following setup procedure is used to obtain a Standalone
- configuration (find more in <link
- linkend="Kernel.ContainerConfiguration">Container
- configuration</link>):</para>
-
- <para>* Configuration that is set explicitly using
- StandaloneContainer.addConfigurationURL(String url) or
- StandaloneContainer.addConfigurationPath(String path) before
- getInstance()</para>
-
- <para>* Configuration from $base:directory/exo-configuration.xml or
- $base:directory/conf/exo-configuration.xml file. Where $base:directory is
- either AS's home directory in case of J2EE AS environment or just the
- current directory in case of a standalone application.</para>
-
- <para>* /conf/exo-configuration.xml in the current classloader (e.g. war,
- ear archive)</para>
-
- <para>* Configuration from
- $service_jar_file/conf/portal/configuration.xml. WARNING: do not rely on
- some concrete jar's configuration if you have more than one jar containing
- conf/portal/configuration.xml file. In this case choosing a configuration
- is unpredictable.</para>
-
- <para>JCR service configuration looks like:</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.RepositoryService</key>
- <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
-</component>
-<component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR repositories configuration file</description>
- <value>jar:/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- <properties-param>
- <name>working-conf</name>
- <description>working-conf</description>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="hsqldb" />
- <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
- </properties-param>
- </init-params>
-</component></programlisting>
-
- <para><emphasis role="bold">conf-path</emphasis> : a path to a
- RepositoryService JCR Configuration.</para>
-
- <para><emphasis role="bold">working-conf</emphasis> : optional; <link
- linkend="JCR.ConfigurationPersister">JCR configuration persister</link>
- configuration. If there isn't a working-conf the persister will be
- disabled.</para>
- </section>
-
- <section>
- <title>JCR Configuration</title>
-
- <para>The Configuration is defined in an XML file (see DTD below)</para>
-
- <para>JCR Service can use multiple <emphasis
- role="bold">Repositories</emphasis> and each repository can have multiple
- <emphasis role="bold">Workspaces</emphasis>.</para>
-
- <para>From v.1.9 JCR repositories configuration parameters support
- human-readable formats of values. They are all case-insensitive:</para>
-
- <itemizedlist>
- <listitem>
- <para>Numbers formats: K,KB - kilobytes, M,MB - megabytes, G,GB -
- gigabytes, T,TB - terabytes. Examples: 100.5 - digit 100.5, 200k - 200
- Kbytes, 4m - 4 Mbytes, 1.4G - 1.4 Gbytes, 10T - 10 Tbytes</para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <listitem>
- <para>Time format endings: ms - milliseconds, m - minutes, h - hours,
- d - days, w - weeks, if no ending - seconds. Examples: 500ms - 500
- milliseconds, 20 - 20 seconds, 30m - 30 minutes, 12h - 12 hours, 5d -
- 5 days, 4w - 4 weeks.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Repository service configuration (JCR repositories
- configuration)</title>
-
- <para>Service configuration may be placed in
- jar:/conf/standalone/exo-jcr-config.xml for standalone mode. For portal
- mode it is located in the portal web application
- portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
-
- <para><emphasis role="bold">default-repository</emphasis> - the name of a
- default repository (one returned by
- RepositoryService.getRepository())</para>
-
- <para><emphasis role="bold">repositories</emphasis> - the list of
- repositories</para>
- </section>
-
- <section>
- <title>Repository configuration:</title>
-
- <para><emphasis role="bold">name</emphasis> - the name of a
- repository</para>
-
- <para><emphasis role="bold">default-workspace</emphasis> - the name of a
- workspace obtained using Session's login() or login(Credentials) methods
- (ones without an explicit workspace name)</para>
-
- <para><emphasis role="bold">system-workspace</emphasis> - name of
- workspace where <emphasis role="bold">/jcr:system</emphasis> node is
- placed</para>
-
- <para><emphasis role="bold">security-domain</emphasis> - the name of a
- security domain for JAAS authentication</para>
-
- <para><emphasis role="bold">access-control</emphasis> - the name of an
- access control policy. There can be 3 types: optional - ACL is created
- on-demand(default), disable - no access control, mandatory - an ACL is
- created for each added node(not supported yet)</para>
-
- <para><emphasis role="bold">authentication-policy</emphasis> - the name of
- an authentication policy class</para>
-
- <para><emphasis role="bold">workspaces</emphasis> - the list of
- workspaces</para>
-
- <para><emphasis role="bold">session-max-age</emphasis> - the time after
- which an idle session will be removed (called logout). If not set, the
- idle session will never be removed.</para>
- </section>
-
- <section>
- <title>Workspace configuration:</title>
-
- <para><emphasis role="bold">name</emphasis> - the name of a
- workspace</para>
-
- <para><emphasis role="bold">auto-init-root-nodetype</emphasis> -
- DEPRECATED in JCR 1.9 (use initializer). The node type for root node
- initialization</para>
-
- <para><emphasis role="bold">container</emphasis> - workspace data
- container (physical storage) configuration</para>
-
- <para><emphasis role="bold">initializer</emphasis> - workspace initializer
- configuration</para>
-
- <para><emphasis role="bold">cache</emphasis> - workspace storage cache
- configuration</para>
-
- <para><emphasis role="bold">query-handler</emphasis> - query handler
- configuration</para>
-
- <para><emphasis role="bold">auto-init-permissions</emphasis> - DEPRECATED
- in JCR 1.9 (use initializer). Default permissions of the root node. It is
- defined as a set of semicolon-delimited permissions containing a group of
- space-delimited identities (user, group etc, see Organization service
- documentation for details) and the type of permission. For example any
- read; <emphasis role="bold">:/admin read;</emphasis>:/admin add_node;
- <emphasis role="bold">:/admin set_property;</emphasis>:/admin remove means
- that users from group <emphasis role="bold">admin</emphasis> have all
- permissions and other users have only a 'read' permission.</para>
- </section>
-
- <section>
- <title>Workspace data container configuration:</title>
-
- <para><emphasis role="bold">class</emphasis> - A workspace data container
- class name</para>
-
- <para><emphasis role="bold">properties</emphasis> - the list of properties
- (name-value pairs) for the concrete Workspace data container</para>
-
- <para><emphasis role="bold">value-storages</emphasis> - the list of value
- storage plugins</para>
- </section>
-
- <section id="JCR.ConfigurationPersister.ValueStoragePlugin">
- <title>Value Storage plugin configuration (for data container):</title>
-
- <note>
- <para>The value-storage element is optional. If you don't include it,
- the values will be stored as BLOBs inside the database.</para>
- </note>
-
- <para><emphasis role="bold">value-storage</emphasis> - Optional value
- Storage plugin definition:</para>
-
- <para><emphasis role="bold">class</emphasis>- a value storage plugin class
- name (attribute)</para>
-
- <para><emphasis role="bold">properties</emphasis> - the list of properties
- (name-value pairs) for a concrete Value Storage plugin</para>
-
- <para><emphasis role="bold">filters</emphasis> - the list of filters
- defining conditions when this plugin is applicable</para>
- </section>
-
- <section>
- <title>Initializer configuration (optional):</title>
-
- <para><emphasis role="bold">class</emphasis> - initializer implementation
- class.</para>
-
- <para><emphasis role="bold">properties</emphasis> - the list of properties
- (name-value pairs). Properties are supported:</para>
-
- <para><emphasis role="bold">root-nodetype</emphasis> - The node type for
- root node initialization</para>
-
- <para><emphasis role="bold">root-permissions</emphasis> - Default
- permissions of the root node. It is defined as a set of
- semicolon-delimited permissions containing a group of space-delimited
- identities (user, group etc, see Organization service documentation for
- details) and the type of permission. For example any read; <emphasis
- role="bold">:/admin read;</emphasis>:/admin add_node; <emphasis
- role="bold">:/admin set_property;</emphasis>:/admin remove means that
- users from group <emphasis role="bold">admin</emphasis> have all
- permissions and other users have only a 'read' permission.</para>
-
- <para>Configurable initializer adds a capability to override workspace
- initial startup procedure (used for Clustering). Also it replaces
- workspace element parameters auto-init-root-nodetype and
- auto-init-permissions with root-nodetype and root-permissions.</para>
- </section>
-
- <section>
- <title>Cache configuration:</title>
-
- <para><emphasis role="bold">enabled</emphasis> - if workspace cache is
- enabled</para>
-
- <para><emphasis role="bold">class</emphasis> - cache implementation class,
- optional from 1.9. Default value is
- org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl.</para>
-
- <para>Cache can be configured to use concrete implementation of
- WorkspaceStorageCache interface. JCR core has two implementation to
- use:</para>
-
- <itemizedlist>
- <listitem>
- <para>LinkedWorkspaceStorageCacheImpl - default, with configurable
- read behavior and statistic.</para>
- </listitem>
-
- <listitem>
- <para>WorkspaceStorageCacheImpl - pre 1.9, still can be used.</para>
- </listitem>
- </itemizedlist>
-
- <para><emphasis role="bold">properties</emphasis> - the list of properties
- (name-value pairs) for Workspace cache:</para>
-
- <para><emphasis role="bold">max-size</emphasis> - cache maximum size
- (maxSize prior to v.1.9).</para>
-
- <para><emphasis role="bold">live-time</emphasis> - cached item live time
- (liveTime prior to v.1.9).</para>
-
- <para>From 1.9 LinkedWorkspaceStorageCacheImpl supports additional
- optional parameters.</para>
-
- <para><emphasis role="bold">statistic-period</emphasis> - period (time
- format) of cache statistic thread execution, 5 minutes by default.</para>
-
- <para><emphasis role="bold">statistic-log</emphasis> - if true cache
- statistic will be printed to default logger (log.info), false by
- default.</para>
-
- <para><emphasis role="bold">statistic-clean</emphasis> - if true cache
- statistic will be cleaned after was gathered, false by default.</para>
-
- <para><emphasis role="bold">cleaner-period</emphasis> - period of eldest
- items remover execution, 20 minutes by default.</para>
-
- <para><emphasis role="bold">blocking-users-count</emphasis> - number of
- concurrent users allowed to read cache storage, 0 - unlimited by
- default.</para>
- </section>
-
- <section>
- <title>Query Handler configuration:</title>
-
- <para><emphasis role="bold">class</emphasis> - A Query Handler class
- name</para>
-
- <para><emphasis role="bold">properties</emphasis> - the list of properties
- (name-value pairs) for a Query Handler (indexDir)</para>
-
- <para>Properties and advanced features described in <link
- linkend="JCR.SearchConfiguration">Search Configuration</link>.</para>
- </section>
-
- <section>
- <title>Lock Manager configuration:</title>
-
- <para><emphasis role="bold">time-out</emphasis> - time after which the
- unused global lock will be removed.</para>
-
- <para><emphasis role="bold">persister</emphasis> - a class for storing
- lock information for future use. For example, remove lock after jcr
- restart.</para>
-
- <para><emphasis role="bold">path</emphasis> - a lock folder, each
- workspace has its own.</para>
-
- <para>Additional information about the configuration of the lock you can
- see in <link linkend="TODO.JCR.Locking">JCR Locks Implementation
- Specification</link>.</para>
-
- <programlisting><!ELEMENT repository-service (repositories)>
-<!ATTLIST repository-service default-repository NMTOKEN #REQUIRED>
-<!ELEMENT repositories (repository)>
-<!ELEMENT repository (security-domain,access-control,session-max-age,authentication-policy,workspaces)>
-<!ATTLIST repository
- default-workspace NMTOKEN #REQUIRED
- name NMTOKEN #REQUIRED
- system-workspace NMTOKEN #REQUIRED
->
-<!ELEMENT security-domain (#PCDATA)>
-<!ELEMENT access-control (#PCDATA)>
-<!ELEMENT session-max-age (#PCDATA)>
-<!ELEMENT authentication-policy (#PCDATA)>
-<!ELEMENT workspaces (workspace+)>
-<!ELEMENT workspace (container,initializer,cache,query-handler)>
-<!ATTLIST workspace name NMTOKEN #REQUIRED>
-<!ELEMENT container (properties,value-storages)>
-<!ATTLIST container class NMTOKEN #REQUIRED>
-<!ELEMENT value-storages (value-storage+)>
-<!ELEMENT value-storage (properties,filters)>
-<!ATTLIST value-storage class NMTOKEN #REQUIRED>
-<!ELEMENT filters (filter+)>
-<!ELEMENT filter EMPTY>
-<!ATTLIST filter property-type NMTOKEN #REQUIRED>
-<!ELEMENT initializer (properties)>
-<!ATTLIST initializer class NMTOKEN #REQUIRED>
-<!ELEMENT cache (properties)>
-<!ATTLIST cache
- enabled NMTOKEN #REQUIRED
- class NMTOKEN #REQUIRED
->
-<!ELEMENT query-handler (properties)>
-<!ATTLIST query-handler class NMTOKEN #REQUIRED>
-<!ELEMENT access-manager (properties)>
-<!ATTLIST access-manager class NMTOKEN #REQUIRED>
-<!ELEMENT lock-manager (time-out,persister)>
-<!ELEMENT time-out (#PCDATA)>
-<!ELEMENT persister (properties)>
-<!ELEMENT properties (property+)>
-<!ELEMENT property EMPTY></programlisting>
- </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="JCR.eXoJCRconfiguration">
+ <?dbhtml filename="ch-exo-jcr-configuration.html"?>
+
+ <title>eXo JCR configuration</title>
+
+ <section>
+ <title>Related documents</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.ConfigurationPersister">Configuration
+ persister</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SearchConfiguration">Search
+ Configuration</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="ch_jdbc_data_container">JDBC Data Container
+ config</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="ch_external_value_storages">External Value
+ Storages</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="none">Workspace SimpleDB storage</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="none">Workspace Persistence Storage</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section id="JCR.eXoJCRconfiguration.PortalAndStandaloneConfiguration">
+ <title>Portal and Standalone configuration</title>
+
+ <para>Like other eXo services eXo JCR can be configured and used in portal
+ or embedded mode (as a service embedded in eXo Portal) and in standalone
+ mode.</para>
+
+ <para>In Embedded mode, JCR services are registered in the Portal
+ container and the second option is to use a Standalone container. The main
+ difference between these container types is that the first one is intended
+ to be used in a Portal (Web) environment, while the second one can be used
+ standalone (see the comprehensive page <link
+ linkend="Kernel.ServiceConfigurationforBeginners">Service Configuration
+ for Beginners</link> for more details).</para>
+
+ <para>The following setup procedure is used to obtain a Standalone
+ configuration (find more in <link
+ linkend="Kernel.ContainerConfiguration">Container
+ configuration</link>):</para>
+
+ <para>* Configuration that is set explicitly using
+ StandaloneContainer.addConfigurationURL(String url) or
+ StandaloneContainer.addConfigurationPath(String path) before
+ getInstance()</para>
+
+ <para>* Configuration from $base:directory/exo-configuration.xml or
+ $base:directory/conf/exo-configuration.xml file. Where $base:directory is
+ either AS's home directory in case of J2EE AS environment or just the
+ current directory in case of a standalone application.</para>
+
+ <para>* /conf/exo-configuration.xml in the current classloader (e.g. war,
+ ear archive)</para>
+
+ <para>* Configuration from
+ $service_jar_file/conf/portal/configuration.xml. WARNING: do not rely on
+ some concrete jar's configuration if you have more than one jar containing
+ conf/portal/configuration.xml file. In this case choosing a configuration
+ is unpredictable.</para>
+
+ <para>JCR service configuration looks like:</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.RepositoryService</key>
+ <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
+</component>
+<component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR repositories configuration file</description>
+ <value>jar:/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ <properties-param>
+ <name>working-conf</name>
+ <description>working-conf</description>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="hsqldb" />
+ <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para><emphasis role="bold">conf-path</emphasis> : a path to a
+ RepositoryService JCR Configuration.</para>
+
+ <para><emphasis role="bold">working-conf</emphasis> : optional; <link
+ linkend="JCR.ConfigurationPersister">JCR configuration persister</link>
+ configuration. If there isn't a working-conf the persister will be
+ disabled.</para>
+ </section>
+
+ <section>
+ <title>JCR Configuration</title>
+
+ <para>The Configuration is defined in an XML file (see DTD below)</para>
+
+ <para>JCR Service can use multiple <emphasis
+ role="bold">Repositories</emphasis> and each repository can have multiple
+ <emphasis role="bold">Workspaces</emphasis>.</para>
+
+ <para>From v.1.9 JCR repositories configuration parameters support
+ human-readable formats of values. They are all case-insensitive:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Numbers formats: K,KB - kilobytes, M,MB - megabytes, G,GB -
+ gigabytes, T,TB - terabytes. Examples: 100.5 - digit 100.5, 200k - 200
+ Kbytes, 4m - 4 Mbytes, 1.4G - 1.4 Gbytes, 10T - 10 Tbytes</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>Time format endings: ms - milliseconds, m - minutes, h - hours,
+ d - days, w - weeks, if no ending - seconds. Examples: 500ms - 500
+ milliseconds, 20 - 20 seconds, 30m - 30 minutes, 12h - 12 hours, 5d -
+ 5 days, 4w - 4 weeks.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Repository service configuration (JCR repositories
+ configuration)</title>
+
+ <para>Service configuration may be placed in
+ jar:/conf/standalone/exo-jcr-config.xml for standalone mode. For portal
+ mode it is located in the portal web application
+ portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
+
+ <para><emphasis role="bold">default-repository</emphasis> - the name of a
+ default repository (one returned by
+ RepositoryService.getRepository())</para>
+
+ <para><emphasis role="bold">repositories</emphasis> - the list of
+ repositories</para>
+ </section>
+
+ <section>
+ <title>Repository configuration:</title>
+
+ <para><emphasis role="bold">name</emphasis> - the name of a
+ repository</para>
+
+ <para><emphasis role="bold">default-workspace</emphasis> - the name of a
+ workspace obtained using Session's login() or login(Credentials) methods
+ (ones without an explicit workspace name)</para>
+
+ <para><emphasis role="bold">system-workspace</emphasis> - name of
+ workspace where <emphasis role="bold">/jcr:system</emphasis> node is
+ placed</para>
+
+ <para><emphasis role="bold">security-domain</emphasis> - the name of a
+ security domain for JAAS authentication</para>
+
+ <para><emphasis role="bold">access-control</emphasis> - the name of an
+ access control policy. There can be 3 types: optional - ACL is created
+ on-demand(default), disable - no access control, mandatory - an ACL is
+ created for each added node(not supported yet)</para>
+
+ <para><emphasis role="bold">authentication-policy</emphasis> - the name of
+ an authentication policy class</para>
+
+ <para><emphasis role="bold">workspaces</emphasis> - the list of
+ workspaces</para>
+
+ <para><emphasis role="bold">session-max-age</emphasis> - the time after
+ which an idle session will be removed (called logout). If not set, the
+ idle session will never be removed.</para>
+ </section>
+
+ <section>
+ <title>Workspace configuration:</title>
+
+ <para><emphasis role="bold">name</emphasis> - the name of a
+ workspace</para>
+
+ <para><emphasis role="bold">auto-init-root-nodetype</emphasis> -
+ DEPRECATED in JCR 1.9 (use initializer). The node type for root node
+ initialization</para>
+
+ <para><emphasis role="bold">container</emphasis> - workspace data
+ container (physical storage) configuration</para>
+
+ <para><emphasis role="bold">initializer</emphasis> - workspace initializer
+ configuration</para>
+
+ <para><emphasis role="bold">cache</emphasis> - workspace storage cache
+ configuration</para>
+
+ <para><emphasis role="bold">query-handler</emphasis> - query handler
+ configuration</para>
+
+ <para><emphasis role="bold">auto-init-permissions</emphasis> - DEPRECATED
+ in JCR 1.9 (use initializer). Default permissions of the root node. It is
+ defined as a set of semicolon-delimited permissions containing a group of
+ space-delimited identities (user, group etc, see Organization service
+ documentation for details) and the type of permission. For example any
+ read; <emphasis role="bold">:/admin read;</emphasis>:/admin add_node;
+ <emphasis role="bold">:/admin set_property;</emphasis>:/admin remove means
+ that users from group <emphasis role="bold">admin</emphasis> have all
+ permissions and other users have only a 'read' permission.</para>
+ </section>
+
+ <section>
+ <title>Workspace data container configuration:</title>
+
+ <para><emphasis role="bold">class</emphasis> - A workspace data container
+ class name</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for the concrete Workspace data container</para>
+
+ <para><emphasis role="bold">value-storages</emphasis> - the list of value
+ storage plugins</para>
+ </section>
+
+ <section id="JCR.ConfigurationPersister.ValueStoragePlugin">
+ <title>Value Storage plugin configuration (for data container):</title>
+
+ <note>
+ <para>The value-storage element is optional. If you don't include it,
+ the values will be stored as BLOBs inside the database.</para>
+ </note>
+
+ <para><emphasis role="bold">value-storage</emphasis> - Optional value
+ Storage plugin definition:</para>
+
+ <para><emphasis role="bold">class</emphasis>- a value storage plugin class
+ name (attribute)</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for a concrete Value Storage plugin</para>
+
+ <para><emphasis role="bold">filters</emphasis> - the list of filters
+ defining conditions when this plugin is applicable</para>
+ </section>
+
+ <section>
+ <title>Initializer configuration (optional):</title>
+
+ <para><emphasis role="bold">class</emphasis> - initializer implementation
+ class.</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs). Properties are supported:</para>
+
+ <para><emphasis role="bold">root-nodetype</emphasis> - The node type for
+ root node initialization</para>
+
+ <para><emphasis role="bold">root-permissions</emphasis> - Default
+ permissions of the root node. It is defined as a set of
+ semicolon-delimited permissions containing a group of space-delimited
+ identities (user, group etc, see Organization service documentation for
+ details) and the type of permission. For example any read; <emphasis
+ role="bold">:/admin read;</emphasis>:/admin add_node; <emphasis
+ role="bold">:/admin set_property;</emphasis>:/admin remove means that
+ users from group <emphasis role="bold">admin</emphasis> have all
+ permissions and other users have only a 'read' permission.</para>
+
+ <para>Configurable initializer adds a capability to override workspace
+ initial startup procedure (used for Clustering). Also it replaces
+ workspace element parameters auto-init-root-nodetype and
+ auto-init-permissions with root-nodetype and root-permissions.</para>
+ </section>
+
+ <section>
+ <title>Cache configuration:</title>
+
+ <para><emphasis role="bold">enabled</emphasis> - if workspace cache is
+ enabled</para>
+
+ <para><emphasis role="bold">class</emphasis> - cache implementation class,
+ optional from 1.9. Default value is
+ org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl.</para>
+
+ <para>Cache can be configured to use concrete implementation of
+ WorkspaceStorageCache interface. JCR core has two implementation to
+ use:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>LinkedWorkspaceStorageCacheImpl - default, with configurable
+ read behavior and statistic.</para>
+ </listitem>
+
+ <listitem>
+ <para>WorkspaceStorageCacheImpl - pre 1.9, still can be used.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for Workspace cache:</para>
+
+ <para><emphasis role="bold">max-size</emphasis> - cache maximum size
+ (maxSize prior to v.1.9).</para>
+
+ <para><emphasis role="bold">live-time</emphasis> - cached item live time
+ (liveTime prior to v.1.9).</para>
+
+ <para>From 1.9 LinkedWorkspaceStorageCacheImpl supports additional
+ optional parameters.</para>
+
+ <para><emphasis role="bold">statistic-period</emphasis> - period (time
+ format) of cache statistic thread execution, 5 minutes by default.</para>
+
+ <para><emphasis role="bold">statistic-log</emphasis> - if true cache
+ statistic will be printed to default logger (log.info), false by
+ default.</para>
+
+ <para><emphasis role="bold">statistic-clean</emphasis> - if true cache
+ statistic will be cleaned after was gathered, false by default.</para>
+
+ <para><emphasis role="bold">cleaner-period</emphasis> - period of eldest
+ items remover execution, 20 minutes by default.</para>
+
+ <para><emphasis role="bold">blocking-users-count</emphasis> - number of
+ concurrent users allowed to read cache storage, 0 - unlimited by
+ default.</para>
+ </section>
+
+ <section>
+ <title>Query Handler configuration:</title>
+
+ <para><emphasis role="bold">class</emphasis> - A Query Handler class
+ name</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for a Query Handler (indexDir)</para>
+
+ <para>Properties and advanced features described in <link
+ linkend="JCR.SearchConfiguration">Search Configuration</link>.</para>
+ </section>
+
+ <section>
+ <title>Lock Manager configuration:</title>
+
+ <para><emphasis role="bold">time-out</emphasis> - time after which the
+ unused global lock will be removed.</para>
+
+ <para><emphasis role="bold">persister</emphasis> - a class for storing
+ lock information for future use. For example, remove lock after jcr
+ restart.</para>
+
+ <para><emphasis role="bold">path</emphasis> - a lock folder, each
+ workspace has its own.</para>
+
+ <programlisting><!ELEMENT repository-service (repositories)>
+<!ATTLIST repository-service default-repository NMTOKEN #REQUIRED>
+<!ELEMENT repositories (repository)>
+<!ELEMENT repository (security-domain,access-control,session-max-age,authentication-policy,workspaces)>
+<!ATTLIST repository
+ default-workspace NMTOKEN #REQUIRED
+ name NMTOKEN #REQUIRED
+ system-workspace NMTOKEN #REQUIRED
+>
+<!ELEMENT security-domain (#PCDATA)>
+<!ELEMENT access-control (#PCDATA)>
+<!ELEMENT session-max-age (#PCDATA)>
+<!ELEMENT authentication-policy (#PCDATA)>
+<!ELEMENT workspaces (workspace+)>
+<!ELEMENT workspace (container,initializer,cache,query-handler)>
+<!ATTLIST workspace name NMTOKEN #REQUIRED>
+<!ELEMENT container (properties,value-storages)>
+<!ATTLIST container class NMTOKEN #REQUIRED>
+<!ELEMENT value-storages (value-storage+)>
+<!ELEMENT value-storage (properties,filters)>
+<!ATTLIST value-storage class NMTOKEN #REQUIRED>
+<!ELEMENT filters (filter+)>
+<!ELEMENT filter EMPTY>
+<!ATTLIST filter property-type NMTOKEN #REQUIRED>
+<!ELEMENT initializer (properties)>
+<!ATTLIST initializer class NMTOKEN #REQUIRED>
+<!ELEMENT cache (properties)>
+<!ATTLIST cache
+ enabled NMTOKEN #REQUIRED
+ class NMTOKEN #REQUIRED
+>
+<!ELEMENT query-handler (properties)>
+<!ATTLIST query-handler class NMTOKEN #REQUIRED>
+<!ELEMENT access-manager (properties)>
+<!ATTLIST access-manager class NMTOKEN #REQUIRED>
+<!ELEMENT lock-manager (time-out,persister)>
+<!ELEMENT time-out (#PCDATA)>
+<!ELEMENT persister (properties)>
+<!ELEMENT properties (property+)>
+<!ELEMENT property EMPTY></programlisting>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -1,170 +1,171 @@
-<?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="JCRMultilanguageSupport">
- <?dbhtml filename="ch-multilanguage-support.html"?>
-
- <title>Multilanguage support in eXo JCR RDB backend</title>
-
- <section>
- <title>Intro</title>
-
- <para>Whenever relational database is used to store multilingual text data
- of eXo Java Content Repository we need to adapt configuration in order to
- support UTF-8 encoding. Here is a short HOWTO instruction for several
- supported RDBMS with examples.</para>
-
- <para>The configuration file you have to modify:
- .../webapps/portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
-
- <note>
- <para>Datasource <parameter>jdbcjcr</parameter> used in examples can be
- configured via <classname>InitialContextInitializer</classname>
- component.</para>
- </note>
- </section>
-
- <section>
- <title>Oracle</title>
-
- <para>In order to run multilanguage JCR on an Oracle backend Unicode
- encoding for characters set should be applied to the database. Other
- Oracle globalization parameters don't make any impact. The only property
- to modify is <constant>NLS_CHARACTERSET</constant>.</para>
-
- <para>We have tested <constant>NLS_CHARACTERSET</constant> =
- <constant>AL32UTF8</constant> and it's works well for many European and
- Asian languages.</para>
-
- <para>Example of database configuration (used for JCR
- testing):<programlisting>NLS_LANGUAGE AMERICAN
-NLS_TERRITORY AMERICA
-NLS_CURRENCY $
-NLS_ISO_CURRENCY AMERICA
-NLS_NUMERIC_CHARACTERS .,
-NLS_CHARACTERSET AL32UTF8
-NLS_CALENDAR GREGORIAN
-NLS_DATE_FORMAT DD-MON-RR
-NLS_DATE_LANGUAGE AMERICAN
-NLS_SORT BINARY
-NLS_TIME_FORMAT HH.MI.SSXFF AM
-NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
-NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
-NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
-NLS_DUAL_CURRENCY $
-NLS_COMP BINARY
-NLS_LENGTH_SEMANTICS BYTE
-NLS_NCHAR_CONV_EXCP FALSE
-NLS_NCHAR_CHARACTERSET AL16UTF16</programlisting></para>
-
- <warning>
- <para>JCR 1.12.x doesn't use NVARCHAR columns, so that the value of the
- parameter NLS_NCHAR_CHARACTERSET does not matter for JCR.</para>
- </warning>
-
- <para>Create database with Unicode encoding and use Oracle dialect for the
- Workspace Container:</para>
-
- <programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="oracle" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting>
- </section>
-
- <section>
- <title>DB2</title>
-
- <para>DB2 Universal Database (DB2 UDB) supports <ulink
- url="http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.i...">UTF-8
- and UTF-16/UCS-2</ulink>. When a Unicode database is created, CHAR,
- VARCHAR, LONG VARCHAR data are stored in UTF-8 form. It's enough for JCR
- multi-lingual support.</para>
-
- <para>Example of UTF-8 database creation:<programlisting>DB2 CREATE DATABASE dbname USING CODESET UTF-8 TERRITORY US</programlisting></para>
-
- <para>Create database with UTF-8 encoding and use db2 dialect for
- Workspace Container on DB2 v.9 and higher:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="db2" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
-
- <note>
- <para>For DB2 v.8.x support change the property "dialect" to
- db2v8.</para>
- </note>
- </section>
-
- <section>
- <title>MySQL</title>
-
- <para>JCR MySQL-backend requires special dialect <ulink
- url="http://jira.exoplatform.org/browse/JCR-375">MySQL-UTF8</ulink> to be
- used for internationalization support. But the database default charset
- should be latin1 to use limited index space effectively (1000 bytes for
- MyISAM engine, 767 for InnoDB). If database default charset is multibyte,
- a JCR database initialization error is thrown concerning index creation
- failure. In other words JCR can work on any singlebyte default charset of
- database, with UTF8 supported by MySQL server. But we have tested it only
- on latin1 database default charset.</para>
-
- <para>Repository configuration, workspace container entry
- example:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="mysql-utf8" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
- </section>
-
- <section>
- <title>PostgreSQL</title>
-
- <para>On PostgreSQL-backend multilingual support can be enabled in <ulink
- url="http://www.postgresql.org/docs/8.3/interactive/charset.html">different
- ways</ulink>:<itemizedlist>
- <listitem>
- <para>Using the locale features of the operating system to provide
- locale-specific collation order, number formatting, translated
- messages, and other aspects. UTF-8 is widely used on Linux
- distributions by default, so it can be useful in such case.</para>
- </listitem>
-
- <listitem>
- <para>Providing a number of different character sets defined in the
- PostgreSQL server, including multiple-byte character sets, to
- support storing text any language, and providing character set
- translation between client and server. We recommend to use UTF-8
- database charset, it will allow any-to-any conversations and make
- this issue transparent for the JCR.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>Create database with UTF-8 encoding and use PgSQL dialect for
- Workspace Container:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="pgsql" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
- </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="JCRMultilanguageSupport">
+ <?dbhtml filename="ch-multilanguage-support.html"?>
+
+ <title>Multilanguage support in eXo JCR RDB backend</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>Whenever relational database is used to store multilingual text data
+ of eXo Java Content Repository we need to adapt configuration in order to
+ support UTF-8 encoding. Here is a short HOWTO instruction for several
+ supported RDBMS with examples.</para>
+
+ <para>The configuration file you have to modify:
+ .../webapps/portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
+
+ <note>
+ <para>Datasource <parameter>jdbcjcr</parameter> used in examples can be
+ configured via <classname>InitialContextInitializer</classname>
+ component.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Oracle</title>
+
+ <para>In order to run multilanguage JCR on an Oracle backend Unicode
+ encoding for characters set should be applied to the database. Other
+ Oracle globalization parameters don't make any impact. The only property
+ to modify is <constant>NLS_CHARACTERSET</constant>.</para>
+
+ <para>We have tested <constant>NLS_CHARACTERSET</constant> =
+ <constant>AL32UTF8</constant> and it's works well for many European and
+ Asian languages.</para>
+
+ <para>Example of database configuration (used for JCR
+ testing):<programlisting>NLS_LANGUAGE AMERICAN
+NLS_TERRITORY AMERICA
+NLS_CURRENCY $
+NLS_ISO_CURRENCY AMERICA
+NLS_NUMERIC_CHARACTERS .,
+NLS_CHARACTERSET AL32UTF8
+NLS_CALENDAR GREGORIAN
+NLS_DATE_FORMAT DD-MON-RR
+NLS_DATE_LANGUAGE AMERICAN
+NLS_SORT BINARY
+NLS_TIME_FORMAT HH.MI.SSXFF AM
+NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
+NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
+NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
+NLS_DUAL_CURRENCY $
+NLS_COMP BINARY
+NLS_LENGTH_SEMANTICS BYTE
+NLS_NCHAR_CONV_EXCP FALSE
+NLS_NCHAR_CHARACTERSET AL16UTF16</programlisting></para>
+
+ <warning>
+ <para>JCR 1.12.x doesn't use NVARCHAR columns, so that the value of the
+ parameter NLS_NCHAR_CHARACTERSET does not matter for JCR.</para>
+ </warning>
+
+ <para>Create database with Unicode encoding and use Oracle dialect for the
+ Workspace Container:</para>
+
+ <programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="oracle" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting>
+ </section>
+
+ <section>
+ <title>DB2</title>
+
+ <para>DB2 Universal Database (DB2 UDB) supports <ulink
+ url="http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.i...">UTF-8
+ and UTF-16/UCS-2</ulink>. When a Unicode database is created, CHAR,
+ VARCHAR, LONG VARCHAR data are stored in UTF-8 form. It's enough for JCR
+ multi-lingual support.</para>
+
+ <para>Example of UTF-8 database creation:<programlisting>DB2 CREATE DATABASE dbname USING CODESET UTF-8 TERRITORY US</programlisting></para>
+
+ <para>Create database with UTF-8 encoding and use db2 dialect for
+ Workspace Container on DB2 v.9 and higher:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="db2" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+
+ <note>
+ <para>For DB2 v.8.x support change the property "dialect" to
+ db2v8.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>MySQL</title>
+
+ <para>JCR MySQL-backend requires special dialect <ulink
+ url="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html"><ulink
+ url="http://jira.exoplatform.org/browse/JCR-375">MySQL-UTF8</ulink></ulink>
+ to be used for internationalization support. But the database default
+ charset should be latin1 to use limited index space effectively (1000
+ bytes for MyISAM engine, 767 for InnoDB). If database default charset is
+ multibyte, a JCR database initialization error is thrown concerning index
+ creation failure. In other words JCR can work on any singlebyte default
+ charset of database, with UTF8 supported by MySQL server. But we have
+ tested it only on latin1 database default charset.</para>
+
+ <para>Repository configuration, workspace container entry
+ example:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="mysql-utf8" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+ </section>
+
+ <section>
+ <title>PostgreSQL</title>
+
+ <para>On PostgreSQL-backend multilingual support can be enabled in <ulink
+ url="http://www.postgresql.org/docs/8.3/interactive/charset.html">different
+ ways</ulink>:<itemizedlist>
+ <listitem>
+ <para>Using the locale features of the operating system to provide
+ locale-specific collation order, number formatting, translated
+ messages, and other aspects. UTF-8 is widely used on Linux
+ distributions by default, so it can be useful in such case.</para>
+ </listitem>
+
+ <listitem>
+ <para>Providing a number of different character sets defined in the
+ PostgreSQL server, including multiple-byte character sets, to
+ support storing text any language, and providing character set
+ translation between client and server. We recommend to use UTF-8
+ database charset, it will allow any-to-any conversations and make
+ this issue transparent for the JCR.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Create database with UTF-8 encoding and use PgSQL dialect for
+ Workspace Container:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="pgsql" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml 2010-08-04 12:33:17 UTC (rev 2873)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml 2010-08-04 13:51:23 UTC (rev 2874)
@@ -1,818 +1,837 @@
-<?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="JCR.SearchConfiguration">
- <?dbhtml filename="ch-search-configuration.html"?>
-
- <title>Search Configuration</title>
-
- <section>
- <title>XML Configuration</title>
-
- <para>JCR index configuration. You can find this file here:
- <filename>.../portal/WEB-INF/conf/jcr/repository-configuration.xml</filename></para>
-
- <programlisting><repository-service default-repository="db1">
- <repositories>
- <repository name="db1" system-workspace="ws" default-workspace="ws">
- ....
- <workspaces>
- <workspace name="ws">
- ....
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="${java.io.tmpdir}/temp/index/db1/ws" />
- <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
- <property name="synonymprovider-config-path" value="/synonyms.properties" />
- <property name="indexing-config-path" value="/indexing-configuration.xml" />
- <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
- </properties>
- </query-handler>
- ...
- </workspace>
- </workspaces>
- </repository>
- </repositories>
-</repository-service></programlisting>
- </section>
-
- <section>
- <title>Configuration parameters</title>
-
- <table>
- <title></title>
-
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Parameter</entry>
-
- <entry>Default</entry>
-
- <entry>Description</entry>
-
- <entry>Since</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>index-dir</entry>
-
- <entry>none</entry>
-
- <entry>The location of the index directory. This parameter is
- mandatory. Up to 1.9 this parameter called "indexDir"</entry>
-
- <entry>1.0</entry>
- </row>
-
- <row>
- <entry>use-compoundfile</entry>
-
- <entry>true</entry>
-
- <entry>Advises lucene to use compound files for the index
- files.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>min-merge-docs</entry>
-
- <entry>100</entry>
-
- <entry>Minimum number of nodes in an index until segments are
- merged.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>volatile-idle-time</entry>
-
- <entry>3</entry>
-
- <entry>Idle time in seconds until the volatile index part is moved
- to a persistent index even though minMergeDocs is not
- reached.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>max-merge-docs</entry>
-
- <entry>Integer.MAX_VALUE</entry>
-
- <entry>Maximum number of nodes in segments that will be merged.
- The default value changed in JCR 1.9 to Integer.MAX_VALUE.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>merge-factor</entry>
-
- <entry>10</entry>
-
- <entry>Determines how often segment indices are merged.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>max-field-length</entry>
-
- <entry>10000</entry>
-
- <entry>The number of words that are fulltext indexed at most per
- property.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>cache-size</entry>
-
- <entry>1000</entry>
-
- <entry>Size of the document number cache. This cache maps uuids to
- lucene document numbers</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>force-consistencycheck</entry>
-
- <entry>false</entry>
-
- <entry>Runs a consistency check on every startup. If false, a
- consistency check is only performed when the search index detects
- a prior forced shutdown.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>auto-repair</entry>
-
- <entry>true</entry>
-
- <entry>Errors detected by a consistency check are automatically
- repaired. If false, errors are only written to the log.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>query-class</entry>
-
- <entry>QueryImpl</entry>
-
- <entry>Class name that implements the javax.jcr.query.Query
- interface.This class must also extend from the class:
- org.exoplatform.services.jcr.impl.core.query.AbstractQueryImpl.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>document-order</entry>
-
- <entry>true</entry>
-
- <entry>If true and the query does not contain an 'order by'
- clause, result nodes will be in document order. For better
- performance when queries return a lot of nodes set to
- 'false'.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>result-fetch-size</entry>
-
- <entry>Integer.MAX_VALUE</entry>
-
- <entry>The number of results when a query is executed. Default
- value: Integer.MAX_VALUE (-> all).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>excerptprovider-class</entry>
-
- <entry>DefaultXMLExcerpt</entry>
-
- <entry>The name of the class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.ExcerptProvider
- and should be used for the rep:excerpt() function in a
- query.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>support-highlighting</entry>
-
- <entry>false</entry>
-
- <entry>If set to true additional information is stored in the
- index to support highlighting using the rep:excerpt()
- function.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>synonymprovider-class</entry>
-
- <entry>none</entry>
-
- <entry>The name of a class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.SynonymProvider.
- The default value is null (-> not set).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>synonymprovider-config-path</entry>
-
- <entry>none</entry>
-
- <entry>The path to the synonym provider configuration file. This
- path interpreted relative to the path parameter. If there is a
- path element inside the SearchIndex element, then this path is
- interpreted relative to the root path of the path. Whether this
- parameter is mandatory depends on the synonym provider
- implementation. The default value is null (-> not set).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>indexing-configuration-path</entry>
-
- <entry>none</entry>
-
- <entry>The path to the indexing configuration file.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>indexing-configuration-class</entry>
-
- <entry>IndexingConfigurationImpl</entry>
-
- <entry>The name of the class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfiguration.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>force-consistencycheck</entry>
-
- <entry>false</entry>
-
- <entry>If set to true a consistency check is performed depending
- on the parameter forceConsistencyCheck. If set to false no
- consistency check is performed on startup, even if a redo log had
- been applied.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>spellchecker-class</entry>
-
- <entry>none</entry>
-
- <entry>The name of a class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>spellchecker-more-popular</entry>
-
- <entry>true</entry>
-
- <entry>If set true - spellchecker return only the suggest words
- that are as frequent or more frequent than the checked word. If
- set false, spellchecker return null (if checked word exit in
- dictionary), or spellchecker will return most close suggest
- word.</entry>
-
- <entry>1.10</entry>
- </row>
-
- <row>
- <entry>spellchecker-min-distance</entry>
-
- <entry>0.55f</entry>
-
- <entry>Minimal distance between checked word and proposed suggest
- word.</entry>
-
- <entry>1.10</entry>
- </row>
-
- <row>
- <entry>errorlog-size</entry>
-
- <entry>50(Kb)</entry>
-
- <entry>The default size of error log file in Kb.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>upgrade-index</entry>
-
- <entry>false</entry>
-
- <entry>Allows JCR to convert an existing index into the new
- format. Also it is possible to set this property via system
- property, for example: -Dupgrade-index=true Indexes before JCR
- 1.12 will not run with JCR 1.12. Hence you have to run an
- automatic migration: Start JCR with -Dupgrade-index=true. The old
- index format is then converted in the new index format. After the
- conversion the new format is used. On the next start you don't
- need this option anymore. The old index is replaced and a back
- conversion is not possible - therefore better take a backup of the
- index before. (Only for migrations from JCR 1.9 and
- later.)</entry>
-
- <entry>1.12</entry>
- </row>
-
- <row>
- <entry>analyzer</entry>
-
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
-
- <entry>Class name of a lucene analyzer to use for fulltext
- indexing of text.</entry>
-
- <entry>1.12</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
-
- <section>
- <title>Global Search Index</title>
-
- <section>
- <title>Global Search Index Configuration</title>
-
- <para>The global search index is configured in the above-mentioned
- configuration file
- (<filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>)
- in the tag "query-handler".</para>
-
- <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>
-
- <para>In fact when using Lucene you always should use the same analyzer
- for indexing and for querying - otherwise the results are unpredictable.
- You don't have to worry about this, eXo JCR does this for you
- automatically. If you don't like the StandardAnalyzer configured by
- default just replace it by your own.</para>
-
- <para>If you don't have a handy QueryHandler you will learn how create a
- customized Handler in 5 minutes.</para>
- </section>
-
- <section>
- <title>Customized Search Indexes and Analyzers</title>
-
- <para>By default Exo JCR uses the Lucene standard Analyzer to index
- contents. This analyzer uses some standard filters in the method that
- analyzes the content:<programlisting>public TokenStream tokenStream(String fieldName, Reader reader) {
- StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);
- tokenStream.setMaxTokenLength(maxTokenLength);
- TokenStream result = new StandardFilter(tokenStream);
- result = new LowerCaseFilter(result);
- result = new StopFilter(result, stopSet);
- return result;
- }</programlisting><itemizedlist>
- <listitem>
- <para>The first one (StandardFilter) removes 's (as 's in
- "Peter's") from the end of words and removes dots from
- acronyms.</para>
- </listitem>
-
- <listitem>
- <para>The second one (LowerCaseFilter) normalizes token text to
- lower case.</para>
- </listitem>
-
- <listitem>
- <para>The last one (StopFilter) removes stop words from a token
- stream. The stop set is defined in the analyzer.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>For specific cases, you may wish to use additional filters like
- <phrase>ISOLatin1AccentFilter</phrase>, which replaces accented
- characters in the ISO Latin 1 character set (ISO-8859-1) by their
- unaccented equivalents.</para>
-
- <para>In order to use a different filter, you have to create a new
- analyzer, and a new search index to use the analyzer. You put it in a
- jar, which is deployed with your application.</para>
-
- <section>
- <title>Create the filter</title>
-
- <para>The ISOLatin1AccentFilter is not present in the current Lucene
- version used by Exo. You can use the attached file. You can also
- create your own filter, the relevant method is<programlisting>public final Token next(final Token reusableToken) throws java.io.IOException</programlisting>which
- defines how chars are read and used by the filter.</para>
- </section>
-
- <section>
- <title>Create the analyzer</title>
-
- <para>The analyzer have to extends
- org.apache.lucene.analysis.standard.StandardAnalyzer, and overload the
- method<programlisting>public TokenStream tokenStream(String fieldName, Reader reader)</programlisting>to
- put your own filters. You can have a glance at the example analyzer
- attached to this article.</para>
- </section>
-
- <section>
- <title>Create the search index</title>
-
- <para>Now, we have the analyzer, we have to write the SearchIndex,
- which will use the analyzer. Your have to extends
- org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex. You
- have to write the constructor, to set the right analyzer, and the
- method<programlisting>public Analyzer getAnalyzer() {
- return MyAnalyzer;
- }</programlisting>to return your analyzer. You can see the attached
- SearchIndex.</para>
-
- <note>
- <para>Since 1.12 version we can set Analyzer directly in
- configuration. So, creation new SearchIndex only for new Analyzer is
- redundant.</para>
- </note>
- </section>
-
- <section>
- <title>Configure your application to use your SearchIndex</title>
-
- <para>In
- <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
- you have to replace each<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>by
- your own class<programlisting><query-handler class="mypackage.indexation.MySearchIndex"></programlisting></para>
- </section>
-
- <section>
- <title>Configure your application to use your Analyzer</title>
-
- <para>In
- <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
- you have to add parameter "analyzer" to each query-handler
- config:<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- ...
- <property name="analyzer" value="org.exoplatform.services.jcr.impl.core.MyAnalyzer"/>
- ...
- </properties>
-</query-handler></programlisting></para>
-
- <para>When you start exo, your SearchIndex will start to index
- contents with the specified filters.</para>
- </section>
- </section>
- </section>
-
- <section>
- <title>Index Adjustments</title>
-
- <section>
- <title>IndexingConfiguration</title>
-
- <para>Starting with version 1.9, the default search index implementation
- in JCR allows you to control which properties of a node are indexed. You
- also can define different analyzers for different nodes.</para>
-
- <para>The configuration parameter is called indexingConfiguration and
- per default is not set. This means all properties of a node are
- indexed.</para>
-
- <para>If you wish to configure the indexing behavior you need to add a
- parameter to the query-handler element in your configuration
- file.</para>
-
- <programlisting><param name="indexing-configuration-path" value="/indexing_configuration.xml"/></programlisting>
- </section>
-
- <section>
- <title>Index rules</title>
-
- <section>
- <title>Node Scope Limit</title>
-
- <para>To optimize the index size you can limit the node scope so that
- <phrase>only certain properties</phrase> of a node type are
- indexed.</para>
-
- <para>With the below configuration only properties named Text are
- indexed for nodes of type nt:unstructured. This configuration also
- applies to all nodes whose type extends from nt:unstructured.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
-
- <para>Please note that you have to declare the <phrase>namespace
- prefixes</phrase> in the configuration element that you are using
- throughout the XML file!</para>
- </section>
-
- <section>
- <title>Index Boost Value</title>
-
- <para>It is also possible to configure a <phrase>boost value</phrase>
- for the nodes that match the index rule. The default boost value is
- 1.0. Higher boost values (a reasonable range is 1.0 - 5.0) will yield
- a higher score value and appear as more relevant.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
-
- <para>If you do not wish to boost the complete node but only certain
- properties you can also provide a boost value for the listed
- properties:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property boost="3.0">Title</property>
- <property boost="1.5">Text</property>
- </index-rule>
-</configuration></programlisting></para>
- </section>
-
- <section>
- <title>Conditional Index Rules</title>
-
- <para>You may also add a <phrase>condition</phrase> to the index rule
- and have multiple rules with the same nodeType. The first index rule
- that matches will apply and all remaining ones are
- ignored:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="@priority = 'high'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting></para>
-
- <para>In the above example the first rule only applies if the
- nt:unstructured node has a priority property with a value 'high'. The
- condition syntax supports only the equals operator and a string
- literal.</para>
-
- <para>You may also reference properties in the condition that are not
- on the current node:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="ancestor::*/@priority = 'high'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured"
- boost="0.5"
- condition="parent::foo/@priority = 'low'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured"
- boost="1.5"
- condition="bar/@priority = 'medium'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting></para>
-
- <para>The indexing configuration also allows you to specify the type
- of a node in the condition. Please note however that the type match
- must be exact. It does not consider sub types of the specified node
- type.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="element(*, nt:unstructured)/@priority = 'high'">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
- </section>
-
- <section>
- <title>Exclusion from the Node Scope Index</title>
-
- <para>Per default all configured properties are fulltext indexed if
- they are of type STRING and included in the node scope index. A node
- scope search finds normally all nodes of an index. That is, the select
- jcr:contains(., 'foo') returns all nodes that have a string property
- containing the word 'foo'. You can exclude explicitly a property from
- the node scope index:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property nodeScopeIndex="false">Text</property>
- </index-rule>
-</configuration></programlisting></para>
- </section>
- </section>
-
- <section>
- <title>Index Aggregates</title>
-
- <para>Sometimes it is useful to include the contents of descendant nodes
- into a single node to easier search on content that is scattered across
- multiple nodes.</para>
-
- <para>JCR allows you to define index aggregates based on relative path
- patterns and primary node types.</para>
-
- <para>The following example creates an index aggregate on nt:file that
- includes the content of the jcr:content node:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include>jcr:content</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>You can also restrict the included nodes to a certain
- type:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include primaryType="nt:resource">jcr:content</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>You may also use the * to match all child nodes:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">http://wiki.exoplatform.com/xwiki/bin/edit/JCR/Search+Configuration
- <include primaryType="nt:resource">*</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>If you wish to include nodes up to a certain depth below the
- current node you can add multiple include elements. E.g. the nt:file
- node may contain a complete XML document under
- jcr:content:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include>*</include>
- <include>*/*</include>
- <include>*/*/*</include>
- </aggregate>
-</configuration></programlisting></para>
- </section>
-
- <section>
- <title>Property-Level Analyzers</title>
-
- <section>
- <title>Example</title>
-
- <para>In this configuration section you define how a property has to
- be analyzed. If there is an analyzer configuration for a property,
- this analyzer is used for indexing and searching of this property. For
- example:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <analyzers>
- <analyzer class="org.apache.lucene.analysis.KeywordAnalyzer">
- <property>mytext</property>
- </analyzer>
- <analyzer class="org.apache.lucene.analysis.WhitespaceAnalyzer">
- <property>mytext2</property>
- </analyzer>
- </analyzers>
-</configuration></programlisting></para>
-
- <para>The configuration above means that the property "mytext" for the
- entire workspace is indexed (and searched) with the Lucene
- KeywordAnalyzer, and property "mytext2" with the WhitespaceAnalyzer.
- Using different analyzers for different languages is particularly
- useful.</para>
-
- <para>The WhitespaceAnalyzer tokenizes a property, the KeywordAnalyzer
- takes the property as a whole.</para>
- </section>
-
- <section>
- <title>Characteristics of Node Scope Searches</title>
-
- <para>When using analyzers, you may encounter an unexpected behavior
- when searching within a property compared to searching within a node
- scope. The reason is that the node scope always uses the global
- analyzer.</para>
-
- <para>Let's suppose that the property "mytext" contains the text :
- "testing my analyzers" and that you haven't configured any analyzers
- for the property "mytext" (and not changed the default analyzer in
- SearchIndex).</para>
-
- <para>If your query is for example:<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting></para>
-
- <para>This xpath does not return a hit in the node with the property
- above and default analyzers.</para>
-
- <para>Also a search on the node scope<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>won't
- give a hit. Realize, that you can only set specific analyzers on a
- node property, and that the node scope indexing/analyzing is always
- done with the globally defined analyzer in the SearchIndex
- element.</para>
-
- <para>Now, if you change the analyzer used to index the "mytext"
- property above to<programlisting><analyzer class="org.apache.lucene.analysis.Analyzer.GermanAnalyzer">
- <property>mytext</property>
-</analyzer></programlisting>and you do the same search again, then
- for<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting>you
- would get a hit because of the word stemming (analyzers -
- analyzer).</para>
-
- <para>The other search,<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>still
- would not give a result, since the node scope is indexed with the
- global analyzer, which in this case does not take into account any
- word stemming.</para>
-
- <para>In conclusion, be aware that when using analyzers for specific
- properties, you might find a hit in a property for some search text,
- and you do not find a hit with the same search text in the node scope
- of the property!</para>
-
- <note>
- <para>Both index rules and index aggregates influence how content is
- indexed in JCR. If you change the configuration the existing content
- is not automatically re-indexed according to the new rules. You
- therefore have to manually re-index the content when you change the
- configuration!</para>
- </note>
- </section>
- </section>
- <section>
- <title>Advanced features</title>
- <para>Exo JCR supports some advanced features, which are not specified in JSR 170:
- * Get a text excerpt with
- <emphasis role="bold">highlighted words</emphasis> that matches the query:
- <ulink url="ExcerptProvider>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">ExcerptProvider</ulink>.
- * Search for a term and its
- <emphasis role="bold">synonyms</emphasis>:
- <ulink url="SynonymSearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SynonymSearch</ulink>
- * Search for
- <emphasis role="bold">similar</emphasis> nodes:
- <ulink url="SimilaritySearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SimilaritySearch</ulink>
- * Check
- <emphasis role="bold">spelling</emphasis> of a fulltext query statement:
- <ulink url="SpellChecker>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SpellChecker</ulink>
- * Define index
- <emphasis role="bold">aggregates and rules</emphasis>: IndexingConfiguration (see this article)
- </para>
- </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="JCR.SearchConfiguration">
+ <?dbhtml filename="ch-search-configuration.html"?>
+
+ <title>Search Configuration</title>
+
+ <section>
+ <title>XML Configuration</title>
+
+ <para>JCR index configuration. You can find this file here:
+ <filename>.../portal/WEB-INF/conf/jcr/repository-configuration.xml</filename></para>
+
+ <programlisting><repository-service default-repository="db1">
+ <repositories>
+ <repository name="db1" system-workspace="ws" default-workspace="ws">
+ ....
+ <workspaces>
+ <workspace name="ws">
+ ....
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="${java.io.tmpdir}/temp/index/db1/ws" />
+ <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+ <property name="synonymprovider-config-path" value="/synonyms.properties" />
+ <property name="indexing-config-path" value="/indexing-configuration.xml" />
+ <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+ </properties>
+ </query-handler>
+ ...
+ </workspace>
+ </workspaces>
+ </repository>
+ </repositories>
+</repository-service></programlisting>
+ </section>
+
+ <section>
+ <title>Configuration parameters</title>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Parameter</entry>
+
+ <entry>Default</entry>
+
+ <entry>Description</entry>
+
+ <entry>Since</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>index-dir</entry>
+
+ <entry>none</entry>
+
+ <entry>The location of the index directory. This parameter is
+ mandatory. Up to 1.9 this parameter called "indexDir"</entry>
+
+ <entry>1.0</entry>
+ </row>
+
+ <row>
+ <entry>use-compoundfile</entry>
+
+ <entry>true</entry>
+
+ <entry>Advises lucene to use compound files for the index
+ files.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>min-merge-docs</entry>
+
+ <entry>100</entry>
+
+ <entry>Minimum number of nodes in an index until segments are
+ merged.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>volatile-idle-time</entry>
+
+ <entry>3</entry>
+
+ <entry>Idle time in seconds until the volatile index part is moved
+ to a persistent index even though minMergeDocs is not
+ reached.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>max-merge-docs</entry>
+
+ <entry>Integer.MAX_VALUE</entry>
+
+ <entry>Maximum number of nodes in segments that will be merged.
+ The default value changed in JCR 1.9 to Integer.MAX_VALUE.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>merge-factor</entry>
+
+ <entry>10</entry>
+
+ <entry>Determines how often segment indices are merged.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>max-field-length</entry>
+
+ <entry>10000</entry>
+
+ <entry>The number of words that are fulltext indexed at most per
+ property.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>cache-size</entry>
+
+ <entry>1000</entry>
+
+ <entry>Size of the document number cache. This cache maps uuids to
+ lucene document numbers</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>force-consistencycheck</entry>
+
+ <entry>false</entry>
+
+ <entry>Runs a consistency check on every startup. If false, a
+ consistency check is only performed when the search index detects
+ a prior forced shutdown.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>auto-repair</entry>
+
+ <entry>true</entry>
+
+ <entry>Errors detected by a consistency check are automatically
+ repaired. If false, errors are only written to the log.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>query-class</entry>
+
+ <entry>QueryImpl</entry>
+
+ <entry>Class name that implements the javax.jcr.query.Query
+ interface.This class must also extend from the class:
+ org.exoplatform.services.jcr.impl.core.query.AbstractQueryImpl.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>document-order</entry>
+
+ <entry>true</entry>
+
+ <entry>If true and the query does not contain an 'order by'
+ clause, result nodes will be in document order. For better
+ performance when queries return a lot of nodes set to
+ 'false'.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>result-fetch-size</entry>
+
+ <entry>Integer.MAX_VALUE</entry>
+
+ <entry>The number of results when a query is executed. Default
+ value: Integer.MAX_VALUE (-> all).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>excerptprovider-class</entry>
+
+ <entry>DefaultXMLExcerpt</entry>
+
+ <entry>The name of the class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.ExcerptProvider
+ and should be used for the rep:excerpt() function in a
+ query.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>support-highlighting</entry>
+
+ <entry>false</entry>
+
+ <entry>If set to true additional information is stored in the
+ index to support highlighting using the rep:excerpt()
+ function.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>synonymprovider-class</entry>
+
+ <entry>none</entry>
+
+ <entry>The name of a class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.SynonymProvider.
+ The default value is null (-> not set).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>synonymprovider-config-path</entry>
+
+ <entry>none</entry>
+
+ <entry>The path to the synonym provider configuration file. This
+ path interpreted relative to the path parameter. If there is a
+ path element inside the SearchIndex element, then this path is
+ interpreted relative to the root path of the path. Whether this
+ parameter is mandatory depends on the synonym provider
+ implementation. The default value is null (-> not set).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>indexing-configuration-path</entry>
+
+ <entry>none</entry>
+
+ <entry>The path to the indexing configuration file.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>indexing-configuration-class</entry>
+
+ <entry>IndexingConfigurationImpl</entry>
+
+ <entry>The name of the class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfiguration.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>force-consistencycheck</entry>
+
+ <entry>false</entry>
+
+ <entry>If set to true a consistency check is performed depending
+ on the parameter forceConsistencyCheck. If set to false no
+ consistency check is performed on startup, even if a redo log had
+ been applied.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-class</entry>
+
+ <entry>none</entry>
+
+ <entry>The name of a class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-more-popular</entry>
+
+ <entry>true</entry>
+
+ <entry>If set true - spellchecker return only the suggest words
+ that are as frequent or more frequent than the checked word. If
+ set false, spellchecker return null (if checked word exit in
+ dictionary), or spellchecker will return most close suggest
+ word.</entry>
+
+ <entry>1.10</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-min-distance</entry>
+
+ <entry>0.55f</entry>
+
+ <entry>Minimal distance between checked word and proposed suggest
+ word.</entry>
+
+ <entry>1.10</entry>
+ </row>
+
+ <row>
+ <entry>errorlog-size</entry>
+
+ <entry>50(Kb)</entry>
+
+ <entry>The default size of error log file in Kb.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>upgrade-index</entry>
+
+ <entry>false</entry>
+
+ <entry>Allows JCR to convert an existing index into the new
+ format. Also it is possible to set this property via system
+ property, for example: -Dupgrade-index=true Indexes before JCR
+ 1.12 will not run with JCR 1.12. Hence you have to run an
+ automatic migration: Start JCR with -Dupgrade-index=true. The old
+ index format is then converted in the new index format. After the
+ conversion the new format is used. On the next start you don't
+ need this option anymore. The old index is replaced and a back
+ conversion is not possible - therefore better take a backup of the
+ index before. (Only for migrations from JCR 1.9 and
+ later.)</entry>
+
+ <entry>1.12</entry>
+ </row>
+
+ <row>
+ <entry>analyzer</entry>
+
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
+
+ <entry>Class name of a lucene analyzer to use for fulltext
+ indexing of text.</entry>
+
+ <entry>1.12</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Global Search Index</title>
+
+ <section>
+ <title>Global Search Index Configuration</title>
+
+ <para>The global search index is configured in the above-mentioned
+ configuration file
+ (<filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>)
+ in the tag "query-handler".</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>
+
+ <para>In fact when using Lucene you always should use the same analyzer
+ for indexing and for querying - otherwise the results are unpredictable.
+ You don't have to worry about this, eXo JCR does this for you
+ automatically. If you don't like the StandardAnalyzer configured by
+ default just replace it by your own.</para>
+
+ <para>If you don't have a handy QueryHandler you will learn how create a
+ customized Handler in 5 minutes.</para>
+ </section>
+
+ <section>
+ <title>Customized Search Indexes and Analyzers</title>
+
+ <para>By default Exo JCR uses the Lucene standard Analyzer to index
+ contents. This analyzer uses some standard filters in the method that
+ analyzes the content:<programlisting>public TokenStream tokenStream(String fieldName, Reader reader) {
+ StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);
+ tokenStream.setMaxTokenLength(maxTokenLength);
+ TokenStream result = new StandardFilter(tokenStream);
+ result = new LowerCaseFilter(result);
+ result = new StopFilter(result, stopSet);
+ return result;
+ }</programlisting><itemizedlist>
+ <listitem>
+ <para>The first one (StandardFilter) removes 's (as 's in
+ "Peter's") from the end of words and removes dots from
+ acronyms.</para>
+ </listitem>
+
+ <listitem>
+ <para>The second one (LowerCaseFilter) normalizes token text to
+ lower case.</para>
+ </listitem>
+
+ <listitem>
+ <para>The last one (StopFilter) removes stop words from a token
+ stream. The stop set is defined in the analyzer.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>For specific cases, you may wish to use additional filters like
+ <phrase>ISOLatin1AccentFilter</phrase>, which replaces accented
+ characters in the ISO Latin 1 character set (ISO-8859-1) by their
+ unaccented equivalents.</para>
+
+ <para>In order to use a different filter, you have to create a new
+ analyzer, and a new search index to use the analyzer. You put it in a
+ jar, which is deployed with your application.</para>
+
+ <section>
+ <title>Create the filter</title>
+
+ <para>The ISOLatin1AccentFilter is not present in the current Lucene
+ version used by Exo. You can use the attached file. You can also
+ create your own filter, the relevant method is<programlisting>public final Token next(final Token reusableToken) throws java.io.IOException</programlisting>which
+ defines how chars are read and used by the filter.</para>
+ </section>
+
+ <section>
+ <title>Create the analyzer</title>
+
+ <para>The analyzer have to extends
+ org.apache.lucene.analysis.standard.StandardAnalyzer, and overload the
+ method<programlisting>public TokenStream tokenStream(String fieldName, Reader reader)</programlisting>to
+ put your own filters. You can have a glance at the example analyzer
+ attached to this article.</para>
+ </section>
+
+ <section>
+ <title>Create the search index</title>
+
+ <para>Now, we have the analyzer, we have to write the SearchIndex,
+ which will use the analyzer. Your have to extends
+ org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex. You
+ have to write the constructor, to set the right analyzer, and the
+ method<programlisting>public Analyzer getAnalyzer() {
+ return MyAnalyzer;
+ }</programlisting>to return your analyzer. You can see the attached
+ SearchIndex.</para>
+
+ <note>
+ <para>Since 1.12 version we can set Analyzer directly in
+ configuration. So, creation new SearchIndex only for new Analyzer is
+ redundant.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Configure your application to use your SearchIndex</title>
+
+ <para>In
+ <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
+ you have to replace each<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>by
+ your own class<programlisting><query-handler class="mypackage.indexation.MySearchIndex"></programlisting></para>
+ </section>
+
+ <section>
+ <title>Configure your application to use your Analyzer</title>
+
+ <para>In
+ <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
+ you have to add parameter "analyzer" to each query-handler
+ config:<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="analyzer" value="org.exoplatform.services.jcr.impl.core.MyAnalyzer"/>
+ ...
+ </properties>
+</query-handler></programlisting></para>
+
+ <para>When you start exo, your SearchIndex will start to index
+ contents with the specified filters.</para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Index Adjustments</title>
+
+ <section>
+ <title>IndexingConfiguration</title>
+
+ <para>Starting with version 1.9, the default search index implementation
+ in JCR allows you to control which properties of a node are indexed. You
+ also can define different analyzers for different nodes.</para>
+
+ <para>The configuration parameter is called indexingConfiguration and
+ per default is not set. This means all properties of a node are
+ indexed.</para>
+
+ <para>If you wish to configure the indexing behavior you need to add a
+ parameter to the query-handler element in your configuration
+ file.</para>
+
+ <programlisting><param name="indexing-configuration-path" value="/indexing_configuration.xml"/></programlisting>
+ </section>
+
+ <section>
+ <title>Index rules</title>
+
+ <section>
+ <title>Node Scope Limit</title>
+
+ <para>To optimize the index size you can limit the node scope so that
+ <phrase>only certain properties</phrase> of a node type are
+ indexed.</para>
+
+ <para>With the below configuration only properties named Text are
+ indexed for nodes of type nt:unstructured. This configuration also
+ applies to all nodes whose type extends from nt:unstructured.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+
+ <para>Please note that you have to declare the <phrase>namespace
+ prefixes</phrase> in the configuration element that you are using
+ throughout the XML file!</para>
+ </section>
+
+ <section>
+ <title>Index Boost Value</title>
+
+ <para>It is also possible to configure a <phrase>boost value</phrase>
+ for the nodes that match the index rule. The default boost value is
+ 1.0. Higher boost values (a reasonable range is 1.0 - 5.0) will yield
+ a higher score value and appear as more relevant.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+
+ <para>If you do not wish to boost the complete node but only certain
+ properties you can also provide a boost value for the listed
+ properties:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property boost="3.0">Title</property>
+ <property boost="1.5">Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+ </section>
+
+ <section>
+ <title>Conditional Index Rules</title>
+
+ <para>You may also add a <phrase>condition</phrase> to the index rule
+ and have multiple rules with the same nodeType. The first index rule
+ that matches will apply and all remaining ones are
+ ignored:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+
+ <para>In the above example the first rule only applies if the
+ nt:unstructured node has a priority property with a value 'high'. The
+ condition syntax supports only the equals operator and a string
+ literal.</para>
+
+ <para>You may also reference properties in the condition that are not
+ on the current node:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="ancestor::*/@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured"
+ boost="0.5"
+ condition="parent::foo/@priority = 'low'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured"
+ boost="1.5"
+ condition="bar/@priority = 'medium'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+
+ <para>The indexing configuration also allows you to specify the type
+ of a node in the condition. Please note however that the type match
+ must be exact. It does not consider sub types of the specified node
+ type.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="element(*, nt:unstructured)/@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>Exclusion from the Node Scope Index</title>
+
+ <para>Per default all configured properties are fulltext indexed if
+ they are of type STRING and included in the node scope index. A node
+ scope search finds normally all nodes of an index. That is, the select
+ jcr:contains(., 'foo') returns all nodes that have a string property
+ containing the word 'foo'. You can exclude explicitly a property from
+ the node scope index:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property nodeScopeIndex="false">Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Index Aggregates</title>
+
+ <para>Sometimes it is useful to include the contents of descendant nodes
+ into a single node to easier search on content that is scattered across
+ multiple nodes.</para>
+
+ <para>JCR allows you to define index aggregates based on relative path
+ patterns and primary node types.</para>
+
+ <para>The following example creates an index aggregate on nt:file that
+ includes the content of the jcr:content node:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include>jcr:content</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>You can also restrict the included nodes to a certain
+ type:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include primaryType="nt:resource">jcr:content</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>You may also use the * to match all child nodes:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">http://wiki.exoplatform.com/xwiki/bin/edit/JCR/Search+Configuration
+ <include primaryType="nt:resource">*</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>If you wish to include nodes up to a certain depth below the
+ current node you can add multiple include elements. E.g. the nt:file
+ node may contain a complete XML document under
+ jcr:content:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include>*</include>
+ <include>*/*</include>
+ <include>*/*/*</include>
+ </aggregate>
+</configuration></programlisting></para>
+ </section>
+
+ <section>
+ <title>Property-Level Analyzers</title>
+
+ <section>
+ <title>Example</title>
+
+ <para>In this configuration section you define how a property has to
+ be analyzed. If there is an analyzer configuration for a property,
+ this analyzer is used for indexing and searching of this property. For
+ example:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <analyzers>
+ <analyzer class="org.apache.lucene.analysis.KeywordAnalyzer">
+ <property>mytext</property>
+ </analyzer>
+ <analyzer class="org.apache.lucene.analysis.WhitespaceAnalyzer">
+ <property>mytext2</property>
+ </analyzer>
+ </analyzers>
+</configuration></programlisting></para>
+
+ <para>The configuration above means that the property "mytext" for the
+ entire workspace is indexed (and searched) with the Lucene
+ KeywordAnalyzer, and property "mytext2" with the WhitespaceAnalyzer.
+ Using different analyzers for different languages is particularly
+ useful.</para>
+
+ <para>The WhitespaceAnalyzer tokenizes a property, the KeywordAnalyzer
+ takes the property as a whole.</para>
+ </section>
+
+ <section>
+ <title>Characteristics of Node Scope Searches</title>
+
+ <para>When using analyzers, you may encounter an unexpected behavior
+ when searching within a property compared to searching within a node
+ scope. The reason is that the node scope always uses the global
+ analyzer.</para>
+
+ <para>Let's suppose that the property "mytext" contains the text :
+ "testing my analyzers" and that you haven't configured any analyzers
+ for the property "mytext" (and not changed the default analyzer in
+ SearchIndex).</para>
+
+ <para>If your query is for example:<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting></para>
+
+ <para>This xpath does not return a hit in the node with the property
+ above and default analyzers.</para>
+
+ <para>Also a search on the node scope<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>won't
+ give a hit. Realize, that you can only set specific analyzers on a
+ node property, and that the node scope indexing/analyzing is always
+ done with the globally defined analyzer in the SearchIndex
+ element.</para>
+
+ <para>Now, if you change the analyzer used to index the "mytext"
+ property above to<programlisting><analyzer class="org.apache.lucene.analysis.Analyzer.GermanAnalyzer">
+ <property>mytext</property>
+</analyzer></programlisting>and you do the same search again, then
+ for<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting>you
+ would get a hit because of the word stemming (analyzers -
+ analyzer).</para>
+
+ <para>The other search,<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>still
+ would not give a result, since the node scope is indexed with the
+ global analyzer, which in this case does not take into account any
+ word stemming.</para>
+
+ <para>In conclusion, be aware that when using analyzers for specific
+ properties, you might find a hit in a property for some search text,
+ and you do not find a hit with the same search text in the node scope
+ of the property!</para>
+
+ <note>
+ <para>Both index rules and index aggregates influence how content is
+ indexed in JCR. If you change the configuration the existing content
+ is not automatically re-indexed according to the new rules. You
+ therefore have to manually re-index the content when you change the
+ configuration!</para>
+ </note>
+ </section>
+ </section>
+
+ <section>
+ <title>Advanced features</title>
+
+ <para>Exo JCR supports some advanced features, which are not specified
+ in JSR 170:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Get a text excerpt with <emphasis role="bold">highlighted
+ words</emphasis> that matches the query: <ulink
+ url="ExcerptProvider>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searchi...">ExcerptProvider</ulink>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Search for a term and its <emphasis
+ role="bold">synonyms</emphasis>: <ulink
+ url="SynonymSearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching...">SynonymSearch</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para>Search for <emphasis role="bold">similar</emphasis> nodes:
+ <ulink
+ url="SimilaritySearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Search...">SimilaritySearch</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para>Check <emphasis role="bold">spelling</emphasis> of a fulltext
+ query statement: <ulink
+ url="SpellChecker>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+...">SpellChecker</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para>Define index <emphasis role="bold">aggregates and
+ rules</emphasis>: IndexingConfiguration (see this article)</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+</chapter>
15 years, 11 months
exo-jcr SVN: r2873 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-04 08:33:17 -0400 (Wed, 04 Aug 2010)
New Revision: 2873
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exact-path-constraint.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-similar-nodes.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/higlight.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/index-boost-value.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/node-scope-index.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/regexp-indexing-rule.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/spell-checker.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/synonim-provider.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/tip-nodename-with-number.xml
Removed:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exaxt-path-constraint.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
Log:
EXOJCR-869: jcr-query-usecases ported
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exact-path-constraint.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exact-path-constraint.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exact-path-constraint.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,129 @@
+<?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">
+<section id="JCR.ExactPathConstraint">
+ <title>Exact Path Constraint</title>
+
+ <para>Find a node with the primary type 'nt:file' that is located on the
+ exact path "/folder1/folder2/document1".</para>
+
+ <section>
+ <title>Repository Structure</title>
+
+ <para>Repository filled by different nodes. There are several folders
+ which contain other folders and files.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>folder1 (nt:folder)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>folder2 (nt:folder)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>document1 (nt:file) // This document we want to
+ find</para>
+ </listitem>
+
+ <listitem>
+ <para>folder3 (nt:folder)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>document1 (nt:file)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query Execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// we want find 'document1'
+String sqlStatement = "SELECT * FROM nt:file WHERE jcr:path = '/folder1/folder2/document1'";
+// create query
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// we want to find 'document1'
+String xpathStatement = "/jcr:root/folder1[1]/folder2[1]/element(document1,nt:file)[1]";
+// create query
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para>Remark: The indexes [1] are used in order to get the same result as
+ the SQL statement. SQL by default only returns the first node, whereas
+ XPath fetches by default all nodes.</para>
+ </section>
+
+ <section>
+ <title>Fetching the Result</title>
+
+ <para>Let's get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return expected "document1".</para>
+
+ <para>We can also get a table:</para>
+
+ <programlisting>String[] columnNames = result.getColumnNames();
+RowIterator rit = result.getRows();
+while (rit.hasNext())
+{
+ Row row = rit.nextRow();
+ // get values of the row
+ Value[] values = row.getValues();
+}</programlisting>
+
+ <para>Table content is: <table>
+ <title>Table content</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>jcr:path</entry>
+
+ <entry>jcr:score</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>/folder1/folder2/document1</entry>
+
+ <entry>1030</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table></para>
+ </section>
+</section>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exaxt-path-constraint.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exaxt-path-constraint.xml 2010-08-04 12:10:15 UTC (rev 2872)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/exaxt-path-constraint.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -1,129 +0,0 @@
-<?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">
-<section id="JCR.ExactPathConstraint">
- <title>Exact Path Constraint</title>
-
- <para>Find a node with the primary type 'nt:file' that is located on the
- exact path "/folder1/folder2/document1".</para>
-
- <section>
- <title>Repository Structure</title>
-
- <para>Repository filled by different nodes. There are several folders
- which contain other folders and files.</para>
-
- <itemizedlist>
- <listitem>
- <para>root</para>
-
- <itemizedlist>
- <listitem>
- <para>folder1 (nt:folder)</para>
-
- <itemizedlist>
- <listitem>
- <para>folder2 (nt:folder)</para>
-
- <itemizedlist>
- <listitem>
- <para>document1 (nt:file) // This document we want to
- find</para>
- </listitem>
-
- <listitem>
- <para>folder3 (nt:folder)</para>
-
- <itemizedlist>
- <listitem>
- <para>document1 (nt:file)</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Query Execution</title>
-
- <para><emphasis role="bold">SQL</emphasis></para>
-
- <programlisting>// make SQL query
-QueryManager queryManager = workspace.getQueryManager();
-// we want find 'document1'
-String sqlStatement = "SELECT * FROM nt:file WHERE jcr:path = '/folder1/folder2/document1'";
-// create query
-Query query = queryManager.createQuery(sqlStatement, Query.SQL);
-// execute query and fetch result
-QueryResult result = query.execute();</programlisting>
-
- <para><emphasis role="bold">XPath</emphasis></para>
-
- <programlisting>// make SQL query
-QueryManager queryManager = workspace.getQueryManager();
-// we want to find 'document1'
-String xpathStatement = "/jcr:root/folder1[1]/folder2[1]/element(document1,nt:file)[1]";
-// create query
-Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
-// execute query and fetch result
-QueryResult result = query.execute();</programlisting>
-
- <para>Remark: The indexes [1] are used in order to get the same result as
- the SQL statement. SQL by default only returns the first node, whereas
- XPath fetches by default all nodes.</para>
- </section>
-
- <section>
- <title>Fetching the Result</title>
-
- <para>Let's get nodes:</para>
-
- <programlisting>NodeIterator it = result.getNodes();
-
-if(it.hasNext())
-{
- Node findedNode = it.nextNode();
-}</programlisting>
-
- <para>NodeIterator will return expected "document1".</para>
-
- <para>We can also get a table:</para>
-
- <programlisting>String[] columnNames = result.getColumnNames();
-RowIterator rit = result.getRows();
-while (rit.hasNext())
-{
- Row row = rit.nextRow();
- // get values of the row
- Value[] values = row.getValues();
-}</programlisting>
-
- <para>Table content is: <table>
- <title>Table content</title>
-
- <tgroup cols="2">
- <thead>
- <row>
- <entry>jcr:path</entry>
-
- <entry>jcr:score</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>/folder1/folder2/document1</entry>
-
- <entry>1030</entry>
- </row>
- </tbody>
- </tgroup>
- </table></para>
- </section>
-</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-similar-nodes.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-similar-nodes.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/find-similar-nodes.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,196 @@
+<?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">
+<section id="JCR.FindSimilarNodes">
+ <title>Find Similar Nodes</title>
+
+ <para>Find similar nodes to node by path '/baseFile/jcr:content'.</para>
+
+ <para>In our example, baseFile will contain text where "terms" word happens
+ many time. Thats why existanse of this word will be used as a criteria of
+ node similarity (for node baseFile).</para>
+
+ <note>
+ <para>See also about Similarity and configuration - <link
+ linkend="JCR.SearchingRepositoryContent">Searching Repository
+ Content</link></para>
+ </note>
+
+ <para>Higlighting support must be added to configuration.
+ test-jcr-config.xml:</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="support-highlighting" value="true" />
+ ...
+ </properties>
+</query-handler></programlisting>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains many nt:file nodes"</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>baseFile (nt:file)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>jcr:content (nt:resource) jcr:data="Similarity is
+ determined by looking up <emphasis
+ role="bold">terms</emphasis> that are common to nodes. There
+ are some conditions that must be met for a <emphasis
+ role="bold">term</emphasis> to be considered. This is required
+ to limit the number possibly relevant <emphasis
+ role="bold">terms</emphasis>. Only <emphasis
+ role="bold">terms</emphasis> with at least 4 characters are
+ considered. Only <emphasis role="bold">terms</emphasis> that
+ occur at least 2 times in the source node are considered. Only
+ <emphasis role="bold">terms</emphasis> that occur in at least
+ 5 nodes are considered."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>target1 (nt:file)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>jcr:content (nt:resource) jcr:data="Similarity is
+ determined by looking up <emphasis
+ role="bold">terms</emphasis> that are common to nodes."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>target2 (nt:file)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>jcr:content (nt:resource) jcr:data="There is no you know
+ what"</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>target3 (nt:file)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>jcr:content (nt:resource) jcr:data=" <emphasis
+ role="bold">Terms</emphasis> occures here"</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM nt:resource WHERE SIMILAR(.,'/baseFile/jcr:content')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*, nt:resource)[rep:similar(., '/testroot/baseFile/jcr:content')]";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return
+ "/baseFile/jcr:content","/target1/jcr:content" and
+ "/target3/jcr:content".</para>
+
+ <para>As you see base node are also in result set.</para>
+
+ <para>We can also get a table:</para>
+
+ <programlisting>String[] columnNames = result.getColumnNames();
+RowIterator rit = result.getRows();
+while (rit.hasNext())
+{
+ Row row = rit.nextRow();
+ // get values of the row
+ Value[] values = row.getValues();
+}</programlisting>
+
+ <para>The table content is</para>
+
+ <table>
+ <title>Table content</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>jcr:path</entry>
+
+ <entry>...</entry>
+
+ <entry>jcr:score</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>/baseFile/jcr:content</entry>
+
+ <entry>...</entry>
+
+ <entry>2674</entry>
+ </row>
+
+ <row>
+ <entry>/target1/jcr:content </entry>
+
+ <entry>...</entry>
+
+ <entry>2674</entry>
+ </row>
+
+ <row>
+ <entry>/target3/jcr:content </entry>
+
+ <entry>...</entry>
+
+ <entry>2674</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/higlight.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/higlight.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/higlight.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,147 @@
+<?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">
+<section id="JCR.HiglightResultofFulltextSearch">
+ <title>Higlight Result of Fulltext Search</title>
+
+ <para>Also its called excerption (see Excerpt configuration in <link
+ linkend="JCR.SearchConfiguration">Search Configuration</link> and in <link
+ linkend="JCR.SearchingRepositoryContent.Highlighting">Searching
+ Repository</link> article).</para>
+
+ <para>The goal of this query is find words "eXo" and "implementation" with
+ fulltext search and highlight this words in result value.</para>
+
+ <section>
+ <title>Base info</title>
+
+ <para>Highlighting is not default feature so we must set it in
+ jcr-config.xml, also excerpt provider must be defined:</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="support-highlighting" value="true" />
+ <property name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.WeightedHTMLExcerpt"/>
+ ...
+ <properties>
+</query-handler></programlisting>
+
+ <para>Also remember that we can make indexing rules, as in example
+ below:</para>
+
+ <para>Let's write rule for all nodes with primary node type
+ 'nt:unstructed' where property 'rule' equal to "excerpt" string. For those
+ nodes we will exclude property "title" from highlighting and set "text"
+ property as highlightable. indexing-configuration.xml must containt next
+ rule:</para>
+
+ <programlisting><index-rule nodeType="nt:unstructured" condition="@rule='excerpt'">
+ <property useInExcerpt="false">title</property>
+ <property>text</property>
+</index-rule></programlisting>
+ </section>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>We have single node with primary type 'nt:unstructured'</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>document (nt:unstructured)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>rule = "excerpt"</para>
+ </listitem>
+
+ <listitem>
+ <para>title = "eXoJCR"</para>
+ </listitem>
+
+ <listitem>
+ <para>text = "eXo is a JCR implementation"</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT rep:excerpt() FROM nt:unstructured WHERE CONTAINS(*, 'eXo implementation')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*,nt:unstructured)[jcr:contains(., 'eXo implementation')]/rep:excerpt(.)";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Now lets see on result table:</para>
+
+ <programlisting>String[] columnNames = result.getColumnNames();
+RowIterator rit = result.getRows();
+while (rit.hasNext())
+{
+ Row row = rit.nextRow();
+ // get values of the row
+ Value[] values = row.getValues();
+}</programlisting>
+
+ <para>Table content is </para>
+
+ <table>
+ <title>Table content</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>rep:excerpt()</entry>
+
+ <entry>jcr:path</entry>
+
+ <entry>jcr:score</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>\<div\>\<span\>\<strong\>eXo\</strong\>
+ is a JCR
+ \<strong\>implementation\</strong\>\</span\>\</div\></entry>
+
+ <entry>/testroot/node1</entry>
+
+ <entry>335</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>As you see, words "eXo" and "implamentation" is highlighted.</para>
+
+ <para>Also we can get exactly "rep:excerpt" value:</para>
+
+ <programlisting>RowIterator rows = result.getRows();
+Value excerpt = rows.nextRow().getValue("rep:excerpt(.)");
+// excerpt will be equal to "<div><span\><strong>eXo</strong> is a JCR <strong>implementation</strong></span></div>"</programlisting>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/index-boost-value.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/index-boost-value.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/index-boost-value.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,123 @@
+<?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">
+<section id="JCR.IndexBoostRule">
+ <title>Change Priority of Node</title>
+
+ <para>In this example, we will set different boost values for predefined
+ nodes, and will check effect by selecting those nodes and order them by
+ jcr:score.</para>
+
+ <para>The default boost value is 1.0. Higher boost values (a reasonable
+ range is 1.0 - 5.0) will yield a higher score value and appear as more
+ relevant.</para>
+
+ <note>
+ <para>See 4.2.2 Index Boost Value <link
+ linkend="JCR.SearchConfiguration">Search Configuration</link> </para>
+ </note>
+
+ <section>
+ <title>Indexing configuration</title>
+
+ <para>In next configuration we will set boost values for nt:ustructured
+ nodes 'text' property. </para>
+
+ <para>indexing-config.xml:</para>
+
+ <programlisting><!--
+This rule actualy do nothing. 'text' property has default boost value.
+-->
+<index-rule nodeType="nt:unstructured" condition="@rule='boost1'">
+ <!-- default boost: 1.0 -->
+ <property>text</property>
+</index-rule>
+
+<!--
+Set boost value as 2.0 for 'text' property in nt:unstructured nodes where property 'rule' equal to 'boost2'
+-->
+<index-rule nodeType="nt:unstructured" condition="@rule='boost2'">
+ <!-- boost: 2.0 -->
+ <property boost="2.0">text</property>
+</index-rule>
+
+<!--
+Set boost value as 3.0 for 'text' property in nt:unstructured nodes where property 'rule' equal to 'boost3'
+-->
+<index-rule nodeType="nt:unstructured" condition="@rule='boost3'">
+ <!-- boost: 3.0 -->
+ <property boost="3.0">text</property>
+</index-rule></programlisting>
+ </section>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains many nodes with primary type nt:unstructured.
+ Each node contains 'text' property and 'rule' property with different
+ values.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>node1(nt:unstructured) rule='boost1' text='The quick brown
+ fox jump...'</para>
+ </listitem>
+
+ <listitem>
+ <para>node2(nt:unstructured) rule='boost2' text='The quick brown
+ fox jump...'</para>
+ </listitem>
+
+ <listitem>
+ <para>node3(nt:unstructured) rule='boost3' text='The quick brown
+ fox jump...'</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM nt:unstructured WHERE CONTAINS(text, 'quick') ORDER BY jcr:score() DESC";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*,nt:unstructured)[jcr:contains(@text, 'quick')] order by @jcr:score descending";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return nodes in next order "node3", "node2",
+ "node1".</para>
+ </section>
+</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-04 12:10:15 UTC (rev 2872)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -1,317 +1,414 @@
-<?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="JCR.QueryUsecases">
- <title>JCR Query Usecases</title>
-
- <section>
- <title>Intro</title>
-
- <para>JCR supports two query languages - JCR and XPath. A query, whether
- XPath or SQL, specifies a subset of nodes within a workspace, called the
- result set. The result set constitutes all the nodes in the workspace that
- meet the constraints stated in the query.</para>
- </section>
-
- <section>
- <title>Query Lifecycle</title>
-
- <section>
- <title>Query Creation and Execution</title>
-
- <para><emphasis role="bold">SQL</emphasis></para>
-
- <programlisting>// get QueryManager
-QueryManager queryManager = workspace.getQueryManager();
-// make SQL query
-Query query = queryManager.createQuery("SELECT * FROM nt:base ", Query.SQL);
-// execute query
-QueryResult result = query.execute();</programlisting>
-
- <para><emphasis role="bold">XPath</emphasis></para>
-
- <programlisting>// get QueryManager
-QueryManager queryManager = workspace.getQueryManager();
-// make XPath query
-Query query = queryManager.createQuery("//element(*,nt:base)", Query.XPATH);
-// execute query
-QueryResult result = query.execute();</programlisting>
- </section>
-
- <section>
- <title>Query Result Processing</title>
-
- <programlisting>// fetch query result
-QueryResult result = query.execute();</programlisting>
-
- <para>Now we can get result in an iterator of nodes:</para>
-
- <programlisting>NodeIterator it = result.getNodes();</programlisting>
-
- <para>or we get the result in a table:</para>
-
- <programlisting>// get column names
-String[] columnNames = result.getColumnNames();
-// get column rows
-RowIterator rowIterator = result.getRows();
-while(rowIterator.hasNext()){
- // get next row
- Row row = rowIterator.nextRow();
- // get all values of row
- Value[] values = row.getValues();
-}</programlisting>
- </section>
-
- <section>
- <title>Scoring</title>
-
- <para>The result returns a score for each row in the result set. The
- score contains a value that indicates a rating of how well the result
- node matches the query. A high value means a better matching than a low
- value. This score can be used for ordering the result.</para>
-
- <para>eXo JCR Scoring is a mapping of Lucene scoring. For a more
- in-depth understanding, please study <ulink
- url="http://lucene.apache.org/java/2_4_1/scoring.html">Lucene
- documentation</ulink>.</para>
-
- <para>jcr:score counted in next way - (lucene score)*1000f.</para>
-
- <para>Score may be increased for specified nodes, see <ulink
- url="Index Boost Value">Index Boost Value</ulink></para>
-
- <para>Also, see an example <link linkend="JCR.OrderByScore">Order by
- Score</link></para>
- </section>
- </section>
-
- <section>
- <title>Query Examples</title>
-
- <section>
- <title>Query result settings</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.SetOffsetandSetLimit">Set Offset And
- Limit</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Type Constraints</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.FindAllNodes">Find All Nodes</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesByPrimaryType">Find Nodes by
- Primary Type</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesByMixinType">Find Nodes by Mixin
- Type</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Property Constraints</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.PropertyComparison">Property
- Comparison</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.LIKEConstraint">LIKE
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.EscapinginLIKEStatements">Escaping in LIKE
- Statements</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.NOTConstraint">NOT Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ANDConstraint">AND Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ORConstraint">OR Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.PropertyExistenceConstraint">Property
- Existence Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindNodesCaseInsensitive">Upper and Lower
- Case Constraints</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.DatePropertyComparison">Date Property
- Comparison</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.NodeNameConstraint">Node Name
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.MultivaluePropertyComparison">Multivalue
- Property Comparison</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Path Constraint</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.ExactPathConstraint">Exact Path
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.ChildNodeConstraint">Child Node
- Constraint</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FindAllDescendantNodes">Find All Descendant
- Nodes</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Ordering specifing</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.OrderByProperty">Order by
- Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByDescendant">Order by Descendant Node
- Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByScore">Order by Score</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.OrderByPathOrName">Order by Path or
- Name</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title><link linkend="JCR.FulltextSearchAndSettings">Fulltext
- Search</link></title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="JCR.FulltextSearchByProperty">Fulltext Search
- by Property</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.FulltextSearchByAllProperties">Fulltext
- Search by All Properties</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.AggregationRule">Find nt:file document by
- content of child jcr:content node</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="JCR.IgnoreAccentSymbols">How to set new
- Analyzer. Accent symblos ignoring</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Indexing rules and additional features</title>
-
- <itemizedlist>
- <listitem>
- <para><ulink url="Aggregation rule">Aggregation rule</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="JCR.Search Result Highlighting">JCR.Search Result
- Highlighting</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="Index Boost Value">Index Boost
- Value</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink
- url="Exclusion from the Node Scope Index>JCR.Node Scope Index">Exclusion
- from the Node Scope Index>JCR.Node Scope Index</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink
- url="Regular expressions as property name in indexing rule > Regexp Indexing Rule">Regular
- expressions as property name in indexing rule > Regexp Indexing
- Rule</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="Synonim Provider">Synonim Provider</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="Spell Checking">Spell Checking</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="Find Similar Nodes">Find Similar
- Nodes</ulink></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>List of examples</title>
-
- <xi:include href="offset-and-limit.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
- </section>
- </section>
-
- <section>
- <title>Tips and tricks</title>
-
- <itemizedlist>
- <listitem>
- <para><ulink url="Xpath and numbers in node names">Xpath and numbers
- in node names</ulink></para>
- </listitem>
- </itemizedlist>
- </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="JCR.QueryUsecases">
+ <?dbhtml filename="ch-jcr-query-usecases.html"?>
+
+ <title>JCR Query Usecases</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>JCR supports two query languages - JCR and XPath. A query, whether
+ XPath or SQL, specifies a subset of nodes within a workspace, called the
+ result set. The result set constitutes all the nodes in the workspace that
+ meet the constraints stated in the query.</para>
+ </section>
+
+ <section>
+ <title>Query Lifecycle</title>
+
+ <section>
+ <title>Query Creation and Execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make SQL query
+Query query = queryManager.createQuery("SELECT * FROM nt:base ", Query.SQL);
+// execute query
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make XPath query
+Query query = queryManager.createQuery("//element(*,nt:base)", Query.XPATH);
+// execute query
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Query Result Processing</title>
+
+ <programlisting>// fetch query result
+QueryResult result = query.execute();</programlisting>
+
+ <para>Now we can get result in an iterator of nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();</programlisting>
+
+ <para>or we get the result in a table:</para>
+
+ <programlisting>// get column names
+String[] columnNames = result.getColumnNames();
+// get column rows
+RowIterator rowIterator = result.getRows();
+while(rowIterator.hasNext()){
+ // get next row
+ Row row = rowIterator.nextRow();
+ // get all values of row
+ Value[] values = row.getValues();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Scoring</title>
+
+ <para>The result returns a score for each row in the result set. The
+ score contains a value that indicates a rating of how well the result
+ node matches the query. A high value means a better matching than a low
+ value. This score can be used for ordering the result.</para>
+
+ <para>eXo JCR Scoring is a mapping of Lucene scoring. For a more
+ in-depth understanding, please study <ulink
+ url="http://lucene.apache.org/java/2_4_1/scoring.html">Lucene
+ documentation</ulink>.</para>
+
+ <para>jcr:score counted in next way - (lucene score)*1000f.</para>
+
+ <para>Score may be increased for specified nodes, see <ulink
+ url="Index Boost Value">Index Boost Value</ulink></para>
+
+ <para>Also, see an example <link linkend="JCR.OrderByScore">Order by
+ Score</link></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Query result settings</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.SetOffsetandSetLimit">Set Offset And
+ Limit</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Type Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.FindAllNodes">Find All Nodes</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesByPrimaryType">Find Nodes by Primary
+ Type</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesByMixinType">Find Nodes by Mixin
+ Type</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Property Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.PropertyComparison">Property
+ Comparison</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.LIKEConstraint">LIKE Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.EscapinginLIKEStatements">Escaping in LIKE
+ Statements</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NOTConstraint">NOT Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ANDConstraint">AND Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ORConstraint">OR Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.PropertyExistenceConstraint">Property
+ Existence Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindNodesCaseInsensitive">Upper and Lower
+ Case Constraints</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.DatePropertyComparison">Date Property
+ Comparison</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NodeNameConstraint">Node Name
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.MultivaluePropertyComparison">Multivalue
+ Property Comparison</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Path Constraint</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.ExactPathConstraint">Exact Path
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.ChildNodeConstraint">Child Node
+ Constraint</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindAllDescendantNodes">Find All Descendant
+ Nodes</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Ordering specifing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.OrderByProperty">Order by
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByDescendant">Order by Descendant Node
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByScore">Order by Score</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.OrderByPathOrName">Order by Path or
+ Name</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title><link linkend="JCR.FulltextSearchAndSettings">Fulltext
+ Search</link></title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByProperty">Fulltext Search by
+ Property</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FulltextSearchByAllProperties">Fulltext
+ Search by All Properties</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.AggregationRule">Find nt:file document by
+ content of child jcr:content node</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.IgnoreAccentSymbols">How to set new Analyzer.
+ Accent symblos ignoring</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Indexing rules and additional features</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.AggregationRule">Aggregation
+ rule</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.HiglightResultofFulltextSearch">Search Result
+ Highlighting</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.IndexBoostRule">Index Boost
+ Value</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.NodeScopeIndex">Exclusion from the Node Scope
+ Index</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.RegexpIndexingRule">Regular expressions as
+ property name in indexing rule</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SynonimProvider">Synonim
+ Provider</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SpellChecker">Spell Checking</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.FindSimilarNodes">Find Similar
+ Nodes</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query Examples</title>
+
+ <xi:include href="offset-and-limit.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-all-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-by-primary-type.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-by-mixin-type.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="like-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="escaping-like-statements.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="not-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="and-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="or-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="property-existance-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-nodes-case-insensitive.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="date-property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="node-name-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="multivalue-property-comparison.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="exact-path-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="child-node-constraint.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-all-descendant-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-property.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-descendant.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-score.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="order-by-path-or-name.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="fulltext-search-by-property.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="fulltext-search-by-all-properties.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="ignore-accent-symbols.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="aggregation-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="index-boost-value.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="node-scope-index.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="regexp-indexing-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="higlight.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="synonim-provider.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="regexp-indexing-rule.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="spell-checker.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="find-similar-nodes.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </section>
+
+ <section>
+ <title>Tips and tricks</title>
+
+ <xi:include href="tip-nodename-with-number.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!--itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.TipNodeNameWithNumber">Xpath and numbers in
+ node names</link></para>
+ </listitem>
+ </itemizedlist-->
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/node-scope-index.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/node-scope-index.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/node-scope-index.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,144 @@
+<?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">
+<section id="JCR.NodeScopeIndex">
+ <title>Remove Nodes Property From Indexing Scope</title>
+
+ <para>In this example, we will exclude some 'text' property of
+ nt:unstructured node from indexind. And, therefore, node will not be found
+ by content of this property, even if it accept all constraints.</para>
+
+ <para>First of all, add rules to indexing-configuration.xml:</para>
+
+ <programlisting><index-rule nodeType="nt:unstructured" condition="@rule='nsiTrue'">
+ <!-- default value for nodeScopeIndex is true -->
+ <property>text</property>
+</index-rule>
+
+<index-rule nodeType="nt:unstructured" condition="@rule='nsiFalse'">
+ <!-- do not include text in node scope index -->
+ <property nodeScopeIndex="false">text</property>
+</index-rule></programlisting>
+
+ <note>
+ <para>See <link linkend="JCR.SearchConfiguration">Search
+ Configuration</link></para>
+ </note>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains nt:unstructured nodes, with same 'text'property
+ and different 'rule' properties (even null)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>node1 (nt:unstructured) rule="nsiTrue" text="The quick brown
+ fox ..."</para>
+ </listitem>
+
+ <listitem>
+ <para>node2 (nt:unstructured) rule="nsiFalse" text="The quick
+ brown fox ..."</para>
+ </listitem>
+
+ <listitem>
+ <para>node3 (nt:unstructured) text="The quick brown fox ..." // as
+ you see this node not mentioned in indexing-coniguration</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM nt:unstructured WHERE CONTAINS(*,'quick')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*,nt:unstructured)[jcr:contains(., 'quick')]";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return "node1" and "node3". Node2, as you see, is
+ not in result set.</para>
+
+ <para>Also we can get a table:</para>
+
+ <programlisting>String[] columnNames = result.getColumnNames();
+RowIterator rit = result.getRows();
+while (rit.hasNext())
+{
+ Row row = rit.nextRow();
+ // get values of the row
+ Value[] values = row.getValues();
+}</programlisting>
+
+ <para>Table contant is</para>
+
+ <table>
+ <title>Table content</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>jcr:primarytype</entry>
+
+ <entry>jcr:path</entry>
+
+ <entry>jcr:score</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>nt:unstructured</entry>
+
+ <entry>/node1</entry>
+
+ <entry>3806</entry>
+ </row>
+
+ <row>
+ <entry>nt:unstructured</entry>
+
+ <entry>/node3 </entry>
+
+ <entry>3806</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/regexp-indexing-rule.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/regexp-indexing-rule.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/regexp-indexing-rule.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,141 @@
+<?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">
+<section id="JCR.RegexpIndexingRule">
+ <title>Regular Expression as Property Name in Indexing Rules</title>
+
+ <para>In this example, we want configure indexind in next way. All
+ properties of nt:unstructured nodes must be excluded from search, except
+ properties which names ends with 'Text' string. First of all, add rules to
+ indexing-configuration.xml:</para>
+
+ <programlisting><index-rule nodeType="nt:unstructured"">
+ <property isRegexp="true">.*Text</property>
+</index-rule></programlisting>
+
+ <note>
+ <para>See <link linkend="JCR.SearchConfiguration">Search
+ Configuration</link></para>
+ </note>
+
+ <para>Now, lets check this rule with simple query - select all nodes with
+ primary type 'nt:unstructured' and containing 'quick' string (fulltext
+ search by full node).</para>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains nt:unstructured nodes, with different
+ 'text'-like named properties</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>node1 (nt:unstructured) Text="The quick brown fox
+ ..."</para>
+ </listitem>
+
+ <listitem>
+ <para>node2 (nt:unstructured) OtherText="The quick brown fox
+ ..."</para>
+ </listitem>
+
+ <listitem>
+ <para>node3 (nt:unstructured) Textle="The quick brown fox
+ ..."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM nt:unstructured WHERE CONTAINS(*,'quick')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*,nt:unstructured)[jcr:contains(., 'quick')]";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return "node1" and "node2". "node3", as you see,
+ is not in result set.</para>
+
+ <para>Also we can get a table:</para>
+
+ <programlisting>String[] columnNames = result.getColumnNames();
+RowIterator rit = result.getRows();
+while (rit.hasNext())
+{
+ Row row = rit.nextRow();
+ // get values of the row
+ Value[] values = row.getValues();
+}</programlisting>
+
+ <para>Table contant is</para>
+
+ <table>
+ <title>Table content</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>jcr:primarytype</entry>
+
+ <entry>jcr:path</entry>
+
+ <entry>jcr:score</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>nt:unstructured</entry>
+
+ <entry>/node1</entry>
+
+ <entry>3806</entry>
+ </row>
+
+ <row>
+ <entry>nt:unstructured</entry>
+
+ <entry>/node2</entry>
+
+ <entry>3806</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml 2010-08-04 12:10:15 UTC (rev 2872)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -1,374 +1,374 @@
-<?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="JCR.SearchingRepositoryContent">
- <?dbhtml filename="ch-jcr-searching-repository-conten.html"?>
-
- <title>Searching Repository Content</title>
-
- <section id="Introduction">
- <title>Introduction</title>
-
- <para>You can find the JCR configuration file here:
- .../portal/WEB-INF/conf/jcr/repository-configuration.xml. Please read also
- <link linkend="JCR.SearchConfiguration">Search Configuration</link> for
- more information about index configuration.</para>
- </section>
-
- <section id="BidirectionalRangeIteratorsince1.9">
- <title>Bi-directional RangeIterator (since 1.9)</title>
-
- <para>QueryResult.getNodes() will return bi-directional NodeIterator
- implementation.</para>
-
- <note>
- <para>Bi-directional NodeIterator is <emphasis role="bold">not
- supported</emphasis> in two cases:</para>
-
- <itemizedlist>
- <listitem>
- <para>SQL query: select * from nt:base</para>
- </listitem>
-
- <listitem>
- <para>XPath query: //* .</para>
- </listitem>
- </itemizedlist>
-
- <para>")</para>
- </note>
-
- <para>TwoWayRangeIterator interface:</para>
-
- <programlisting>/**
- * Skip a number of elements in the iterator.
- *
- * @param skipNum the non-negative number of elements to skip
- * @throws java.util.NoSuchElementException if skipped past the first element
- * in the iterator.
- */
-public void skipBack(long skipNum);</programlisting>
-
- <para>Usage:</para>
-
- <programlisting>NodeIterator iter = queryResult.getNodes();
-while (iter.hasNext()) {
- if (skipForward) {
- iter.skip(10); // Skip 10 nodes in forward direction
- } else if (skipBack) {
- TwoWayRangeIterator backIter = (TwoWayRangeIterator) iter;
- backIter.skipBack(10); // Skip 10 nodes back
- }
- .......
-}</programlisting>
- </section>
-
- <section id="FuzzySearchessince1.0">
- <title>Fuzzy Searches (since 1.0)</title>
-
- <para>JCR supports such features as Lucene Fuzzy Searches <ulink
- url="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Apache
- Lucene - Query Parser Syntax</ulink>.</para>
-
- <para>To use it you have to form a query like described below:</para>
-
- <programlisting>QueryManager qman = session.getWorkspace().getQueryManager();
-Query q = qman.createQuery("select * from nt:base where contains(field, 'ccccc~')", Query.SQL);
-QueryResult res = q.execute();</programlisting>
- </section>
-
- <section id="SynonymSearchsince1.9">
- <title>SynonymSearch (since 1.9)</title>
-
- <para>Searching with synonyms is integrated in the jcr:contains() function
- and uses the same syntax as synonym searches in Google. If a search term
- is prefixed by a tilde symbol ( ~ ) also synonyms of the search term are
- taken into consideration. Example:</para>
-
- <programlisting>SQL: select * from nt:resource where contains(., '~parameter')
-
-XPath: //element(*, nt:resource)[jcr:contains(., '~parameter')</programlisting>
-
- <para>This feature is disabled per default and you need to add a
- configuration parameter to the query-handler element in your jcr
- configuration file to enable it.</para>
-
- <programlisting><param name="synonymprovider-config-path" value="..you path to configuration file....."/>
-<param name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider"/></programlisting>
-
- <programlisting>/**
- * <code>SynonymProvider</code> defines an interface for a component that
- * returns synonyms for a given term.
- */
-public interface SynonymProvider {
-
- /**
- * Initializes the synonym provider and passes the file system resource to
- * the synonym provider configuration defined by the configuration value of
- * the <code>synonymProviderConfigPath</code> parameter. The resource may be
- * <code>null</code> if the configuration parameter is not set.
- *
- * @param fsr the file system resource to the synonym provider
- * configuration.
- * @throws IOException if an error occurs while initializing the synonym
- * provider.
- */
- public void initialize(InputStream fsr) throws IOException;
-
- /**
- * Returns an array of terms that are considered synonyms for the given
- * <code>term</code>.
- *
- * @param term a search term.
- * @return an array of synonyms for the given <code>term</code> or an empty
- * array if no synonyms are known.
- */
- public String[] getSynonyms(String term);
-}</programlisting>
- </section>
-
- <section id="HighlightingSince1.9">
- <title>Highlighting (Since 1.9)</title>
-
- <para>An ExcerptProvider retrieves text excerpts for a node in the query
- result and marks up the words in the text that match the query
- terms.</para>
-
- <para>Per default highlighting words that matched the query is disabled
- because this feature requires that additional information is written to
- the search index. To enable this feature you need to add a configuration
- parameter to the query-handler element in your jcr configuration file to
- enable it.</para>
-
- <programlisting><param name="support-highlighting" value="true"/></programlisting>
-
- <para>Additionally there is a parameter that controls the format of the
- excerpt created. In JCR 1.9 the default is set to
- org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt.
- The configuration parameter for this setting is:</para>
-
- <programlisting><param name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultXMLExcerpt"/></programlisting>
-
- <section id="DefaultXMLExcerpt">
- <title>DefaultXMLExcerpt</title>
-
- <para>This excerpt provider creates an XML fragment of the following
- form:</para>
-
- <programlisting><excerpt>
- <fragment>
- <highlight>exoplatform</highlight> implements both the mandatory
- XPath and optional SQL <highlight>query</highlight> syntax.
- </fragment>
- <fragment>
- Before parsing the XPath <highlight>query</highlight> in
- <highlight>exoplatform</highlight>, the statement is surrounded
- </fragment>
-</excerpt></programlisting>
- </section>
-
- <section id="DefaultHTMLExcerpt">
- <title>DefaultHTMLExcerpt</title>
-
- <para>This excerpt provider creates an HTML fragment of the following
- form:</para>
-
- <programlisting><div>
- <span>
- <strong>exoplatform</strong> implements both the mandatory XPath
- and optional SQL <strong>query</strong> syntax.
- </span>
- <span>
- Before parsing the XPath <strong>query</strong> in
- <strong>exoplatform</strong>, the statement is surrounded
- </span>
-</div></programlisting>
- </section>
-
- <section id="Howtouseit">
- <title>How to use it</title>
-
- <para>If you are using XPath you must use the rep:excerpt() function in
- the last location step, just like you would select properties:</para>
-
- <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
-Query q = qm.createQuery("//*[jcr:contains(., 'exoplatform')]/(@Title|rep:excerpt(.))", Query.XPATH);
-QueryResult result = q.execute();
-for (RowIterator it = result.getRows(); it.hasNext(); ) {
- Row r = it.nextRow();
- Value title = r.getValue("Title");
- Value excerpt = r.getValue("rep:excerpt(.)");
-}</programlisting>
-
- <para>The above code searches for nodes that contain the word
- exoplatform and then gets the value of the Title property and an excerpt
- for each result node.</para>
-
- <para>It is also possible to use a relative path in the call
- Row.getValue() while the query statement still remains the same. Also
- you may use a relative path to a string property. The returned value
- will then be an excerpt based on string value of the property.</para>
-
- <para>Both available excerpt provider will create fragments of about 150
- characters and up to 3 fragments.</para>
-
- <para>In SQL the function is called excerpt() without the rep prefix,
- but the column in the RowIterator will nonetheless be labled
- rep:excerpt(.)!</para>
-
- <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
-Query q = qm.createQuery("select excerpt(.) from nt:resource where contains(., 'exoplatform')", Query.SQL);
-QueryResult result = q.execute();
-for (RowIterator it = result.getRows(); it.hasNext(); ) {
- Row r = it.nextRow();
- Value excerpt = r.getValue("rep:excerpt(.)");
-}</programlisting>
- </section>
- </section>
-
- <section id="SpellChecker">
- <title>SpellChecker</title>
-
- <para>The lucene based query handler implementation supports a pluggable
- spell checker mechanism. Per default spell checking is not available and
- you have to configure it first. See parameter spellCheckerClass on page
- <link linkend="JCR.SearchConfiguration">Search Configuration</link> JCR
- currently provides an implementation class , which uses the <ulink
- url="http://wiki.apache.org/jakarta-lucene/SpellChecker">lucene-spellchecker</ulink>
- contrib . The dictionary is derived from the fulltext indexed content of
- the workspace and updated periodically. You can configure the refresh
- interval by picking one of the available inner classes of
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker:</para>
-
- <itemizedlist>
- <listitem>
- <para>OneMinuteRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>FiveMinutesRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>ThirtyMinutesRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>OneHourRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>SixHoursRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>TwelveHoursRefreshInterval</para>
- </listitem>
-
- <listitem>
- <para>OneDayRefreshInterval</para>
- </listitem>
- </itemizedlist>
-
- <para>E.g. if you want a refresh interval of six hours the class name is:
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$SixHoursRefreshInterval.
- If you use
- org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker
- the refresh interval will be one hour.</para>
-
- <para>The spell checker dictionary is stored as a lucene index under
- <emphasis role="bold">"index-dir"/spellchecker</emphasis>. If it does not
- exist, a background thread will create it on startup. Similarly the
- dictionary refresh is also done in a background thread to not block
- regular queries.</para>
-
- <section id="HowdoIuseit">
- <title>How do I use it?</title>
-
- <para>You can spell check a fulltext statement either with an XPath or a
- SQL query:</para>
-
- <programlisting>// rep:spellcheck('explatform') will always evaluate to true
-Query query = qm.createQuery("/jcr:root[rep:spellcheck('explatform')]/(rep:spellcheck())", Query.XPATH);
-RowIterator rows = query.execute().getRows();
-// the above query will always return the root node no matter what string we check
-Row r = rows.nextRow();
-// get the result of the spell checking
-Value v = r.getValue("rep:spellcheck()");
-if (v == null) {
- // no suggestion returned, the spelling is correct or the spell checker
- // does not know how to correct it.
-} else {
- String suggestion = v.getString();
-}</programlisting>
-
- <para>And the same using SQL:</para>
-
- <programlisting>// SPELLCHECK('exoplatform') will always evaluate to true
-Query query = qm.createQuery("SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('explatform')", Query.SQL);
-RowIterator rows = query.execute().getRows();
-// the above query will always return the root node no matter what string we check
-Row r = rows.nextRow();
-// get the result of the spell checking
-Value v = r.getValue("rep:spellcheck()");
-if (v == null) {
- // no suggestion returned, the spelling is correct or the spell checker
- // does not know how to correct it.
-} else {
- String suggestion = v.getString();
-}</programlisting>
- </section>
- </section>
-
- <section id="SimilaritySince1.12">
- <title>Similarity (Since 1.12)</title>
-
- <para>Starting with version, 1.12 JCR allows you to search for nodes that
- are similar to an existing node.</para>
-
- <para>Similarity is determined by looking up terms that are common to
- nodes. There are some conditions that must be met for a term to be
- considered. This is required to limit the number possibly relevant
- terms.</para>
-
- <itemizedlist>
- <listitem>
- <para>Only terms with at least 4 characters are considered.</para>
- </listitem>
-
- <listitem>
- <para>Only terms that occur at least 2 times in the source node are
- considered.</para>
- </listitem>
-
- <listitem>
- <para>Only terms that occur in at least 5 nodes are considered.</para>
- </listitem>
- </itemizedlist>
-
- <para>Note: The similarity functionality requires that the
- supportHightlighting is enabled. Please make sure that you have the
- following parameter set for the query handler in your
- workspace.xml.</para>
-
- <programlisting><param name="support-highlighting" value="true"/></programlisting>
-
- <para>The functions are called rep:similar() (in XPath) and similar() (in
- SQL) and have two arguments:</para>
-
- <para>relativePath: a relative path to a descendant node or . for the
- current node. absoluteStringPath: a string literal that contains the path
- to the node for which to find similar nodes.</para>
-
- <warning>
- <para>Relative path is not supported yet.</para>
- </warning>
-
- <para>Examples:</para>
-
- <programlisting>//element(*, nt:resource)[rep:similar(., '/parentnode/node.txt/jcr:content')]</programlisting>
-
- <para>Finds nt:resource nodes, which are similar to node by path
- /parentnode/node.txt/jcr:content.</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="JCR.SearchingRepositoryContent">
+ <?dbhtml filename="ch-jcr-searching-repository-conten.html"?>
+
+ <title>Searching Repository Content</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>You can find the JCR configuration file here:
+ .../portal/WEB-INF/conf/jcr/repository-configuration.xml. Please read also
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> for
+ more information about index configuration.</para>
+ </section>
+
+ <section>
+ <title>Bi-directional RangeIterator (since 1.9)</title>
+
+ <para>QueryResult.getNodes() will return bi-directional NodeIterator
+ implementation.</para>
+
+ <note>
+ <para>Bi-directional NodeIterator is <emphasis role="bold">not
+ supported</emphasis> in two cases:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL query: select * from nt:base</para>
+ </listitem>
+
+ <listitem>
+ <para>XPath query: //* .</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>")</para>
+ </note>
+
+ <para>TwoWayRangeIterator interface:</para>
+
+ <programlisting>/**
+ * Skip a number of elements in the iterator.
+ *
+ * @param skipNum the non-negative number of elements to skip
+ * @throws java.util.NoSuchElementException if skipped past the first element
+ * in the iterator.
+ */
+public void skipBack(long skipNum);</programlisting>
+
+ <para>Usage:</para>
+
+ <programlisting>NodeIterator iter = queryResult.getNodes();
+while (iter.hasNext()) {
+ if (skipForward) {
+ iter.skip(10); // Skip 10 nodes in forward direction
+ } else if (skipBack) {
+ TwoWayRangeIterator backIter = (TwoWayRangeIterator) iter;
+ backIter.skipBack(10); // Skip 10 nodes back
+ }
+ .......
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Fuzzy Searches (since 1.0)</title>
+
+ <para>JCR supports such features as Lucene Fuzzy Searches <ulink
+ url="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Apache
+ Lucene - Query Parser Syntax</ulink>.</para>
+
+ <para>To use it you have to form a query like described below:</para>
+
+ <programlisting>QueryManager qman = session.getWorkspace().getQueryManager();
+Query q = qman.createQuery("select * from nt:base where contains(field, 'ccccc~')", Query.SQL);
+QueryResult res = q.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>SynonymSearch (since 1.9)</title>
+
+ <para>Searching with synonyms is integrated in the jcr:contains() function
+ and uses the same syntax as synonym searches in Google. If a search term
+ is prefixed by a tilde symbol ( ~ ) also synonyms of the search term are
+ taken into consideration. Example:</para>
+
+ <programlisting>SQL: select * from nt:resource where contains(., '~parameter')
+
+XPath: //element(*, nt:resource)[jcr:contains(., '~parameter')</programlisting>
+
+ <para>This feature is disabled per default and you need to add a
+ configuration parameter to the query-handler element in your jcr
+ configuration file to enable it.</para>
+
+ <programlisting><param name="synonymprovider-config-path" value="..you path to configuration file....."/>
+<param name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider"/></programlisting>
+
+ <programlisting>/**
+ * <code>SynonymProvider</code> defines an interface for a component that
+ * returns synonyms for a given term.
+ */
+public interface SynonymProvider {
+
+ /**
+ * Initializes the synonym provider and passes the file system resource to
+ * the synonym provider configuration defined by the configuration value of
+ * the <code>synonymProviderConfigPath</code> parameter. The resource may be
+ * <code>null</code> if the configuration parameter is not set.
+ *
+ * @param fsr the file system resource to the synonym provider
+ * configuration.
+ * @throws IOException if an error occurs while initializing the synonym
+ * provider.
+ */
+ public void initialize(InputStream fsr) throws IOException;
+
+ /**
+ * Returns an array of terms that are considered synonyms for the given
+ * <code>term</code>.
+ *
+ * @param term a search term.
+ * @return an array of synonyms for the given <code>term</code> or an empty
+ * array if no synonyms are known.
+ */
+ public String[] getSynonyms(String term);
+}</programlisting>
+ </section>
+
+ <section id="JCR.SearchingRepositoryContent.Highlighting">
+ <title>Highlighting (Since 1.9)</title>
+
+ <para>An ExcerptProvider retrieves text excerpts for a node in the query
+ result and marks up the words in the text that match the query
+ terms.</para>
+
+ <para>Per default highlighting words that matched the query is disabled
+ because this feature requires that additional information is written to
+ the search index. To enable this feature you need to add a configuration
+ parameter to the query-handler element in your jcr configuration file to
+ enable it.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>Additionally there is a parameter that controls the format of the
+ excerpt created. In JCR 1.9 the default is set to
+ org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt.
+ The configuration parameter for this setting is:</para>
+
+ <programlisting><param name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultXMLExcerpt"/></programlisting>
+
+ <section>
+ <title>DefaultXMLExcerpt</title>
+
+ <para>This excerpt provider creates an XML fragment of the following
+ form:</para>
+
+ <programlisting><excerpt>
+ <fragment>
+ <highlight>exoplatform</highlight> implements both the mandatory
+ XPath and optional SQL <highlight>query</highlight> syntax.
+ </fragment>
+ <fragment>
+ Before parsing the XPath <highlight>query</highlight> in
+ <highlight>exoplatform</highlight>, the statement is surrounded
+ </fragment>
+</excerpt></programlisting>
+ </section>
+
+ <section>
+ <title>DefaultHTMLExcerpt</title>
+
+ <para>This excerpt provider creates an HTML fragment of the following
+ form:</para>
+
+ <programlisting><div>
+ <span>
+ <strong>exoplatform</strong> implements both the mandatory XPath
+ and optional SQL <strong>query</strong> syntax.
+ </span>
+ <span>
+ Before parsing the XPath <strong>query</strong> in
+ <strong>exoplatform</strong>, the statement is surrounded
+ </span>
+</div></programlisting>
+ </section>
+
+ <section>
+ <title>How to use it</title>
+
+ <para>If you are using XPath you must use the rep:excerpt() function in
+ the last location step, just like you would select properties:</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("//*[jcr:contains(., 'exoplatform')]/(@Title|rep:excerpt(.))", Query.XPATH);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value title = r.getValue("Title");
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+
+ <para>The above code searches for nodes that contain the word
+ exoplatform and then gets the value of the Title property and an excerpt
+ for each result node.</para>
+
+ <para>It is also possible to use a relative path in the call
+ Row.getValue() while the query statement still remains the same. Also
+ you may use a relative path to a string property. The returned value
+ will then be an excerpt based on string value of the property.</para>
+
+ <para>Both available excerpt provider will create fragments of about 150
+ characters and up to 3 fragments.</para>
+
+ <para>In SQL the function is called excerpt() without the rep prefix,
+ but the column in the RowIterator will nonetheless be labled
+ rep:excerpt(.)!</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("select excerpt(.) from nt:resource where contains(., 'exoplatform')", Query.SQL);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>SpellChecker</title>
+
+ <para>The lucene based query handler implementation supports a pluggable
+ spell checker mechanism. Per default spell checking is not available and
+ you have to configure it first. See parameter spellCheckerClass on page
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> JCR
+ currently provides an implementation class , which uses the <ulink
+ url="http://wiki.apache.org/jakarta-lucene/SpellChecker">lucene-spellchecker</ulink>
+ contrib . The dictionary is derived from the fulltext indexed content of
+ the workspace and updated periodically. You can configure the refresh
+ interval by picking one of the available inner classes of
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>OneMinuteRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>FiveMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>ThirtyMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneHourRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>SixHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>TwelveHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneDayRefreshInterval</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>E.g. if you want a refresh interval of six hours the class name is:
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$SixHoursRefreshInterval.
+ If you use
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker
+ the refresh interval will be one hour.</para>
+
+ <para>The spell checker dictionary is stored as a lucene index under
+ <emphasis role="bold">"index-dir"/spellchecker</emphasis>. If it does not
+ exist, a background thread will create it on startup. Similarly the
+ dictionary refresh is also done in a background thread to not block
+ regular queries.</para>
+
+ <section>
+ <title>How do I use it?</title>
+
+ <para>You can spell check a fulltext statement either with an XPath or a
+ SQL query:</para>
+
+ <programlisting>// rep:spellcheck('explatform') will always evaluate to true
+Query query = qm.createQuery("/jcr:root[rep:spellcheck('explatform')]/(rep:spellcheck())", Query.XPATH);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+
+ <para>And the same using SQL:</para>
+
+ <programlisting>// SPELLCHECK('exoplatform') will always evaluate to true
+Query query = qm.createQuery("SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('explatform')", Query.SQL);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Similarity (Since 1.12)</title>
+
+ <para>Starting with version, 1.12 JCR allows you to search for nodes that
+ are similar to an existing node.</para>
+
+ <para>Similarity is determined by looking up terms that are common to
+ nodes. There are some conditions that must be met for a term to be
+ considered. This is required to limit the number possibly relevant
+ terms.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Only terms with at least 4 characters are considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur at least 2 times in the source node are
+ considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur in at least 5 nodes are considered.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note: The similarity functionality requires that the
+ supportHightlighting is enabled. Please make sure that you have the
+ following parameter set for the query handler in your
+ workspace.xml.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>The functions are called rep:similar() (in XPath) and similar() (in
+ SQL) and have two arguments:</para>
+
+ <para>relativePath: a relative path to a descendant node or . for the
+ current node. absoluteStringPath: a string literal that contains the path
+ to the node for which to find similar nodes.</para>
+
+ <warning>
+ <para>Relative path is not supported yet.</para>
+ </warning>
+
+ <para>Examples:</para>
+
+ <programlisting>//element(*, nt:resource)[rep:similar(., '/parentnode/node.txt/jcr:content')]</programlisting>
+
+ <para>Finds nt:resource nodes, which are similar to node by path
+ /parentnode/node.txt/jcr:content.</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/spell-checker.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/spell-checker.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/spell-checker.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,88 @@
+<?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">
+<section id="JCR.SpellChecker">
+ <title>Check Spelling of Phrase</title>
+
+ <para>Check correct spelling of phrase 'quik OR (-foo bar)' according to
+ data already stored in index.</para>
+
+ <note>
+ <para>See also about SpellChecker configuration - <link
+ linkend="JCR.SearchingRepositoryContent">Searching Repository
+ Content</link></para>
+ </note>
+
+ <para>SpellChecker must be settled in query-handler config. </para>
+
+ <para>test-jcr-config.xml:</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
+ ...
+ </properties>
+</query-handler></programlisting>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains node, with string property "The quick brown fox
+ jumps over the lazy dog."</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>node1 property="The quick brown fox jumps over the lazy
+ dog."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para>Query looks only for root node, because spell checker looks for
+ suggestions by full index. So complicated query is redundant.</para>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('quik OR (-foo bar)')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "/jcr:root[rep:spellcheck('quik OR (-foo bar)')]/(rep:spellcheck())";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Get suggestion of coorect spelling our phrase:</para>
+
+ <programlisting>RowIterator it = result.getRows();
+Row r = rows.nextRow();
+Value v = r.getValue("rep:spellcheck()");
+String correctPhrase = v.getString();</programlisting>
+
+ <para>So, correct spelling for phrase "quik OR (-foo bar)" is "quick OR
+ (-fox bar)".</para>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/synonim-provider.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/synonim-provider.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/synonim-provider.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,94 @@
+<?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">
+<section id="JCR.SynonimProvider">
+ <title>Search By Synonim</title>
+
+ <para>Find all mix:title nodes where title contains synonims to 'fast'
+ word.</para>
+
+ <note>
+ <para>See also about synonim propvider configuration - <link
+ linkend="JCR.SearchingRepositoryContent">Searching Repository
+ Content</link></para>
+ </note>
+
+ <para>Synonim provider must be configured in indexing-configuration.xml
+ :</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+ <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+ ...
+ </properties>
+</query-handler></programlisting>
+
+ <para>File synonim.properties contains next synonims list:</para>
+
+ <programlisting>ASF=Apache Software Foundation
+quick=fast
+sluggish=lazy</programlisting>
+
+ <section>
+ <title>Repository structure:</title>
+
+ <para>Repository contains mix:title nodes, where jcr:title has different
+ values.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>document1 (mix:title) jcr:title="The quick brown fox jumps
+ over the lazy dog."</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM mix:title WHERE CONTAINS(jcr:title, '~fast')";
+Query query = queryManager.createQuery(sqlStatement, Query.SQL);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// make XPath query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String xpathStatement = "//element(*,mix:title)[jcr:contains(@jcr:title, '~fast')]";
+Query query = queryManager.createQuery(xpathStatement, Query.XPATH);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>NodeIterator will return expected document1. This is a purpose of
+ synonim providers. Find by specified word, but return by all synonims
+ to.</para>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/tip-nodename-with-number.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/tip-nodename-with-number.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/tip-nodename-with-number.xml 2010-08-04 12:33:17 UTC (rev 2873)
@@ -0,0 +1,42 @@
+<?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">
+<section id="JCR.TipNodeNameWithNumber">
+ <title>XPath queries containing node names starting with a number</title>
+
+ <para>If you execute an XPath request like this:</para>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make XPath query
+Query query = queryManager.createQuery("/jcr:root/Documents/Publie/2010//element(*, exo:article)", Query.XPATH);</programlisting>
+
+ <para>You will have an error : "Invalid request". This happens because XML
+ does not allow names starting with a number - and XPath is part of XML:
+ <ulink
+ url="http://www.w3.org/TR/REC-xml/#NT-Name">http://www.w3.org/TR/REC-xml/#NT-Name</ulink></para>
+
+ <para>Therefore you cannot do XPath requests using a node name that starts
+ with a number.</para>
+
+ <para>Easy workarounds:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Use an SQL request.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use escaping :</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make XPath query
+Query query = queryManager.createQuery("/jcr:root/Documents/Publie/_x0032_010//element(*, exo:article)", Query.XPATH);</programlisting>
+</section>
15 years, 11 months