exo-jcr SVN: r2415 - jcr/trunk/applications.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-05-20 09:55:28 -0400 (Thu, 20 May 2010)
New Revision: 2415
Modified:
jcr/trunk/applications/Readme.txt
jcr/trunk/applications/pom.xml
jcr/trunk/applications/product-exo-jcr-as-jboss-ear.xml
jcr/trunk/applications/product-exo-jcr-as-jonas-ear.xml
jcr/trunk/applications/product-exo-jcr-as-tomcat6.xml
Log:
EXOJCR-739 poms for deploying applications added to modules in application's reactor
Modified: jcr/trunk/applications/Readme.txt
===================================================================
--- jcr/trunk/applications/Readme.txt 2010-05-20 13:27:54 UTC (rev 2414)
+++ jcr/trunk/applications/Readme.txt 2010-05-20 13:55:28 UTC (rev 2415)
@@ -5,7 +5,7 @@
1.2. exo directory structure.
1.3. Maven version 2.2.1 (or higher).
1.4. Make sure you have run mvn insctal within ./config folder.
-2. Run "mvn -f product-exo-jcr-as-tomcat6.xml clean install antrun:run" command.
+2. Run "mvn -f product-exo-jcr-as-tomcat6.xml clean install -P deploy" command.
3. If the command has executed successfully, go to exo-tomcat and run "eXo run" command.
4. You may use other product-exo-jcr-as* and an application server if you need.
@@ -13,4 +13,4 @@
exo-configuration.xml - the main config file for the samles.
For now you may automatically deploy our samples for tomcat (WARs, JARs should be in tomcat/lib) and jboss (EAR) application server.
-Deployment procedure has been tested with tomcat-6.0.24, jboss-5.1.0.GA.
\ No newline at end of file
+Deployment procedure has been tested with tomcat-6.0.24, jboss-5.1.0.GA.
Modified: jcr/trunk/applications/pom.xml
===================================================================
--- jcr/trunk/applications/pom.xml 2010-05-20 13:27:54 UTC (rev 2414)
+++ jcr/trunk/applications/pom.xml 2010-05-20 13:55:28 UTC (rev 2415)
@@ -41,5 +41,8 @@
<module>exo.jcr.applications.fckeditor</module>
<module>exo.jcr.applications.rest</module>
<module>exo.jcr.ear</module>
+ <module>product-exo-jcr-as-jboss-ear.xml</module>
+ <module>product-exo-jcr-as-jonas-ear.xml</module>
+ <module>product-exo-jcr-as-tomcat6.xml</module>
</modules>
</project>
Modified: jcr/trunk/applications/product-exo-jcr-as-jboss-ear.xml
===================================================================
--- jcr/trunk/applications/product-exo-jcr-as-jboss-ear.xml 2010-05-20 13:27:54 UTC (rev 2414)
+++ jcr/trunk/applications/product-exo-jcr-as-jboss-ear.xml 2010-05-20 13:55:28 UTC (rev 2415)
@@ -26,14 +26,14 @@
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>exo.product.jcr</artifactId>
- <packaging>jar</packaging>
- <name>eXo JCR Product</name>
+ <artifactId>exo.jcr.applications.jboss</artifactId>
+ <packaging>pom</packaging>
+ <name>eXo JCR :: Applications :: JBoss AS</name>
<url>http://www.exoplatform.org</url>
- <description>eXo JCR Product</description>
-
- <properties>
- <enforcer.skip>true</enforcer.skip>
+ <description>eXo JCR JBoss Applications Server</description>
+
+ <properties>
+ <enforcer.skip>true</enforcer.skip>
</properties>
<dependencies>
@@ -52,7 +52,13 @@
</dependency>
</dependencies>
- <build>
+ <profiles>
+ <profile>
+ <id>deploy</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
@@ -74,6 +80,14 @@
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>install</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
<configuration>
<tasks>
<!--copying the AS-->
@@ -110,11 +124,15 @@
<fileset dir="${basedir}/target/lib-binary.dir/">
<include name="**/hsqldb*.jar" />
</fileset>
- </copy -->
+ </copy
+-->
</tasks>
</configuration>
</plugin>
</plugins>
- </build>
+ </build>
+ </profile>
+ </profiles>
+
</project>
Modified: jcr/trunk/applications/product-exo-jcr-as-jonas-ear.xml
===================================================================
--- jcr/trunk/applications/product-exo-jcr-as-jonas-ear.xml 2010-05-20 13:27:54 UTC (rev 2414)
+++ jcr/trunk/applications/product-exo-jcr-as-jonas-ear.xml 2010-05-20 13:55:28 UTC (rev 2415)
@@ -26,14 +26,14 @@
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>exo.product.jcr</artifactId>
- <packaging>jar</packaging>
- <name>eXo JCR Product</name>
+ <artifactId>exo.jcr.applications.jonas</artifactId>
+ <packaging>pom</packaging>
+ <name>eXo JCR :: Applications :: Jonas AS</name>
<url>http://www.exoplatform.org</url>
- <description>eXo JCR Product</description>
-
- <properties>
- <enforcer.skip>true</enforcer.skip>
+ <description>eXo JCR Jonas Applications Server</description>
+
+ <properties>
+ <enforcer.skip>true</enforcer.skip>
</properties>
<dependencies>
@@ -52,7 +52,13 @@
</dependency>
</dependencies>
- <build>
+ <profiles>
+ <profile>
+ <id>deploy</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
@@ -74,6 +80,14 @@
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>install</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
<configuration>
<tasks>
<!--copying the AS-->
@@ -118,6 +132,8 @@
</configuration>
</plugin>
</plugins>
- </build>
+ </build>
+ </profile>
+ </profiles>
</project>
Modified: jcr/trunk/applications/product-exo-jcr-as-tomcat6.xml
===================================================================
--- jcr/trunk/applications/product-exo-jcr-as-tomcat6.xml 2010-05-20 13:27:54 UTC (rev 2414)
+++ jcr/trunk/applications/product-exo-jcr-as-tomcat6.xml 2010-05-20 13:55:28 UTC (rev 2415)
@@ -27,12 +27,12 @@
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>exo.product.jcr</artifactId>
+ <artifactId>exo.jcrapplications.tomcat</artifactId>
<packaging>jar</packaging>
- <name>eXo JCR Product</name>
+ <name>eXo JCR :: Applications :: Tomcat AS</name>
<url>http://www.exoplatform.org</url>
- <description>eXo JCR Product</description>
-
+ <description>eXo JCR Tomcat Applications Server</description>
+
<dependencies>
<dependency>
<groupId>hsqldb</groupId>
@@ -44,13 +44,19 @@
<artifactId>slf4j-log4j12</artifactId>
<scope>runtime</scope>
</dependency>
- </dependencies>
-
- <properties>
- <enforcer.skip>true</enforcer.skip>
- </properties>
+ </dependencies>
+
+ <properties>
+ <enforcer.skip>true</enforcer.skip>
+ </properties>
- <build>
+ <profiles>
+ <profile>
+ <id>deploy</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
@@ -72,6 +78,14 @@
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>install</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
<configuration>
<tasks>
<delete>
@@ -110,6 +124,8 @@
</configuration>
</plugin>
</plugins>
- </build>
+ </build>
+ </profile>
+ </profiles>
</project>
14 years
exo-jcr SVN: r2414 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2010-05-20 09:27:54 -0400 (Thu, 20 May 2010)
New Revision: 2414
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
Log:
EXOJCR-737 : Improvement exception messages in JobRepositoryRestore.
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2010-05-20 13:26:22 UTC (rev 2413)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2010-05-20 13:27:54 UTC (rev 2414)
@@ -194,15 +194,20 @@
catch (InvalidItemStateException e)
{
restored = false;
- throw new RepositoryRestoreExeption("The repository '" + "/" + repositoryEntry.getName() + "/"
- + currennWorkspaceName + "' can not be restored! There was database error!", e);
+
+ log.error("Can not restore workspace \"" + currennWorkspaceName + " in repository \"" + repositoryEntry.getName() + "\".", e);
+
+ throw new RepositoryRestoreExeption("Can not restore workspace \"" + currennWorkspaceName + " in repository \"" + repositoryEntry.getName() + "\"."
+ + " There was database error.", e);
}
catch (Throwable t)
{
restored = false;
- throw new RepositoryRestoreExeption("The repository '" + "/" + repositoryEntry.getName() + "/"
- + currennWorkspaceName + "' can not be restored!", t);
+
+ log.error("Can not restore workspace \"" + currennWorkspaceName + " in repository \"" + repositoryEntry.getName() + "\".", t);
+
+ throw new RepositoryRestoreExeption("Can not restore workspace \"" + currennWorkspaceName + " in repository \"" + repositoryEntry.getName() + "\".", t);
}
finally
@@ -231,7 +236,7 @@
}
catch (Throwable thr)
{
- log.error("The partly restored repository '" + "/" + repositoryEntry.getName() + "' can not be removed!", thr);
+ log.error("The partly restored repository \"" + repositoryEntry.getName() + "\" can not be removed.", thr);
}
}
}
14 years
exo-jcr SVN: r2413 - jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2010-05-20 09:26:22 -0400 (Thu, 20 May 2010)
New Revision: 2413
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-737 : Use case was added to that issue.
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-05-20 13:25:49 UTC (rev 2412)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-05-20 13:26:22 UTC (rev 2413)
@@ -1838,6 +1838,33 @@
<init-params>
<value-param>
<name>bind-name</name>
+ <value>jdbcjcr25</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/jcr25" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
<value>jdbcjcr_to_rest_repo_1</value>
</value-param>
<value-param>
14 years
exo-jcr SVN: r2412 - jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2010-05-20 09:25:49 -0400 (Thu, 20 May 2010)
New Revision: 2412
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestBackupManager.java
Log:
EXOJCR-737 : Use case was added to that issue.
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestBackupManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestBackupManager.java 2010-05-20 09:22:35 UTC (rev 2411)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestBackupManager.java 2010-05-20 13:25:49 UTC (rev 2412)
@@ -1130,4 +1130,95 @@
// ok.
}
}
+
+ public void testIncrementalBackupRestoreEXOJCR_737() throws Exception
+ {
+ // full backup with BLOBs & incremental with BLOBs
+
+ // BLOBs for full
+ File tempf = createBLOBTempFile("testIncrementalBackupRestore737-", 5 * 1024); // 5M
+ tempf.deleteOnExit();
+
+ File backDir = new File("target/backup/ws1.incr737");
+ backDir.mkdirs();
+
+ BackupConfig config = new BackupConfig();
+ config.setRepository(repository.getName());
+ config.setWorkspace("ws1");
+ config.setBackupType(BackupManager.FULL_AND_INCREMENTAL);
+
+ config.setBackupDir(backDir);
+
+ backup.startBackup(config);
+
+ BackupChain bch = backup.findBackup(repository.getName(), "ws1");
+
+ // wait till full backup will be stopped
+ while (bch.getFullBackupState() != BackupJob.FINISHED)
+ {
+ Thread.yield();
+ Thread.sleep(50);
+ }
+
+ // add data
+ ws1Session.getRootNode().addNode("node_101").setProperty("exo:data", new FileInputStream(tempf));
+ ws1Session.getRootNode().addNode("node_102").setProperty("exo:extraData", new FileInputStream(tempf));
+ ws1Session.getRootNode().save(); // log here via listener
+
+ // stop backup
+ if (bch != null)
+ backup.stopBackup(bch);
+ else
+ fail("Can't get fullBackup chain");
+
+ //remove data
+ ws1Session.getRootNode().getNode("node_101").remove();
+ ws1Session.getRootNode().getNode("node_102").remove();
+ ws1Session.getRootNode().save();
+
+ // restore
+ RepositoryEntry re = (RepositoryEntry)ws1Session.getContainer().getComponentInstanceOfType(RepositoryEntry.class);
+ WorkspaceEntry ws1back = makeWorkspaceEntry("ws1back.incr737", "jdbcjcr25");
+
+ File backLog = new File(bch.getLogFilePath());
+ if (backLog.exists())
+ {
+ BackupChainLog bchLog = new BackupChainLog(backLog);
+
+ assertNotNull(bchLog.getStartedTime());
+ assertNotNull(bchLog.getFinishedTime());
+
+ backup.restore(bchLog, re.getName(), ws1back, false);
+
+ // check
+ SessionImpl back1 = null;
+ try
+ {
+ back1 = (SessionImpl)repository.login(credentials, ws1back.getName());
+
+ Node node_101 = back1.getRootNode().getNode("node_101");
+ assertNotNull(node_101);
+ assertEquals(tempf.length(), node_101.getProperty("exo:data").getStream().available());
+ compareStream(new FileInputStream(tempf), node_101.getProperty("exo:data").getStream());
+
+ Node node_102 = back1.getRootNode().getNode("node_102");
+ assertNotNull(node_102);
+ assertEquals(tempf.length(), node_102.getProperty("exo:extraData").getStream().available());
+ compareStream(new FileInputStream(tempf), node_102.getProperty("exo:extraData").getStream());
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ finally
+ {
+ if (back1 != null)
+ back1.logout();
+ }
+ }
+ else
+ fail("There are no backup files in " + backDir.getAbsolutePath());
+ }
}
14 years
exo-jcr SVN: r2411 - in core/trunk: exo.core.component.document and 1 other directories.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-05-20 05:22:35 -0400 (Thu, 20 May 2010)
New Revision: 2411
Modified:
core/trunk/exo.core.component.document/pom.xml
core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java
core/trunk/pom.xml
Log:
EXOJCR-640: Upgrading to PDFBox-1.1.0.
Modified: core/trunk/exo.core.component.document/pom.xml
===================================================================
--- core/trunk/exo.core.component.document/pom.xml 2010-05-19 13:50:04 UTC (rev 2410)
+++ core/trunk/exo.core.component.document/pom.xml 2010-05-20 09:22:35 UTC (rev 2411)
@@ -46,7 +46,7 @@
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
- <groupId>pdfbox</groupId>
+ <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
</dependency>
<dependency>
@@ -102,4 +102,4 @@
</testResource>
</testResources>
</build>
-</project>
\ No newline at end of file
+</project>
Modified: core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java
===================================================================
--- core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java 2010-05-19 13:50:04 UTC (rev 2410)
+++ core/trunk/exo.core.component.document/src/main/java/org/exoplatform/services/document/impl/PDFDocumentReader.java 2010-05-20 09:22:35 UTC (rev 2411)
@@ -26,8 +26,8 @@
import org.exoplatform.services.document.DocumentReadException;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.pdfbox.pdmodel.PDDocument;
-import org.pdfbox.util.PDFTextStripper;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.util.PDFTextStripper;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2010-05-19 13:50:04 UTC (rev 2410)
+++ core/trunk/pom.xml 2010-05-20 09:22:35 UTC (rev 2411)
@@ -267,9 +267,9 @@
</dependency>
<dependency>
- <groupId>pdfbox</groupId>
+ <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
- <version>0.7.3</version>
+ <version>1.1.0</version>
</dependency>
<dependency>
14 years
exo-jcr SVN: r2410 - in jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US: modules and 1 other directory.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2010-05-19 09:50:04 -0400 (Wed, 19 May 2010)
New Revision: 2410
Added:
jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml
Modified:
jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/master.xml
Log:
EXOJCR-706 merge with trunk docs
Modified: jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/master.xml
===================================================================
--- jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/master.xml 2010-05-19 13:40:27 UTC (rev 2409)
+++ jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/master.xml 2010-05-19 13:50:04 UTC (rev 2410)
@@ -57,6 +57,9 @@
<xi:include href="modules/performance.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="modules/portal-container.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>
Copied: jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml (from rev 2409, jcr/trunk/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml)
===================================================================
--- jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml (rev 0)
+++ jcr/tags/1.12.2-CR1/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml 2010-05-19 13:50:04 UTC (rev 2410)
@@ -0,0 +1,2516 @@
+<?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">
+<part>
+ <title>How to extend my GateIn instance?</title>
+
+ <chapter id="Introduction">
+ <title>Introduction</title>
+
+ <section id="Overview">
+ <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 id="Motivations">
+ <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>
+ </chapter>
+
+ <chapter id="Prerequisites">
+ <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 id="Removeallthehardcodedportalcontainernamei.e.portal">
+ <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 id="Removeallthehardcodedrestcontextnamei.e.rest">
+ <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 id="Removeallthehardcodedrealmnamei.e.exodomain">
+ <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 id="MakeyourHttpFilterscompatible">
+ <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 id="MakeyourHttpServletscompatible">
+ <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 id="MakeyourHttpSessionListenerscompatible">
+ <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 id="UseinittasksifyouneedaPortalContainertoinitializeanHttpFilteroranHttpServlet">
+ <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 id="MakeyourLoginModulescompatible">
+ <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 id="Avoidstaticmodifieroncomponentdependency">
+ <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 id="Avoidcomponentinitializationbasedoncomponentdependencyintheconstructor">
+ <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>
+ </chapter>
+
+ <chapter id="FAQ">
+ <title>FAQ</title>
+
+ <section id="Whathaschangedsincethepreviousversions">
+ <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 id="Whatisthemainpurposeofaportalextension">
+ <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 id="Whatisthemainpurposeofthestarter">
+ <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 id="Howaportalandaportalcontainerarerelated">
+ <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 id="HowtodefineandregisteraPortalContainerDefinition">
+ <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 wiki article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration">http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration</ulink>).</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 id="HowtheplatforminterpretsthedependencyorderdefinedintothePortalContainerDefinition">
+ <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 id="HowtochangetheServletContextnametherealmnameandortherestcontextnameofmyportalwithoutusingaPortalContainerDefinition">
+ <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 wiki article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration">http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration</ulink>).</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 id="OnJBosstestedonJBoss5.1.0.GA">
+ <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 id="OnTomcattestedonTomcat6.0.20">
+ <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 id="Howtoaddnewconfigurationfiletoagivenportalfromawarfile">
+ <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 id="Howtocreatedefineaportalextension">
+ <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 id="Howtodeployaportalextension">
+ <title>How to deploy a portal extension?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ extension?</emphasis></para>
+ </section>
+
+ <section id="Howtocreatedefineanewportal">
+ <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 id="Howtodeployanewportal">
+ <title>How to deploy a new portal?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ portal?</emphasis></para>
+ </section>
+
+ <section id="Howtoimportproperlyaconfigurationfileusingtheprefixwar">
+ <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 id="Howtoavoidduplicatingconfigurationfilesjusttorenameasimplevalue">
+ <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 id="HowtoaddorchangeaRepositoryandoraWorkspace">
+ <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 id="HowtoaddnewResourceBundlestomyportal">
+ <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 id="HowtooverwriteexistingResourceBundlesinmyportal">
+ <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 id="Howtoreplaceagroovytemplateofmyportal">
+ <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 id="HowtoaddnewPortalConfigurationsNavigationsPagesorPortletPreferencestomyportal">
+ <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 id="HowtoaddnewHttpFilterstomyportalwithoutmodifyingtheportalbinary">
+ <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 id="HowtoaddnewHttpSessionListenersandorServletContextListenerstomyportalwithoutmodifyingtheportalbinary">
+ <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 id="HowtoaddnewHttpServlettomyportalwithoutmodifyingtheportalbinary">
+ <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 wiki
+ article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/WS">http://wiki.exoplatform.com/xwiki/bin/view/WS</ulink>.</para>
+ </section>
+
+ <section id="HowtooverrideoraddaContextParametertomyportalwithoutmodifyingtheportalbinary">
+ <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 id="WherecanIfoundanexampleofhowtoextendmyportal">
+ <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 id="Howtodeploythesampleextension">
+ <title>How to deploy the sample extension?</title>
+
+ <section id="OnJBosstestedonJBoss5.1.0.GA2">
+ <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 id="OnTomcattestedonTomcat6.0.202">
+ <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 id="WherecanIfoundanexampleofhowtocreateanewportal">
+ <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 id="Howtodeploythesampleportal">
+ <title>How to deploy the sample portal?</title>
+
+ <section id="OnJBosstestedonJBoss5.1.0.GA3">
+ <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 id="OnTomcattestedonTomcat6.0.203">
+ <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 id="Igetjava.lang.IllegalStateExceptionNopreinittaskscanbeaddedtotheportalcontainerportalbecauseithasalreadybeeninitialized.whatcanIdotofixit">
+ <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 id="WhathasbeendonetoallowGateInextensions">
+ <title>What has been done to allow GateIn extensions?</title>
+
+ <para>Refer to the dedicated wiki article <ulink
+ url="What has been done to allow GateIn extensions?">What has been done
+ to allow GateIn extensions?</ulink></para>
+ </section>
+ </chapter>
+
+ <chapter id="Recommendations">
+ <title>Recommendations</title>
+
+ <section id="Dontshipyourconfigurationfileswithyourjarfiles">
+ <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 id="Useadedicatedworkspacerepositoryforyourextension">
+ <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>
+ </chapter>
+</part>
14 years
exo-jcr SVN: r2409 - in jcr/trunk/docs/userguide/en/src/main/docbook/en-US: modules and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-05-19 09:40:27 -0400 (Wed, 19 May 2010)
New Revision: 2409
Added:
jcr/trunk/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml
Modified:
jcr/trunk/docs/userguide/en/src/main/docbook/en-US/master.xml
Log:
EXOJCR-706: Uploading converted from confluence document about portal container.
Modified: jcr/trunk/docs/userguide/en/src/main/docbook/en-US/master.xml
===================================================================
--- jcr/trunk/docs/userguide/en/src/main/docbook/en-US/master.xml 2010-05-19 13:15:14 UTC (rev 2408)
+++ jcr/trunk/docs/userguide/en/src/main/docbook/en-US/master.xml 2010-05-19 13:40:27 UTC (rev 2409)
@@ -57,6 +57,9 @@
<xi:include href="modules/performance.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="modules/portal-container.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>
Added: jcr/trunk/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml
===================================================================
--- jcr/trunk/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml (rev 0)
+++ jcr/trunk/docs/userguide/en/src/main/docbook/en-US/modules/portal-container.xml 2010-05-19 13:40:27 UTC (rev 2409)
@@ -0,0 +1,2516 @@
+<?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">
+<part>
+ <title>How to extend my GateIn instance?</title>
+
+ <chapter id="Introduction">
+ <title>Introduction</title>
+
+ <section id="Overview">
+ <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 id="Motivations">
+ <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>
+ </chapter>
+
+ <chapter id="Prerequisites">
+ <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 id="Removeallthehardcodedportalcontainernamei.e.portal">
+ <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 id="Removeallthehardcodedrestcontextnamei.e.rest">
+ <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 id="Removeallthehardcodedrealmnamei.e.exodomain">
+ <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 id="MakeyourHttpFilterscompatible">
+ <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 id="MakeyourHttpServletscompatible">
+ <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 id="MakeyourHttpSessionListenerscompatible">
+ <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 id="UseinittasksifyouneedaPortalContainertoinitializeanHttpFilteroranHttpServlet">
+ <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 id="MakeyourLoginModulescompatible">
+ <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 id="Avoidstaticmodifieroncomponentdependency">
+ <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 id="Avoidcomponentinitializationbasedoncomponentdependencyintheconstructor">
+ <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>
+ </chapter>
+
+ <chapter id="FAQ">
+ <title>FAQ</title>
+
+ <section id="Whathaschangedsincethepreviousversions">
+ <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 id="Whatisthemainpurposeofaportalextension">
+ <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 id="Whatisthemainpurposeofthestarter">
+ <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 id="Howaportalandaportalcontainerarerelated">
+ <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 id="HowtodefineandregisteraPortalContainerDefinition">
+ <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 wiki article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration">http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration</ulink>).</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 id="HowtheplatforminterpretsthedependencyorderdefinedintothePortalContainerDefinition">
+ <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 id="HowtochangetheServletContextnametherealmnameandortherestcontextnameofmyportalwithoutusingaPortalContainerDefinition">
+ <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 wiki article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration">http://wiki.exoplatform.com/xwiki/bin/view/Kernel/Container+Configuration</ulink>).</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 id="OnJBosstestedonJBoss5.1.0.GA">
+ <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 id="OnTomcattestedonTomcat6.0.20">
+ <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 id="Howtoaddnewconfigurationfiletoagivenportalfromawarfile">
+ <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 id="Howtocreatedefineaportalextension">
+ <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 id="Howtodeployaportalextension">
+ <title>How to deploy a portal extension?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ extension?</emphasis></para>
+ </section>
+
+ <section id="Howtocreatedefineanewportal">
+ <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 id="Howtodeployanewportal">
+ <title>How to deploy a new portal?</title>
+
+ <para>Refer to <emphasis>How to deploy the sample
+ portal?</emphasis></para>
+ </section>
+
+ <section id="Howtoimportproperlyaconfigurationfileusingtheprefixwar">
+ <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 id="Howtoavoidduplicatingconfigurationfilesjusttorenameasimplevalue">
+ <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 id="HowtoaddorchangeaRepositoryandoraWorkspace">
+ <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 id="HowtoaddnewResourceBundlestomyportal">
+ <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 id="HowtooverwriteexistingResourceBundlesinmyportal">
+ <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 id="Howtoreplaceagroovytemplateofmyportal">
+ <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 id="HowtoaddnewPortalConfigurationsNavigationsPagesorPortletPreferencestomyportal">
+ <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 id="HowtoaddnewHttpFilterstomyportalwithoutmodifyingtheportalbinary">
+ <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 id="HowtoaddnewHttpSessionListenersandorServletContextListenerstomyportalwithoutmodifyingtheportalbinary">
+ <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 id="HowtoaddnewHttpServlettomyportalwithoutmodifyingtheportalbinary">
+ <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 wiki
+ article <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/WS">http://wiki.exoplatform.com/xwiki/bin/view/WS</ulink>.</para>
+ </section>
+
+ <section id="HowtooverrideoraddaContextParametertomyportalwithoutmodifyingtheportalbinary">
+ <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 id="WherecanIfoundanexampleofhowtoextendmyportal">
+ <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 id="Howtodeploythesampleextension">
+ <title>How to deploy the sample extension?</title>
+
+ <section id="OnJBosstestedonJBoss5.1.0.GA2">
+ <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 id="OnTomcattestedonTomcat6.0.202">
+ <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 id="WherecanIfoundanexampleofhowtocreateanewportal">
+ <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 id="Howtodeploythesampleportal">
+ <title>How to deploy the sample portal?</title>
+
+ <section id="OnJBosstestedonJBoss5.1.0.GA3">
+ <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 id="OnTomcattestedonTomcat6.0.203">
+ <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 id="Igetjava.lang.IllegalStateExceptionNopreinittaskscanbeaddedtotheportalcontainerportalbecauseithasalreadybeeninitialized.whatcanIdotofixit">
+ <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 id="WhathasbeendonetoallowGateInextensions">
+ <title>What has been done to allow GateIn extensions?</title>
+
+ <para>Refer to the dedicated wiki article <ulink
+ url="What has been done to allow GateIn extensions?">What has been done
+ to allow GateIn extensions?</ulink></para>
+ </section>
+ </chapter>
+
+ <chapter id="Recommendations">
+ <title>Recommendations</title>
+
+ <section id="Dontshipyourconfigurationfileswithyourjarfiles">
+ <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 id="Useadedicatedworkspacerepositoryforyourextension">
+ <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>
+ </chapter>
+</part>
14 years
exo-jcr SVN: r2408 - in jcr/branches/1.14.x: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow and 2 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-05-19 09:15:14 -0400 (Wed, 19 May 2010)
New Revision: 2408
Modified:
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/TransientValueData.java
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java
jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/StreamPersistedValueData.java
jcr/branches/1.14.x/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/PendingChangesLog.java
Log:
EXOJCR-732: Using SpoolFile instead of File in ValueData's constructors
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -39,6 +39,7 @@
import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
import org.exoplatform.services.jcr.impl.storage.JCRItemExistsException;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import java.io.EOFException;
@@ -441,8 +442,8 @@
(TransientValueData)(propertyData.getValues().get(listFixupStream.get(i).getValueDataId()));
// re-init the value
- tvd.delegate(new TransientValueData(tvd.getOrderNumber(), null, null, listFile.get(i), fileCleaner, -1,
- null, true));
+ tvd.delegate(new TransientValueData(tvd.getOrderNumber(), null, null, new SpoolFile(listFile.get(i)
+ .getAbsolutePath()), fileCleaner, -1, null, true));
}
}
}
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -43,6 +43,7 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.util.JCRDateFormat;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -768,8 +769,8 @@
if (pfile != null)
{
vdata =
- new TransientValueData(currentProperty.getValues().size(), null, null, pfile,
- fileCleaner, maxBufferSize, null, true);
+ new TransientValueData(currentProperty.getValues().size(), null, null,
+ new SpoolFile(pfile.getAbsolutePath()), fileCleaner, maxBufferSize, null, true);
}
else
{
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.dataflow;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -59,7 +60,7 @@
}
// TODO use InputStream instead of spoolFile and use Channel.transferFrom.
- public NewEditableValueData(File spoolFile, int orderNumber, FileCleaner fileCleaner, int maxBufferSize,
+ public NewEditableValueData(SpoolFile spoolFile, int orderNumber, FileCleaner fileCleaner, int maxBufferSize,
File tempDirectory) throws IOException
{
@@ -68,11 +69,11 @@
this.maxIOBuffSize = calcMaxIOSize();
- File sf = null;
+ SpoolFile sf = null;
FileChannel sch = null;
try
{
- sf = File.createTempFile("jcrvdedit", null, tempDirectory);
+ sf = SpoolFile.createTempFile("jcrvdedit", null, tempDirectory);
sch = new RandomAccessFile(sf, "rw").getChannel();
@@ -123,7 +124,7 @@
this.maxIOBuffSize = calcMaxIOSize();
- File sf = File.createTempFile("jcrvdedit", null, tempDirectory);
+ SpoolFile sf = SpoolFile.createTempFile("jcrvdedit", null, tempDirectory);
OutputStream sfout = new FileOutputStream(sf);
try
{
@@ -177,44 +178,6 @@
return buffSize;
}
- // public TransientValueData createTransientCopy() throws RepositoryException
- // {
- // if (isByteArray())
- // {
- // // bytes, make a copy of real data
- // byte[] newBytes = new byte[data.length];
- // System.arraycopy(data, 0, newBytes, 0, newBytes.length);
- // return new TransientValueData(newBytes, orderNumber);
- // }
- // else
- // {
- // // stream, make a copy
- // try
- // {
- // // force changes made to the file
- // spoolChannel.force(false);
- //
- // InputStream thisStream = getAsStream();
- // try
- // {
- // TransientValueData copy =
- // new TransientValueData(orderNumber, null, thisStream, null, fileCleaner, maxBufferSize,
- // tempDirectory, true);
- // copy.spoolInputStream(); // force spool - read now, till the source isn't changed
- // return copy;
- // }
- // finally
- // {
- // thisStream.close();
- // }
- // }
- // catch (IOException e)
- // {
- // throw new RepositoryException("Create transient copy error. " + e, e);
- // }
- // }
- // }
-
/**
* Update with <code>length</code> bytes from the specified <code>stream</code> to this value data
* at <code>position</code>.
@@ -294,13 +257,13 @@
{
// switch from bytes to file/channel
- File chf = null;
+ SpoolFile chf = null;
FileChannel chch = null;
long newIndex = 0; // first pos to write
try
{
- chf = File.createTempFile("jcrvdedit", null, tempDirectory);
+ chf = SpoolFile.createTempFile("jcrvdedit", null, tempDirectory);
chch = new RandomAccessFile(chf, "rw").getChannel();
// allocate the space for whole file
@@ -397,11 +360,11 @@
else
{
// switch from bytes to file/channel
- File chf = null;
+ SpoolFile chf = null;
FileChannel chch = null;
try
{
- chf = File.createTempFile("jcrvdedit", null, tempDirectory);
+ chf = SpoolFile.createTempFile("jcrvdedit", null, tempDirectory);
chch = new RandomAccessFile(chf, "rw").getChannel();
ReadableByteChannel bch = Channels.newChannel(new ByteArrayInputStream(this.data));
@@ -504,7 +467,7 @@
this.delegate = new NewEditableValueData(bytes, orderNumber, fileCleaner, maxBufferSize, tempDirectory);
}
- public EditableValueData(File spoolFile, int orderNumber, FileCleaner fileCleaner, int maxBufferSize,
+ public EditableValueData(SpoolFile spoolFile, int orderNumber, FileCleaner fileCleaner, int maxBufferSize,
File tempDirectory) throws IOException
{
this.delegate = new NewEditableValueData(spoolFile, orderNumber, fileCleaner, maxBufferSize, tempDirectory);
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/TransientValueData.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/TransientValueData.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/TransientValueData.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -70,7 +70,7 @@
protected InputStream tmpStream;
- protected File spoolFile;
+ protected SpoolFile spoolFile;
protected final boolean closeTmpStream;
@@ -146,7 +146,7 @@
* @throws IOException
* if read error
*/
- protected NewValueData(int orderNumber, byte[] bytes, InputStream stream, File spoolFile,
+ protected NewValueData(int orderNumber, byte[] bytes, InputStream stream, SpoolFile spoolFile,
FileCleaner fileCleaner, int maxBufferSize, File tempDirectory, boolean deleteSpoolFile, boolean closeTmpStream)
throws IOException
{
@@ -163,10 +163,7 @@
if (spoolFile != null)
{
- if (spoolFile instanceof SpoolFile)
- {
- ((SpoolFile)spoolFile).acquire(this);
- }
+ spoolFile.acquire(this);
if (this.tmpStream != null)
{
@@ -744,7 +741,7 @@
* @throws IOException
* if read error
*/
- public TransientValueData(int orderNumber, byte[] bytes, InputStream stream, File spoolFile,
+ public TransientValueData(int orderNumber, byte[] bytes, InputStream stream, SpoolFile spoolFile,
FileCleaner fileCleaner, int maxBufferSize, File tempDirectory, boolean deleteSpoolFile, boolean closeTmpStream)
throws IOException
{
@@ -775,7 +772,7 @@
* @throws IOException
* if read error
*/
- public TransientValueData(int orderNumber, byte[] bytes, InputStream stream, File spoolFile,
+ public TransientValueData(int orderNumber, byte[] bytes, InputStream stream, SpoolFile spoolFile,
FileCleaner fileCleaner, int maxBufferSize, File tempDirectory, boolean deleteSpoolFile) throws IOException
{
this.delegate =
@@ -823,7 +820,7 @@
* @throws IOException
* if read error
*/
- public TransientValueData(int orderNumber, File spoolFile, FileCleaner fileCleaner, boolean deleteSpoolFile)
+ public TransientValueData(int orderNumber, SpoolFile spoolFile, FileCleaner fileCleaner, boolean deleteSpoolFile)
throws IOException
{
this.delegate =
@@ -1191,7 +1188,7 @@
*
* @return File temp file
*/
- public File getSpoolFile()
+ public SpoolFile getSpoolFile()
{
if (delegate instanceof NewValueData)
{
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -21,7 +21,6 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.AbstractPersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.util.io.SwapFile;
import java.io.Externalizable;
import java.io.File;
Modified: jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/StreamPersistedValueData.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/StreamPersistedValueData.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/StreamPersistedValueData.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -41,7 +41,7 @@
protected InputStream stream;
- protected File tempFile;
+ protected SpoolFile tempFile;
/**
* StreamPersistedValueData constructor for stream data.
@@ -61,7 +61,7 @@
* @param tempFile File
* @throws FileNotFoundException
*/
- public StreamPersistedValueData(int orderNumber, File tempFile) throws FileNotFoundException
+ public StreamPersistedValueData(int orderNumber, SpoolFile tempFile) throws FileNotFoundException
{
this(orderNumber, tempFile, null);
}
@@ -91,15 +91,15 @@
* @param tempFile File
* @throws FileNotFoundException
*/
- public StreamPersistedValueData(int orderNumber, File tempFile, File destFile) throws FileNotFoundException
+ public StreamPersistedValueData(int orderNumber, SpoolFile tempFile, File destFile) throws FileNotFoundException
{
super(orderNumber, destFile);
this.tempFile = tempFile;
this.stream = null;
- if (tempFile != null && tempFile instanceof SpoolFile)
+ if (tempFile != null)
{
- ((SpoolFile)tempFile).acquire(this);
+ tempFile.acquire(this);
}
}
@@ -129,7 +129,7 @@
*
* @return File temporary file or null
*/
- public File getTempFile()
+ public SpoolFile getTempFile()
{
return tempFile;
}
@@ -233,9 +233,9 @@
((SwapFile)file).release(this);
}
- if (tempFile != null && tempFile instanceof SpoolFile)
+ if (tempFile != null)
{
- ((SpoolFile)tempFile).release(this);
+ tempFile.release(this);
}
}
finally
Modified: jcr/branches/1.14.x/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/PendingChangesLog.java
===================================================================
--- jcr/branches/1.14.x/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/PendingChangesLog.java 2010-05-18 12:29:14 UTC (rev 2407)
+++ jcr/branches/1.14.x/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/PendingChangesLog.java 2010-05-19 13:15:14 UTC (rev 2408)
@@ -25,6 +25,7 @@
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SpoolFile;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -472,7 +473,7 @@
public void restore() throws IOException
{
// TODO same code as in BackupWorkspaceInitializer?
-
+
List<ItemState> listItemState = itemDataChangesLog.getAllStates();
for (int i = 0; i < this.listFixupStream.size(); i++)
{
@@ -484,8 +485,8 @@
(TransientValueData)(propertyData.getValues().get(listFixupStream.get(i).getValueDataId()));
// re-init the value
- tvd.delegate(new TransientValueData(tvd.getOrderNumber(), null, null, listFile.get(i), fileCleaner, -1,
- null, true));
+ tvd.delegate(new TransientValueData(tvd.getOrderNumber(), null, null, new SpoolFile(listFile.get(i)
+ .getAbsolutePath()), fileCleaner, -1, null, true));
}
if (listRandomAccessFile != null)
14 years
exo-jcr SVN: r2407 - jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2010-05-18 08:29:14 -0400 (Tue, 18 May 2010)
New Revision: 2407
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestJCRSerializationEditData.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestPropsDeserialization.java
Log:
EXOJCR-497 : Tests was adapted to CASable storage.
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestJCRSerializationEditData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestJCRSerializationEditData.java 2010-05-18 11:25:19 UTC (rev 2406)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestJCRSerializationEditData.java 2010-05-18 12:29:14 UTC (rev 2407)
@@ -50,22 +50,39 @@
contentNode.setProperty("jcr:mimeType", "plain/text");
contentNode.setProperty("jcr:lastModified", session.getValueFactory().createValue(Calendar.getInstance()));
session.save();
+
+ // check 1
+ List<TransactionChangesLog> srcLog = pl.pushChanges();
+ File jcrfile = super.serializeLogs(srcLog);
+
+ List<TransactionChangesLog> destLog = super.deSerializeLogs(jcrfile);
+
+ assertEquals(srcLog.size(), destLog.size());
+
+ for (int i = 0; i < srcLog.size(); i++)
+ checkIterator(srcLog.get(i).getAllStates().iterator(), destLog.get(i).getAllStates().iterator());
+
+ // edit 1
+ pl = new TesterItemsPersistenceListener(this.session);
String newData = "____________simple_data_2____________";
-
session.getRootNode().getNode("cms3").getNode("test").getNode("nnn").getNode("jcr:content").setProperty(
"jcr:data", newData);
session.save();
- List<TransactionChangesLog> srcLog = pl.pushChanges();
+ // check 1
+ srcLog = pl.pushChanges();
- File jcrfile = super.serializeLogs(srcLog);
+ jcrfile = super.serializeLogs(srcLog);
- List<TransactionChangesLog> destLog = super.deSerializeLogs(jcrfile);
+ destLog = super.deSerializeLogs(jcrfile);
assertEquals(srcLog.size(), destLog.size());
for (int i = 0; i < srcLog.size(); i++)
checkIterator(srcLog.get(i).getAllStates().iterator(), destLog.get(i).getAllStates().iterator());
+
+
+
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestPropsDeserialization.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestPropsDeserialization.java 2010-05-18 11:25:19 UTC (rev 2406)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/serialization/TestPropsDeserialization.java 2010-05-18 12:29:14 UTC (rev 2407)
@@ -54,9 +54,7 @@
session.save();
- contentNode.setProperty("jcr:data", new FileInputStream(content2));
- session.save();
-
+ // check 1
List<TransactionChangesLog> logs = pl.pushChanges();
File jcrfile = super.serializeLogs(logs);
@@ -67,6 +65,23 @@
for (int i = 0; i < logs.size(); i++)
checkIterator(logs.get(i).getAllStates().iterator(), destLog.get(i).getAllStates().iterator());
+
+ // set value
+ pl = new TesterItemsPersistenceListener(this.session);
+ contentNode.setProperty("jcr:data", new FileInputStream(content2));
+ session.save();
+
+ // check 2
+ logs = pl.pushChanges();
+
+ jcrfile = super.serializeLogs(logs);
+
+ destLog = super.deSerializeLogs(jcrfile);
+
+ assertEquals(logs.size(), destLog.size());
+
+ for (int i = 0; i < logs.size(); i++)
+ checkIterator(logs.get(i).getAllStates().iterator(), destLog.get(i).getAllStates().iterator());
}
}
14 years
exo-jcr SVN: r2406 - in jcr/tags/1.12.2-CR1: applications/exo.jcr.applications.backupconsole/bin and 1 other directories.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2010-05-18 07:25:19 -0400 (Tue, 18 May 2010)
New Revision: 2406
Modified:
jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.cmd
jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.sh
jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jboss-ear.xml
jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jonas-ear.xml
jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-tomcat6.xml
jcr/tags/1.12.2-CR1/exo.jcr.connectors.localadapter/src/main/rar/META-INF/ra.xml
Log:
EXOJCR-733 versions in files
Modified: jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.cmd
===================================================================
--- jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.cmd 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.cmd 2010-05-18 11:25:19 UTC (rev 2406)
@@ -1 +1 @@
-java -jar exo.jcr.applications.backupconsole-1.12.2-GA-SNAPSHOT.jar %*
+java -jar exo.jcr.applications.backupconsole-1.12.2-CR1.jar %*
Modified: jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.sh
===================================================================
--- jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.sh 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/applications/exo.jcr.applications.backupconsole/bin/jcrbackup.sh 2010-05-18 11:25:19 UTC (rev 2406)
@@ -1,3 +1,3 @@
#!/bin/sh
-java -jar exo.jcr.applications.backupconsole-1.12.2-GA-SNAPSHOT.jar $*
+java -jar exo.jcr.applications.backupconsole-1.12.2-CR1.jar $*
Modified: jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jboss-ear.xml
===================================================================
--- jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jboss-ear.xml 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jboss-ear.xml 2010-05-18 11:25:19 UTC (rev 2406)
@@ -22,7 +22,7 @@
<parent>
<groupId>org.exoplatform.jcr</groupId>
<artifactId>exo.jcr.applications.config</artifactId>
- <version>1.12.2-GA-SNAPSHOT</version>
+ <version>1.12.2-CR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -40,7 +40,7 @@
<dependency>
<groupId>org.exoplatform.jcr</groupId>
<artifactId>exo.jcr.ear</artifactId>
- <version>1.12.2-GA-SNAPSHOT</version>
+ <version>1.12.2-CR1</version>
<type>ear</type>
<scope>runtime</scope>
</dependency>
Modified: jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jonas-ear.xml
===================================================================
--- jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jonas-ear.xml 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-jonas-ear.xml 2010-05-18 11:25:19 UTC (rev 2406)
@@ -22,7 +22,7 @@
<parent>
<groupId>org.exoplatform.jcr</groupId>
<artifactId>exo.jcr.applications.config</artifactId>
- <version>1.12.2-GA-SNAPSHOT</version>
+ <version>1.12.2-CR1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -40,7 +40,7 @@
<dependency>
<groupId>org.exoplatform.jcr</groupId>
<artifactId>exo.jcr.ear</artifactId>
- <version>1.12.2-GA-SNAPSHOT</version>
+ <version>1.12.2-CR1</version>
<type>ear</type>
<scope>runtime</scope>
</dependency>
Modified: jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-tomcat6.xml
===================================================================
--- jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-tomcat6.xml 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/applications/product-exo-jcr-as-tomcat6.xml 2010-05-18 11:25:19 UTC (rev 2406)
@@ -22,7 +22,7 @@
<parent>
<groupId>org.exoplatform.jcr</groupId>
<artifactId>exo.jcr.applications.config</artifactId>
- <version>1.12.2-GA-SNAPSHOT</version>
+ <version>1.12.2-CR1</version>
<relativePath>exo.jcr.applications.config</relativePath>
</parent>
Modified: jcr/tags/1.12.2-CR1/exo.jcr.connectors.localadapter/src/main/rar/META-INF/ra.xml
===================================================================
--- jcr/tags/1.12.2-CR1/exo.jcr.connectors.localadapter/src/main/rar/META-INF/ra.xml 2010-05-18 10:01:39 UTC (rev 2405)
+++ jcr/tags/1.12.2-CR1/exo.jcr.connectors.localadapter/src/main/rar/META-INF/ra.xml 2010-05-18 11:25:19 UTC (rev 2406)
@@ -25,7 +25,7 @@
<display-name>JCR repository</display-name>
<vendor-name>exoplatform</vendor-name>
<eis-type />
- <resourceadapter-version>1.12.2-GA-SNAPSHOT</resourceadapter-version>
+ <resourceadapter-version>1.12.2-CR1</resourceadapter-version>
<license>
<license-required>false</license-required>
</license>
14 years