exo-jcr SVN: r2972 - in jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer: reference/en and 1 other directory.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-23 08:30:54 -0400 (Mon, 23 Aug 2010)
New Revision: 2972
Removed:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/pom.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/userguide/
Modified:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/pom.xml
Log:
EXOJCR-905: userguide deleted
Deleted: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/pom.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/pom.xml 2010-08-23 12:20:14 UTC (rev 2971)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/pom.xml 2010-08-23 12:30:54 UTC (rev 2972)
@@ -1,38 +0,0 @@
-<!--
-
- Copyright (C) 2009 eXo Platform SAS.
-
- This is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this software; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.exoplatform.jcr</groupId>
- <artifactId>exo.jcr.docs</artifactId>
- <version>1.12.4-GA-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>exo.jcr.docs.developer</artifactId>
-
- <name>eXo JCR :: Developer Documentation :: Reactor</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>reference</module>
- <module>userguide</module>
- </modules>
-</project>
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/pom.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/pom.xml 2010-08-23 12:20:14 UTC (rev 2971)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/pom.xml 2010-08-23 12:30:54 UTC (rev 2972)
@@ -1,127 +1,127 @@
-<!--
-
- Copyright (C) 2009 eXo Platform SAS.
-
- This is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this software; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.exoplatform.jcr</groupId>
- <artifactId>reference-docs</artifactId>
- <version>1.12.4-GA-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>reference-docs-${translation}</artifactId>
-
- <name>eXo JCR :: Developer Documentation :: Reference (${translation})</name>
- <packaging>jdocbook</packaging>
-
- <properties>
- <translation>en</translation>
- <enforcer.skip>true</enforcer.skip>
- </properties>
-
- <build>
- <finalName>${project.parent.artifactId}_${translation}-${version}</finalName>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>xml-maven-plugin</artifactId>
- <!-- version>1.0-beta-2</version -->
- </plugin>
-
- <plugin>
- <groupId>org.jboss.maven.plugins</groupId>
- <artifactId>maven-jdocbook-plugin</artifactId>
- <version>2.1.1</version>
- <extensions>true</extensions>
- <dependencies>
- <dependency>
- <groupId>org.exoplatform.doc</groupId>
- <artifactId>exo-docbook-xslt</artifactId>
- <version>${org.exoplatform.doc-style.version}</version>
- </dependency>
- <dependency>
- <groupId>org.exoplatform.doc</groupId>
- <artifactId>exo-jdocbook-style</artifactId>
- <version>${org.exoplatform.doc-style.version}</version>
- <type>jdocbook-style</type>
- </dependency>
- <!-- dependency>
- <groupId>xalan</groupId>
- <artifactId>xalan</artifactId>
- <version>2.7.1</version>
- </dependency -->
- <!-- dependency>
- <groupId>net.sf.saxon</groupId>
- <artifactId>saxon</artifactId>
- <version>9.1.0.8</version>
- </dependency -->
- </dependencies>
- <configuration>
- <sourceDocumentName>master.xml</sourceDocumentName>
-
- <!--sourceDocumentName>modules/lock-manager-config.xml</sourceDocumentName-->
- <imageResource>
- <directory>${pom.basedir}/src/main/resources</directory>
- <includes>
- <include>images/**/*</include>
- </includes>
- </imageResource>
-
- <formats>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/exojcr/xhtml.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/xslt/org/exojcr/xhtml-single.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <!--format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath://xslt/org/exojcr/pdf.xsl</stylesheetResource>
- <finalName>${pom.name}.pdf</finalName>
- </format-->
- <!-- format>
- <formatName>eclipse</formatName>
- <stylesheetResource>classpath:/xslt/org/exojcr/eclipse.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format -->
- </formats>
-
- <options>
- <xincludeSupported>true</xincludeSupported>
- <xmlTransformerType>saxon</xmlTransformerType>
- <!-- needed for uri-resolvers; can be ommitted if using 'current' uri scheme -->
- <!-- could also locate the docbook dependency and inspect its version... -->
- <docbookVersion>1.74.0</docbookVersion>
- </options>
-
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.exoplatform.jcr</groupId>
+ <artifactId>reference-docs</artifactId>
+ <version>1.12.4-GA-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>reference-docs-${translation}</artifactId>
+
+ <name>eXo JCR :: Developer Documentation :: Reference (${translation})</name>
+ <packaging>jdocbook</packaging>
+
+ <properties>
+ <translation>en</translation>
+ <enforcer.skip>true</enforcer.skip>
+ </properties>
+
+ <build>
+ <finalName>${project.parent.artifactId}_${translation}-${version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>xml-maven-plugin</artifactId>
+ <!-- version>1.0-beta-2</version -->
+ </plugin>
+
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+ <version>2.1.1</version>
+ <extensions>true</extensions>
+ <dependencies>
+ <dependency>
+ <groupId>org.exoplatform.doc</groupId>
+ <artifactId>exo-docbook-xslt</artifactId>
+ <version>${org.exoplatform.doc-style.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.doc</groupId>
+ <artifactId>exo-jdocbook-style</artifactId>
+ <version>${org.exoplatform.doc-style.version}</version>
+ <type>jdocbook-style</type>
+ </dependency>
+ <!-- dependency>
+ <groupId>xalan</groupId>
+ <artifactId>xalan</artifactId>
+ <version>2.7.1</version>
+ </dependency -->
+ <!-- dependency>
+ <groupId>net.sf.saxon</groupId>
+ <artifactId>saxon</artifactId>
+ <version>9.1.0.8</version>
+ </dependency -->
+ </dependencies>
+ <configuration>
+ <sourceDocumentName>master.xml</sourceDocumentName>
+
+ <!--sourceDocumentName>modules/lock-manager-config.xml</sourceDocumentName-->
+ <imageResource>
+ <directory>${pom.basedir}/src/main/resources</directory>
+ <includes>
+ <include>images/**/*</include>
+ </includes>
+ </imageResource>
+
+ <formats>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/exojcr/xhtml.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/xslt/org/exojcr/xhtml-single.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath://xslt/org/exojcr/pdf.xsl</stylesheetResource>
+ <finalName>index.pdf</finalName>
+ </format>
+ <!-- format>
+ <formatName>eclipse</formatName>
+ <stylesheetResource>classpath:/xslt/org/exojcr/eclipse.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format -->
+ </formats>
+
+ <options>
+ <xincludeSupported>true</xincludeSupported>
+ <xmlTransformerType>saxon</xmlTransformerType>
+ <!-- needed for uri-resolvers; can be ommitted if using 'current' uri scheme -->
+ <!-- could also locate the docbook dependency and inspect its version... -->
+ <docbookVersion>1.74.0</docbookVersion>
+ </options>
+
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
13 years, 10 months
exo-jcr SVN: r2971 - jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-08-23 08:20:14 -0400 (Mon, 23 Aug 2010)
New Revision: 2971
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java
Log:
EXOJCR-915: move IndexMerger.run() loging to debug level
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java 2010-08-23 12:17:50 UTC (rev 2970)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexMerger.java 2010-08-23 12:20:14 UTC (rev 2971)
@@ -283,6 +283,7 @@
/**
* Implements the index merging.
*/
+ @Override
public void run()
{
for (;;)
@@ -344,7 +345,7 @@
{
docCount += readers[i].numDocs();
}
- log.info("merged " + docCount + " documents in " + time + " ms into " + index.getName() + ".");
+ log.debug("merged " + docCount + " documents in " + time + " ms into " + index.getName() + ".");
}
finally
{
@@ -483,6 +484,7 @@
/**
* @inheritDoc
*/
+ @Override
public String toString()
{
return name + ":" + numDocs;
13 years, 10 months
exo-jcr SVN: r2970 - in jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main: docbook/en-US/modules and 3 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-23 08:17:50 -0400 (Mon, 23 Aug 2010)
New Revision: 2970
Added:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gatein.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/how-to-extend-my-gatein-instance.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/managed-datasources-under-jboss-as.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/performance-tuning-guide.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results.jpg
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results_2.jpg
Modified:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/master.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-905: userguide chapters merged into reference
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/master.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/master.xml 2010-08-23 12:02:15 UTC (rev 2969)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/master.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -66,9 +66,14 @@
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" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/jcr-with-gatein.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+
+
</book>
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/performance-tuning-guide.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/performance-tuning-guide.xml (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/performance-tuning-guide.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -0,0 +1,323 @@
+<?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.PerformanceTuningGuide">
+ <?dbhtml filename="ch-jcr-performance-tuning.html"?>
+
+ <title>JCR Performance Tuning Guide</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>This guide will show you possible ways of improving JCR
+ performance.</para>
+
+ <para>It is intended to GateIn Administrators and those who wants to use
+ JCR features.</para>
+ </section>
+
+ <section>
+ <title>JCR Performance and Scalability</title>
+
+ <section>
+ <title>Cluster configuration</title>
+
+ <para><citetitle>EC2 network</citetitle>: 1Gbit</para>
+
+ <para><citetitle>Servers hardware</citetitle>:<simplelist>
+ <member>7.5 GB memory</member>
+
+ <member>4 EC2 Compute Units (2 virtual cores with 2 EC2 Compute
+ Units each)</member>
+
+ <member>850 GB instance storage (2×420 GB plus 10 GB root
+ partition)</member>
+
+ <member>64-bit platform</member>
+
+ <member>I/O Performance: High</member>
+
+ <member>API name: m1.large</member>
+ </simplelist></para>
+
+ <note>
+ <para>NFS and statistics (cacti snmp) server were located on one
+ physical server.</para>
+ </note>
+
+ <para><citetitle>JBoss AS configuration</citetitle></para>
+
+ <para><code>JAVA_OPTS: -Dprogram.name=run.sh -server -Xms4g -Xmx4g
+ -XX:MaxPermSize=512m -Dorg.jboss.resolver.warning=true
+ -Dsun.rmi.dgc.client.gcInterval=3600000
+ -Dsun.rmi.dgc.server.gcInterval=3600000 -XX:+UseParallelGC
+ -Djava.net.preferIPv4Stack=true</code></para>
+ </section>
+
+ <section>
+ <title>JCR Clustered Performance</title>
+
+ <para>Benchmark test using webdav (Complex read/write load test
+ (benchmark)) with 20K same file. To obtain per-operation results we have
+ used custom output from the testscase threads to CSV file.</para>
+
+ <para><citetitle>Read operation</citetitle>:<simplelist>
+ <member>Warm-up iterations: 100</member>
+
+ <member>Run iterations: 2000</member>
+
+ <member>Background writing threads: 25</member>
+
+ <member>Reading threads: 225</member>
+ </simplelist></para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/perf_EC2_results.jpg" />
+ </imageobject>
+ </mediaobject>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Nodes count</entry>
+
+ <entry>tps</entry>
+
+ <entry> Responses >2s</entry>
+
+ <entry>Responses >4s</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>1</entry>
+
+ <entry>523</entry>
+
+ <entry>6.87%</entry>
+
+ <entry>1.27% </entry>
+ </row>
+
+ <row>
+ <entry>2</entry>
+
+ <entry>1754</entry>
+
+ <entry>0.64% </entry>
+
+ <entry>0.08% </entry>
+ </row>
+
+ <row>
+ <entry>3</entry>
+
+ <entry>2388</entry>
+
+ <entry>0.49% </entry>
+
+ <entry>0.09% </entry>
+ </row>
+
+ <row>
+ <entry>4</entry>
+
+ <entry>2706</entry>
+
+ <entry>0.46% </entry>
+
+ <entry> 0.1% </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para><citetitle>Read operaion with more threads</citetitle>:</para>
+
+ <simplelist>
+ <member>Warm-up iterations: 100</member>
+
+ <member>Run iterations: 2000</member>
+
+ <member>Background writing threads: 50</member>
+
+ <member>Reading threads: 450</member>
+ </simplelist>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/perf_EC2_results_2.jpg" />
+ </imageobject>
+ </mediaobject>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Nodes count</entry>
+
+ <entry>tps</entry>
+
+ <entry>Responses >2s</entry>
+
+ <entry>Responses >4s</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>1</entry>
+
+ <entry>116</entry>
+
+ <entry>?</entry>
+
+ <entry>?</entry>
+ </row>
+
+ <row>
+ <entry>2</entry>
+
+ <entry>1558</entry>
+
+ <entry>6.1%</entry>
+
+ <entry>0.6%</entry>
+ </row>
+
+ <row>
+ <entry>3</entry>
+
+ <entry>2242</entry>
+
+ <entry>3.1%</entry>
+
+ <entry>0.38%</entry>
+ </row>
+
+ <row>
+ <entry>4</entry>
+
+ <entry>2756 </entry>
+
+ <entry>2.2%</entry>
+
+ <entry>0.41%</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ <section>
+ <title>Performance Tuning Guide</title>
+
+ <section>
+ <title>JBoss AS Tuning</title>
+
+ <para>You can use <parameter>maxThreads</parameter> parameter to
+ increase maximum amount of threads that can be launched in AS instance.
+ This can improve performance if you need a high level of concurrency.
+ also you can use <code>-XX:+UseParallelGC</code> java directory to use
+ paralel garbage collector.</para>
+
+ <tip>
+ <para>Beware of setting <parameter>maxThreads</parameter> too big,
+ this can cause <exceptionname>OutOfMemoryError</exceptionname>. We've
+ got it with <code>maxThreads=1250</code> on such machine:</para>
+
+ <simplelist>
+ <member>7.5 GB memory</member>
+
+ <member>4 EC2 Compute Units (2 virtual cores with 2 EC2 Compute
+ Units each)</member>
+
+ <member>850 GB instance storage (2×420 GB plus 10 GB root
+ partition)</member>
+
+ <member>64-bit platform</member>
+
+ <member>I/O Performance: High</member>
+
+ <member>API name: m1.large</member>
+
+ <member>java -Xmx 4g</member>
+ </simplelist>
+ </tip>
+ </section>
+
+ <section>
+ <title>JCR Cache Tuning</title>
+
+ <para><citetitle>Cache size</citetitle></para>
+
+ <para>JCR-cluster implementation is built using JBoss Cache as
+ distributed, replicated cache. But there is one particularity related to
+ remove action in it. Speed of this operation depends on the actual size
+ of cache. As many nodes are currently in cache as much time is needed to
+ remove one particular node (subtree) from it.</para>
+
+ <para><citetitle>Eviction</citetitle></para>
+
+ <para>Manipulations with eviction <parameter>wakeUpInterval</parameter>
+ value doestn't affect on performance. Performance results with values
+ from 500 up to 3000 are approximately equal.</para>
+
+ <para><citetitle>Transaction Timeout</citetitle></para>
+
+ <para>Using short timeout for long transactions such as Export/Import,
+ removing huge subtree defined timeout may cause
+ <exceptionname>TransactionTimeoutException</exceptionname>. [TODO] put
+ recomended timeout value</para>
+ </section>
+
+ <section>
+ <title>Clustering</title>
+
+ <para>For performance it is better to have loadbalacer, DB server and
+ shared NFS on different computers. If in some reasons you see that one
+ node gets more load than others you can decrease this load using load
+ value in load balancer.</para>
+
+ <para><citetitle>JGroups configuration</citetitle></para>
+
+ <para>It's recommended to use "multiplexer stack" feature present in
+ JGroups. It is set by default in eXo JCR and offers higher performance
+ in cluster, using less network connections also. If there are two or
+ more clusters in your network, please check that they use different
+ ports and different cluster names.</para>
+
+ <para><citetitle>Write performance in cluster</citetitle></para>
+
+ <para>Exo JCR implementation uses Lucene indexing engine to provide
+ search capabilities. But Lucene brings some limitations for write
+ operations: it can perform indexing only in one thread. Thats why write
+ performance in cluster is not higher than in singleton environment. Data
+ is indexed on coordinator node, so increasing write-load on cluster may
+ lead to ReplicationTimeout exception. It occurs because writing threads
+ queue in the indexer and under high load timeout for replication to
+ coordinator will be exceeded.</para>
+
+ <para>Taking in consideration this fact, it is recommended to exceed
+ <parameter>replTimeout</parameter> value in cache configurations in case
+ of high write-load.</para>
+
+ <para><citetitle>Replication timeout</citetitle></para>
+
+ <para>Some operations may take too much time. So if you get
+ <exceptionname>ReplicationTimeoutException</exceptionname> try
+ increasing replication timeout:<programlisting> <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
+ ...
+ <sync replTimeout="60000" />
+ </clustering></programlisting>value is set in miliseconds.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gatein.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gatein.xml (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gatein.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -0,0 +1,15 @@
+<?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-jcr-with-gatein.html"?>
+
+ <title>eXo JCR with GateIn</title>
+
+ <xi:include href="jcr-with-gtn/how-to-extend-my-gatein-instance.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr-with-gtn/managed-datasources-under-jboss-as.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+</part>
+
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/how-to-extend-my-gatein-instance.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/how-to-extend-my-gatein-instance.xml (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/how-to-extend-my-gatein-instance.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -0,0 +1,2460 @@
+<?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="JCRWithGateIn.HowToExtendMyGateInInstance">
+ <?dbhtml filename="ch-how-to-extend-my-gatein-instance.html"?>
+
+ <title>How to extend my GateIn instance?</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>Since GateIn beta 2, we added a set of features in order to
+ customize a GateIn instance without modifying the GateIn binary, this
+ usecase will be called <emphasis>portal extension</emphasis> in this
+ documentation. Those features are also required to be able to launch
+ several portal instances at the same time, in "eXo terminology" that
+ means to have several "portal.war".</para>
+ </section>
+
+ <section>
+ <title>Motivations</title>
+
+ <para>Up to now, to create an application over an eXo portal such as
+ DMS, WCM, CS and KS, we need to modify files into the "portal.war". This
+ has many painful consequences, such as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>It is quite hard to manage from the support point of view
+ since we never know if or how the customer changed his eXo
+ product.</para>
+ </listitem>
+
+ <listitem>
+ <para>It is hard to be able to package several eXo products (WCM,
+ CS...) as we need to merge everything manually which is quite error
+ prone.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Finally, at the very beginning, eXo was developed to be able to
+ support several portal instances (which also means several portal
+ containers) but with the time several bad practices made it impossible.
+ So it was important to review the whole code base in order to
+ help/enforce all the GateIn developers to follow the "good
+ practices".</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+
+ <para>To be able to migrate an application to GateIn, the first thing we
+ need to do is to ensure that our application supports properly several
+ portal container instances. The following section aims to help you to be
+ compatible with GateIn.</para>
+
+ <section>
+ <title>Remove all the hard coded portal container name (i.e.
+ "portal")</title>
+
+ <para>Now if we need to get the portal container name (even in a
+ standalone mode: in case of standalone mode the default value will be
+ returned), we can:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the component is instantiated by Pico container, you can
+ add in the constructor of your component, the component
+ <emphasis>ExoContainerContext</emphasis>, then call the method
+ <emphasis>getPortalContainerName()</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>If the component is not instantiated by Pico container, you
+ can call at runtime the static method
+ <emphasis>PortalContainer.getCurrentPortalContainerName()</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>In js files, you can use the variable
+ <emphasis>currentContext</emphasis> if your script must be loaded
+ before the variable <emphasis>eXo.env.server.context</emphasis>,
+ otherwise use <emphasis>eXo.env.server.context</emphasis>
+ instead.</para>
+ </listitem>
+
+ <listitem>
+ <para>In jsp files, you can use
+ <emphasis>request.getContextPath()</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Remove all the hard coded rest context name (i.e. "rest")</title>
+
+ <para>Now if we need to get the rest context name (even in a standalone
+ mode: in case of standalone mode the default value will be returned), we
+ can:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the component is instantiated by Pico container, you can
+ add in the constructor of your component, the component
+ <emphasis>ExoContainerContext</emphasis>, then call the method
+ <emphasis>getRestContextName()</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>If the component is not instantiated by Pico container, you
+ can call at runtime the static method
+ <emphasis>PortalContainer.getCurrentRestContextName()</emphasis></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Remove all the hard coded realm name (i.e. "exo-domain")</title>
+
+ <para>Now if we need to get the realm name (even in a standalone mode:
+ in case of standalone mode the default value will be returned), we
+ can:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the component is instantiated by Pico container, you can
+ add in the constructor of your component, the component
+ <emphasis>ExoContainerContext</emphasis>, then call the method
+ <emphasis>getRealmName()</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>If the component is not instantiated by Pico container, you
+ can call at runtime the static method
+ <emphasis>PortalContainer.getCurrentRealmName()</emphasis></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Make your Http Filters compatible</title>
+
+ <para>Now all your Http Filters that need to get the current
+ <emphasis>ExoContainer</emphasis> must extends
+ <emphasis>org.exoplatform.container.web.AbstractFilter</emphasis>. You
+ just need to call the method <emphasis>getContainer()</emphasis> to get
+ the current <emphasis>ExoContainer</emphasis>.</para>
+ </section>
+
+ <section>
+ <title>Make your HttpServlets compatible</title>
+
+ <para>Now all your HttpServlets that need to get the current
+ <emphasis>ExoContainer</emphasis> must extends
+ <emphasis>org.exoplatform.container.web.AbstractHttpServlet</emphasis>.
+ This abstract class will ensure that the environment has been properly
+ set, so you will be able to call the usual methods such as
+ <emphasis>ExoContainerContext.getCurrentContainer()</emphasis> (if it
+ must also be compatible with the standalone mode) or
+ <emphasis>PortalContainer.getInstance()</emphasis> (if it will only work
+ on a portal environment mode).</para>
+
+ <para>If you had to implement the method
+ <emphasis>service(HttpServletRequest req, HttpServletResponse
+ res)</emphasis>, now you will need to implement
+ <emphasis>onService(ExoContainer container, HttpServletRequest req,
+ HttpServletResponse res)</emphasis>, this method will directly give you
+ the current <emphasis>ExoContainer</emphasis> in its signature.</para>
+
+ <important>
+ <title>Useful Information</title>
+
+ <para>In the class
+ <emphasis>org.exoplatform.container.web.AbstractHttpServlet</emphasis>
+ you have a method called
+ <emphasis>requirePortalEnvironment()</emphasis> that is used to
+ indicate that we would like the abstract class to setup or not the
+ full portal environment ( <emphasis>PortalContainer</emphasis>,
+ <emphasis>ClassLoader</emphasis> and
+ <emphasis>ServletContext</emphasis>) before executing the servlet.
+ This value should return true when the servlet is executed within the
+ web application of a portal container. By default, it checks if the
+ name of the current <emphasis>ServletContext</emphasis> is a portal
+ container name, it is sufficient in most cases but you can still
+ overload this method if you already know that the servlet will always
+ been executed within the web application of portal container (i.e. the
+ method always return true) or will never be executed within the web
+ application of a portal container (i.e. the method always return
+ false) .</para>
+ </important>
+ </section>
+
+ <section>
+ <title>Make your HttpSessionListeners compatible</title>
+
+ <para>Now all your HttpSessionListeners that need to get the current
+ <emphasis>ExoContainer</emphasis> must extends
+ <emphasis>org.exoplatform.container.web.AbstractHttpSessionListener</emphasis>.
+ This abstract class will give you the current
+ <emphasis>ExoContainer</emphasis> directly in the signature of the
+ methods to implement which are _ onSessionCreated(ExoContainer
+ container, HttpSessionEvent event)\_ and
+ <emphasis>onSessionDestroyed(ExoContainer container, HttpSessionEvent
+ event)</emphasis></para>
+
+ <para>You will also need to implement the method called
+ <emphasis>requirePortalEnvironment()</emphasis> that is used to indicate
+ that we would like the abstract class to setup or not the full portal
+ environment ( <emphasis>PortalContainer</emphasis> and
+ <emphasis>ClassLoader</emphasis>) before processing the event. This
+ value should return true when the event is processed within the web
+ application of a portal container.</para>
+ </section>
+
+ <section>
+ <title>Use init tasks if you need a PortalContainer to initialize an
+ Http Filter or an HttpServlet</title>
+
+ <para>If your Http <emphasis>Filter</emphasis> or your
+ <emphasis>HttpServlet</emphasis> requires a PortalContainer to
+ initialize, you need to convert your code in order to launch the code
+ responsible for the initialization in the method
+ <emphasis>onAlreadyExists</emphasis> of an
+ <emphasis>org.exoplatform.container.RootContainer.PortalContainerInitTask</emphasis>.</para>
+
+ <para>We need to rely on init tasks, in order to be sure that the portal
+ container is at the right state when the task is executed, in other
+ words the task could be delayed if you try to execute it too early. Each
+ task is linked to a web application, so when we add a new task, we first
+ retrieve all the portal containers that depend on this web application
+ according to the <emphasis>PortalContainerDefinitions</emphasis>, and
+ for each container we add the task in a sorted queue which order is in
+ fact the order of the web applications dependencies defined in the
+ <emphasis>PortalContainerDefinition</emphasis>. If no
+ <emphasis>PortalContainerDefinition</emphasis> can be found we execute
+ synchronously the task which is in fact the old behavior (i.e. without
+ the starter).</para>
+
+ <para>The supported init tasks are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The
+ <emphasis>org.exoplatform.container.RootContainer.PortalContainerPreInitTask</emphasis>
+ which are executed before the portal container has been
+ initialized</para>
+ </listitem>
+
+ <listitem>
+ <para>The
+ <emphasis>org.exoplatform.container.RootContainer.PortalContainerPostInitTask</emphasis>
+ which are executed after the portal container has been
+ initialized</para>
+ </listitem>
+
+ <listitem>
+ <para>The
+ <emphasis>org.exoplatform.container.RootContainer.PortalContainerPostCreateTask</emphasis>
+ which are executed after the portal container has been fully created
+ (i.e. after all the post init tasks).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>A init task is defined as below</para>
+
+ <note>
+ <title>PortalContainerPreInitTask</title>
+
+ <programlisting> /**
+ * This interface is used to define a task that needs to be launched at a given state during the
+ * initialization of a portal container
+ */
+ public static interface PortalContainerInitTask
+ {
+
+ /**
+ * This method allows the implementation to define what the state "already exists"
+ * means for a portal container
+ *
+ * @param portalContainer the value of the current portal container
+ * @return <code>true</code> if the portal container exists according to the task
+ * requirements, <code>false</code> otherwise
+ */
+ public boolean alreadyExists(PortalContainer portalContainer);
+
+ /**
+ * This method is called if the related portal container has already been registered
+ *
+ * @param context the servlet context of the web application
+ * @param portalContainer the value of the current portal container
+ */
+ public void onAlreadyExists(ServletContext context, PortalContainer portalContainer);
+
+ /**
+ * Executes the task
+ *
+ * @param context the servlet context of the web application
+ * @param container The portal container on which we would like to execute the task
+ */
+ public void execute(ServletContext context, PortalContainer portalContainer);
+
+ /**
+ * @return the type of the task
+ */
+ public String getType();
+ }</programlisting>
+ </note>
+
+ <para>To add a task you can either call:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>PortalContainer.addInitTask(ServletContext context,
+ PortalContainerInitTask task)</emphasis> in order to execute the
+ task on all the portal containers that depend on the given
+ <emphasis>ServletContext</emphasis> according to the
+ <emphasis>PortalContainerDefinitions</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>PortalContainer.addInitTask(ServletContext context,
+ PortalContainerInitTask task, String portalContainerName)</emphasis>
+ in order to execute the task on a given portal container.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>RootContainer.addInitTask(ServletContext context,
+ PortalContainerInitTask task)</emphasis> in order to execute the
+ task on the portal container which name is the name of the given
+ <emphasis>ServletContext</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>We will take for example the class
+ <emphasis>GadgetRegister</emphasis> that is used to register new google
+ gadgets on a given portal container.</para>
+
+ <para><emphasis role="underline">The old code was:</emphasis></para>
+
+ <note>
+ <title>Old GadgetRegister.java</title>
+
+ <programlisting>...
+public class GadgetRegister implements ServletContextListener
+{
+...
+ public void contextInitialized(ServletContextEvent event)
+ {
+ try
+ {
+ ExoContainer pcontainer = ExoContainerContext.getContainerByName("portal") ;
+ SourceStorage sourceStorage = (SourceStorage)pcontainer.getComponentInstanceOfType(SourceStorage.class);
+ ...
+ }
+ ...
+}</programlisting>
+ </note>
+
+ <para>The new code relies on a
+ <emphasis>org.exoplatform.container.RootContainer.PortalContainerPostInitTask</emphasis>,
+ as you can see below</para>
+
+ <note>
+ <title>New GadgetRegister.java</title>
+
+ <programlisting>...
+public class GadgetRegister implements ServletContextListener {
+...
+ public void contextInitialized(ServletContextEvent event)
+ {
+ // Create a new post init task
+ final PortalContainerPostInitTask task = new PortalContainerPostInitTask()
+ {
+
+ public void execute(ServletContext context, PortalContainer portalContainer)
+ {
+ contextInitialized(context, portalContainer);
+ }
+ };
+ // Add the init task to all the related portal containers
+ PortalContainer.addInitTask(event.getServletContext(), task);
+ }
+
+ private void contextInitialized(ServletContext context, PortalContainer pcontainer)
+ {
+ try
+ {
+ SourceStorage sourceStorage = (SourceStorage)pcontainer.getComponentInstanceOfType(SourceStorage.class);
+ ...
+ }
+ ...
+}</programlisting>
+ </note>
+ </section>
+
+ <section>
+ <title>Make your LoginModules compatible</title>
+
+ <para>Now all your LoginModules that need to get the current
+ <emphasis>ExoContainer</emphasis> must extends
+ <emphasis>org.exoplatform.services.security.jaas.AbstractLoginModule</emphasis>.
+ You just need to call the method <emphasis>getContainer()</emphasis> to
+ get the current <emphasis>ExoContainer</emphasis>.</para>
+
+ <important>
+ <title>Useful Information</title>
+
+ <para>The class
+ <emphasis>org.exoplatform.services.security.jaas.AbstractLoginModule</emphasis>
+ supports 2 login module options which are
+ <emphasis>portalContainerName</emphasis> and
+ <emphasis>realmName</emphasis>, to allow you to indicate the realm
+ name and the portal container name, if you want to change the default
+ value.</para>
+ </important>
+ </section>
+
+ <section>
+ <title>Avoid <emphasis>static</emphasis> modifier on component
+ dependency</title>
+
+ <para>A local variable that stores a component dependency must not be
+ static. In other words, when you create a component A that depends on
+ component B, we don't store B in a static variable of A otherwise we
+ cannot have several different instances of A in the same JVM which is
+ not compatible with a multi-portal instance.</para>
+ </section>
+
+ <section>
+ <title>Avoid component initialization based on component dependency in
+ the constructor</title>
+
+ <para>We will have more and more extensible components (i.e. that can be
+ extended thanks to an external plugin) which means that those components
+ can only be initialized in the <emphasis>start</emphasis> method, thus
+ it is not a good practice to initialize a component in its constructor
+ if this initialization uses other components because those components
+ may not be initialized. For example, now the ResourceBundleService is
+ extensible, so if you create a component that depends on the
+ ResourceBundleService and you need the ResourceBundleService to
+ initialize your component, your component will need to be "Startable"
+ and you will have to initialize your component in a
+ <emphasis>start</emphasis> method.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>FAQ</title>
+
+ <section>
+ <title>What has changed since the previous versions?</title>
+
+ <para>The main difference with previous versions is the way to package
+ your application, in previous versions you had to change the content of
+ the file <emphasis>portal.war</emphasis> in order to customize the
+ portal. Now we more consider your application as an add-on that you can
+ packaged in another ear/war file. You just need to follow some rules in
+ order to notify the platform that it must take into account your add-on
+ in order to customize the portal.</para>
+
+ <para>Among other things, you will have to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Indicate the platform how to initialize and manage your
+ application by defining and registering the
+ <emphasis>PortalContainerDefinition</emphasis> related to your
+ portal instance.</para>
+ </listitem>
+
+ <listitem>
+ <para>Deploy the <emphasis>starter</emphasis> ear/war file that is
+ used to create and start all the portals (i.e. portal
+ containers).</para>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <title>Warning</title>
+
+ <para>Please take into account, that you need to ensure that the
+ <emphasis>starter</emphasis> is launched after all the other ear/war
+ files.</para>
+ </warning>
+
+ <important>
+ <title>Nota Bene</title>
+
+ <para>If you don't need to customize the portal, you don't have to
+ deploy the starter. The old way to deploy an application is still
+ compatible.</para>
+ </important>
+ </section>
+
+ <section>
+ <title>What is the main purpose of a <emphasis>portal
+ extension</emphasis>?</title>
+
+ <para>An <emphasis>extension</emphasis> is just a set of files that we
+ use to customize or add new features to a given portal. An extension
+ must be the least intrusive as possible, as we could potentially have
+ several extensions for the same portal. In other words we are supposed
+ to only add what is missing in the portal and avoid to change or
+ duplicate files that are in the portal.war.</para>
+ </section>
+
+ <section>
+ <title>What is the main purpose of the
+ <emphasis>starter</emphasis>?</title>
+
+ <para>The <emphasis>sarter</emphasis> is a web application that has been
+ added to create and start all the portals (i.e. portal containers) at
+ the same time when all the other web applications have already been
+ started. In fact all other web applications can potentially defined
+ several things at startup such as skins, javascripts, google gadgets and
+ configuration files, thus the loading order is important as we can
+ redefine skins or configuration files or a javascript from a web
+ application 1 could depend on another javascript from a web application
+ 2 so if the web application 2 is loaded after the web application 1, we
+ will get errors in the merged javascript file.</para>
+
+ <para>If a <emphasis>PortalContainerDefinition</emphasis> has been
+ defined, the loading order will be the order that has been used to
+ define the list of dependency. And if you defined a
+ <emphasis>PortalContainerDefinition</emphasis> you need to deploy the
+ starter otherwise the loading order will be the default one (i.e. the
+ loading order of the Application Server)</para>
+
+ <para>So if you need to customize your portal by adding a new extension
+ and/or a new portal, you need to defined the related
+ <emphasis>PortalContainerDefinitions</emphasis> so you need to deploy
+ also the starter. Otherwise, you don't need to define any
+ <emphasis>PortalContainerDefinition</emphasis> and to deploy the
+ <emphasis>starter</emphasis>.</para>
+ </section>
+
+ <section>
+ <title>How a portal and a portal container are related?</title>
+
+ <para>Each portal instance has its own portal container which allows the
+ portal to have its own set of components/services. It will ensure the
+ isolation between the different portal instances.</para>
+ </section>
+
+ <section>
+ <title>How to define and register a
+ <emphasis>PortalContainerDefinition</emphasis>?</title>
+
+ <para>A <emphasis>PortalContainerDefinition</emphasis> allows you to
+ indicate the platform how it must initialize and manage your portal. In
+ a <emphasis>PortalContainerDefinition</emphasis>, you can define a set
+ of properties, such as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The name of the portal container</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the context name of the rest web
+ application</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the realm</para>
+ </listitem>
+
+ <listitem>
+ <para>The list of all the dependencies of the portal container
+ ordered by priority</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You can define and register a
+ <emphasis>PortalContainerDefinition</emphasis> thanks to an external
+ plugin that has to be treated at the <emphasis>RootContainer</emphasis>
+ level. In other words, your configuration file must be a file
+ <emphasis>conf/configuration.xml</emphasis> packaged into a jar file or
+ $AS_HOME/exo-conf/configuration.xml (for more details please have a look
+ to the article <link linkend="Kernel.ContainerConfiguration">Container
+ Configuration</link>).</para>
+
+ <para><emphasis role="underline">See below an example of configuration
+ file that define and register a
+ PortalContainerDefinition:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the PortalContainerConfig -->
+ <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Add PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the PortalContainerDefinitions -->
+ <set-method>registerPlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
+ <init-params>
+ <object-param>
+ <name>portal</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinition">
+ <!-- The name of the portal container -->
+ <field name="name"><string>portal</string></field>
+ <!-- The name of the context name of the rest web application -->
+ <field name="restContextName"><string>rest</string></field>
+ <!-- The name of the realm -->
+ <field name="realmName"><string>exo-domain</string></field>
+ <!-- All the dependencies of the portal container ordered by loading priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>eXoResources</string>
+ </value>
+ <value>
+ <string>portal</string>
+ </value>
+ <value>
+ <string>dashboard</string>
+ </value>
+ <value>
+ <string>exoadmin</string>
+ </value>
+ <value>
+ <string>eXoGadgets</string>
+ </value>
+ <value>
+ <string>eXoGadgetServer</string>
+ </value>
+ <value>
+ <string>rest</string>
+ </value>
+ <value>
+ <string>web</string>
+ </value>
+ <value>
+ <string>wsrp-producer</string>
+ </value>
+ <value>
+ <string>sample-ext</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+
+ <para>In the previous example, we define a portal container called
+ "portal", which rest context name is "rest", which realm name is
+ "exo-domain" and which dependencies are the web applications
+ "eXoResources", "portal"... The platform will load first "eXoResources",
+ then "portal" and so on.</para>
+ </section>
+
+ <section>
+ <title>How the platform interprets the dependency order defined into the
+ PortalContainerDefinition?</title>
+
+ <para>The dependency order defined into the
+ <emphasis>PortalContainerDefinition</emphasis> 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 is less important than the second element and so on.</para>
+
+ <para><emphasis role="underline">So it is currently used
+ to:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>know loading order of all the dependencies</para>
+ </listitem>
+
+ <listitem>
+ <para>If we have several
+ <emphasis>PortalContainerConfigOwner</emphasis> (see next section
+ for more details about a PortalContainerConfigOwner)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The ServletContext of all the
+ <emphasis>PortalContainerConfigOwner</emphasis> will be unified,
+ if we use the unified ServletContext
+ (PortalContainer.getPortalContext()) to get a resource, it will
+ try to get the resource in the ServletContext of the most
+ important <emphasis>PortalContainerConfigOwner</emphasis> (i.e.
+ last in the dependency list) and if it cans find it, it will try
+ with the second most important
+ <emphasis>PortalContainerConfigOwner</emphasis> and so
+ on.</para>
+ </listitem>
+
+ <listitem>
+ <para>The ClassLoader of all the
+ <emphasis>PortalContainerConfigOwner</emphasis> will be unified,
+ if we use the unified ClassLoader
+ (PortalContainer.getPortalClassLoader()) to get a resource, it
+ will try to get the resource in the ClassLoader of the most
+ important <emphasis>PortalContainerConfigOwner</emphasis> (i.e.
+ last in the dependency list) and if it cans find it, it will try
+ with the second most important
+ <emphasis>PortalContainerConfigOwner</emphasis> and so
+ on.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How to change the ServletContext name, the realm name and/or the
+ rest context name of my portal without using a
+ PortalContainerDefinition?</title>
+
+ <para>To do that you need first to change the default values used by a
+ PortalContainer that has not been defined thanks to a
+ <emphasis>PortalContainerDefinition</emphasis>. Those default values can
+ be modified thanks to a set of init parameters of the component
+ <emphasis>PortalContainerConfig</emphasis>.</para>
+
+ <para>The component <emphasis>PortalContainerConfig</emphasis> must be
+ registered at the <emphasis>RootContainer</emphasis> level. In other
+ words, your configuration file must be a file
+ <emphasis>conf/configuration.xml</emphasis> packaged into a jar file or
+ $AS_HOME/exo-conf/configuration.xml (for more details please have a look
+ to the article <link linkend="Kernel.ContainerConfiguration">Container
+ Configuration</link>).</para>
+
+ <para><emphasis role="underline">In the example below we will
+ rename:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the portal name "portal" to "myPortal".</para>
+ </listitem>
+
+ <listitem>
+ <para>the rest servlet context name "rest" to "myRest".</para>
+ </listitem>
+
+ <listitem>
+ <para>the realm name "exo-domain" to "my-exo-domain".</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="underline">See below an example</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <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>
+ </init-params>
+ </component>
+</configuration></programlisting>
+
+ <para>Once your configuration is ready, you need to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Update the file <emphasis>WEB-INF/web.xml</emphasis> of the
+ file "portal.war" by changing the "display-name" (the new value is
+ "myPortal") and the "realm-name" in the "login-config" (the new
+ value is "my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>If you use JBoss AS: Update the file
+ <emphasis>WEB-INF/jboss-web.xml</emphasis> of the file "portal.war"
+ by changing the "security-domain" (the new value is
+ "java:/jaas/my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the "portal.war" to "myPortal.war" (or "02portal.war"
+ to "02myPortal.war")</para>
+ </listitem>
+
+ <listitem>
+ <para>Update the file <emphasis>WEB-INF/web.xml</emphasis> of the
+ file "rest.war" by changing the "display-name" (the new value is
+ "myRest") and the "realm-name" in the "login-config" (the new value
+ is "my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>If you use JBoss AS: Update the file
+ <emphasis>WEB-INF/jboss-web.xml</emphasis> of the file "rest.war" by
+ changing the "security-domain" (the new value is
+ "java:/jaas/my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the "rest.war" to "myRest.war"</para>
+ </listitem>
+
+ <listitem>
+ <para>If "portal.war" and "rest.war" were embedded into an ear file:
+ Update the file <emphasis>META-INF/application.xml</emphasis> of the
+ file "exoplatform.ear" by remaming "02portal.war" to
+ "02myPortal.war", "portal" to "myPortal", "rest.war" to "myRest.war"
+ and "rest" to "myRest".</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The end of the process depends on your application server</para>
+
+ <section>
+ <title>On JBoss (tested on JBoss 5.1.0.GA)</title>
+
+ <para>You need to change the name of the application policy in your
+ file <emphasis>conf/login-config.xml</emphasis> (the new name is
+ "my-exo-domain").</para>
+ </section>
+
+ <section>
+ <title>On Tomcat (tested on Tomcat 6.0.20)</title>
+
+ <para><emphasis role="underline">You need to:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Update the file
+ <emphasis>tomcat/conf/Catalina/localhost/portal.xml</emphasis> by
+ changing the "path" (the new value is "/myPortal"), the "docBase"
+ (the new value is "myPortal") and the "appName" in the "Realm"
+ definition (the new value is "my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the file
+ <emphasis>tomcat/conf/Catalina/localhost/portal.xml</emphasis> to
+ <emphasis>myPortal.xml</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Update the file
+ <emphasis>tomcat/conf/Catalina/localhost/rest.xml</emphasis> by
+ changing the "path" (the new value is "/myRest"), the "docBase"
+ (the new value is "myRest") and the "appName" in the "Realm"
+ definition (the new value is "my-exo-domain").</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the file
+ <emphasis>tomcat/conf/Catalina/localhost/rest.xml</emphasis> to
+ <emphasis>myRest.xml</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Change the realm name in the file
+ <emphasis>tomcat/conf/jaas.conf</emphasis> (the new name is
+ "my-exo-domain").</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>How to add new configuration file to a given portal from a war
+ file?</title>
+
+ <para>To indicate the platform that a given web application has
+ configuration file to provide, you need to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>add the ServletContextListener
+ <emphasis>org.exoplatform.container.web.PortalContainerConfigOwner</emphasis>
+ in its web.xml.</para>
+ </listitem>
+
+ <listitem>
+ <para>add the servlet context name of this web application as a new
+ dependency in the <emphasis>PortalContainerDefinition</emphasis> of
+ all the portal containers for which you want to share the
+ configuration file embedded into the war file, located at
+ <emphasis>WEB-INF/conf/configuration.xml</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The simple fact to add this Servlet Context Listener, will add the
+ Servlet Context of this web application to the Unified Servlet Context
+ of all the <emphasis>PortalContainers</emphasis> that depend on this web
+ application according to their
+ <emphasis>PortalContainerDefinition</emphasis>.</para>
+
+ <important>
+ <title>Useful Information #1</title>
+
+ <para>The position of the servlet context name of this web application
+ in the dependency list is important since the last configuration file
+ loaded has always right towards other configuration files. Each
+ configuration file loaded, could potentially redefine a configuration
+ file that has already been loaded. Moreover, as we now use a unified
+ Servlet Context to load the configuration files, if you want for
+ instance to import the file
+ <emphasis>war:/conf/database/database-configuration.xml</emphasis> and
+ this file exists in 2 different web applications, the file from the
+ last (according to the dependency order) web application will be
+ loaded.</para>
+ </important>
+
+ <important>
+ <title>Useful Information #2</title>
+
+ <para>A portal is implicitly considered as a
+ <emphasis>PortalContainerConfigOwner</emphasis> without having to
+ define the ServletContextListener
+ <emphasis>org.exoplatform.container.web.PortalContainerConfigOwner</emphasis>
+ in its web.xml.</para>
+ </important>
+
+ <para>See an example of a web.xml below:</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>
+ <display-name>sample-ext</display-name>
+
+ <context-param>
+ <param-name>org.exoplatform.frameworks.jcr.command.web.fckeditor.digitalAssetsWorkspace</param-name>
+ <param-value>collaboration</param-value>
+ <description>Binary assets workspace name</description>
+ </context-param>
+
+ <context-param>
+ <param-name>org.exoplatform.frameworks.jcr.command.web.fckeditor.digitalAssetsPath</param-name>
+ <param-value>/Digital Assets/</param-value>
+ <description>Binary assets path</description>
+ </context-param>
+
+ <context-param>
+ <param-name>CurrentFolder</param-name>
+ <param-value>/Digital Assets/</param-value>
+ <description>Binary assets workspace name</description>
+ </context-param>
+
+ <!-- ================================================================== -->
+ <!-- RESOURCE FILTER TO CACHE MERGED JAVASCRIPT AND CSS -->
+ <!-- ================================================================== -->
+ <filter>
+ <filter-name>ResourceRequestFilter</filter-name>
+ <filter-class>org.exoplatform.portal.application.ResourceRequestFilter</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>ResourceRequestFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+
+ <!-- ================================================================== -->
+ <!-- LISTENER -->
+ <!-- ================================================================== -->
+ <listener>
+ <listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
+ </listener>
+ <!-- ================================================================== -->
+ <!-- SERVLET -->
+ <!-- ================================================================== -->
+ <servlet>
+ <servlet-name>GateInServlet</servlet-name>
+ <servlet-class>org.gatein.wci.api.GateInServlet</servlet-class>
+ <load-on-startup>0</load-on-startup>
+ </servlet>
+ <!-- ================================================================= -->
+ <servlet-mapping>
+ <servlet-name>GateInServlet</servlet-name>
+ <url-pattern>/gateinservlet</url-pattern>
+ </servlet-mapping>
+</web-app></programlisting>
+ </section>
+
+ <section>
+ <title>How to create/define a portal extension?</title>
+
+ <para>A portal extension is in fact a web application declared as a
+ <emphasis>PortalContainerConfigOwner</emphasis> (see previous section
+ for more details about a
+ <emphasis>PortalContainerConfigOwner</emphasis>) that has been added to
+ the dependency list of the
+ <emphasis>PortalContainerDefinition</emphasis> of a given portal.</para>
+
+ <para><emphasis role="underline">See below an example of configuration
+ file that add the portal extension "portal-ext" to the dependency list
+ of the portal "portal":</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the PortalContainerConfig -->
+ <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Add PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the PortalContainerDefinitions -->
+ <set-method>registerPlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
+ <init-params>
+ <object-param>
+ <name>portal</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinition">
+ <!-- The name of the portal container -->
+ <field name="name"><string>portal</string></field>
+ <!-- The name of the context name of the rest web application -->
+ <field name="restContextName"><string>rest</string></field>
+ <!-- The name of the realm -->
+ <field name="realmName"><string>exo-domain</string></field>
+ <!-- All the dependencies of the portal container ordered by loading priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>eXoResources</string>
+ </value>
+ <value>
+ <string>portal</string>
+ </value>
+ <value>
+ <string>dashboard</string>
+ </value>
+ <value>
+ <string>exoadmin</string>
+ </value>
+ <value>
+ <string>eXoGadgets</string>
+ </value>
+ <value>
+ <string>eXoGadgetServer</string>
+ </value>
+ <value>
+ <string>rest</string>
+ </value>
+ <value>
+ <string>web</string>
+ </value>
+ <value>
+ <string>wsrp-producer</string>
+ </value>
+ <!-- The sample-ext has been added at the end of the dependency list in order to have the highest priority towards
+ the other web applications and particularly towards "portal" -->
+ <value>
+ <string>sample-ext</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>How to deploy a portal extension?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ extension?</emphasis></para>
+ </section>
+
+ <section>
+ <title>How to create/define a new portal?</title>
+
+ <para>You have no need anymore, to duplicate the entire "portal.war"
+ file to create a new portal, you just to duplicate the following files
+ from the original "portal.war":</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>login/jsp/login.jsp</para>
+ </listitem>
+
+ <listitem>
+ <para>login/skin: You can customize the css files and
+ pictures</para>
+ </listitem>
+
+ <listitem>
+ <para>bookmark.jsp</para>
+ </listitem>
+
+ <listitem>
+ <para>favicon.ico: You can replace it by your own logo</para>
+ </listitem>
+
+ <listitem>
+ <para>index.jsp</para>
+ </listitem>
+
+ <listitem>
+ <para>portal-unavailable.jsp</para>
+ </listitem>
+
+ <listitem>
+ <para>portal-warning.jsp</para>
+ </listitem>
+
+ <listitem>
+ <para>WEB-INF/web.xml: You just need to change the "display-name"
+ and set a different value for the "realm-name" in the
+ "login-config". Indeed, we must have one realm name per
+ portal.</para>
+ </listitem>
+
+ <listitem>
+ <para>WEB-INF/jboss-web.xml: If you use JBoss AS, you need to
+ duplicate also this file and set the new "security-domain" with the
+ new realm name.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You need also to duplicate the "rest.war" file to create a
+ dedicated rest web application for your portal as we must have one rest
+ web application per portal, in fact you just need to duplicate the
+ following files from the original "rest.war":</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>WEB-INF/web.xml: You just need to change the "display-name"
+ and set a different value for the "realm-name" in the
+ "login-config". Indeed, we must have one realm name per
+ portal.</para>
+ </listitem>
+
+ <listitem>
+ <para>WEB-INF/jboss-web.xml: If you use JBoss AS, you need to
+ duplicate also this file and set the new "security-domain" with the
+ new realm name.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Finally you need to register and define the corresponding
+ <emphasis>PortalContainerDefinition</emphasis>. The
+ <emphasis>PortalContainerDefinition</emphasis> of your portal will be
+ composed of:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The name of new portal</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the context name of the new rest web
+ application</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the new realm</para>
+ </listitem>
+
+ <listitem>
+ <para>The list of all the dependencies of the original portal, with
+ the new name of the rest web application instead of the old name
+ (i.e. "rest") and with a new dependency which is in fact the name of
+ your portal. As we leave the dependency of the original portal in
+ the list of dependencies, it will load the configuration files of
+ original "portal.war" file.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="underline">See an example below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the PortalContainerConfig -->
+ <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Add PortalContainer Definitions</name>
+ <!-- The name of the method to call on the PortalContainerConfig in order to register the PortalContainerDefinitions -->
+ <set-method>registerPlugin</set-method>
+ <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
+ <type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
+ <init-params>
+ <object-param>
+ <name>sample-portal</name>
+ <object type="org.exoplatform.container.definition.PortalContainerDefinition">
+ <!-- The name of the portal container -->
+ <field name="name"><string>sample-portal</string></field>
+ <!-- The name of the context name of the rest web application -->
+ <field name="restContextName"><string>rest-sample-portal</string></field>
+ <!-- The name of the realm -->
+ <field name="realmName"><string>exo-domain-sample-portal</string></field>
+ <!-- All the dependencies of the portal container ordered by loading priority -->
+ <field name="dependencies">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>eXoResources</string>
+ </value>
+ <value>
+ <string>portal</string>
+ </value>
+ <value>
+ <string>dashboard</string>
+ </value>
+ <value>
+ <string>exoadmin</string>
+ </value>
+ <value>
+ <string>eXoGadgets</string>
+ </value>
+ <value>
+ <string>eXoGadgetServer</string>
+ </value>
+ <value>
+ <string>rest-sample-portal</string>
+ </value>
+ <value>
+ <string>web</string>
+ </value>
+ <value>
+ <string>wsrp-producer</string>
+ </value>
+ <value>
+ <string>sample-portal</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+
+ <important>
+ <title>Useful Information #1</title>
+
+ <para>A portal is implicitly a
+ <emphasis>PortalContainerConfigOwner</emphasis> which means that it
+ shares the configuration file embedded into the war file, located at
+ <emphasis>WEB-INF/conf/configuration.xml</emphasis></para>
+ </important>
+
+ <important>
+ <title>Useful Information #2</title>
+
+ <para>The position of the servlet context name of this web application
+ in the dependency list is important since the last configuration file
+ loaded has always right towards other configuration files. Each
+ configuration file loaded, could potentially redefine a configuration
+ file that has already been loaded. Moreover, as we now use a unified
+ Servlet Context to load the configuration files, if you want for
+ instance to import the file
+ <emphasis>war:/conf/database/database-configuration.xml</emphasis> and
+ this file exists in 2 different web applications, the file from the
+ last (according to the dependency order) web application will be
+ loaded.</para>
+ </important>
+ </section>
+
+ <section>
+ <title>How to deploy a new portal?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ portal?</emphasis></para>
+ </section>
+
+ <section>
+ <title>How to import properly a configuration file using the prefix
+ "war:"?</title>
+
+ <para>Now, the <emphasis>ConfigurationManager</emphasis> uses by default
+ the unified servlet context of the portal in order to get any resources
+ in particular the configuration files. The unified servlet context is
+ aware of the priorities that has been set in the
+ <emphasis>PortalContainerDefinition</emphasis> of the portal. In other
+ words, if you want for instance to import the file
+ <emphasis>war:/conf/database/database-configuration.xml</emphasis> and
+ this file exists in 2 different web applications, the file from the last
+ (according to the dependency order) web application will be
+ loaded.</para>
+
+ <para>So, in order to avoid issues when we would like to package several
+ products at the same time (i.e. WCM, DMS, CS, KS), we need to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Avoid the best you can to redefine a configuration file from
+ the "portal.war" by using the exact same path (like the previous
+ example)</para>
+ </listitem>
+
+ <listitem>
+ <para>Add your configuration files in a dedicated folder which name
+ will be the name of the product, in oder to ensure that no other
+ products will use the same path</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The example below, is an the example of a file
+ <emphasis>WEB-INF/conf/configuration.xml</emphasis> of the product
+ "sample-ext".</para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <import>war:/conf/sample-ext/common/common-configuration.xml</import>
+ <import>war:/conf/sample-ext/jcr/jcr-configuration.xml</import>
+ <import>war:/conf/sample-ext/portal/portal-configuration.xml</import>
+ <import>war:/conf/sample-ext/web/web-inf-extension-configuration.xml</import>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>How to avoid duplicating configuration files just to rename a
+ simple value?</title>
+
+ <para>In your configuration file, you can use a special variable called
+ <emphasis>container.name.suffix</emphasis> in order to add a suffix to
+ values that could change between portal containers. The value of this
+ variable will be an empty sting if no
+ <emphasis>PortalContainerDefinition</emphasis> has been defined
+ otherwise the value will be
+ <emphasis>\-$portal.container.name</emphasis>. <emphasis
+ role="underline">See an example below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <jmx-name>database:type=HibernateService</jmx-name>
+ <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+ <init-params>
+ <properties-param>
+ <name>hibernate.properties</name>
+ <description>Default Hibernate Service</description>
+ <property name="hibernate.show_sql" value="false"/>
+ <property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
+ <property name="hibernate.connection.url" value="jdbc:hsqldb:file:../temp/data/exodb${container.name.suffix}"/>
+ <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
+ <property name="hibernate.connection.autocommit" value="true"/>
+ <property name="hibernate.connection.username" value="sa"/>
+ <property name="hibernate.connection.password" value=""/>
+ <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
+ <property name="hibernate.c3p0.min_size" value="5"/>
+ <property name="hibernate.c3p0.max_size" value="20"/>
+ <property name="hibernate.c3p0.timeout" value="1800"/>
+ <property name="hibernate.c3p0.max_statements" value="50"/>
+ </properties-param>
+ </init-params>
+ </component>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>How to add or change a Repository and/or a Workspace?</title>
+
+ <para>Now you can add new JCR repositories or workspaces thanks to an
+ external plugin, the configuration of your JCR Repositories will be
+ merged knowing that the merge algorithm will:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>add missing Repository Definitions and/or Workspace
+ Definitions.</para>
+ </listitem>
+
+ <listitem>
+ <para>change the properties of a Repository Definition if it has
+ already been defined</para>
+ </listitem>
+
+ <listitem>
+ <para>replace the Workspace Definition if it has already been
+ defined.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="underline">See an example of jcr-configuration.xml
+ below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the RepositoryServiceConfiguration -->
+ <target-component>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Sample RepositoryServiceConfiguration Plugin</name>
+ <!-- The name of the method to call on the RepositoryServiceConfiguration in order to add the RepositoryServiceConfigurations -->
+ <set-method>addConfig</set-method>
+ <!-- The full qualified name of the RepositoryServiceConfigurationPlugin -->
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationPlugin</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>war:/conf/sample-ext/jcr/repository-configuration.xml</value>
+ </value-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+
+ <para>See an example of repository-configuration.xml below:</para>
+
+ <programlisting><repository-service default-repository="repository">
+ <repositories>
+ <repository name="repository" system-workspace="system" default-workspace="portal-system">
+ <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="sample-ws">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcexo${container.name.suffix}" />
+ <property name="dialect" value="hsqldb" />
+ <property name="multi-db" value="false" />
+ <property name="update-storage" value="true" />
+ <property name="max-buffer-size" value="204800" />
+ <property name="swap-directory" value="../temp/swap/sample-ws${container.name.suffix}" />
+ </properties>
+ <value-storages>
+ <value-storage id="sample-ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="../temp/values/sample-ws${container.name.suffix}" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions"
+ value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true">
+ <properties>
+ <property name="max-size" value="20000" />
+ <property name="live-time" value="30000" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="../temp/jcrlucenedb/sample-ws${container.name.suffix}" />
+ </properties>
+ </query-handler>
+ <lock-manager>
+ <time-out>15m</time-out><!-- 15min -->
+ <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+ <properties>
+ <property name="path" value="../temp/lock/sample-ws${container.name.suffix}" />
+ </properties>
+ </persister>
+ </lock-manager>
+ </workspace>
+ </workspaces>
+ </repository>
+ </repositories>
+</repository-service></programlisting>
+
+ <warning>
+ <title>Warning</title>
+
+ <para>If you have to change the default repository or the default
+ workspace, please be careful since it could cause side effects as you
+ could be incompatible with some portal configuration files that refer
+ explicitly to <emphasis>portal-system</emphasis> and/or to
+ <emphasis>repository</emphasis>. To solve this problem you can either
+ redefine the configuration file in a portal extension to change the
+ workspace name and/or the repository name or you could also add your
+ own repository instead of your own workspace.</para>
+ </warning>
+ </section>
+
+ <section>
+ <title>How to add new ResourceBundles to my portal?</title>
+
+ <para>Now you can add new Resource Bundles, thanks to an external
+ plugin.</para>
+
+ <para><emphasis role="underline">See an example below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the ResourceBundleService -->
+ <target-component>org.exoplatform.services.resources.ResourceBundleService</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Sample ResourceBundle Plugin</name>
+ <!-- The name of the method to call on the ResourceBundleService in order to register the ResourceBundles -->
+ <set-method>addResourceBundle</set-method>
+ <!-- The full qualified name of the BaseResourceBundlePlugin -->
+ <type>org.exoplatform.services.resources.impl.BaseResourceBundlePlugin</type>
+ <init-params>
+ <!--values-param>
+ <name>classpath.resources</name>
+ <description>The resources that start with the following package name should be load from file system</description>
+ <value>locale.portlet</value>
+ </values-param-->
+ <values-param>
+ <name>init.resources</name>
+ <description>Store the following resources into the db for the first launch </description>
+ <value>locale.portal.sample</value>
+ </values-param>
+ <values-param>
+ <name>portal.resource.names</name>
+ <description>The properties files of the portal , those file will be merged
+ into one ResoruceBundle properties </description>
+ <value>locale.portal.sample</value>
+ </values-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>How to overwrite existing ResourceBundles in my portal?</title>
+
+ <para>Now each portal container has its own
+ <emphasis>ClassLoader</emphasis> which is automatically set for you at
+ runtime (FYI: it could be retrieved thanks to
+ <emphasis>portalContainer.getPortalClassLoader()</emphasis>). This
+ <emphasis>ClassLoader</emphasis> is an unified
+ <emphasis>ClassLoader</emphasis> that is also aware of the dependency
+ order defined into the <emphasis>PortalContainerDefinition</emphasis>,
+ so to add new keys or update key values, you just need to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the corresponding resource bundle with the same name, with
+ <emphasis role="underline">the same extension</emphasis> (xml or
+ properties) at the same location into the
+ <emphasis>classpath</emphasis> of your Web application (i.e.
+ directly into the <emphasis>WEB-INF/classes</emphasis> directory or
+ into a jar file in the <emphasis>WEB-INF/lib</emphasis>
+ directory)</para>
+ </listitem>
+
+ <listitem>
+ <para>Ensure that your web application is defined after the web
+ application of the portal in the dependency list of the related
+ <emphasis>PortalContainerDefinition</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In the example below, we want to change the values of the keys
+ <emphasis>UIHomePagePortlet.Label.Username</emphasis> and
+ <emphasis>UIHomePagePortlet.Label.Password</emphasis>, and add the new
+ key <emphasis>UIHomePagePortlet.Label.SampleKey</emphasis> into the
+ Resource Bundle <emphasis>locale.portal.webui</emphasis>.</para>
+
+ <note>
+ <title>WEB-INF/classes/local/portal/webui_en.properties</title>
+
+ <programlisting>#############################################################################
+#org.exoplatform.portal.webui.component.UIHomePagePortlet #
+#############################################################################
+
+UIHomePagePortlet.Label.Username=Usr:
+UIHomePagePortlet.Label.Password=Pwd:
+UIHomePagePortlet.Label.SampleKey=This is a new key that has been added to the Resource Bundle "locale.portal.webui" of "sample-ext"</programlisting>
+ </note>
+ </section>
+
+ <section>
+ <title>How to replace a groovy template of my portal?</title>
+
+ <para>Now each portal container has its own
+ <emphasis>ServletContext</emphasis> which is automatically set for you
+ at runtime (FYI: it could be retrieved thanks to
+ <emphasis>portalContainer.getPortalContext()</emphasis>). This
+ <emphasis>ServletContext</emphasis> is an unified
+ <emphasis>ServletContext</emphasis> that is also aware of the dependency
+ order defined into the <emphasis>PortalContainerDefinition</emphasis> so
+ to replace a groovy template of the portal, you just need to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the corresponding groovy template with the same name at
+ the same location into your Web application</para>
+ </listitem>
+
+ <listitem>
+ <para>Ensure that your web application is defined after the web
+ application of the portal in the dependency list of the related
+ <emphasis>PortalContainerDefinition</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How to add new Portal Configurations, Navigations, Pages or
+ Portlet Preferences to my portal?</title>
+
+ <para>Now you can add new Portal Configurations, Navigations, Pages or
+ Portlet Preferences thanks to an external plugin.</para>
+
+ <para><emphasis role="underline">See an example below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the UserPortalConfigService -->
+ <target-component>org.exoplatform.portal.config.UserPortalConfigService</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>new.portal.config.user.listener</name>
+ <!-- The name of the method to call on the UserPortalConfigService in order to register the NewPortalConfigs -->
+ <set-method>initListener</set-method>
+ <!-- The full qualified name of the NewPortalConfigListener -->
+ <type>org.exoplatform.portal.config.NewPortalConfigListener</type>
+ <description>this listener init the portal configuration</description>
+ <init-params>
+ <object-param>
+ <name>portal.configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.portal.config.NewPortalConfig">
+ <field name="predefinedOwner">
+ <collection type="java.util.HashSet">
+ <value>
+ <string>classic</string>
+ </value>
+ </collection>
+ </field>
+ <field name="ownerType">
+ <string>portal</string>
+ </field>
+ <field name="templateLocation">
+ <string>war:/conf/sample-ext/portal</string>
+ </field>
+ </object>
+ </object-param>
+ <object-param>
+ <name>group.configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.portal.config.NewPortalConfig">
+ <field name="predefinedOwner">
+ <collection type="java.util.HashSet">
+ <value>
+ <string>platform/users</string>
+ </value>
+ </collection>
+ </field>
+ <field name="ownerType">
+ <string>group</string>
+ </field>
+ <field name="templateLocation">
+ <string>war:/conf/sample-ext/portal</string>
+ </field>
+ </object>
+ </object-param>
+ <object-param>
+ <name>user.configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.portal.config.NewPortalConfig">
+ <field name="predefinedOwner">
+ <collection type="java.util.HashSet">
+ <value>
+ <string>root</string>
+ </value>
+ </collection>
+ </field>
+ <field name="ownerType">
+ <string>user</string>
+ </field>
+ <field name="templateLocation">
+ <string>war:/conf/sample-ext/portal</string>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>How to add new Http Filters to my portal without modifying the
+ portal binary?</title>
+
+ <para>We added a <emphasis>GenericFilter</emphasis> that allows you to
+ define new Http Filters thanks to an external plugin. Your filter will
+ need to implement the interface
+ <emphasis>org.exoplatform.web.filter.Filter</emphasis>.</para>
+
+ <para><emphasis role="underline">See an example of configuration
+ below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the ExtensibleFilter -->
+ <target-component>org.exoplatform.web.filter.ExtensibleFilter</target-component>
+ <component-plugin>
+ <!-- The name of the plugin -->
+ <name>Sample Filter Definition Plugin</name>
+ <!-- The name of the method to call on the ExtensibleFilter in order to register the FilterDefinitions -->
+ <set-method>addFilterDefinitions</set-method>
+ <!-- The full qualified name of the FilterDefinitionPlugin -->
+ <type>org.exoplatform.web.filter.FilterDefinitionPlugin</type>
+ <init-params>
+ <object-param>
+ <name>Sample Filter Definition</name>
+ <object type="org.exoplatform.web.filter.FilterDefinition">
+ <!-- The filter instance -->
+ <field name="filter"><object type="org.exoplatform.sample.ext.web.SampleFilter"/></field>
+ <!-- The mapping to use -->
+ <!-- WARNING: the mapping is expressed with regular expressions -->
+ <field name="patterns">
+ <collection type="java.util.ArrayList" item-type="java.lang.String">
+ <value>
+ <string>/.*</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+
+ <para>See an example of Filter below:</para>
+
+ <note>
+ <title>SampleFilter.java</title>
+
+ <programlisting>...
+import org.exoplatform.web.filter.Filter;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+public class SampleFilter implements Filter
+{
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
+ ServletException
+ {
+ System.out.println("SampleFilter start");
+ try
+ {
+ chain.doFilter(request, response);
+ }
+ finally
+ {
+ System.out.println("SampleFilter end");
+ }
+ }
+}</programlisting>
+ </note>
+ </section>
+
+ <section>
+ <title>How to add new <emphasis>HttpSessionListeners</emphasis> and/or
+ <emphasis>ServletContextListeners</emphasis> to my portal without
+ modifying the portal binary?</title>
+
+ <para>We added a <emphasis>GenericHttpListener</emphasis> that allows
+ you to define new <emphasis>HttpSessionListeners</emphasis> and/or
+ <emphasis>ServletContextListeners</emphasis> thanks to an external
+ plugin. Actually, the <emphasis>GenericHttpListener</emphasis> will
+ broadcast events thanks to the <emphasis>ListenerService</emphasis> that
+ you can easily capture. The events that it broadcasts are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>org.exoplatform.web.GenericHttpListener.sessionCreated</emphasis>:
+ When a new session is created in the portal.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>org.exoplatform.web.GenericHttpListener.sessionDestroyed</emphasis>:
+ When a session is destroyed in the portal.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>org.exoplatform.web.GenericHttpListener.contextInitialized</emphasis>:
+ When the servlet context of the portal is initialized.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>org.exoplatform.web.GenericHttpListener.contextDestroyed</emphasis>:
+ When the servlet context of the portal is destroyed.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you want to listen to
+ <emphasis>org.exoplatform.web.GenericHttpListener.sessionCreated</emphasis>,
+ you will need to create a Listener that extends
+ _Listener<PortalContainer, HttpSessionEvent>_If you want to listen
+ to \_org.exoplatform.web.GenericHttpListener.sessionDestroyed_, you will
+ need to create a Listener that extends _Listener<PortalContainer,
+ HttpSessionEvent>_If you want to listen to
+ \_org.exoplatform.web.GenericHttpListener.contextInitialized_, you will
+ need to create a Listener that extends _Listener<PortalContainer,
+ ServletContextEvent>_If you want to listen to
+ \_org.exoplatform.web.GenericHttpListener.contextDestroyed_, you will
+ need to create a Listener that extends
+ <emphasis>Listener<PortalContainer,
+ ServletContextEvent></emphasis></para>
+
+ <para><emphasis role="underline">See an example of configuration
+ below:</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <external-component-plugins>
+ <!-- The full qualified name of the ListenerService -->
+ <target-component>org.exoplatform.services.listener.ListenerService</target-component>
+ <component-plugin>
+ <!-- The name of the listener that is also the name of the target event -->
+ <name>org.exoplatform.web.GenericHttpListener.sessionCreated</name>
+ <!-- The name of the method to call on the ListenerService in order to register the Listener -->
+ <set-method>addListener</set-method>
+ <!-- The full qualified name of the Listener -->
+ <type>org.exoplatform.sample.ext.web.SampleHttpSessionCreatedListener</type>
+ </component-plugin>
+ <component-plugin>
+ <!-- The name of the listener that is also the name of the target event -->
+ <name>org.exoplatform.web.GenericHttpListener.sessionDestroyed</name>
+ <!-- The name of the method to call on the ListenerService in order to register the Listener -->
+ <set-method>addListener</set-method>
+ <!-- The full qualified name of the Listener -->
+ <type>org.exoplatform.sample.ext.web.SampleHttpSessionDestroyedListener</type>
+ </component-plugin>
+ <component-plugin>
+ <!-- The name of the listener that is also the name of the target event -->
+ <name>org.exoplatform.web.GenericHttpListener.contextInitialized</name>
+ <!-- The name of the method to call on the ListenerService in order to register the Listener -->
+ <set-method>addListener</set-method>
+ <!-- The full qualified name of the Listener -->
+ <type>org.exoplatform.sample.ext.web.SampleContextInitializedListener</type>
+ </component-plugin>
+ <component-plugin>
+ <!-- The name of the listener that is also the name of the target event -->
+ <name>org.exoplatform.web.GenericHttpListener.contextDestroyed</name>
+ <!-- The name of the method to call on the ListenerService in order to register the Listener -->
+ <set-method>addListener</set-method>
+ <!-- The full qualified name of the Listener -->
+ <type>org.exoplatform.sample.ext.web.SampleContextDestroyedListener</type>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+
+ <para>See an example of Session Listener below:</para>
+
+ <note>
+ <title>SampleHttpSessionCreatedListener.java</title>
+
+ <programlisting>..
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.services.listener.Event;
+import org.exoplatform.services.listener.Listener;
+
+import javax.servlet.http.HttpSessionEvent;
+
+public class SampleHttpSessionCreatedListener extends Listener<PortalContainer, HttpSessionEvent>
+{
+
+ @Override
+ public void onEvent(Event<PortalContainer, HttpSessionEvent> event) throws Exception
+ {
+ System.out.println("Creating a new session");
+ }
+}</programlisting>
+ </note>
+
+ <para>See an example of Context Listener below:</para>
+
+ <note>
+ <title>SampleContextInitializedListener.java</title>
+
+ <programlisting>..
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.services.listener.Event;
+import org.exoplatform.services.listener.Listener;
+
+import javax.servlet.ServletContextEvent;
+
+public class SampleContextInitializedListener extends Listener<PortalContainer, ServletContextEvent>
+{
+
+ @Override
+ public void onEvent(Event<PortalContainer, ServletContextEvent> event) throws Exception
+ {
+ System.out.println("Initializing the context");
+ }
+}</programlisting>
+ </note>
+ </section>
+
+ <section>
+ <title>How to add new <emphasis>HttpServlet</emphasis> to my portal
+ without modifying the portal binary?</title>
+
+ <para>Actually, it is not possible but you can create a rest component
+ instead. For more details about rest, please refer to the following
+ article <link linkend="WS">WS</link>.</para>
+ </section>
+
+ <section>
+ <title>How to override or add a Context Parameter to my portal without
+ modifying the portal binary?</title>
+
+ <para>Actually, you have nothing to do, you just need to ensure that you
+ get the context parameter value from the unified servlet context of the
+ portal, that should be set for you but you can still get it from
+ <emphasis>portalContainer.getPortalContext()</emphasis>.</para>
+ </section>
+
+ <section>
+ <title>Where can I found an example of how to extend my portal?</title>
+
+ <para>We added an example of portal extension (i.e. ability to customize
+ a portal without changing anything in the portal.ear) that you can find
+ in the svn of gatein at gatein/sample/extension.</para>
+ </section>
+
+ <section>
+ <title>How to deploy the sample extension?</title>
+
+ <section>
+ <title>On JBoss (tested on JBoss 5.1.0.GA)</title>
+
+ <para>We assume that you have a clean JBoss version of GateIn, in
+ other words, we assume that you have already the file
+ <emphasis>exoplatform.ear</emphasis> in the
+ <emphasis>deploy</emphasis> directory of JBoss and you have the
+ related application policy in your
+ <emphasis>conf/login-config.xml</emphasis>.</para>
+
+ <para><emphasis role="underline">You need to:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the file <emphasis>sample-ext.ear</emphasis> from
+ sample/extension/ear/target/ to the deploy directory of JBoss,
+ this file contains:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The file <emphasis>sample-ext.war</emphasis> which is
+ the web application that contains (potentially) configuration
+ files, groovy templates, resource bundles, skins and
+ javascript files, that will extend the portal.</para>
+ </listitem>
+
+ <listitem>
+ <para>The file
+ <emphasis>exo.portal.sample.extension.config-X.Y.Z.jar</emphasis>
+ which is the file in which we defined the
+ <emphasis>PortalContainerDefinition</emphasis> of the original
+ portal in which we added <emphasis>sample-ext</emphasis> at
+ the end of dependency list.</para>
+ </listitem>
+
+ <listitem>
+ <para>The file
+ <emphasis>exo.portal.sample.extension.jar-X.Y.Z.jar</emphasis>
+ which is the file in which we have internal classes that are
+ actualy a set of sample classes <emphasis>(SampleFilter,
+ SampleContextInitializedListener,
+ SampleContextDestroyedListener,
+ SampleHttpSessionCreatedListener and
+ SampleHttpSessionDestroyedListener)</emphasis></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Add the file <emphasis>starter.ear</emphasis> from
+ starter/ear/target/ to the deploy directory of JBoss, this file
+ contains:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The file <emphasis>starter.war</emphasis> which is the
+ web application that will create and start all the portal
+ containers, that is why it must be launched after all the
+ other web applications.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <title>Warning #1</title>
+
+ <para>This can only work if a Unified ClassLoader has been
+ configured on your JBoss (default behavior) and the load order is
+ first the <emphasis>exoplatform.ear</emphasis> then the
+ <emphasis>sample-ext.ear</emphasis> and finally the
+ <emphasis>starter.ear</emphasis>.</para>
+ </warning>
+
+ <warning>
+ <title>Warning #2</title>
+
+ <para>The file <emphasis>starter.ear</emphasis> must always been
+ started last.</para>
+ </warning>
+ </section>
+
+ <section>
+ <title>On Tomcat (tested on Tomcat 6.0.20)</title>
+
+ <para>We assume that you have a clean Tomcat version of GateIn, in
+ other words, we assume that you have already all the jar files of
+ GateIn and their dependencies into <emphasis>tomcat/lib</emphasis>,
+ you have all the war files of GateIn into
+ <emphasis>tomcat/webapps</emphasis> and you have the realm name
+ "exo-domain" defined into the file
+ <emphasis>tomcat/conf/jaas.conf</emphasis>.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the file <emphasis>sample-ext.war</emphasis> from
+ sample/extension/war/target/ to the
+ <emphasis>tomcat/webapps</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the folder <emphasis>starter</emphasis> from
+ starter/war/target/ to the <emphasis>tomcat/webapps</emphasis>
+ directory. <emphasis>(See the purpose of this file in the JBoss
+ section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the directory (unzipped folder)
+ <emphasis>starter</emphasis> to <emphasis>starter.war</emphasis>
+ (for more details see the warning below)</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the jar file
+ <emphasis>exo.portal.sample.extension.config-X.Y.Z.jar</emphasis>
+ from sample/extension/config/target/ to the
+ <emphasis>tomcat/lib</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the jar file
+ <emphasis>exo.portal.sample.extension.jar-X.Y.Z.jar</emphasis>
+ from sample/extension/jar/target/ to the
+ <emphasis>tomcat/lib</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <title>Warning</title>
+
+ <para>This can only work if the <emphasis>starter.war</emphasis> is
+ the last war file to be loaded, so don't hesitate to rename it if
+ your war files are loaded following to the alphabetic order.</para>
+ </warning>
+ </section>
+ </section>
+
+ <section>
+ <title>Where can I found an example of how to create a new
+ portal?</title>
+
+ <para>We added an example of new portal (i.e. ability to create a new
+ portal from another portal without changing anything in the portal.ear)
+ that you can find in the svn of gatein at gatein/sample/portal.</para>
+ </section>
+
+ <section>
+ <title>How to deploy the sample portal?</title>
+
+ <section>
+ <title>On JBoss (tested on JBoss 5.1.0.GA)</title>
+
+ <para>We assume that you have a clean JBoss version of GateIn, in
+ other words, we assume that you have already the file
+ <emphasis>exoplatform.ear</emphasis> in the
+ <emphasis>deploy</emphasis> directory of JBoss and you have the
+ related application policy in your
+ <emphasis>conf/login-config.xml</emphasis>.</para>
+
+ <para><emphasis role="underline">You need to:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the file <emphasis>sample-portal.ear</emphasis> from
+ <emphasis>sample/portal/ear/target/</emphasis> to the deploy
+ directory of JBoss, this file contains:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The file <emphasis>sample-portal.war</emphasis> which is
+ the entry point of the new portal</para>
+ </listitem>
+
+ <listitem>
+ <para>The file <emphasis>rest-sample-portal.war</emphasis>
+ which is the entry point for <emphasis>rest</emphasis> outside
+ the portal (in the portal you can access to
+ <emphasis>rest</emphasis> thanks to path prefix
+ <emphasis>/sample-portal/rest</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>The file
+ <emphasis>exo.portal.sample.portal.config-X.Y.Z.jar</emphasis>
+ which is the file in which we defined the
+ <emphasis>PortalContainerDefinition</emphasis> of this
+ portal</para>
+ </listitem>
+
+ <listitem>
+ <para>The file
+ <emphasis>exo.portal.sample.portal.jar-X.Y.Z.jar</emphasis>
+ which is the file in which we have internal classes that are
+ actualy a set of sample classes <emphasis>(SampleFilter,
+ SampleContextInitializedListener,
+ SampleContextDestroyedListener,
+ SampleHttpSessionCreatedListener and
+ SampleHttpSessionDestroyedListener)</emphasis></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Add the file <emphasis>starter.ear</emphasis> from
+ starter/ear/target/ to the deploy directory of JBoss, this file
+ contains:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The file <emphasis>starter.war</emphasis> which is the
+ web application that will create and start all the portal
+ containers, that is why it must be launched after all the
+ other web applications.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Define the related application policy in your file
+ <emphasis>conf/login-config.xml</emphasis>, as below:</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting> <application-policy name="exo-domain-sample-portal">
+ <authentication>
+ <login-module code="org.exoplatform.web.security.PortalLoginModule" flag="required">
+ <module-option name="portalContainerName">sample-portal</module-option>
+ <module-option name="realmName">exo-domain-sample-portal</module-option>
+ </login-module>
+ <login-module code="org.exoplatform.services.security.jaas.SharedStateLoginModule" flag="required">
+ <module-option name="portalContainerName">sample-portal</module-option>
+ <module-option name="realmName">exo-domain-sample-portal</module-option>
+ </login-module>
+ <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required">
+ <module-option name="portalContainerName">sample-portal</module-option>
+ <module-option name="realmName">exo-domain-sample-portal</module-option>
+ </login-module>
+ </authentication>
+ </application-policy></programlisting>
+
+ <warning>
+ <title>Warning #1</title>
+
+ <para>This can only work if a Unified ClassLoader has been
+ configured on your JBoss (default behavior) and the load order is
+ first the <emphasis>exoplatform.ear</emphasis> then the
+ <emphasis>sample-portal.ear</emphasis> and finally the
+ <emphasis>starter.ear</emphasis>.</para>
+ </warning>
+
+ <warning>
+ <title>Warning #2</title>
+
+ <para>The file <emphasis>starter.ear</emphasis> must always been
+ started last.</para>
+ </warning>
+ </section>
+
+ <section>
+ <title>On Tomcat (tested on Tomcat 6.0.20)</title>
+
+ <para>We assume that you have a clean Tomcat version of GateIn, in
+ other words, we assume that you have already all the jar files of
+ GateIn and their dependencies into <emphasis>tomcat/lib</emphasis>,
+ you have all the war files of GateIn into
+ <emphasis>tomcat/webapps</emphasis> and you have the realm name
+ "exo-domain" defined into the file
+ <emphasis>tomcat/conf/jaas.conf</emphasis>.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the file <emphasis>sample-portal.war</emphasis> from
+ sample/portal/war/target/ to the
+ <emphasis>tomcat/webapps</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the file <emphasis>rest-sample-portal.war</emphasis>
+ from sample/portal/rest-war/target/ to the
+ <emphasis>tomcat/webapps</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the folder <emphasis>starter</emphasis> from
+ starter/war/target/ to the <emphasis>tomcat/webapps</emphasis>
+ directory. <emphasis>(See the purpose of this file in the JBoss
+ section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the directory (unzipped folder)
+ <emphasis>starter</emphasis> to <emphasis>starter.war</emphasis>
+ <emphasis>(for more details see the warning
+ below)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the jar file
+ <emphasis>exo.portal.sample.portal.config-X.Y.Z.jar</emphasis>
+ from sample/portal/config/target/ to the
+ <emphasis>tomcat/lib</emphasis> directory. <emphasis>(See the
+ purpose of this file in the JBoss section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add the jar file
+ <emphasis>exo.portal.sample.portal.jar-X.Y.Z.jar</emphasis> from
+ sample/portal/jar/target/ to the <emphasis>tomcat/lib</emphasis>
+ directory. <emphasis>(See the purpose of this file in the JBoss
+ section)</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Define the related realm in your file
+ <emphasis>tomcat/conf/jaas.conf</emphasis>, as below:</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <title>tomcat/conf/jaas.conf</title>
+
+ <programlisting>...
+exo-domain-sample-portal {
+ org.exoplatform.web.security.PortalLoginModule required
+ portalContainerName="sample-portal"
+ realmName="exo-domain-sample-portal";
+ org.exoplatform.services.security.jaas.SharedStateLoginModule required
+ portalContainerName="sample-portal"
+ realmName="exo-domain-sample-portal";
+ org.exoplatform.services.security.j2ee.TomcatLoginModule required
+ portalContainerName="sample-portal"
+ realmName="exo-domain-sample-portal";
+};</programlisting>
+ </note>
+
+ <itemizedlist>
+ <listitem>
+ <para>Define the context of <emphasis>sample-portal</emphasis> by
+ creating a file called <emphasis>sample-portal.xml</emphasis> into
+ <emphasis>tomcat/conf/Catalina/localhost/</emphasis> with the
+ following content:</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <title>tomcat/conf/Catalina/localhost/sample-portal.xml</title>
+
+ <programlisting><Context path='/sample-portal' docBase='sample-portal' debug='0' reloadable='true' crossContext='true' privileged='true'>
+ <Logger className='org.apache.catalina.logger.SystemOutLogger'
+ prefix='localhost_portal_log.' suffix='.txt' timestamp='true'/>
+ <Manager className='org.apache.catalina.session.PersistentManager' saveOnRestart='false'/>
+ <Realm className='org.apache.catalina.realm.JAASRealm'
+ appName='exo-domain-sample-portal'
+ userClassNames='org.exoplatform.services.security.jaas.UserPrincipal'
+ roleClassNames='org.exoplatform.services.security.jaas.RolePrincipal'
+ debug='0' cache='false'/>
+ <Valve className='org.apache.catalina.authenticator.FormAuthenticator' characterEncoding='UTF-8'/></Context></programlisting>
+ </note>
+
+ <itemizedlist>
+ <listitem>
+ <para>Define the context of
+ <emphasis>rest-sample-portal</emphasis> by creating a file called
+ <emphasis>rest-sample-portal.xml</emphasis> into
+ <emphasis>tomcat/conf/Catalina/localhost/</emphasis> with the
+ following content:</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <title>tomcat/conf/Catalina/localhost/rest-sample-portal.xml</title>
+
+ <programlisting><Context path="/rest-sample-portal" docBase="rest-sample-portal" reloadable="true" crossContext="false">
+
+ <Logger className='org.apache.catalina.logger.SystemOutLogger'
+ prefix='localhost_portal_log.' suffix='.txt' timestamp='true'/>
+ <Manager className='org.apache.catalina.session.PersistentManager' saveOnRestart='false'/>
+ <Realm className='org.apache.catalina.realm.JAASRealm'
+ appName='exo-domain-sample-portal'
+ userClassNames="org.exoplatform.services.security.jaas.UserPrincipal"
+ roleClassNames="org.exoplatform.services.security.jaas.RolePrincipal"
+ debug='0' cache='false'/>
+</Context></programlisting>
+ </note>
+
+ <warning>
+ <title>Warning</title>
+
+ <para>This can only work if the <emphasis>starter.war</emphasis> is
+ the last war file to be loaded, so don't hesitate to rename it if
+ your war files are loaded following to the alphabetic order.</para>
+ </warning>
+ </section>
+ </section>
+
+ <section>
+ <title>I get "java.lang.IllegalStateException: No pre init tasks can be
+ added to the portal container 'portal', because it has already been
+ initialized." what can I do to fix it?</title>
+
+ <para>To fix this issue you need to check if:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The file <emphasis>starter-gatein.ear</emphasis> (which will
+ be <emphasis>starter.war</emphasis> for Tomcat) has been
+ deployed</para>
+ </listitem>
+
+ <listitem>
+ <para>The file <emphasis>starter-gatein.ear</emphasis> (which will
+ be <emphasis>starter.war</emphasis> for Tomcat) is the last ear file
+ to be launched</para>
+ </listitem>
+ </orderedlist>
+
+ <note>
+ <title>Note</title>
+
+ <para>With Tomcat to prevent any alphabetic issue, the good way to
+ solve this problem is to:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Unzip the archive <emphasis>starter.war</emphasis> into a
+ directory called <emphasis>starter</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Remove the archive <emphasis>starter.war</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Rename the folder <emphasis>starter</emphasis> to
+ <emphasis>starter.war</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This tip works because folders corresponding to unzipped wars
+ are launched after war files.</para>
+ </note>
+ </section>
+ </section>
+
+ <section>
+ <title>Recommendations</title>
+
+ <section>
+ <title>Don't ship your configuration files with your jar files?</title>
+
+ <para>Remove all the configuration files from the jar files (
+ <emphasis>conf/configuration.xml</emphasis> and
+ <emphasis>conf/portal/configuration.xml</emphasis>) and move them to the
+ war file of your extension, otherwise your configuration files will be
+ loaded for all the portal containers which could cause incompatibility
+ issues with other portals.</para>
+
+ <para>Each extension should manage independently, its css files, js
+ files, google gadgets and configuration files. If you add configuration
+ files into the jar files of your extension, you brake this law.</para>
+ </section>
+
+ <section>
+ <title>Use a dedicated workspace/repository for your extension?</title>
+
+ <para>In order to avoid conflicts with other extensions and to manage
+ each extension independently, it is highly recommended to use a
+ dedicated workspace or repository per extension.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/managed-datasources-under-jboss-as.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/managed-datasources-under-jboss-as.xml (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr-with-gtn/managed-datasources-under-jboss-as.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -0,0 +1,102 @@
+<?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="JCRWithGateIn.HowToUseDataSourceUnderJBoss">
+ <title>How to use AS Managed DataSource under JBoss AS</title>
+
+ <?dbhtml filename="ch-how-to-use-managed-datasource-under-jboss.html"?>
+
+ <section>
+ <title>Configurations Steps</title>
+
+ <important>
+ <para>Checked under Gatein 3.1.0-GA Final</para>
+ </important>
+
+ <important>
+ <para>only no-tx-datasource is supported in JCR 1.12</para>
+ </important>
+
+ <section>
+ <title>Declaring the datasources in the AS</title>
+
+ <para>Under JBoss, just put a file XXX-ds.xml in the deploy server
+ (example: \server\default\deploy). In this file we will configure all
+ datasources which eXo will need. (there should be 4 named:
+ jdbcjcr_portal, jdbcjcr_portal-sample, jdbcidm_portal &
+ jdbcidm_sample-portal).</para>
+
+ <para>Example:<programlisting><?xml version="1.0" encoding="UTF-8"?>
+<datasources>
+ <no-tx-datasource>
+ <jndi-name>jdbcjcr_portal</jndi-name>
+ <connection-url>jdbc:hsqldb:${jboss.server.data.dir}/data/jdbcjcr_portal</connection-url>
+ <driver-class>org.hsqldb.jdbcDriver</driver-class>
+ <user-name>sa</user-name>
+ <password></password>
+ </no-tx-datasource>
+
+ <no-tx-datasource>
+ <jndi-name>jdbcjcr_sample-portal</jndi-name>
+ <connection-url>jdbc:hsqldb:${jboss.server.data.dir}/data/jdbcjcr_sample-portal</connection-url>
+ <driver-class>org.hsqldb.jdbcDriver</driver-class>
+ <user-name>sa</user-name>
+ <password></password>
+ </no-tx-datasource>
+
+ <no-tx-datasource>
+ <jndi-name>jdbcidm_portal</jndi-name>
+ <connection-url>jdbc:hsqldb:${jboss.server.data.dir}/data/jdbcidm_portal</connection-url>
+ <driver-class>org.hsqldb.jdbcDriver</driver-class>
+ <user-name>sa</user-name>
+ <password></password>
+ </no-tx-datasource>
+
+ <no-tx-datasource>
+ <jndi-name>jdbcidm_sample-portal</jndi-name>
+ <connection-url>jdbc:hsqldb:${jboss.server.data.dir}/data/jdbcidm_sample-portal</connection-url>
+ <driver-class>org.hsqldb.jdbcDriver</driver-class>
+ <user-name>sa</user-name>
+ <password></password>
+ </no-tx-datasource>
+</datasources></programlisting></para>
+
+ <para>Which properties can be set for datasource can be found here:
+ <ulink
+ url="http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/Conn...">Configuring
+ JDBC DataSources - The non transactional DataSource configuration
+ schema</ulink></para>
+ </section>
+
+ <section>
+ <title>Do not let eXo bind datasources explicitly</title>
+
+ <para>Edit server/default/conf/gatein/configuration.properties and
+ comment out next rows in JCR section:</para>
+
+ <programlisting>#gatein.jcr.datasource.driver=org.hsqldb.jdbcDriver
+#gatein.jcr.datasource.url=jdbc:hsqldb:file:${gatein.db.data.dir}/data/jdbcjcr_${name}
+#gatein.jcr.datasource.username=sa
+#gatein.jcr.datasource.password=</programlisting>
+
+ <para>and in IDM section:</para>
+
+ <programlisting>#gatein.idm.datasource.driver=org.hsqldb.jdbcDriver
+#gatein.idm.datasource.url=jdbc:hsqldb:file:${gatein.db.data.dir}/data/jdbcidm_${name}
+#gatein.idm.datasource.username=sa
+#gatein.idm.datasource.password=</programlisting>
+
+ <para>In jcr-configuration.xml and idm-configuration.xml comment out the
+ plugin InitialContextInitializer.</para>
+
+ <programlisting><!-- Commented because, Datasources are declared and bound by AS, not in eXo -->
+<!--
+<external-component-plugins>
+ [...]
+</external-component-plugins>
+--></programlisting>
+
+ <para>Running eXo after these configurations goes well.</para>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-23 12:02:15 UTC (rev 2969)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-23 12:17:50 UTC (rev 2970)
@@ -148,4 +148,7 @@
<xi:include href="jcr/data-container-howto.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <!-- tuning guide -->
+ <xi:include href="jcr/performance-tuning-guide.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results_2.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/resources/images/perf_EC2_results_2.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
13 years, 10 months
exo-jcr SVN: r2969 - jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-08-23 08:02:15 -0400 (Mon, 23 Aug 2010)
New Revision: 2969
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberCache.java
Log:
EXOJCR-913: move DocNumberCache.get() logging in debug level
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberCache.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberCache.java 2010-08-23 10:23:16 UTC (rev 2968)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/DocNumberCache.java 2010-08-23 12:02:15 UTC (rev 2969)
@@ -150,7 +150,7 @@
{
entry = (Entry)cacheSegment.get(key);
}
- if (log.isInfoEnabled())
+ if (log.isDebugEnabled())
{
accesses++;
if (entry == null)
@@ -177,7 +177,7 @@
statistics.append(", #hits=").append((accesses - misses));
statistics.append(", #misses=").append(misses);
statistics.append(", cacheRatio=").append(ratio).append("%");
- log.info(statistics.toString());
+ log.debug(statistics.toString());
accesses = 0;
misses = 0;
lastLog = System.currentTimeMillis();
13 years, 10 months
exo-jcr SVN: r2968 - in jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules: jcr/backup and 3 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-23 06:23:16 -0400 (Mon, 23 Aug 2010)
New Revision: 2968
Modified:
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
Log:
EXOJCR-912: ids and xml injection fixed
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-23 07:45:14 UTC (rev 2967)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-23 10:23:16 UTC (rev 2968)
@@ -1,477 +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>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>
+ <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/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml 2010-08-23 07:45:14 UTC (rev 2967)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml 2010-08-23 10:23:16 UTC (rev 2968)
@@ -1,141 +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">
-<chapter id="JCR.RegistryService">
- <?dbhtml filename="ch-jcr-registry-service.html"?>
-
- <title>Registry Service</title>
-
- <section id="Concept">
- <title>Concept</title>
-
- <para>The Registry Service is one of the key parts of the infrastructure
- built around eXo JCR. Each JCR based service, applications etc may have
- its own configuration and settings data and other data that have to be
- stored persistently and used by the approptiate service or application
- (let's call it <emphasis role="bold">Consumer</emphasis>).</para>
-
- <para>The service acts as a centralized collector (Registry) for such
- data. Naturally, a registry storage is JCR based i.e. stored in some JCR
- workspace (one per Repository) as an Item tree under <emphasis
- role="bold">/exo:registry</emphasis> node.</para>
-
- <para>Despite the fact that the structure of the tree is well defined (see
- the scheme below), it is not recommended for other services to manipulate
- data using JCR API directly for better flexibility. So the Registry
- Service acts as a mediator between a Consumer and its settings.</para>
-
- <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)
- exo:services/ <-- service data storage (exo:registryGroup)
- service1/
- Consumer data (exo:registryEntry)
- ...
- exo:applications/ <-- application data storage (exo:registryGroup)
- app1/
- Consumer data (exo:registryEntry)
- ...
- exo:users/ <-- user personal data storage (exo:registryGroup)
- user1/
- Consumer data (exo:registryEntry)
- ...</programlisting>
-
- <para>Each upper level eXo Service may store its configuration in Exo
- Registry. First time start from xml-config (in jar etc). Each next will be
- from Registry. In configuration file you can add force-xml-configuration
- parameter to component to ignore reading parameters initialization from
- RegistryService and to use file instead:</para>
-
- <programlisting><value-param>
- <name>force-xml-configuration</name>
- <value>true</value>
-</value-param></programlisting>
- </section>
-
- <section>
- <title>The API</title>
-
- <para>The main functionality of the Registry Service is pretty simple and
- straightforward, it is described in the Registry abstract class as
- following:</para>
-
- <programlisting>public abstract class Registry {
-
- /**
- * Returns the Registry object which wraps the Node of the "exo:registry" type
- */
- public abstract RegistryNode getRegistry(SessionProvider sessionProvider)
- throws RepositoryConfigurationException, RepositoryException;
-
- /**
- * Returns the existing RegistryEntry which wraps the Node of the "exo:registryEntry" type
- */
- public abstract RegistryEntry getEntry(SessionProvider sessionProvider, String groupName,
- String entryName) throws RepositoryException;
-
- /**
- * Creates a new RegistryEntry
- */
- public abstract void createEntry(SessionProvider sessionProvider,
- String groupName, RegistryEntry entry) throws RepositoryException;
-
- /**
- * Replaces a RegistryEntry
- */
- public abstract void recreateEntry(SessionProvider sessionProvider,
- String groupName, RegistryEntry entry) throws RepositoryException;
-
- /**
- * Removes a RegistryEntry
- */
- public abstract void removeEntry(SessionProvider sessionProvider,
- String groupName, String entryName) throws RepositoryException;</programlisting>
-
- <para>As you can see it mainly looks like a simple CRUD interface for the
- RegistryEntry object which wraps registry data for some Consumer as a
- Registry Entry. The Registry Service itself knows nothing about the
- wrapping data, it is Consumer's responsibility to manage and use its data
- in its own way.</para>
-
- <para>To create an Entity Consumer you should have an idea how to
- serialize the data to some XML structure and then create a RegistryEntry
- from these data at once or populate them in a RegistryEntry object (using
- RegistryEntry(String entryName) constructor and then obtain and fill a DOM
- document).</para>
-
- <para>Example of RegistryService using:</para>
-
- <programlisting> RegistryService regService = (RegistryService) container
- .getComponentInstanceOfType(RegistryService.class);
-
- RegistryEntry registryEntry = regService.getEntry(sessionProvider,
- RegistryService.EXO_SERVICES, "my-service");
-
- Document doc = registryEntry.getDocument();
-
- String mySetting = getElementsByTagName("tagname").item(index).getTextContent();
- .....</programlisting>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <para>RegistryService has only one optional properties parameter <emphasis
- role="bold">locations</emphasis>. It is used to mention where exo:registry
- is placed for each repository. The name of each property is interpreted as
- a repository name and its value as a workspace name (a system workspace by
- default).</para>
-
- <programlisting><component>
- <type>org.exoplatform.services.jcr.ext.registry.RegistryService</type>
- <init-params>
- <properties-param>
- <name>locations</name>
- <property name="db1" value="ws2"/>
- </properties-param>
- </init-params>
-</component></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.RegistryService">
+ <?dbhtml filename="ch-jcr-registry-service.html"?>
+
+ <title>Registry Service</title>
+
+ <section>
+ <title>Concept</title>
+
+ <para>The Registry Service is one of the key parts of the infrastructure
+ built around eXo JCR. Each JCR based service, applications etc may have
+ its own configuration and settings data and other data that have to be
+ stored persistently and used by the approptiate service or application
+ (let's call it <emphasis role="bold">Consumer</emphasis>).</para>
+
+ <para>The service acts as a centralized collector (Registry) for such
+ data. Naturally, a registry storage is JCR based i.e. stored in some JCR
+ workspace (one per Repository) as an Item tree under <emphasis
+ role="bold">/exo:registry</emphasis> node.</para>
+
+ <para>Despite the fact that the structure of the tree is well defined (see
+ the scheme below), it is not recommended for other services to manipulate
+ data using JCR API directly for better flexibility. So the Registry
+ Service acts as a mediator between a Consumer and its settings.</para>
+
+ <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)
+ exo:services/ <-- service data storage (exo:registryGroup)
+ service1/
+ Consumer data (exo:registryEntry)
+ ...
+ exo:applications/ <-- application data storage (exo:registryGroup)
+ app1/
+ Consumer data (exo:registryEntry)
+ ...
+ exo:users/ <-- user personal data storage (exo:registryGroup)
+ user1/
+ Consumer data (exo:registryEntry)
+ ...</programlisting>
+
+ <para>Each upper level eXo Service may store its configuration in Exo
+ Registry. First time start from xml-config (in jar etc). Each next will be
+ from Registry. In configuration file you can add force-xml-configuration
+ parameter to component to ignore reading parameters initialization from
+ RegistryService and to use file instead:</para>
+
+ <programlisting><value-param>
+ <name>force-xml-configuration</name>
+ <value>true</value>
+</value-param></programlisting>
+ </section>
+
+ <section>
+ <title>The API</title>
+
+ <para>The main functionality of the Registry Service is pretty simple and
+ straightforward, it is described in the Registry abstract class as
+ following:</para>
+
+ <programlisting>public abstract class Registry {
+
+ /**
+ * Returns the Registry object which wraps the Node of the "exo:registry" type
+ */
+ public abstract RegistryNode getRegistry(SessionProvider sessionProvider)
+ throws RepositoryConfigurationException, RepositoryException;
+
+ /**
+ * Returns the existing RegistryEntry which wraps the Node of the "exo:registryEntry" type
+ */
+ public abstract RegistryEntry getEntry(SessionProvider sessionProvider, String groupName,
+ String entryName) throws RepositoryException;
+
+ /**
+ * Creates a new RegistryEntry
+ */
+ public abstract void createEntry(SessionProvider sessionProvider,
+ String groupName, RegistryEntry entry) throws RepositoryException;
+
+ /**
+ * Replaces a RegistryEntry
+ */
+ public abstract void recreateEntry(SessionProvider sessionProvider,
+ String groupName, RegistryEntry entry) throws RepositoryException;
+
+ /**
+ * Removes a RegistryEntry
+ */
+ public abstract void removeEntry(SessionProvider sessionProvider,
+ String groupName, String entryName) throws RepositoryException;</programlisting>
+
+ <para>As you can see it mainly looks like a simple CRUD interface for the
+ RegistryEntry object which wraps registry data for some Consumer as a
+ Registry Entry. The Registry Service itself knows nothing about the
+ wrapping data, it is Consumer's responsibility to manage and use its data
+ in its own way.</para>
+
+ <para>To create an Entity Consumer you should have an idea how to
+ serialize the data to some XML structure and then create a RegistryEntry
+ from these data at once or populate them in a RegistryEntry object (using
+ RegistryEntry(String entryName) constructor and then obtain and fill a DOM
+ document).</para>
+
+ <para>Example of RegistryService using:</para>
+
+ <programlisting> RegistryService regService = (RegistryService) container
+ .getComponentInstanceOfType(RegistryService.class);
+
+ RegistryEntry registryEntry = regService.getEntry(sessionProvider,
+ RegistryService.EXO_SERVICES, "my-service");
+
+ Document doc = registryEntry.getDocument();
+
+ String mySetting = getElementsByTagName("tagname").item(index).getTextContent();
+ .....</programlisting>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>RegistryService has only one optional properties parameter <emphasis
+ role="bold">locations</emphasis>. It is used to mention where exo:registry
+ is placed for each repository. The name of each property is interpreted as
+ a repository name and its value as a workspace name (a system workspace by
+ default).</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.jcr.ext.registry.RegistryService</type>
+ <init-params>
+ <properties-param>
+ <name>locations</name>
+ <property name="db1" value="ws2"/>
+ </properties-param>
+ </init-params>
+</component></programlisting>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml 2010-08-23 07:45:14 UTC (rev 2967)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/data-container.xml 2010-08-23 10:23:16 UTC (rev 2968)
@@ -2,7 +2,7 @@
<chapter id="JCR.WorkspaceDataContainer">
<?dbhtml filename="ch-data-container.html"?>
<title>JCR Workspace Data Container (architecture contract)</title>
- <section id="Goals">
+ <section>
<title>Goals</title>
<itemizedlist>
<listitem>
@@ -16,9 +16,9 @@
</listitem>
</itemizedlist>
</section>
- <section id="Concepts">
+ <section>
<title>Concepts</title>
- <section id="Containerandconnection">
+ <section>
<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
@@ -76,7 +76,7 @@
change parameters. Configuration consists of implementation class and set of properties and Value Storages
configuration.</para>
</section>
- <section id="Valuestorages">
+ <section>
<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).
@@ -90,7 +90,7 @@
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">
+ <section>
<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.
@@ -99,7 +99,7 @@
guaranties transaction support for write operations.
Commit or rollback should free/clean all resources consumed by the container (connection).</para>
</section>
- <section id="Valuestoragelifecycle">
+ <section>
<title>Value storage lifecycle</title>
<para>Value storage used from the container inside. Reads are related to a container reads. Writes are commit
related.
@@ -107,11 +107,11 @@
operations.</para>
</section>
</section>
- <section id="Requirements">
+ <section>
<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">
+ <section>
<title>Read operations</title>
<itemizedlist>
<listitem>
@@ -158,7 +158,7 @@
<programlisting>List<PropertyData> getReferencesData(String nodeIdentifier) throws RepositoryException,IllegalStateException,UnsupportedOperationException;
</programlisting>
</section>
- <section id="Writeoperations">
+ <section>
<title>Write operations</title>
<itemizedlist>
<listitem>
@@ -227,7 +227,7 @@
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">
+ <section>
<title>State operations</title>
<itemizedlist>
<listitem>
@@ -237,7 +237,7 @@
<programlisting>boolean isOpened();
</programlisting>
</section>
- <section id="Validationofwriteoperations">
+ <section>
<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)
@@ -285,7 +285,7 @@
</listitem>
</itemizedlist>
</section>
- <section id="Consistencyofsave">
+ <section>
<title>Consistency of save</title>
<para>The container (connection) should implement consistency of Commit (Rollback) in
<emphasis role="bold">transaction manner</emphasis>.
@@ -298,9 +298,9 @@
</para>
</section>
</section>
- <section id="ValuestoragesAPI">
+ <section>
<title>Value storages API</title>
- <section id="Storagesprovider">
+ <section>
<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>
@@ -319,7 +319,7 @@
</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">
+ <section>
<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>
@@ -345,7 +345,7 @@
<programlisting>public abstract boolean isSame(String valueDataDescriptor);
</programlisting>
</section>
- <section id="ValueIOchannel">
+ <section>
<title>Value I/O channel</title>
<para>Channel should implement ValueIOChannel interface. CRUD operation for Value Storage:</para>
<itemizedlist>
@@ -370,7 +370,7 @@
<programlisting>void delete(String propertyId) throws IOException;
</programlisting>
</section>
- <section id="Transactionsupportviachannel">
+ <section>
<title>Transaction support via channel</title>
<para>Modification operations should be applied only on commit. Rollback is required for data created cleanup.</para>
<itemizedlist>
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-23 07:45:14 UTC (rev 2967)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-23 10:23:16 UTC (rev 2968)
@@ -1,414 +1,405 @@
-<?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>
+<?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="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" />
+
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-23 07:45:14 UTC (rev 2967)
+++ jcr/branches/1.12.x/exo.jcr.docs/exo.jcr.docs.developer/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-23 10:23:16 UTC (rev 2968)
@@ -1,704 +1,704 @@
-<?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.ServiceConfigurationinDetail">
- <?dbhtml filename="ch-service-configuration-in-detail.html"?>
-
- <title>Service Configuration in Detail</title>
-
- <para><emphasis role="bold">Related documents</emphasis></para>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="Kernel.ServiceConfigurationforBeginners">Service
- Configuration for Beginners</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="Kernel.ServicesWiring">Services
- Wiring</link></para>
- </listitem>
-
- <listitem>
- <para><link
- linkend="Kernel.ContainerConfiguration.ConfigurationNamespace">Kernel
- Configuration File</link></para>
- </listitem>
- </itemizedlist>
-
- <section id="Objectives">
- <title>Objectives</title>
-
- <para>This article shows in the first chapters how to setup a sample
- service with some configurations and how to access to the configuration
- parameters. The later chapters describe all details of the configuration
- file (parameters, object-params, plugins, imports, etc.) it also shows how
- to access the configuration values. You may consider this article as a
- <emphasis role="bold">reference</emphasis>, but you can also use this
- article as a <emphasis role="bold">tutorial</emphasis> and read it from
- the beginning to the end.</para>
- </section>
-
- <section id="Requirements">
- <title>Requirements</title>
-
- <para>You should have read and understood <link
- 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">
- <title>Sample Service</title>
-
- <section id="JavaClass">
- <title>Java Class</title>
-
- <para>Imagine you are working for a publishing company called "La
- Verdad" that is going to use eXo platform. Your boss asks you be able to
- calculate the number of sentences of an article.</para>
-
- <para>You remember in eXo product everything is a <emphasis
- role="bold">service</emphasis> so you decide to create a simple class.
- In future you want to be able to plug different implementations of your
- service, so that you should define an <emphasis
- role="bold">interface</emphasis> that defines your service.</para>
-
- <programlisting>package com.laverdad.services;
-public interface ArticleStatsService {
- public abstract int calcSentences(String article);
-}</programlisting>
-
- <para>A very simple implementation:</para>
-
- <programlisting>public class ArticleStatsServiceImpl implements ArticleStatsService {
- public int calcSentences(String article) {
- throw new RuntimeException("Not implemented");
- }
-}</programlisting>
-
- <para>That's it! You see there are no special prerequisites for a
- service.</para>
-
- <para>You should already have prepared your working environment, where
- you have a base folder (let's call it our service base folder). If you
- wish to try out this example create this class in the
- com/laverdad/services/ArticleStatsService subfolder.</para>
- </section>
-
- <section id="Firstconfigurationfile">
- <title>First configuration file</title>
-
- <para>When creating a service you also should declare its existence to
- the <emphasis role="bold">Container</emphasis>, therefore you create a
- first simple configuration file. Copy the following code to a file that
- is called "configuration.xml" and place this file in a /conf
- subdirectory of your service base folder. As you already know the
- container looks for a "/conf/configuration.xml" file in each
- jar-file.</para>
-
- <programlisting><?xml version="1.0" encoding="UTF8"?>
-<configuration
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
- xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
- <component>
- <key>com.laverdad.services.ArticleStatsService</key>
- <type>com.laverdad.services.ArticleStatsServiceImpl</type>
- </component>
-</configuration></programlisting>
-
- <note>
- <para>You are correctly using the namespace of the configuration
- schema ( <uri>http://www.exoplaform.org/xml/ns/kernel_1_1.xsd</uri>).
- Most of the configuration schema is explained in this
- articles,therefore you do not need to open and understand the schema.
- For backward compatibility it is not necessary to declare the
- schema.</para>
-
- <para>When eXo kernel reads a configuration it loads the file from the
- kernel jar using the classloader and does not use an internet
- connection to resolve the file.</para>
- </note>
- </section>
-
- <section id="InitParameters">
- <title>Init Parameters</title>
-
- <para>You see your service has a configuration file, but you wonder how
- the file could possibly access to its configuration. Imagine you are
- asked to implement two different calculation methods: fast and
- exact.</para>
-
- <para>You create one init parameter containing the calculation methods.
- For the exact method you wish to configure more details for the service.
- Let's enhance the word service configuration file:</para>
-
- <programlisting> <component>
- <key>com.laverdad.services.ArticleStatsService</key>
- <type>com.laverdad.services.ArticleStatsServiceImpl</type>
- <init-params>
- <value-param>
- <name>calc-method</name>
- <description>calculation method: fast, exact</description>
- <value>fast</value>
- </value-param>
- <properties-param>
- <name>details-for-exact-method</name>
- <description>details for exact phrase counting</description>
- <property name="language" value="English" />
- <property name="variant" value="us" />
- </properties-param>
- </init-params>
- </component></programlisting>
-
- <note>
- <para>When configuring your service, you are <emphasis
- role="bold">totally free</emphasis>. You can provide as many <emphasis
- role="bold">value-param</emphasis>, <emphasis
- role="bold">property-param</emphasis>, and <emphasis
- role="bold">properties</emphasis> you wish and you can give them any
- names or values. You only must respect the xml structure.</para>
- </note>
-
- <para>Now let's see how our service can read this configuration. The
- implementation of the calcSentences() method serves just as a simple
- example. It's up to your imagination to implement the exact
- method.</para>
-
- <programlisting>public class ArticleStatsServiceImpl implements ArticleStatsService {
-
- private String calcMethod = "fast";
- private String variant = "French";
- private String language = "France";
-
- public ArticleStatsServiceImpl(InitParams initParams) {
- super();
- calcMethod = initParams.getValueParam("calc-method").getValue();
- PropertiesParam detailsForExactMethod = initParams.getPropertiesParam("details-for-exact-method");
- if ( detailsForExactMethod != null) {
- language = detailsForExactMethod.getProperty("language");
- variant = detailsForExactMethod.getProperty("variant");
- }
- }
-
- public int calcSentences(String article) {
- if (calcMethod == "fast") {
- // just count the number of periods "."
- int res = 0;
- int period = article.indexOf('.');
- while (period != -1) {
- res++;
- article = article.substring(period+1);
- period = article.indexOf('.');
- }
- return res;
- }
- throw new RuntimeException("Not implemented");
- }
-}</programlisting>
-
- <para>You see you just have to declare a parameter of
- org.exoplatform.container.xml.InitParams in your constructor. The
- container provides an InitParams object that correspond to the xml tree
- of init-param.</para>
- </section>
-
- <section id="ServiceAccess">
- <title>Service Access</title>
-
- <para>As you want to follow the principle of <emphasis
- role="bold">Inversion of Control</emphasis> you <emphasis
- role="bold">must not</emphasis> access the service directly. You need a
- <emphasis role="bold">Container</emphasis> to access the service.</para>
-
- <para>With this command you get your current container:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">ExoContainer myContainer =
- ExoContainerContext.getCurrentContainer();</emphasis></para>
- </listitem>
- </itemizedlist>
-
- <para>This might be a PortalContainer or a StandaloneContainer,
- dependant on the <link
- linkend="Kernel.ServiceConfigurationinDetail.ExecutionModes">execution
- mode</link> in which you are running your application.</para>
-
- <para>Whenever you need one of the services that you have configured use
- the method:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis
- role="bold">myContainer.getComponentInstance(class)</emphasis></para>
- </listitem>
- </itemizedlist>
-
- <para>In our case:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">ArticleStatsService statsService =
- (ArticleStatsService)
- myContainer.getComponentInstance(ArticleStatsService.class);</emphasis></para>
- </listitem>
- </itemizedlist>
-
- <para>Recapitulation:</para>
-
- <programlisting>package com.laverdad.common;
-
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
-import com.laverdad.services.*;
-
-public class Statistics {
-
- public int makeStatistics(String articleText) {
- ExoContainer myContainer = ExoContainerContext.getCurrentContainer();
- ArticleStatsService statsService = (ArticleStatsService)
- myContainer.getComponentInstance(ArticleStatsService.class);
- int numberOfSentences = statsService.calcSentences(articleText);
- return numberOfSentences;
- }
-
- public static void main( String args[]) {
- Statistics stats = new Statistics();
- String newText = "This is a normal text. The method only counts the number of periods. "
- + "You can implement your own implementation with a more exact counting. "
- + "Let`s make a last sentence.";
- System.out.println("Number of sentences: " + stats.makeStatistics(newText));
- }
-}</programlisting>
-
- <para>If you test this sample in standalone mode, you need to put all
- jars of eXo Kernel in your buildpath, furthermore picoContainer is
- needed.</para>
- </section>
- </section>
-
- <section id="Parameters">
- <title>Parameters</title>
-
- <section id="ValueParam">
- <title>Value-Param</title>
-
- <para>There is an value-param example:</para>
-
- <programlisting> <component>
- <key>org.exoplatform.portal.config.UserACL</key>
- <type>org.exoplatform.portal.config.UserACL</type>
- <init-params>
-...
- <value-param>
- <name>access.control.workspace</name>
- <description>groups with memberships that have the right to access the User Control Workspace</description>
- <value>*:/platform/administrators,*:/organization/management/executive-board</value>
- </value-param>
-...
- </component></programlisting>
-
- <para>The UserACL class accesses to the <emphasis
- role="bold">value-param</emphasis> in its constructor.</para>
-
- <programlisting>package org.exoplatform.portal.config;
-public class UserACL {
-
- public UserACL(InitParams params) {
- UserACLMetaData md = new UserACLMetaData();
- ValueParam accessControlWorkspaceParam = params.getValueParam("access.control.workspace");
- if(accessControlWorkspaceParam != null) md.setAccessControlWorkspace(accessControlWorkspaceParam.getValue());
-...</programlisting>
- </section>
-
- <section id="PropertiesParam">
- <title>Properties-Param</title>
-
- <para>Properties are name-value pairs. Both the name and the value are
- Java Strings.</para>
-
- <para>Here you see the hibernate configuration example:</para>
-
- <programlisting> <component>
- <key>org.exoplatform.services.database.HibernateService</key>
- <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
- <init-params>
- <properties-param>
- <name>hibernate.properties</name>
- <description>Default Hibernate Service</description>
- <property name="hibernate.show_sql" value="false"/>
- <property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
- <property name="hibernate.connection.url" value="jdbc:hsqldb:file:../temp/data/exodb"/>
- <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
-...
- </properties-param>
- </init-params>
- </component></programlisting>
-
- <para>In the org.exoplatform.services.database.impl.HibernateServiceImpl
- you will find that the name "hibernate.properties" of the
- properties-param is used to access the properties.</para>
-
- <programlisting>package org.exoplatform.services.database.impl;
-
-public class HibernateServiceImpl implements HibernateService, ComponentRequestLifecycle {
- public HibernateServiceImpl(InitParams initParams, CacheService cacheService) {
- PropertiesParam param = initParams.getPropertiesParam("hibernate.properties");
-...
-}</programlisting>
- </section>
-
- <section id="ObjectParam">
- <title>Object-Param</title>
-
- <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>
- <key>org.exoplatform.services.ldap.LDAPService</key>
- <type>org.exoplatform.services.ldap.impl.LDAPServiceImpl</type>
- <init-params>
- <object-param>
- <name>ldap.config</name>
- <description>Default ldap config</description>
- <object type="org.exoplatform.services.ldap.impl.LDAPConnectionConfig">
- <field name="providerURL"><string>ldaps://10.0.0.3:636</string></field>
- <field name="rootdn"><string>CN=Administrator,CN=Users,DC=exoplatform,DC=org</string></field>
- <field name="password"><string>exo</string></field>
- <field name="version"><string>3</string></field>
- <field name="minConnection"><int>5</int></field>
- <field name="maxConnection"><int>10</int></field>
- <field name="referralMode"><string>ignore</string></field>
- <field name="serverName"><string>active.directory</string></field>
- </object>
- </object-param>
- </init-params>
-</component></programlisting>
-
- <para>You see here an <emphasis role="bold">object-param</emphasis> is
- being used to pass the parameters inside an object (actually a java
- bean). It consists of a <emphasis role="bold">name</emphasis>, a
- <emphasis role="bold">description</emphasis> and exactly one <emphasis
- role="bold">object</emphasis>. The object defines the <emphasis
- role="bold">type</emphasis> and a number of <emphasis
- role="bold">fields</emphasis>.</para>
-
- <para>Here you see how the service accesses the object:</para>
-
- <programlisting>package org.exoplatform.services.ldap.impl;
-
-public class LDAPServiceImpl implements LDAPService {
-...
- public LDAPServiceImpl(InitParams params) {
- LDAPConnectionConfig config = (LDAPConnectionConfig) params.getObjectParam("ldap.config")
- .getObject();
-...</programlisting>
-
- <para>The passed object is LDAPConnectionConfig which is a classic
- <emphasis role="bold">java bean</emphasis>. It contains all fields and
- also the appropriate getters and setters (not listed here). You also can
- provide default values. The container creates a new instance of your
- bean and calls all setters whose values are configured in the
- configuration file.</para>
-
- <programlisting>package org.exoplatform.services.ldap.impl;
-
-public class LDAPConnectionConfig {
- private String providerURL = "ldap://127.0.0.1:389";
- private String rootdn;
- private String password;
- private String version;
- private String authenticationType = "simple";
- private String serverName = "default";
- private int minConnection;
- private int maxConnection;
- private String referralMode = "follow";
-...</programlisting>
-
- <para>You see that the types (String, int) of the fields in the
- configuration correspond with the bean. A short glance in the
- kernel_1_0.xsd file let us discover more simple types:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">string, int, long, boolean, date,
- double</emphasis></para>
- </listitem>
- </itemizedlist>
-
- <para>Have a look on this type test xml file: <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>
- </section>
-
- <section id="Collection">
- <title>Collection</title>
-
- <para>You also can use java collections to configure your service. In
- order to see an example let's open the
- database-organization-configuration.xml file. This file defines a
- default user organization (users, groups, memberships/roles) of your
- portal. They use component-plugins which are explained later. You wil
- see that object-param is used again.</para>
-
- <para>There are two collections: The first collection is an <emphasis
- role="bold">ArrayList</emphasis>. This ArrayList contains only one
- value, but there could be more. The only value is an object which
- defines the field of the NewUserConfig$JoinGroup bean.</para>
-
- <para>The second collection is a <emphasis
- role="bold">HashSet</emphasis> that is a set of strings.</para>
-
- <programlisting> <component-plugin>
- <name>new.user.event.listener</name>
- <set-method>addListenerPlugin</set-method>
- <type>org.exoplatform.services.organization.impl.NewUserEventListener</type>
- <description>this listener assign group and membership to a new created user</description>
- <init-params>
- <object-param>
- <name>configuration</name>
- <description>description</description>
- <object type="org.exoplatform.services.organization.impl.NewUserConfig">
- <field name="group">
- <collection type="java.util.ArrayList">
- <value>
- <object type="org.exoplatform.services.organization.impl.NewUserConfig$JoinGroup">
- <field name="groupId"><string>/platform/users</string></field>
- <field name="membership"><string>member</string></field>
- </object>
- </value>
- </collection>
- </field>
- <field name="ignoredUser">
- <collection type="java.util.HashSet">
- <value><string>root</string></value>
- <value><string>john</string></value>
- <value><string>marry</string></value>
- <value><string>demo</string></value>
- <value><string>james</string></value>
- </collection>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin></programlisting>
-
- <para>Let's look at the
- org.exoplatform.services.organization.impl.NewUserConfig bean:</para>
-
- <programlisting>public class NewUserConfig {
- private List role;
- private List group;
- private HashSet ignoredUser;
-
- ...
-
- public void setIgnoredUser(String user) {
- ignoredUser.add(user);
-
- ...
-
- static public class JoinGroup {
- public String groupId;
- public String membership;
- ...
-}</programlisting>
-
- <para>You see the values of the HashSet are set one by one by the
- container, and it's the responsibility of the bean to add these values
- to its HashSet.</para>
-
- <para>The JoinGroup object is just an inner class and implements a bean
- of its own. It can be accessed like any other inner class using
- NewUserConfig.JoinGroup.</para>
- </section>
- </section>
-
- <section id="ExternalPlugin">
- <title>External Plugin</title>
-
- <para>The External Plugin allows you to add configuration on the
- fly.</para>
-
- <para>As you have carefully read <link
- 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,
- etc.).</para>
-
- <para>Let's have a look at the configuration of the TaxonomyPlugin of the
- CategoriesService:</para>
-
- <programlisting> <external-component-plugins>
- <target-component>org.exoplatform.services.cms.categories.CategoriesService</target-component>
- <component-plugin>
- <name>predefinedTaxonomyPlugin</name>
- <set-method>addTaxonomyPlugin</set-method>
- <type>org.exoplatform.services.cms.categories.impl.TaxonomyPlugin</type>
- <init-params>
- <value-param>
- <name>autoCreateInNewRepository</name>
- <value>true</value>
- </value-param>
- <value-param>
- <name>repository</name>
- <value>repository</value>
- </value-param>
- <object-param>
- <name>taxonomy.configuration</name>
- <description>configuration predefined taxonomies to inject in jcr</description>
- <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig">
- <field name="taxonomies">
- <collection type="java.util.ArrayList">
- <!-- cms taxonomy -->
- <value>
- <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig$Taxonomy">
- <field name="name"><string>cmsTaxonomy</string></field>
- <field name="path"><string>/cms</string></field>
- </object>
- </value>
- <value>
- <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig$Taxonomy">
- <field name="name"><string>newsTaxonomy</string></field>
- <field name="path"><string>/cms/news</string></field>
- </object>
- </value>
- </field>
- </object>
- </object-param>
- </init-params>
- </component-plugin>
-<external-component-plugins></programlisting>
-
- <para>The <emphasis role="bold"><target-component></emphasis>
- defines the service for which the plugin is defined. The configuration is
- injected by the container using a method that is defined in <emphasis
- role="bold"><set-method></emphasis>. The method has exactly one
- argument of the type
- org.exoplatform.services.cms.categories.impl.TaxonomyPlugin:</para>
-
- <itemizedlist>
- <listitem>
- <para>addTaxonomyPlugin(org.exoplatform.services.cms.categories.impl.TaxonomyPlugin
- plugin)</para>
- </listitem>
- </itemizedlist>
-
- <para>The content of <emphasis role="bold"><init-params></emphasis>
- corresponds to the structure of the TaxonomyPlugin object.</para>
-
- <note>
- <para>You can configure the component CategoriesService using the
- addTaxonomyPlugin as often as you wish, you can also call
- addTaxonomyPlugin in different configuration files. The method
- addTaxonomyPlugin is then called several times, everything else depends
- on the implementation of the method</para>
- </note>
- </section>
-
- <section id="Import">
- <title>Import</title>
-
- <para>The import tag allows to link to other configuration files. These
- imported files can be placed anywhere. If you write a default
- configuration which is part of your jar file you should not import files
- from outside your jar.</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">war</emphasis>: Imports from <emphasis
- role="bold">portal.war/WEB-INF</emphasis></para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">jar</emphasis> or <emphasis
- role="bold">classpath</emphasis>: Uses the <emphasis
- role="bold">classloader</emphasis>, you can use this prefix in the
- default configuration for importing an other configuration file which
- is accessible by the classloader.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">file</emphasis>: Uses an <emphasis
- role="bold">absolute path</emphasis>, you also can put a <emphasis
- role="bold">URL</emphasis>.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">without any prefix</emphasis>:</para>
-
- <itemizedlist>
- <listitem>
- <para>Standalone mode: <emphasis role="bold">user
- directory</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Portal mode: $AS-HOME, that means the application server
- home, for example " <emphasis
- role="bold">exo-tomcat</emphasis>".</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- <para>If you open the
- "portal/trunk/web/portal/src/main/webapp/WEB-INF/conf.configuration.xml"
- you will see that it consists only of imports: <programlisting><import>war:/conf/common/common-configuration.xml</import>
-<import>war:/conf/common/logs-configuration.xml</import>
-<import>war:/conf/database/database-configuration.xml</import>
-<import>war:/conf/jcr/jcr-configuration.xml</import>
-<import>war:/conf/common/portlet-container-configuration.xml</import>
-... </programlisting></para>
- </section>
-
- <section id="Systemproperties">
- <title>System 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. This makes it
- possible to resolve properties at runtime instead of providing a value at
- packaging time.</para>
-
- <para>In
- portal/trunk/web/portal/src/main/webapp/WEB-INF/conf/database/database-configuration.tmpl.xml
- you find an example for system properties:</para>
-
- <programlisting> <component>
- <key>org.exoplatform.services.database.HibernateService</key>
- <jmx-name>database:type=HibernateService</jmx-name>
- <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
- <init-params>
- <properties-param>
- <name>hibernate.properties</name>
- <description>Default Hibernate Service</description>
-...
- <property name="hibernate.connection.url" value="${connectionUrl}"/>
- <property name="hibernate.connection.driver_class" value="${driverClass}"/>
- <property name="hibernate.connection.username" value="${username}"/>
- <property name="hibernate.connection.password" value="${password}"/>
- <property name="hibernate.dialect" value="${dialect}"/>
-...
- </properties-param>
- </init-params>
- </component></programlisting>
-
- <para>As these are system properties you use the -D command: <emphasis
- role="bold">java -DconnectionUrl=jdbc:hsqldb:file:../temp/data/exodb
- -DdriverClass=org.hsqldb.jdbcDriver</emphasis> Or better use the
- parameters of eXo.bat / eXo.sh when you start eXo Portal: <emphasis
- role="bold">set
- EXO_OPTS="-DconnectionUrl=jdbc:hsqldb:file:../temp/data/exodb
- -DdriverClass=org.hsqldb.jdbcDriver"</emphasis></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.ServiceConfigurationinDetail">
+ <?dbhtml filename="ch-service-configuration-in-detail.html"?>
+
+ <title>Service Configuration in Detail</title>
+
+ <para><emphasis role="bold">Related documents</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="Kernel.ServiceConfigurationforBeginners">Service
+ Configuration for Beginners</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="Kernel.ServicesWiring">Services
+ Wiring</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link
+ linkend="Kernel.ContainerConfiguration.ConfigurationNamespace">Kernel
+ Configuration File</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <section>
+ <title>Objectives</title>
+
+ <para>This article shows in the first chapters how to setup a sample
+ service with some configurations and how to access to the configuration
+ parameters. The later chapters describe all details of the configuration
+ file (parameters, object-params, plugins, imports, etc.) it also shows how
+ to access the configuration values. You may consider this article as a
+ <emphasis role="bold">reference</emphasis>, but you can also use this
+ article as a <emphasis role="bold">tutorial</emphasis> and read it from
+ the beginning to the end.</para>
+ </section>
+
+ <section>
+ <title>Requirements</title>
+
+ <para>You should have read and understood <link
+ 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>
+ <title>Sample Service</title>
+
+ <section id="JavaClass">
+ <title>Java Class</title>
+
+ <para>Imagine you are working for a publishing company called "La
+ Verdad" that is going to use eXo platform. Your boss asks you be able to
+ calculate the number of sentences of an article.</para>
+
+ <para>You remember in eXo product everything is a <emphasis
+ role="bold">service</emphasis> so you decide to create a simple class.
+ In future you want to be able to plug different implementations of your
+ service, so that you should define an <emphasis
+ role="bold">interface</emphasis> that defines your service.</para>
+
+ <programlisting>package com.laverdad.services;
+public interface ArticleStatsService {
+ public abstract int calcSentences(String article);
+}</programlisting>
+
+ <para>A very simple implementation:</para>
+
+ <programlisting>public class ArticleStatsServiceImpl implements ArticleStatsService {
+ public int calcSentences(String article) {
+ throw new RuntimeException("Not implemented");
+ }
+}</programlisting>
+
+ <para>That's it! You see there are no special prerequisites for a
+ service.</para>
+
+ <para>You should already have prepared your working environment, where
+ you have a base folder (let's call it our service base folder). If you
+ wish to try out this example create this class in the
+ com/laverdad/services/ArticleStatsService subfolder.</para>
+ </section>
+
+ <section>
+ <title>First configuration file</title>
+
+ <para>When creating a service you also should declare its existence to
+ the <emphasis role="bold">Container</emphasis>, therefore you create a
+ first simple configuration file. Copy the following code to a file that
+ is called "configuration.xml" and place this file in a /conf
+ subdirectory of your service base folder. As you already know the
+ container looks for a "/conf/configuration.xml" file in each
+ jar-file.</para>
+
+ <programlisting><?xml version="1.0" encoding="UTF8"?>
+<configuration
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <component>
+ <key>com.laverdad.services.ArticleStatsService</key>
+ <type>com.laverdad.services.ArticleStatsServiceImpl</type>
+ </component>
+</configuration></programlisting>
+
+ <note>
+ <para>You are correctly using the namespace of the configuration
+ schema ( <uri>http://www.exoplaform.org/xml/ns/kernel_1_1.xsd</uri>).
+ Most of the configuration schema is explained in this
+ articles,therefore you do not need to open and understand the schema.
+ For backward compatibility it is not necessary to declare the
+ schema.</para>
+
+ <para>When eXo kernel reads a configuration it loads the file from the
+ kernel jar using the classloader and does not use an internet
+ connection to resolve the file.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Init Parameters</title>
+
+ <para>You see your service has a configuration file, but you wonder how
+ the file could possibly access to its configuration. Imagine you are
+ asked to implement two different calculation methods: fast and
+ exact.</para>
+
+ <para>You create one init parameter containing the calculation methods.
+ For the exact method you wish to configure more details for the service.
+ Let's enhance the word service configuration file:</para>
+
+ <programlisting> <component>
+ <key>com.laverdad.services.ArticleStatsService</key>
+ <type>com.laverdad.services.ArticleStatsServiceImpl</type>
+ <init-params>
+ <value-param>
+ <name>calc-method</name>
+ <description>calculation method: fast, exact</description>
+ <value>fast</value>
+ </value-param>
+ <properties-param>
+ <name>details-for-exact-method</name>
+ <description>details for exact phrase counting</description>
+ <property name="language" value="English" />
+ <property name="variant" value="us" />
+ </properties-param>
+ </init-params>
+ </component></programlisting>
+
+ <note>
+ <para>When configuring your service, you are <emphasis
+ role="bold">totally free</emphasis>. You can provide as many <emphasis
+ role="bold">value-param</emphasis>, <emphasis
+ role="bold">property-param</emphasis>, and <emphasis
+ role="bold">properties</emphasis> you wish and you can give them any
+ names or values. You only must respect the xml structure.</para>
+ </note>
+
+ <para>Now let's see how our service can read this configuration. The
+ implementation of the calcSentences() method serves just as a simple
+ example. It's up to your imagination to implement the exact
+ method.</para>
+
+ <programlisting>public class ArticleStatsServiceImpl implements ArticleStatsService {
+
+ private String calcMethod = "fast";
+ private String variant = "French";
+ private String language = "France";
+
+ public ArticleStatsServiceImpl(InitParams initParams) {
+ super();
+ calcMethod = initParams.getValueParam("calc-method").getValue();
+ PropertiesParam detailsForExactMethod = initParams.getPropertiesParam("details-for-exact-method");
+ if ( detailsForExactMethod != null) {
+ language = detailsForExactMethod.getProperty("language");
+ variant = detailsForExactMethod.getProperty("variant");
+ }
+ }
+
+ public int calcSentences(String article) {
+ if (calcMethod == "fast") {
+ // just count the number of periods "."
+ int res = 0;
+ int period = article.indexOf('.');
+ while (period != -1) {
+ res++;
+ article = article.substring(period+1);
+ period = article.indexOf('.');
+ }
+ return res;
+ }
+ throw new RuntimeException("Not implemented");
+ }
+}</programlisting>
+
+ <para>You see you just have to declare a parameter of
+ org.exoplatform.container.xml.InitParams in your constructor. The
+ container provides an InitParams object that correspond to the xml tree
+ of init-param.</para>
+ </section>
+
+ <section>
+ <title>Service Access</title>
+
+ <para>As you want to follow the principle of <emphasis
+ role="bold">Inversion of Control</emphasis> you <emphasis
+ role="bold">must not</emphasis> access the service directly. You need a
+ <emphasis role="bold">Container</emphasis> to access the service.</para>
+
+ <para>With this command you get your current container:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">ExoContainer myContainer =
+ ExoContainerContext.getCurrentContainer();</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This might be a PortalContainer or a StandaloneContainer,
+ dependant on the <link
+ linkend="Kernel.ServiceConfigurationinDetail.ExecutionModes">execution
+ mode</link> in which you are running your application.</para>
+
+ <para>Whenever you need one of the services that you have configured use
+ the method:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis
+ role="bold">myContainer.getComponentInstance(class)</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In our case:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">ArticleStatsService statsService =
+ (ArticleStatsService)
+ myContainer.getComponentInstance(ArticleStatsService.class);</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Recapitulation:</para>
+
+ <programlisting>package com.laverdad.common;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import com.laverdad.services.*;
+
+public class Statistics {
+
+ public int makeStatistics(String articleText) {
+ ExoContainer myContainer = ExoContainerContext.getCurrentContainer();
+ ArticleStatsService statsService = (ArticleStatsService)
+ myContainer.getComponentInstance(ArticleStatsService.class);
+ int numberOfSentences = statsService.calcSentences(articleText);
+ return numberOfSentences;
+ }
+
+ public static void main( String args[]) {
+ Statistics stats = new Statistics();
+ String newText = "This is a normal text. The method only counts the number of periods. "
+ + "You can implement your own implementation with a more exact counting. "
+ + "Let`s make a last sentence.";
+ System.out.println("Number of sentences: " + stats.makeStatistics(newText));
+ }
+}</programlisting>
+
+ <para>If you test this sample in standalone mode, you need to put all
+ jars of eXo Kernel in your buildpath, furthermore picoContainer is
+ needed.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Parameters</title>
+
+ <section>
+ <title>Value-Param</title>
+
+ <para>There is an value-param example:</para>
+
+ <programlisting> <component>
+ <key>org.exoplatform.portal.config.UserACL</key>
+ <type>org.exoplatform.portal.config.UserACL</type>
+ <init-params>
+...
+ <value-param>
+ <name>access.control.workspace</name>
+ <description>groups with memberships that have the right to access the User Control Workspace</description>
+ <value>*:/platform/administrators,*:/organization/management/executive-board</value>
+ </value-param>
+...
+ </component></programlisting>
+
+ <para>The UserACL class accesses to the <emphasis
+ role="bold">value-param</emphasis> in its constructor.</para>
+
+ <programlisting>package org.exoplatform.portal.config;
+public class UserACL {
+
+ public UserACL(InitParams params) {
+ UserACLMetaData md = new UserACLMetaData();
+ ValueParam accessControlWorkspaceParam = params.getValueParam("access.control.workspace");
+ if(accessControlWorkspaceParam != null) md.setAccessControlWorkspace(accessControlWorkspaceParam.getValue());
+...</programlisting>
+ </section>
+
+ <section>
+ <title>Properties-Param</title>
+
+ <para>Properties are name-value pairs. Both the name and the value are
+ Java Strings.</para>
+
+ <para>Here you see the hibernate configuration example:</para>
+
+ <programlisting> <component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+ <init-params>
+ <properties-param>
+ <name>hibernate.properties</name>
+ <description>Default Hibernate Service</description>
+ <property name="hibernate.show_sql" value="false"/>
+ <property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
+ <property name="hibernate.connection.url" value="jdbc:hsqldb:file:../temp/data/exodb"/>
+ <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
+...
+ </properties-param>
+ </init-params>
+ </component></programlisting>
+
+ <para>In the org.exoplatform.services.database.impl.HibernateServiceImpl
+ you will find that the name "hibernate.properties" of the
+ properties-param is used to access the properties.</para>
+
+ <programlisting>package org.exoplatform.services.database.impl;
+
+public class HibernateServiceImpl implements HibernateService, ComponentRequestLifecycle {
+ public HibernateServiceImpl(InitParams initParams, CacheService cacheService) {
+ PropertiesParam param = initParams.getPropertiesParam("hibernate.properties");
+...
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Object-Param</title>
+
+ <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>
+ <key>org.exoplatform.services.ldap.LDAPService</key>
+ <type>org.exoplatform.services.ldap.impl.LDAPServiceImpl</type>
+ <init-params>
+ <object-param>
+ <name>ldap.config</name>
+ <description>Default ldap config</description>
+ <object type="org.exoplatform.services.ldap.impl.LDAPConnectionConfig">
+ <field name="providerURL"><string>ldaps://10.0.0.3:636</string></field>
+ <field name="rootdn"><string>CN=Administrator,CN=Users,DC=exoplatform,DC=org</string></field>
+ <field name="password"><string>exo</string></field>
+ <field name="version"><string>3</string></field>
+ <field name="minConnection"><int>5</int></field>
+ <field name="maxConnection"><int>10</int></field>
+ <field name="referralMode"><string>ignore</string></field>
+ <field name="serverName"><string>active.directory</string></field>
+ </object>
+ </object-param>
+ </init-params>
+</component></programlisting>
+
+ <para>You see here an <emphasis role="bold">object-param</emphasis> is
+ being used to pass the parameters inside an object (actually a java
+ bean). It consists of a <emphasis role="bold">name</emphasis>, a
+ <emphasis role="bold">description</emphasis> and exactly one <emphasis
+ role="bold">object</emphasis>. The object defines the <emphasis
+ role="bold">type</emphasis> and a number of <emphasis
+ role="bold">fields</emphasis>.</para>
+
+ <para>Here you see how the service accesses the object:</para>
+
+ <programlisting>package org.exoplatform.services.ldap.impl;
+
+public class LDAPServiceImpl implements LDAPService {
+...
+ public LDAPServiceImpl(InitParams params) {
+ LDAPConnectionConfig config = (LDAPConnectionConfig) params.getObjectParam("ldap.config")
+ .getObject();
+...</programlisting>
+
+ <para>The passed object is LDAPConnectionConfig which is a classic
+ <emphasis role="bold">java bean</emphasis>. It contains all fields and
+ also the appropriate getters and setters (not listed here). You also can
+ provide default values. The container creates a new instance of your
+ bean and calls all setters whose values are configured in the
+ configuration file.</para>
+
+ <programlisting>package org.exoplatform.services.ldap.impl;
+
+public class LDAPConnectionConfig {
+ private String providerURL = "ldap://127.0.0.1:389";
+ private String rootdn;
+ private String password;
+ private String version;
+ private String authenticationType = "simple";
+ private String serverName = "default";
+ private int minConnection;
+ private int maxConnection;
+ private String referralMode = "follow";
+...</programlisting>
+
+ <para>You see that the types (String, int) of the fields in the
+ configuration correspond with the bean. A short glance in the
+ kernel_1_0.xsd file let us discover more simple types:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">string, int, long, boolean, date,
+ double</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Have a look on this type test xml file: <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>
+ </section>
+
+ <section>
+ <title>Collection</title>
+
+ <para>You also can use java collections to configure your service. In
+ order to see an example let's open the
+ database-organization-configuration.xml file. This file defines a
+ default user organization (users, groups, memberships/roles) of your
+ portal. They use component-plugins which are explained later. You wil
+ see that object-param is used again.</para>
+
+ <para>There are two collections: The first collection is an <emphasis
+ role="bold">ArrayList</emphasis>. This ArrayList contains only one
+ value, but there could be more. The only value is an object which
+ defines the field of the NewUserConfig$JoinGroup bean.</para>
+
+ <para>The second collection is a <emphasis
+ role="bold">HashSet</emphasis> that is a set of strings.</para>
+
+ <programlisting> <component-plugin>
+ <name>new.user.event.listener</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.exoplatform.services.organization.impl.NewUserEventListener</type>
+ <description>this listener assign group and membership to a new created user</description>
+ <init-params>
+ <object-param>
+ <name>configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.services.organization.impl.NewUserConfig">
+ <field name="group">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.organization.impl.NewUserConfig$JoinGroup">
+ <field name="groupId"><string>/platform/users</string></field>
+ <field name="membership"><string>member</string></field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ <field name="ignoredUser">
+ <collection type="java.util.HashSet">
+ <value><string>root</string></value>
+ <value><string>john</string></value>
+ <value><string>marry</string></value>
+ <value><string>demo</string></value>
+ <value><string>james</string></value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin></programlisting>
+
+ <para>Let's look at the
+ org.exoplatform.services.organization.impl.NewUserConfig bean:</para>
+
+ <programlisting>public class NewUserConfig {
+ private List role;
+ private List group;
+ private HashSet ignoredUser;
+
+ ...
+
+ public void setIgnoredUser(String user) {
+ ignoredUser.add(user);
+
+ ...
+
+ static public class JoinGroup {
+ public String groupId;
+ public String membership;
+ ...
+}</programlisting>
+
+ <para>You see the values of the HashSet are set one by one by the
+ container, and it's the responsibility of the bean to add these values
+ to its HashSet.</para>
+
+ <para>The JoinGroup object is just an inner class and implements a bean
+ of its own. It can be accessed like any other inner class using
+ NewUserConfig.JoinGroup.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>External Plugin</title>
+
+ <para>The External Plugin allows you to add configuration on the
+ fly.</para>
+
+ <para>As you have carefully read <link
+ 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,
+ etc.).</para>
+
+ <para>Let's have a look at the configuration of the TaxonomyPlugin of the
+ CategoriesService:</para>
+
+ <programlisting> <external-component-plugins>
+ <target-component>org.exoplatform.services.cms.categories.CategoriesService</target-component>
+ <component-plugin>
+ <name>predefinedTaxonomyPlugin</name>
+ <set-method>addTaxonomyPlugin</set-method>
+ <type>org.exoplatform.services.cms.categories.impl.TaxonomyPlugin</type>
+ <init-params>
+ <value-param>
+ <name>autoCreateInNewRepository</name>
+ <value>true</value>
+ </value-param>
+ <value-param>
+ <name>repository</name>
+ <value>repository</value>
+ </value-param>
+ <object-param>
+ <name>taxonomy.configuration</name>
+ <description>configuration predefined taxonomies to inject in jcr</description>
+ <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig">
+ <field name="taxonomies">
+ <collection type="java.util.ArrayList">
+ <!-- cms taxonomy -->
+ <value>
+ <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig$Taxonomy">
+ <field name="name"><string>cmsTaxonomy</string></field>
+ <field name="path"><string>/cms</string></field>
+ </object>
+ </value>
+ <value>
+ <object type="org.exoplatform.services.cms.categories.impl.TaxonomyConfig$Taxonomy">
+ <field name="name"><string>newsTaxonomy</string></field>
+ <field name="path"><string>/cms/news</string></field>
+ </object>
+ </value>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+<external-component-plugins></programlisting>
+
+ <para>The <emphasis role="bold"><target-component></emphasis>
+ defines the service for which the plugin is defined. The configuration is
+ injected by the container using a method that is defined in <emphasis
+ role="bold"><set-method></emphasis>. The method has exactly one
+ argument of the type
+ org.exoplatform.services.cms.categories.impl.TaxonomyPlugin:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>addTaxonomyPlugin(org.exoplatform.services.cms.categories.impl.TaxonomyPlugin
+ plugin)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The content of <emphasis role="bold"><init-params></emphasis>
+ corresponds to the structure of the TaxonomyPlugin object.</para>
+
+ <note>
+ <para>You can configure the component CategoriesService using the
+ addTaxonomyPlugin as often as you wish, you can also call
+ addTaxonomyPlugin in different configuration files. The method
+ addTaxonomyPlugin is then called several times, everything else depends
+ on the implementation of the method</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Import</title>
+
+ <para>The import tag allows to link to other configuration files. These
+ imported files can be placed anywhere. If you write a default
+ configuration which is part of your jar file you should not import files
+ from outside your jar.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">war</emphasis>: Imports from <emphasis
+ role="bold">portal.war/WEB-INF</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">jar</emphasis> or <emphasis
+ role="bold">classpath</emphasis>: Uses the <emphasis
+ role="bold">classloader</emphasis>, you can use this prefix in the
+ default configuration for importing an other configuration file which
+ is accessible by the classloader.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">file</emphasis>: Uses an <emphasis
+ role="bold">absolute path</emphasis>, you also can put a <emphasis
+ role="bold">URL</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">without any prefix</emphasis>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Standalone mode: <emphasis role="bold">user
+ directory</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Portal mode: $AS-HOME, that means the application server
+ home, for example " <emphasis
+ role="bold">exo-tomcat</emphasis>".</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you open the
+ "portal/trunk/web/portal/src/main/webapp/WEB-INF/conf.configuration.xml"
+ you will see that it consists only of imports: <programlisting><import>war:/conf/common/common-configuration.xml</import>
+<import>war:/conf/common/logs-configuration.xml</import>
+<import>war:/conf/database/database-configuration.xml</import>
+<import>war:/conf/jcr/jcr-configuration.xml</import>
+<import>war:/conf/common/portlet-container-configuration.xml</import>
+... </programlisting></para>
+ </section>
+
+ <section>
+ <title>System 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. This makes it
+ possible to resolve properties at runtime instead of providing a value at
+ packaging time.</para>
+
+ <para>In
+ portal/trunk/web/portal/src/main/webapp/WEB-INF/conf/database/database-configuration.tmpl.xml
+ you find an example for system properties:</para>
+
+ <programlisting> <component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <jmx-name>database:type=HibernateService</jmx-name>
+ <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+ <init-params>
+ <properties-param>
+ <name>hibernate.properties</name>
+ <description>Default Hibernate Service</description>
+...
+ <property name="hibernate.connection.url" value="${connectionUrl}"/>
+ <property name="hibernate.connection.driver_class" value="${driverClass}"/>
+ <property name="hibernate.connection.username" value="${username}"/>
+ <property name="hibernate.connection.password" value="${password}"/>
+ <property name="hibernate.dialect" value="${dialect}"/>
+...
+ </properties-param>
+ </init-params>
+ </component></programlisting>
+
+ <para>As these are system properties you use the -D command: <emphasis
+ role="bold">java -DconnectionUrl=jdbc:hsqldb:file:../temp/data/exodb
+ -DdriverClass=org.hsqldb.jdbcDriver</emphasis> Or better use the
+ parameters of eXo.bat / eXo.sh when you start eXo Portal: <emphasis
+ role="bold">set
+ EXO_OPTS="-DconnectionUrl=jdbc:hsqldb:file:../temp/data/exodb
+ -DdriverClass=org.hsqldb.jdbcDriver"</emphasis></para>
+ </section>
+</chapter>
13 years, 10 months
exo-jcr SVN: r2967 - jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-23 03:45:14 -0400 (Mon, 23 Aug 2010)
New Revision: 2967
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java
Log:
EXOJCR-908 IDENTITY_DELIMITER constant removed from org.exoplatform.services.jcr.impl.core.value.PermissionValue use org.exoplatform.services.jcr.access.AccessControlEntry.DELIMITER instead.
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java 2010-08-23 07:44:40 UTC (rev 2966)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java 2010-08-23 07:45:14 UTC (rev 2967)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.core.value;
+import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.PermissionType;
import org.exoplatform.services.jcr.access.SystemIdentity;
import org.exoplatform.services.jcr.core.ExtendedPropertyType;
@@ -42,8 +43,6 @@
private static final int TYPE = ExtendedPropertyType.PERMISSION;
- private static final String IDENTITY_DELIMITER = " ";
-
private String identity;
private String permission;
@@ -85,7 +84,7 @@
static public String[] parse(String pstring)
{
- StringTokenizer parser = new StringTokenizer(pstring, IDENTITY_DELIMITER);
+ StringTokenizer parser = new StringTokenizer(pstring, AccessControlEntry.DELIMITER);
String identityString = parser.nextToken();
String permissionString = parser.nextToken();
@@ -122,7 +121,7 @@
static protected String asString(String identity, String permission)
{
if (identity != null || permission != null) // SystemIdentity.ANY, PermissionType.ALL
- return (identity != null ? identity : SystemIdentity.ANY) + IDENTITY_DELIMITER
+ return (identity != null ? identity : SystemIdentity.ANY) + AccessControlEntry.DELIMITER
+ (permission != null ? permission : PermissionType.READ);
else
return "";
13 years, 10 months
exo-jcr SVN: r2966 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-23 03:44:40 -0400 (Mon, 23 Aug 2010)
New Revision: 2966
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java
Log:
EXOJCR-908 IDENTITY_DELIMITER constant removed from org.exoplatform.services.jcr.impl.core.value.PermissionValue use org.exoplatform.services.jcr.access.AccessControlEntry.DELIMITER instead.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java 2010-08-23 07:34:56 UTC (rev 2965)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/PermissionValue.java 2010-08-23 07:44:40 UTC (rev 2966)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.core.value;
+import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.PermissionType;
import org.exoplatform.services.jcr.access.SystemIdentity;
import org.exoplatform.services.jcr.core.ExtendedPropertyType;
@@ -42,8 +43,6 @@
private static final int TYPE = ExtendedPropertyType.PERMISSION;
- private static final String IDENTITY_DELIMITER = " ";
-
private String identity;
private String permission;
@@ -85,7 +84,7 @@
static public String[] parse(String pstring)
{
- StringTokenizer parser = new StringTokenizer(pstring, IDENTITY_DELIMITER);
+ StringTokenizer parser = new StringTokenizer(pstring, AccessControlEntry.DELIMITER);
String identityString = parser.nextToken();
String permissionString = parser.nextToken();
@@ -122,7 +121,7 @@
static protected String asString(String identity, String permission)
{
if (identity != null || permission != null) // SystemIdentity.ANY, PermissionType.ALL
- return (identity != null ? identity : SystemIdentity.ANY) + IDENTITY_DELIMITER
+ return (identity != null ? identity : SystemIdentity.ANY) + AccessControlEntry.DELIMITER
+ (permission != null ? permission : PermissionType.READ);
else
return "";
13 years, 10 months
exo-jcr SVN: r2965 - in core: trunk/packaging/module/src/main/javascript and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-08-23 03:34:56 -0400 (Mon, 23 Aug 2010)
New Revision: 2965
Modified:
core/branches/2.3.x/packaging/module/src/main/javascript/core.packaging.module.js
core/trunk/packaging/module/src/main/javascript/core.packaging.module.js
Log:
EXOJCR-886: updating modeule.js for core packeging
Modified: core/branches/2.3.x/packaging/module/src/main/javascript/core.packaging.module.js
===================================================================
--- core/branches/2.3.x/packaging/module/src/main/javascript/core.packaging.module.js 2010-08-20 13:13:27 UTC (rev 2964)
+++ core/branches/2.3.x/packaging/module/src/main/javascript/core.packaging.module.js 2010-08-23 07:34:56 UTC (rev 2965)
@@ -43,8 +43,10 @@
addDependency(new Project("bouncycastle", "bcmail-jdk14", "jar", "136")).
addDependency(new Project("bouncycastle", "bcprov-jdk14", "jar", "136")).
addDependency(new Project("html-parser", "html-parser", "jar", "1.6")).
- addDependency(new Project("org.apache.poi", "poi", "jar", "3.0.2-FINAL")).
- addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.0.2-FINAL"));
+ addDependency(new Project("org.apache.poi", "poi", "jar", "3.6")).
+ addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.6"));
+ addDependency(new Project("org.apache.poi", "poi-ooxml", "jar", "3.6"));
+ addDependency(new Project("org.apache.xmlbeans", "xmlbeans", "jar", "2.3.0"));
module.component.organization =
new Project("org.exoplatform.core", "exo.core.component.organization.api", "jar", module.version).
Modified: core/trunk/packaging/module/src/main/javascript/core.packaging.module.js
===================================================================
--- core/trunk/packaging/module/src/main/javascript/core.packaging.module.js 2010-08-20 13:13:27 UTC (rev 2964)
+++ core/trunk/packaging/module/src/main/javascript/core.packaging.module.js 2010-08-23 07:34:56 UTC (rev 2965)
@@ -43,8 +43,10 @@
addDependency(new Project("bouncycastle", "bcmail-jdk14", "jar", "136")).
addDependency(new Project("bouncycastle", "bcprov-jdk14", "jar", "136")).
addDependency(new Project("html-parser", "html-parser", "jar", "1.6")).
- addDependency(new Project("org.apache.poi", "poi", "jar", "3.0.2-FINAL")).
- addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.0.2-FINAL"));
+ addDependency(new Project("org.apache.poi", "poi", "jar", "3.6")).
+ addDependency(new Project("org.apache.poi", "poi-scratchpad", "jar", "3.6"));
+ addDependency(new Project("org.apache.poi", "poi-ooxml", "jar", "3.6"));
+ addDependency(new Project("org.apache.xmlbeans", "xmlbeans", "jar", "2.3.0"));
module.component.organization =
new Project("org.exoplatform.core", "exo.core.component.organization.api", "jar", module.version).
13 years, 10 months
exo-jcr SVN: r2964 - in jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core: value and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-20 09:13:27 -0400 (Fri, 20 Aug 2010)
New Revision: 2964
Added:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java
Removed:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java
Log:
EXOJCR-908 Added tests for PermissionValue.parse(String) and PermissionValue.asString(String, String) methods.
Copied: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value (from rev 2962, jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value)
Deleted: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java 2010-08-20 13:13:27 UTC (rev 2964)
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2003-2007 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-
-package org.exoplatform.services.jcr.impl.core.value;
-
-import junit.framework.TestCase;
-
-public class TestPermissionValue extends TestCase
-{
-
- public void testParse() {
-
- String[] parsedValues = PermissionValue.parse("root read");
- assertEquals(2, parsedValues.length);
- assertEquals("root", parsedValues[0]);
- assertEquals("read", parsedValues[1]);
-
- }
-
- public void testAsString() {
-
- assertEquals("root read", PermissionValue.asString("root", "read"));
-
- }
-
-}
Copied: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java (from rev 2962, jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java)
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/value/TestPermissionValue.java 2010-08-20 13:13:27 UTC (rev 2964)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+
+package org.exoplatform.services.jcr.impl.core.value;
+
+import junit.framework.TestCase;
+
+public class TestPermissionValue extends TestCase
+{
+
+ public void testParse() {
+
+ String[] parsedValues = PermissionValue.parse("root read");
+ assertEquals(2, parsedValues.length);
+ assertEquals("root", parsedValues[0]);
+ assertEquals("read", parsedValues[1]);
+
+ }
+
+ public void testAsString() {
+
+ assertEquals("root read", PermissionValue.asString("root", "read"));
+
+ }
+
+}
13 years, 10 months
exo-jcr SVN: r2963 - in jcr/branches/1.14-ISPN/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan and 4 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-08-20 09:07:54 -0400 (Fri, 20 Aug 2010)
New Revision: 2963
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-config.xml
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-lock.xml
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
Log:
EXOJCR-830: fix failed test, code cleanup
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-08-20 13:07:54 UTC (rev 2963)
@@ -57,7 +57,6 @@
/**
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
* @version $Id: InfinispanLockManagerImpl.java 111 2010-11-11 11:11:11Z tolusha $
- *
*/
@Managed
@NameTemplate(@Property(key = "service", value = "lockmanager"))
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2010-08-20 13:07:54 UTC (rev 2963)
@@ -39,8 +39,7 @@
import java.util.concurrent.TimeUnit;
/**
- * Decorator over the JBossCache that stores changes in buffer, then sorts and applies to
- * JBossCache.
+ * Decorator over the Infinispan Cache that stores changes in buffer, then sorts and applies it.
*
* @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
* @version $Id$
@@ -58,10 +57,6 @@
private ThreadLocal<Boolean> local = new ThreadLocal<Boolean>();
- private final boolean useExpiration;
-
- private final long expirationTimeOut;
-
protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.BufferedISPNCache");
public static enum ChangesType {
@@ -83,12 +78,8 @@
protected final boolean localMode;
- protected final boolean useExpiration;
-
- protected final long timeOut;
-
public ChangesContainer(CacheKey key, ChangesType changesType, Cache<Serializable, Object> cache,
- int historicalIndex, boolean localMode, boolean useExpiration, long timeOut)
+ int historicalIndex, boolean localMode)
{
super();
this.key = key;
@@ -96,8 +87,6 @@
this.cache = cache;
this.historicalIndex = historicalIndex;
this.localMode = localMode;
- this.useExpiration = useExpiration;
- this.timeOut = timeOut;
}
/**
@@ -162,13 +151,6 @@
}
}
- public final void putExpiration(CacheKey key)
- {
- // setCacheLocalMode();
- // // TODO
- // cache.put(efqn, ExpirationAlgorithmConfig.EXPIRATION_KEY, new Long(System.currentTimeMillis() + timeOut));
- }
-
public abstract void apply();
}
@@ -180,9 +162,9 @@
private final Object value;
public PutObjectContainer(CacheKey key, Object value, Cache<Serializable, Object> cache, int historicalIndex,
- boolean local, boolean useExpiration, long timeOut)
+ boolean local)
{
- super(key, ChangesType.PUT, cache, historicalIndex, local, useExpiration, timeOut);
+ super(key, ChangesType.PUT, cache, historicalIndex, local);
this.value = value;
}
@@ -192,11 +174,6 @@
{
setCacheLocalMode();
cache.put(key, value);
-
- if (useExpiration)
- {
- putExpiration(key);
- }
}
}
@@ -209,9 +186,9 @@
private final Object value;
public AddToListContainer(CacheKey key, Object value, Cache<Serializable, Object> cache, int historicalIndex,
- boolean local, boolean useExpiration, long timeOut)
+ boolean local)
{
- super(key, ChangesType.PUT, cache, historicalIndex, local, useExpiration, timeOut);
+ super(key, ChangesType.PUT, cache, historicalIndex, local);
this.value = value;
}
@@ -235,11 +212,6 @@
}
newSet.add(value);
- if (useExpiration)
- {
- putExpiration(key);
- }
-
setCacheLocalMode();
cache.put(key, newSet);
}
@@ -260,9 +232,9 @@
private final Object value;
public RemoveFromListContainer(CacheKey key, Object value, Cache<Serializable, Object> cache,
- int historicalIndex, boolean local, boolean useExpiration, long timeOut)
+ int historicalIndex, boolean local)
{
- super(key, ChangesType.REMOVE, cache, historicalIndex, local, useExpiration, timeOut);
+ super(key, ChangesType.REMOVE, cache, historicalIndex, local);
this.value = value;
}
@@ -283,11 +255,6 @@
Set<Object> newSet = new HashSet<Object>((Set<Object>)existingObject);
newSet.remove(value);
- if (useExpiration)
- {
- putExpiration(key);
- }
-
setCacheLocalMode();
cache.put(key, newSet);
}
@@ -299,10 +266,9 @@
*/
public static class RemoveObjectContainer extends ChangesContainer
{
- public RemoveObjectContainer(CacheKey key, Cache<Serializable, Object> cache, int historicalIndex, boolean local,
- boolean useExpiration, long timeOut)
+ public RemoveObjectContainer(CacheKey key, Cache<Serializable, Object> cache, int historicalIndex, boolean local)
{
- super(key, ChangesType.REMOVE, cache, historicalIndex, local, useExpiration, timeOut);
+ super(key, ChangesType.REMOVE, cache, historicalIndex, local);
}
@Override
@@ -313,12 +279,10 @@
}
}
- public BufferedISPNCache(Cache<Serializable, Object> parentCache, boolean useExpiration, long expirationTimeOut)
+ public BufferedISPNCache(Cache<Serializable, Object> parentCache)
{
super();
this.parentCache = parentCache;
- this.useExpiration = useExpiration;
- this.expirationTimeOut = expirationTimeOut;
}
/**
@@ -802,7 +766,7 @@
{
CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
changesContainer.add(new PutObjectContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
- .get(), useExpiration, expirationTimeOut));
+ .get()));
return parentCache.get(key);
}
@@ -813,7 +777,7 @@
@Override
public Object put(Serializable key, Object value)
{
- return parentCache.put(key, value);
+ throw new UnsupportedOperationException("Unexpected method call use put(CacheKey key, Object value)");
}
/**
@@ -833,7 +797,7 @@
{
CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
changesContainer.add(new RemoveObjectContainer((CacheKey)key, parentCache, changesContainer.getHistoryIndex(),
- local.get(), useExpiration, expirationTimeOut));
+ local.get()));
return parentCache.get(key);
}
@@ -997,7 +961,7 @@
{
CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
changesContainer.add(new AddToListContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
- .get(), useExpiration, expirationTimeOut));
+ .get()));
}
/**
@@ -1014,7 +978,7 @@
Object prevObject = getObjectFromChangesContainer(changesContainer, key);
changesContainer.add(new PutObjectContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
- .get(), useExpiration, expirationTimeOut));
+ .get()));
if (prevObject != null)
{
@@ -1051,7 +1015,7 @@
{
CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
changesContainer.add(new RemoveFromListContainer(key, value, parentCache, changesContainer.getHistoryIndex(),
- local.get(), useExpiration, expirationTimeOut));
+ local.get()));
}
public Object getFromBuffer(CacheKey key)
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-08-20 13:07:54 UTC (rev 2963)
@@ -58,11 +58,12 @@
*
* Cache based on Infinispan.<p/>
*
- * TODO: structure
- *
* <ul>
* <li>cache transparent: or item cached or not, we should not generate "not found" Exceptions </li>
*
+ * This cache implementation stores items by UUID and parent UUID with QPathEntry.
+ * Except this cache stores list of children UUID.
+ *
* <p/>
* Current state notes (subject of change):
* <ul>
@@ -212,27 +213,7 @@
// create parent JBossCache instance
Cache<Serializable, Object> parentCache = factory.createCache(wsConfig.getCache());
- // // get all eviction configurations
- // List<EvictionRegionConfig> evictionConfigurations =
- // parentCache.getConfiguration().getEvictionConfig().getEvictionRegionConfigs();
- // // append and default eviction configuration, since it is not present in region configurations
- // evictionConfigurations.add(parentCache.getConfiguration().getEvictionConfig().getDefaultEvictionRegionConfig());
- //
- // boolean useExpiration = false;
- // // looking over all eviction configurations till the end or till some expiration algorithm subclass not found.
- // for (EvictionRegionConfig evictionRegionConfig : evictionConfigurations)
- // {
- // if (evictionRegionConfig.getEvictionAlgorithmConfig() instanceof ExpirationAlgorithmConfig)
- // {
- // // force set expiration key to default value in all Expiration configurations (if any)
- // ((ExpirationAlgorithmConfig)evictionRegionConfig.getEvictionAlgorithmConfig())
- // .setExpirationKeyName(ExpirationAlgorithmConfig.EXPIRATION_KEY);
- // useExpiration = true;
- // }
- // }
-
- // if expiration is used, set appropriate factory with with timeout set via configuration (or default one 15minutes)
- this.cache = new BufferedISPNCache(parentCache, false, -1);
+ this.cache = new BufferedISPNCache(parentCache);
}
/**
@@ -443,17 +424,6 @@
public void addChildPropertiesList(NodeData parent, List<PropertyData> childProperties)
{
// TODO not implemented, will force read from DB
- // try
- // {
- // cache.beginTransaction();
- // cache.setLocal(true);
- //
- // }
- // finally
- // {
- // cache.setLocal(false);
- // cache.commitTransaction();
- // }
}
/**
@@ -793,7 +763,7 @@
TransientNodeData newNode =
new TransientNodeData(newPath, prevNode.getIdentifier(), prevNode.getPersistedVersion(),
prevNode.getPrimaryTypeName(), prevNode.getMixinTypeNames(), prevNode.getOrderNumber(),
- prevNode.getParentIdentifier(), inheritACL ? acl : prevNode.getACL()); // TODO check ACL
+ prevNode.getParentIdentifier(), inheritACL ? acl : prevNode.getACL());
// update this node
if (key instanceof CacheId)
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-08-20 13:07:54 UTC (rev 2963)
@@ -38,10 +38,6 @@
* Path to Infinispan configuration or template and cache name should be
* provided as "infinispan-configuration" and "infinispan-cache-name" properties
* in parameterEntry instance respectively.
- * <br>
- * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
- * "jgroups-configuration" parameters then Multiplexing stack is enabled
- * in Infinispan (this is highly recommended by RH specialists).
*
* @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
* @version $Id$
@@ -54,12 +50,8 @@
public static final String JGROUPS_CONFIG = "jgroups-configuration";
- public static final String JGROUPS_MUX_ENABLED = "jgroups-multiplexer-stack";
-
private final TemplateConfigurationHelper configurationHelper;
- private ConfigurationManager configurationManager;
-
private final Log log = ExoLogger.getLogger("exo.jcr.component.core.InfinispanCacheFactory");
/**
@@ -70,7 +62,6 @@
*/
public InfinispanCacheFactory(ConfigurationManager configurationManager)
{
- this.configurationManager = configurationManager;
this.configurationHelper = TemplateConfigurationHelper.createJBossCacheHelper(configurationManager);
}
@@ -79,9 +70,6 @@
* Path to Infinispan configuration or template should be provided as
* "infinispan-configuration" property in parameterEntry instance.
* <br>
- * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
- * "jgroups-configuration" parameters then Multiplexing stack is enabled
- * in Infinispan (this is highly recommended by RH specialists)
*
* @param parameterEntry
* @return
@@ -89,7 +77,7 @@
*/
public Cache<K, V> createCache(MappedParametrizedObjectEntry parameterEntry) throws RepositoryConfigurationException
{
- // get Infinispan configuration file path and cache name
+ // get Infinispan configuration file path
final String configurationPath = parameterEntry.getParameterValue(INFINISPAN_CONFIG);
log.info("Infinispan Cache configuration used: " + configurationPath);
@@ -125,48 +113,6 @@
};
Cache<K, V> cache = AccessController.doPrivileged(action);
- // JGroups multiplexer configuration if enabled
- // if (parameterEntry.getParameterBoolean(JGROUPS_MUX_ENABLED, false))
- // {
- // try
- // {
- // // Get path to JGroups configuration
- // String jgroupsConfigurationFilePath = parameterEntry.getParameterValue(JGROUPS_CONFIG);
- // if (jgroupsConfigurationFilePath != null)
- // {
- // // Create and inject multiplexer factory
- // JChannelFactory muxFactory = new JChannelFactory();
- // muxFactory.setMultiplexerConfig(configurationManager.getResource(jgroupsConfigurationFilePath));
- // cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(muxFactory);
- // log.info("Multiplexer stack successfully enabled for the cache.");
- // }
- // }
- // catch (Exception e)
- // {
- // // exception occurred setting mux factory
- // e.printStackTrace();
- // throw new RepositoryConfigurationException("Error setting multiplexer configuration.", e);
- // }
- // }
- // else
- // {
- // // Multiplexer is not enabled. If jGroups configuration preset it is applied
- // String jgroupsConfigurationFilePath = parameterEntry.getParameterValue(JGROUPS_CONFIG, null);
- // if (jgroupsConfigurationFilePath != null)
- // {
- // try
- // {
- // cache.getConfiguration().setJgroupsConfigFile(
- // configurationManager.getResource(jgroupsConfigurationFilePath));
- // log.info("Custom JGroups configuration set:"
- // + configurationManager.getResource(jgroupsConfigurationFilePath));
- // }
- // catch (Exception e)
- // {
- // throw new RepositoryConfigurationException("Error setting JGroups configuration.", e);
- // }
- // }
- // }
return cache;
}
}
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java 2010-08-20 13:07:54 UTC (rev 2963)
@@ -44,6 +44,7 @@
private TransactionService txService;
+ @Override
public void setUp() throws Exception
{
super.setUp();
@@ -115,7 +116,7 @@
ut.begin();
log.info("after begin");
// we need to create the session within the transaction to ensure that it will be enlisted
- Session session = (SessionImpl)repository.login(credentials, "ws");
+ Session session = repository.login(credentials, "ws");
session.getRootNode().addNode("txcommit");
session.save();
assertNotNull(session.getItem("/txcommit"));
@@ -143,7 +144,7 @@
ut.begin();
// we need to create the session within the transaction to ensure that it will be enlisted
- Session session = (SessionImpl)repository.login(credentials, "ws");
+ Session session = repository.login(credentials, "ws");
session.getRootNode().addNode("txrollback");
session.save();
assertNotNull(session.getItem("/txrollback"));
@@ -233,10 +234,10 @@
Session s2 =
repository.login(new SimpleCredentials("admin", "admin".toCharArray()), session.getWorkspace().getName());
-
+
Node tx1 = s1.getRootNode().getNode("pretx").addNode("tx1");
s1.save();
-
+
Node tx2 = s2.getRootNode().getNode("pretx").addNode("tx2");
s2.save();
@@ -251,13 +252,19 @@
catch (Exception e)
{
// ok
- assertNotNull(((XASession) s1).getCommitException());
+ assertNotNull(((XASession)s1).getCommitException());
}
- try {
+ s1.logout();
+ s2.logout();
+
+ try
+ {
session.getItem("/pretx/tx1");
fail("PathNotFoundException should be thrown");
- } catch(PathNotFoundException e) {
+ }
+ catch (PathNotFoundException e)
+ {
// ok
}
}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-config.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-config.xml 2010-08-20 13:07:54 UTC (rev 2963)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<infinispan
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:infinispan:config:4.0 http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
+ xmlns="urn:infinispan:config:4.0">
+
+ <global>
+ <evictionScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+ <properties>
+ <property name="threadNamePrefix" value="EvictionThread"/>
+ </properties>
+ </evictionScheduledExecutor>
+
+ <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+
+ <transport transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport" clusterName="${infinispan-cluster-name}" distributedSyncTimeout="20000">
+ <properties>
+ <property name="configurationFile" value="${jgroups-configuration}"/>
+ </properties>
+ </transport>
+ </global>
+
+ <default>
+ <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <deadlockDetection enabled="true" spinDuration="100"/>
+ <eviction strategy="LRU" wakeUpInterval="5000" threadPolicy="DEFAULT" maxEntries="5000"/>
+ </default>
+</infinispan>
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-lock.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-lock.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-infinispan-lock.xml 2010-08-20 13:07:54 UTC (rev 2963)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<infinispan
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:infinispan:config:4.0 http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
+ xmlns="urn:infinispan:config:4.0">
+
+ <global>
+ <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+
+ <transport transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport" clusterName="${infinispan-cluster-name}" distributedSyncTimeout="20000">
+ <properties>
+ <property name="configurationFile" value="${jgroups-configuration}"/>
+ </properties>
+ </transport>
+ </global>
+
+ <default>
+ <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <deadlockDetection enabled="true" spinDuration="100"/>
+
+ <loaders passivation="false" shared="true" preload="true">
+ <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
+ <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
+ <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
+ <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
+ <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
+ <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
+ <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
+ <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
+ <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
+ <property name="connectionFactoryClass" value="${infinispan-cl-cache.jdbc.connectionFactory}"/>
+ <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
+ </properties>
+ <async enabled="false"/>
+ </loader>
+ </loaders>
+ </default>
+
+</infinispan>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-08-20 13:07:54 UTC (rev 2963)
@@ -26,6 +26,12 @@
<global>
<globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+
+ <transport transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport" clusterName="${infinispan-cluster-name}" distributedSyncTimeout="20000">
+ <properties>
+ <property name="configurationFile" value="${jgroups-configuration}"/>
+ </properties>
+ </transport>
</global>
<default>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-08-20 13:02:43 UTC (rev 2962)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-08-20 13:07:54 UTC (rev 2963)
@@ -59,23 +59,14 @@
<property name="root-nodetype" value="nt:unstructured" />
</properties>
</initializer>
- <!-- initializer class="org.exoplatform.services.jcr.impl.core.RestoreWorkspaceInitializer">
- <properties>
- <property name="restore-path" value="./sv_export_root.xml" />
- <property name="restore-path" value="./src/test/resources/import-export/restore_db1_ws1.xml" />
- </properties>
- </initializer -->
<cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
<properties>
<property name="index-dir" value="target/temp/index/db1/ws" />
- <!-- property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JbossCacheIndexChangesFilter" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" /-->
-
</properties>
</query-handler>
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
13 years, 10 months