exo-jcr SVN: r2846 - in jcr/branches/1.12.x/docs/reference/en/src/main: docbook/en-US/modules/core and 1 other directories.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-30 11:13:44 -0400 (Fri, 30 Jul 2010)
New Revision: 2846
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/conversationstate-when-membership-changed.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-configuration-hibernate.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-schema-creator-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/ldap-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-initalizer.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-listener.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/security-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/spring-security-integration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/login-page.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/organization-exo.jpg
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core.xml
Log:
EXOJCR-868 core documentation added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/conversationstate-when-membership-changed.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/conversationstate-when-membership-changed.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/conversationstate-when-membership-changed.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter>
+ <title>Update ConversationState when user's Membership changed</title>
+
+ <para>When user logged in portal in ConversationRegistry added
+ ConversationSate for this user. ConversationState keeps user's Identity that
+ is actual for logged in time. In this case even user's Membership updated in
+ OrganizationService ConversationState still keeps old (not actual Identity).
+ User must logged out and loggin in again to update Identity. To fix this
+ issue need add special listener in configuration of OrganizationServicer.
+ This listener is extended MembershipEventListener.</para>
+
+ <para>Example of configuration.</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>
+ <target-component>org.exoplatform.services.organization.OrganizationService</target-component>
+.....
+.....
+ <component-plugin>
+ <name>MembershipUpdateListener</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.exoplatform.services.organization.impl.MembershipUpdateListener</type>
+ </component-plugin>
+
+ <external-component-plugins>
+</configuration></programlisting>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-configuration-hibernate.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-configuration-hibernate.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-configuration-hibernate.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreDatabaseConfigurationforHibernate">
+ <title>Database Configuration for Hibernate</title>
+
+ <para>As usual, it is quite simple to use our configuration XML syntax to
+ configure and parametrize different Databases for eXo tables but also for
+ your own use.</para>
+
+ <section>
+ <title>Generic configuration</title>
+
+ <para>The default DB configuration uses HSQLDB, a Java Database quite
+ useful for demonstrations.</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <jmx-name>exo-service: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/portal"/>
+ <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></programlisting>
+
+ <para>In the init parameter section, we define the default hibernate
+ properties including the DB URL, the driver and the credentials in
+ use.</para>
+
+ <para>As for any portal that configuration can be overridden depending on
+ the needs of your environment.</para>
+
+ <para>Several databases have been tested and can be used in
+ production....which is not the case of HSQLDB, HSQLDB can only be used for
+ development environments and for demonstrations.</para>
+ </section>
+
+ <section>
+ <title>Example DB configuration</title>
+
+ <para>For MySQL</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.database.HibernateService</key>
+ <jmx-name>database:type=HibernateService</jmx-name>
+ <type>org.exoplatform.services.database.impl.HibernateServiceImpl</type>
+ <init-params>
+ <properties-param>
+ <name>hibernate.properties</name>
+ <description>Default Hibernate Service</description>
+ <property name="hibernate.show_sql" value="false"/>
+ <property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
+ <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/exodb?relaxAutoCommit=true&amp;amp;autoReconnect=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8"/>
+ <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
+ <property name="hibernate.connection.autocommit" value="true"/>
+ <property name="hibernate.connection.username" value="exo"/>
+ <property name="hibernate.connection.password" value="exo"/>
+ <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
+ <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></programlisting>
+ </section>
+
+ <section>
+ <title>Register custom Hibernate XML files into the service</title>
+
+ <para>It is possible to use the eXo hibernate service and register your
+ hibernate hbm.xml files to leverage some add-on features of the service
+ such as the table automatic creation as well as the cache of the hibernate
+ session in a ThreadLocal object during all the request lifecycle. To do so
+ you just have to add a plugin and indicate the location of your
+ files.</para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration>
+ <external-component-plugins>
+ <target-component>org.exoplatform.services.database.HibernateService</target-component>
+ <component-plugin>
+ <name>add.hibernate.mapping</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.database.impl.AddHibernateMappingPlugin</type>
+ <init-params>
+ <values-param>
+ <name>hibernate.mapping</name>
+ <value>org/exoplatform/services/organization/impl/UserImpl.hbm.xml</value>
+ <value>org/exoplatform/services/organization/impl/MembershipImpl.hbm.xml</value>
+ <value>org/exoplatform/services/organization/impl/GroupImpl.hbm.xml</value>
+ <value>org/exoplatform/services/organization/impl/MembershipTypeImpl.hbm.xml</value>
+ <value>org/exoplatform/services/organization/impl/UserProfileData.hbm.xml</value>
+ </values-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+</configuration></programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-schema-creator-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-schema-creator-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-schema-creator-service.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreDBSchemacreatorserviceJDBCimplementation">
+ <title>DB Schema creator service (JDBC implementation)</title>
+
+ <para>DB Schema Creator is responsible for database schema creating using a
+ DDL script inside service configuration or in an external file,
+ calling:</para>
+
+ <programlisting> org.exoplatform.services.database.jdbc.DBSchemaCreator.createTables(String dsName, String script)</programlisting>
+
+ <para>via</para>
+
+ <programlisting>org.exoplatform.services.database.jdbc.CreateDBSchemaPlugin component plugin</programlisting>
+
+ <para>A configuration example:</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.database.jdbc.DBSchemaCreator</key>
+ <type>org.exoplatform.services.database.jdbc.DBSchemaCreator</type>
+ <component-plugins>
+ <component-plugin>
+ <name>jcr.dbschema</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.database.jdbc.CreateDBSchemaPlugin</type>
+ <init-params>
+ <value-param>
+ <name>data-source</name>
+ <value>jdbcjcr</value>
+ </value-param>
+ <value-param>
+ <name>script-file</name>
+ <value>conf/storage/jcr-mjdbc.sql</value>
+ </value-param>
+ </init-params>
+ </component-plugin>
+ ........</programlisting>
+
+ <para>An example of a DDL script:</para>
+
+ <programlisting>CREATE TABLE JCR_MITEM(
+ ID VARCHAR(255) NOT NULL PRIMARY KEY,
+ VERSION INTEGER NOT NULL,
+ PATH VARCHAR(1024) NOT NULL
+ );
+CREATE INDEX JCR_IDX_MITEM_PATH ON JCR_MITEM(PATH);</programlisting>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/ldap-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/ldap-configuration.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/ldap-configuration.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,849 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreLDAPConfiguration">
+ <title>LDAP Configuration</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>You may decide that you want eXo users to be mapped to an existing
+ directory. eXo provides a flexible implementation of its
+ OrganizationService on top of LDAP. It can be used on any LDAP compliant
+ directory and even Active Directory. This page will guide you how to
+ configure eXo Platform to work with your directory.</para>
+ </section>
+
+ <section>
+ <title>Quickstart</title>
+
+ <para>If you just want to have a look at how eXo works with ldap. eXo
+ comes with a predefined ldap configuration. You just need to activate it
+ and eXo will create all it needs to work at startup.</para>
+
+ <para>You need to have a working ldap server and a user with write
+ permissions.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Open <emphasis
+ role="bold">exo-tomcat/webapps/portal/WEB-INF/conf/configuration.xml</emphasis>
+ and replace:</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><import>war:/conf/organization/hibernate-configuration.xml</import></programlisting>
+
+ <para>With</para>
+
+ <programlisting><import>war:/conf/organization/ldap-configuration.xml</import></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>0pen <emphasis role="bold">ldap-configuration.xml</emphasis> and
+ update the <emphasis role="bold">providerURL</emphasis>, <emphasis
+ role="bold">rootdn</emphasis> and password settings according to your
+ environment</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><field name="providerURL"><string>ldap://127.0.0.1:389</string></field>
+<field name="rootdn"><string>CN=Manager,DC=MyCompany,DC=com</string></field>
+<field name="password"><string>secret</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>Delete <emphasis role="bold">exo-tomcat/temp/</emphasis>* to
+ have a clean database and then start tomcat.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>eXo starts and autocreates its organization model in your directory
+ tree. Finally the structure of the default LDAP schema looks like:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/organization-exo.jpg" />
+ </imageobject>
+ </mediaobject>
+
+ <para>That's it! Now eXo uses your LDAP directory as its org model
+ storage. Users, groups and memberships are now stored and retrieved from
+ there. We suggest that you complete some guideline functions with eXo user
+ management portlet and see what it changes in your directory tree.</para>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>If you have an existing LDAP server, the eXo predefined settings
+ will likely not match your directory structure. eXo LDAP organization
+ service implementation was written with flexibility in mind and can
+ certainly be configured to meet your requirements.</para>
+
+ <para>The configuration is done in <emphasis
+ role="bold">ldap-configuration.xml</emphasis> file, and this chapter will
+ explain the numerous parameters it contains.</para>
+
+ <section>
+ <title>Connection Settings</title>
+
+ <para>Firstly, start by connection settings which will tell eXo how to
+ connect to your directory server. These settings are very close to
+ <ulink url="JNDI API>http://java.sun.com/products/jndi">JNDI
+ API>http://java.sun.com/products/jndi</ulink> context parameters.
+ This configuration is activated by the init-param ldap.config of service
+ LDAPServiceImpl.</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.ldap.LDAPService</key>
+ <type>org.exoplatform.services.ldap.impl.LDAPServiceImpl</type>
+ <init-params>
+ <object-param>
+ <name>ldap.config</name>
+ <description>Default ldap config</description>
+ <object type="org.exoplatform.services.ldap.impl.LDAPConnectionConfig">
+ <field name="providerURL"><string>ldap://127.0.0.1:389,10.0.0.1:389</string></field>
+ <field name="rootdn"><string>CN=Manager,DC=exoplatform,DC=org</string></field>
+ <field name="password"><string>secret</string></field>
+ <!-- field name="authenticationType"><string>simple</string></field-->
+ <field name="version"><string>3</string></field>
+ <field name="referralMode"><string>follow</string></field>
+ <!-- field name="serverName"><string>active.directory</string></field-->
+ </object>
+ </object-param>
+ </init-params>
+</component></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">providerURL</emphasis>: LDAP server URL
+ (see <ulink
+ url="PROVIDER_URL>http://java.sun.com/products/jndi/1.2/javadoc/javax/namin...">PROVIDER_URL>http://java.sun.com/products/jndi/1.2/javadoc/javax/namin...</ulink>).
+ For multiple ldap servers, use comma separated list of host:port
+ (Ex. ldap://127.0.0.1:389,10.0.0.1:389).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">rootdn</emphasis>: dn of user that will
+ be used by the service to authenticate on the server (see <ulink
+ url="SECURITY_PRINCIPAL>http://java.sun.com/products/jndi/1.2/javadoc/javax...">SECURITY_PRINCIPAL>http://java.sun.com/products/jndi/1.2/javadoc/javax...</ulink>).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">password</emphasis>: password for user
+ rootdn (see <ulink
+ url="SECURITY_CREDENTIALS>http://java.sun.com/products/jndi/1.2/javadoc/jav...">SECURITY_CREDENTIALS>http://java.sun.com/products/jndi/1.2/javadoc/jav...</ulink>).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">authenticationType</emphasis>: type of
+ authentication to be used (see <ulink
+ url="SECURITY_AUTHENTICATION>http://java.sun.com/products/jndi/1.2/javadoc/...">SECURITY_AUTHENTICATION>http://java.sun.com/products/jndi/1.2/javadoc/...</ulink>).
+ Use one of none, simple, strong. Default is simple.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">version</emphasis>: LDAP protocol
+ version (see <ulink
+ url="java.naming.ldap.version>http://java.sun.com/products/jndi/tutorial/ld...">java.naming.ldap.version>http://java.sun.com/products/jndi/tutorial/ld...</ulink>).
+ Set to 3 if your server supports LDAP V3.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">referalMode</emphasis>: one of follow,
+ ignore,throw (see <ulink
+ url="REFERRAL>http://java.sun.com/products/jndi/1.2/javadoc/javax/naming/Co...">REFERRAL>http://java.sun.com/products/jndi/1.2/javadoc/javax/naming/Co...</ulink>).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">serverName</emphasis>: you will need to
+ set this to active.directory in order to work with Active Directory
+ servers. Any other value will be ignore and the service will act as
+ on a standard LDAP.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Organization Service Configuration</title>
+
+ <para>Next, you need to configure the eXo <emphasis
+ role="bold">OrganizationService</emphasis> to tell him how the directory
+ is structured and how to interact with it. This is managed by a couple
+ of of init-params : <emphasis role="bold">ldap.userDN.key</emphasis> and
+ <emphasis role="bold">ldap.attribute.mapping</emphasis> in file
+ <emphasis role="bold">ldap-configuration.xml</emphasis> (by default
+ located at portal.war/WEB-INF/conf/organization)</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.organization.OrganizationService</key>
+ <type>org.exoplatform.services.organization.ldap.OrganizationServiceImpl</type>
+ [...]
+ <init-params>
+ <value-param>
+ <name>ldap.userDN.key</name>
+ <description>The key used to compose user DN</description>
+ <value>cn</value>
+ </value-param>
+ <object-param>
+ <name>ldap.attribute.mapping</name>
+ <description>ldap attribute mapping</description>
+ <object type="org.exoplatform.services.organization.ldap.LDAPAttributeMapping">
+ [...]
+ </object-param>
+ </init-params>
+ [...]
+</component></programlisting>
+
+ <para><emphasis role="bold">ldap.attribute.mapping</emphasis> maps your
+ ldap to eXo. At first there are two main parameters to configure in
+ it:</para>
+
+ <programlisting><field name="baseURL"><string>dc=exoplatform,dc=org</string></field>
+<field name="ldapDescriptionAttr"><string>description</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">baseURL</emphasis>: root dn for eXo
+ organizational entities. This entry can't be created by eXo and must
+ preexist in directory.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">ldapDescriptionAttr</emphasis> (since
+ core 2.2+) : Name of a common attribute that will be used as
+ description for groups and membership types.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>(since core 2.2+) : Name of a common attribute that will be used
+ as description for groups and membership types.</para>
+ </note>
+
+ <para>Other parameters are discussed in the following sections.</para>
+
+ <section>
+ <title>Users</title>
+
+ <section>
+ <title>Main parameters</title>
+
+ <para>Here are the main parameters to map eXo users to your
+ directory :</para>
+
+ <programlisting><field name="userURL"><string>ou=users,ou=portal,dc=exoplatform,dc=org</string></field>
+<field name="userObjectClassFilter"><string>objectClass=person</string></field>
+<field name="userLDAPClasses"><string>top,person,organizationalPerson,inetOrgPerson</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">userURL</emphasis> : base dn for
+ users. Users are created in a flat structure under this base
+ with a dn of the form: <emphasis
+ role="bold">ldap.userDN.key=username,userURL</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : </para>
+
+ <programlisting>uid=john,cn=People,o=MyCompany,c=com</programlisting>
+
+ <para>However, if users exist deeply under userURL, eXo will be able
+ to retrieve them.</para>
+
+ <para>Example : </para>
+
+ <programlisting>uid=tom,ou=France,ou=EMEA,cn=People,o=MyCompany,c=com</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">userObjectClassFilter</emphasis>:
+ Filter used under userURL branch to distinguish eXo user entries
+ from others.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : john and tom will be recognized as valid eXo users
+ but EMEA and France entries will be ignored in the following subtree
+ :</para>
+
+ <programlisting>uid=john,cn=People,o=MyCompany,c=com
+ objectClass: person
+ …
+ou=EMEA,cn=People,o=MyCompany,c=com
+ objectClass: organizationalUnit
+ …
+ ou=France,ou=EMEA,cn=People,o=MyCompany,c=com
+ objectClass: organizationalUnit
+ …
+ uid=tom,ou=EMEA,cn=People,o=MyCompany,c=com
+ objectClass: person
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">userLDAPClasses</emphasis> : comma
+ separated list of classes used for user creation.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When creating a new user, an entry will be created with the
+ given objectClass attributes. The classes must at least define cn
+ and any attribute refernced in the user mapping.</para>
+
+ <para>Example : Adding the user Marry Simons could produce :</para>
+
+ <programlisting>uid=marry,cn=users,ou=portal,dc=exoplatform,dc=org
+ objectclass: top
+ objectClass: person
+ objectClass: organizationalPerson
+ objectClass: inetOrgPerson
+ …</programlisting>
+ </section>
+
+ <section>
+ <title>User mapping</title>
+
+ <para>The following parameters maps ldap attributes to eXo User java
+ objects attributes.</para>
+
+ <programlisting><field name="userUsernameAttr"><string>uid</string></field>
+<field name="userPassword"><string>userPassword</string></field>
+<field name="userFirstNameAttr"><string>givenName</string></field>
+<field name="userLastNameAttr"><string>sn</string></field>
+<field name="userDisplayNameAttr"><string>displayName</string></field>
+<field name="userMailAttr"><string>mail</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">userUsernameAttr</emphasis>:
+ username (login)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">userPassword</emphasis>: password
+ (used when portal authentication is done by eXo login
+ module)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">userFirstNameAttr</emphasis>:
+ firstname</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">userLastNameAttr</emphasis>:
+ lastname</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">userDisplayNameAttr</emphasis>:
+ displayed name</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">userMailAttr</emphasis>: email
+ address</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : In the previous example, user Marry Simons could
+ produce :</para>
+
+ <programlisting>uid=marry,cn=users,ou=portal,dc=exoplatform,dc=org
+ objectclass: top
+ objectClass: person
+ objectClass: organizationalPerson
+ objectClass: inetOrgPerson
+ …</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Groups</title>
+
+ <para>eXo groups can be mapped to organizational or applicative groups
+ defined in your directory.</para>
+
+ <programlisting><field name="groupsURL"><string>ou=groups,ou=portal,dc=exoplatform,dc=org</string></field>
+<field name="groupLDAPClasses"><string>top,organizationalUnit</string></field>
+<field name="groupObjectClassFilter"><string>objectClass=organizationalUnit</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">groupsURL</emphasis> : base dn for eXo
+ groups</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Groups can be structured hierarchically under groupsURL.</para>
+
+ <para>Example: Groups communication, communication/marketing and
+ communication/press would map to :</para>
+
+ <programlisting>ou=communication,ou=groups,ou=portal,dc=exoplatform,dc=org
+…
+ ou=marketing,ou=communication,ou=groups,ou=portal,dc=exoplatform,dc=org
+ …
+ ou=press,ou=communication,ou=groups,ou=portal,dc=exoplatform,dc=org
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">groupLDAPClasses</emphasis>: comma
+ separated list of classes used for group creation.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When creating a new group, an entry will be created with the
+ given objectClass attributes. The classes must define at least the
+ required attributes: <emphasis role="bold">ou</emphasis>, <emphasis
+ role="bold">description</emphasis> and <emphasis
+ role="bold">l</emphasis>.</para>
+
+ <note>
+ <para>l attribute corresponds to the City property in OU property
+ editor</para>
+ </note>
+
+ <para>Example : Adding the group human-resources could produce:</para>
+
+ <programlisting>ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ objectclass: top
+ objectClass: organizationalunit
+ ou: human-resources
+ description: The human resources department
+ l: Human Resources
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">groupObjectClassFilter</emphasis>:
+ filter used under groupsURL branch to distinguish eXo groups from
+ other entries. You can also use a complex filter if you
+ need.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : groups WebDesign, WebDesign/Graphists and Sales could
+ be retrieved in :</para>
+
+ <programlisting>l=Paris,dc=sites,dc=mycompany,dc=com
+ …
+ ou=WebDesign,l=Paris,dc=sites,dc=mycompany,dc=com
+ …
+ ou=Graphists,WebDesign,l=Paris,dc=sites,dc=mycompany,dc=com
+ …
+l=London,dc=sites,dc=mycompany,dc=com
+ …
+ ou=Sales,l=London,dc=sites,dc=mycompany,dc=com
+ …</programlisting>
+ </section>
+
+ <section>
+ <title>Membership Types</title>
+
+ <para>Membership types are the possible roles that can be assigned to
+ users in groups.</para>
+
+ <programlisting><field name="membershipTypeURL"><string>ou=memberships,ou=portal,dc=exoplatform,dc=org</string></field>
+<field name="membershipTypeLDAPClasses"><string>top,organizationalRole</string></field>
+<field name="membershipTypeNameAttr"><string>cn</string></field></programlisting>
+
+ <para></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipTypeURL</emphasis> : base dn
+ for membership types storage.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>eXo stores membership types in a flat structure under
+ membershipTypeURL.</para>
+
+ <para>Example : Roles manager, user, admin and editor could by defined
+ by the subtree :</para>
+
+ <programlisting>ou=roles,ou=portal,dc=exoplatform,dc=org
+…
+ cn=manager,ou=roles,ou=portal,dc=exoplatform,dc=org
+ …
+ cn=user,ou=roles,ou=portal,dc=exoplatform,dc=org
+ …
+ cn=admin,ou=roles,ou=portal,dc=exoplatform,dc=org
+ …
+ cn=editor,ou=roles,ou=portal,dc=exoplatform,dc=org
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipTypeLDAPClasses</emphasis>:
+ comma separated list of classes for membership types
+ creation.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When creating a new membership type, an entry will be created
+ with the given objectClass attributes. The classes must define the
+ required attributes : <emphasis role="bold">description</emphasis>,
+ <emphasis role="bold">cn</emphasis></para>
+
+ <para>Example : Adding membership type validator would produce
+ :</para>
+
+ <programlisting>cn=validator,ou=roles,ou=portal,dc=exoplatform,dc=org
+ objectclass: top
+ objectClass: organizationalRole
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipTypeNameAttr</emphasis> :
+ Attribute that will be used as the name of the role</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : If membershipTypeNameAttr is 'cn', then role name is
+ 'manager' for the following membership type entry :</para>
+
+ <programlisting>cn=manager,ou=roles,ou=portal,dc=exoplatform,dc=org </pre></programlisting>
+ </section>
+
+ <section>
+ <title>Memberships</title>
+
+ <para>Memberships are used to assign a role within a group. They are
+ entries that are placed under the group entry of their scope group.
+ Users in this role are defined as attributes of the membership
+ entry.</para>
+
+ <para>Example: To designate tom as the manager of the group
+ human-resources :</para>
+
+ <programlisting>ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ …
+ cn=manager,ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ member: uid=tom,ou=users,ou=portal,dc=exoplatform,dc=org
+ …</programlisting>
+
+ <para>The parameters to configure memberships are :</para>
+
+ <programlisting><field name="membershipLDAPClasses"><string>top,groupOfNames</string></field>
+<field name="membershipTypeMemberValue"><string>member</string></field>
+<field name="membershipTypeRoleNameAttr"><string>cn</string></field>
+<field name="membershipTypeObjectClassFilter"><string>objectClass=organizationalRole</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipLDAPClasses</emphasis> :
+ comma separated list of classes used to create memberships.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When creating a new membership, an entry will be created with
+ the given objectClass attributes. The classes must at least define the
+ attribute designated by membershipTypeMemberValue.</para>
+
+ <para>Example : Adding membership validator would produce : </para>
+
+ <programlisting>cn=validator,ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ objectclass: top
+ objectClass: groupOfNames
+ …</programlisting>
+
+ <para><pre>
+ cn=validator,ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ objectclass: top objectClass: groupOfNames ... </pre></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipTypeMemberValue</emphasis>:
+ Multivalued attribute used in memberships to reference users that
+ have the role in the group.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Values should be a user dn.</para>
+
+ <para>Example: james and root have admin role within the group
+ human-resources, would give:</para>
+
+ <programlisting>cn=admin,ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ member: cn=james,ou=users,ou=portal,dc=exoplatform,dc=org
+ member: cn=root,ou=users,ou=portal,dc=exoplatform,dc=org
+ …</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">membershipTypeRoleNameAttr</emphasis>:
+ Attribute of the membership entry whose value references the
+ membership type.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example : In the following membership entry:</para>
+
+ <para><pre>
+ cn=manager,ou=human-resources,ou=groups,ou=portal,dc=exoplatform,dc=org
+ </pre></para>
+
+ <para>'cn' attribute is used to designate the 'manager' membership
+ type. Which could also be said : The name of the role is given by 'cn'
+ the attribute.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis
+ role="bold">membershipTypeObjectClassFilter</emphasis> : Filter
+ used to distinguish membership entries under groups.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You can use rather complex filters.</para>
+
+ <para>Example: Here is a filter we used for a customer that needed to
+ trigger a dynlist overlay on openldap.</para>
+
+ <programlisting>(&amp;(objectClass=ExoMembership)(membershipURL=*))
+</programlisting>
+
+ <para>Note : Pay attention to the xml escaping of the '&' (and)
+ operator</para>
+ </section>
+
+ <section>
+ <title>User Profiles</title>
+
+ <para>eXo User profiles also have entries in the ldap but the actual
+ storage is still done with the hibernate service. You will need the
+ following parameters :</para>
+
+ <programlisting><field name="profileURL"><string>ou=profiles,ou=portal,dc=exoplatform,dc=org</string></field>
+<field name="profileLDAPClasses"><string>top,organizationalPerson</string></field></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">profileURL</emphasis>: base dn to
+ store user profiles</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">profileLDAPClasses</emphasis>: Classes
+ used to when creating user profiles</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Advanced topics</title>
+
+ <section>
+ <title>Automatic directory population</title>
+
+ <para>At startup eXo can populate the organization model based on</para>
+
+ <para>eXo organizational model has User,Group,Membership and Profile
+ entities. For each, we define a base dn that should be below baseURL. At
+ startup, if one of userURL, groupsURL, membershipTypeURL or profileURL
+ does not exist fully, eXo will attempt to create the missing subtree by
+ parsing the dn and creating entries on-the-fly. To determine the classes
+ of the created entries, the following rules are applied :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>ou=... : objectClass=top,objectClass=organizationalUnit</para>
+ </listitem>
+
+ <listitem>
+ <para>cn=... : objectClass=top,objectClass=organizationalRole</para>
+ </listitem>
+
+ <listitem>
+ <para>c=... : objectClass=country</para>
+ </listitem>
+
+ <listitem>
+ <para>o=... : objectClass=organization</para>
+ </listitem>
+
+ <listitem>
+ <para>dc=.. :
+ objectClass=top,objectClass=dcObject,objectClass=organization</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Example:</para>
+
+ <para>If baseURL is <emphasis role="bold">o=MyCompany,c=com</emphasis>
+ and groupsURL is <emphasis
+ role="bold">dc=groups,cn=Extranet,c=France,ou=EMEA,o=MyCompany,c=com</emphasis>
+ then, the following subtree will be created :</para>
+
+ <programlisting>ou=EMEA,o=MyCompany,c=com
+ objectClass: top
+ objectClass: organizationalUnit
+ …
+ c=France,ou=EMEA,o=MyCompany,c=com
+ objectClass: top
+ objectClass: country
+ …
+ cn=Extranet,c=France,ou=EMEA,o=MyCompany,c=com
+ objectClass: top
+ objectClass: organizationalRole
+ …
+ dc=groups,cn=Extranet,c=France,ou=EMEA,o=MyCompany,c=com
+ objectClass: top
+ objectClass: dcObject
+ objectClass: organization
+ …</programlisting>
+ </section>
+
+ <section>
+ <title>Active Directory sample configuration</title>
+
+ <para>Here is an alternative configuration for active directory that you
+ can find in <emphasis
+ role="bold">activedirectory-configuration.xml</emphasis></para>
+
+ <note>
+ <para>There is a microsoft limitation: password can't be set in AD via
+ unsecured connection you have to use the ldaps protocol</para>
+ </note>
+
+ <para>#info("There is a microsoft limitation: password can't be set in
+ AD via unsecured connection you have to use the ldaps protocol")</para>
+
+ <para>here is how to use LDAPS protocol with Active Directory :</para>
+
+ <programlisting>1 setup AD to use SSL:
+
+ * add Active Directory Certificate Services role
+ * install right certificate for DC machine
+
+2 enable Java VM to use certificate from AD:
+
+ * import root CA used in AD, to keystore, something like
+
+ keytool -importcert -file 2008.cer -keypass changeit -keystore /home/user/java/jdk1.6/jre/lib/security/cacerts
+
+ * set java options
+
+ JAVA_OPTS="${JAVA_OPTS} -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=/home/user/java/jdk1.6/jre/lib/security/cacerts"</programlisting>
+
+ <programlisting>[...]
+ <component>
+ <key>org.exoplatform.services.ldap.LDAPService</key>
+[..]
+ <object type="org.exoplatform.services.ldap.impl.LDAPConnectionConfig">
+ <!-- for multiple ldap servers, use comma seperated list of host:port (Ex. ldap://127.0.0.1:389,10.0.0.1:389) -->
+ <!-- whether or not to enable ssl, if ssl is used ensure that the javax.net.ssl.keyStore & java.net.ssl.keyStorePassword properties are set -->
+ <!-- exo portal default installed javax.net.ssl.trustStore with file is java.home/lib/security/cacerts-->
+ <!-- ldap service will check protocol, if protocol is ldaps, ssl is enable (Ex. for enable ssl: ldaps://10.0.0.3:636 ;for disable ssl: ldap://10.0.0.3:389 ) -->
+ <!-- when enable ssl, ensure server name is *.directory and port (Ex. active.directory) -->
+ <field name="providerURL"><string>ldaps://10.0.0.3:636</string></field>
+ <field name="rootdn"><string>CN=Administrator,CN=Users, DC=exoplatform,DC=org</string></field>
+ <field name="password"><string>site</string></field>
+ <field name="version"><string>3</string></field>
+ <field name="referralMode"><string>ignore</string></field>
+ <field name="serverName"><string>active.directory</string></field>
+ </object>
+[..]
+ <component>
+ <key>org.exoplatform.services.organization.OrganizationService</key>
+ [...]
+ <object type="org.exoplatform.services.organization.ldap.LDAPAttributeMapping">
+ [...]
+ <field name="userAuthenticationAttr"><string>mail</string></field>
+ <field name="userUsernameAttr"><string>sAMAccountName</string></field>
+ <field name="userPassword"><string>unicodePwd</string></field>
+ <field name="userLastNameAttr"><string>sn</string></field>
+ <field name="userDisplayNameAttr"><string>displayName</string></field>
+ <field name="userMailAttr"><string>mail</string></field>
+ [..]
+ <field name="membershipTypeLDAPClasses"><string>top,group</string></field>
+ <field name="membershipTypeObjectClassFilter"><string>objectClass=group</string></field>
+ [..]
+ <field name="membershipLDAPClasses"><string>top,group</string></field>
+ <field name="membershipObjectClassFilter"><string>objectClass=group</string></field>
+ </object>
+ [...]
+</component> </programlisting>
+ </section>
+
+ <section>
+ <title>OpenLDAP dynlist overlays</title>
+
+ <para>If you use OpenLDAP, you may want to use the <ulink
+ url="overlays > http://www.openldap.org/faq/data/cache/1169.html">overlays
+ > http://www.openldap.org/faq/data/cache/1169.html</ulink>. Here is
+ how you can use the <ulink
+ url="dynlist overlay > http://www.openldap.org/faq/data/cache/1209.html">dynlist
+ overlay > http://www.openldap.org/faq/data/cache/1209.html</ulink> to
+ have memberships dynamically populated.</para>
+
+ <para>The main idea is to have your memberships populated dynamically by
+ an ldap query. Thus, you no longer have to maintain manually the roles
+ on users.</para>
+
+ <para>To configure the dynlist, add the following to your <emphasis
+ role="bold">slapd.conf</emphasis> :</para>
+
+ <programlisting>dynlist-attrset ExoMembership membershipURL member</programlisting>
+
+ <para>This snipet means : On entries that have ExoMembership class, use
+ the URL defined in the value of attribute membershipURL as a query and
+ populate results under the multivalues attribute member.</para>
+
+ <para>Now let's declare the corresponding schema (replace XXXXX to adapt
+ to your own IANA code):</para>
+
+ <programlisting>attributeType ( 1.3.6.1.4.1.XXXXX.1.59 NAME 'membershipURL' SUP memberURL )</programlisting>
+
+ <para>membershipURL inherits from memberURL.</para>
+
+ <programlisting>objectClass ( 1.3.6.1.4.1.XXXXX.2.12 NAME 'ExoMembership' SUP top MUST ( cn ) MAY (membershipURL $ member $ description ) )</programlisting>
+
+ <para>ExoMembership must define cn and can have attributes :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>membershipURL: trigger for the dynlist</para>
+ </listitem>
+
+ <listitem>
+ <para>member : attribute populated by the dynlist</para>
+ </listitem>
+
+ <listitem>
+ <para>description : used by eXo for display</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting># the TestGroup group
+dn: ou=testgroup,ou=groups,ou=portal,o=MyCompany,c=com
+objectClass: top
+objectClass: organizationalUnit
+ou: testgroup
+l: TestGroup
+description: the Test Group</programlisting>
+
+ <para>On this group, we can bind an eXo membership where the overlay
+ will occur:</para>
+
+ <programlisting># the manager membership on group TestGroup
+dn: cn=manager, ou=TestGroup,ou=groups,ou=portal,o=MyCompany,c=com
+objectClass: top
+objectClass: ExoMembership
+membershipURL: ldap:///ou=users,ou=portal,o=MyCompany,c=com??sub?(uid=*)
+cn: manager</programlisting>
+
+ <para>This dynlist assigns the role <emphasis
+ role="bold">manager:/testgroup</emphasis> to any user.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-initalizer.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-initalizer.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-initalizer.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreOrganizationServiceInitializer">
+ <title>Organization Service Initializer</title>
+
+ <para>Use the Organization Service Initializer to create users, groups and
+ membership types by default.</para>
+
+ <programlisting><external-component-plugins>
+ <target-component>org.exoplatform.services.organization.OrganizationService</target-component>
+ <component-plugin>
+ <name>init.service.listener</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.exoplatform.services.organization.OrganizationDatabaseInitializer</type>
+ <description>this listener populate organization data for the first launch</description>
+ <init-params>
+ <value-param>
+ <name>checkDatabaseAlgorithm</name>
+ <description>check database</description>
+ <value>entry</value>
+ </value-param>
+ <value-param>
+ <name>printInformation</name>
+ <description>Print information init database</description>
+ <value>false</value>
+ </value-param>
+ <object-param>
+ <name>configuration</name>
+ <description>description</description>
+ <object type="org.exoplatform.services.organization.OrganizationConfig">
+ <field name="membershipType">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.organization.OrganizationConfig$MembershipType">
+ <field name="type">
+ <string>manager</string>
+ </field>
+ <field name="description">
+ <string>manager membership type</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+
+ <field name="group">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.organization.OrganizationConfig$Group">
+ <field name="name">
+ <string>platform</string>
+ </field>
+ <field name="parentId">
+ <string></string>
+ </field>
+ <field name="description">
+ <string>the /platform group</string>
+ </field>
+ <field name="label">
+ <string>Platform</string>
+ </field>
+ </object>
+ </value>
+ <value>
+ <object type="org.exoplatform.services.organization.OrganizationConfig$Group">
+ <field name="name">
+ <string>administrators</string>
+ </field>
+ <field name="parentId">
+ <string>/platform</string>
+ </field>
+ <field name="description">
+ <string>the /platform/administrators group</string>
+ </field>
+ <field name="label">
+ <string>Administrators</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+
+ <field name="user">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.organization.OrganizationConfig$User">
+ <field name="userName">
+ <string>root</string>
+ </field>
+ <field name="password">
+ <string>exo</string>
+ </field>
+ <field name="firstName">
+ <string>Root</string>
+ </field>
+ <field name="lastName">
+ <string>Root</string>
+ </field>
+ <field name="email">
+ <string>root@localhost</string>
+ </field>
+ <field name="groups">
+ <string>
+ manager:/platform/administrators
+ </string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins></programlisting>
+
+ <para>Params for membership type: </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>type - The membership type's name</para>
+ </listitem>
+
+ <listitem>
+ <para>description - The membership type's description</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Params for group:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>name - The group's name</para>
+ </listitem>
+
+ <listitem>
+ <para>parentId - The id of the parent group. If the parent id is null,
+ it mean that the group is at the first level. The parentId should have
+ the form: /ancestor/parent</para>
+ </listitem>
+
+ <listitem>
+ <para>description - The group's description</para>
+ </listitem>
+
+ <listitem>
+ <para>label - The group's label</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Params for user:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>userName - The user's name</para>
+ </listitem>
+
+ <listitem>
+ <para>password - The user's password</para>
+ </listitem>
+
+ <listitem>
+ <para>firstName - The user's first name</para>
+ </listitem>
+
+ <listitem>
+ <para>lastName - The user's last name</para>
+ </listitem>
+
+ <listitem>
+ <para>email - The user's email</para>
+ </listitem>
+
+ <listitem>
+ <para>groups - The user's membership types and groups in which he
+ consist.</para>
+ </listitem>
+ </itemizedlist>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-listener.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-listener.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-listener.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"hp://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreOrganizationListener">
+ <title>Organization Listener</title>
+
+ <section>
+ <title>Overview</title>
+
+ <para>The <link linkend="CoreOrganizationService">Organization
+ Service</link>The Core Organization Service provides a mechanism to
+ receive notifications when :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>a User is created, deleted or modified</para>
+ </listitem>
+
+ <listitem>
+ <para>a Group is created, deleted or modified</para>
+ </listitem>
+
+ <listitem>
+ <para>a Membership is created or removed</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This mechanism is very useful to cascade some actions when the
+ organization model is modified. For example, it is currently used to
+ :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>initialize the personal portal pages</para>
+ </listitem>
+
+ <listitem>
+ <para>initialize the personal calendars, address books and mail
+ accounts in CS</para>
+ </listitem>
+
+ <listitem>
+ <para>create drives and personal areas in ECM</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Writing your own listeners</title>
+
+ <para>To implement your own listener you just need to write extend some
+ existing listener classes. These classes define hooks that are invoked
+ before or after operations are performed on organization model.</para>
+
+ <section>
+ <title>UserEventListener</title>
+
+ <para>To listen to user changes, you need to extend
+ <>org.exoplatform.services.organization.UserEventListener</>
+ :</para>
+
+ <programlisting>public class MyUserListener extends UserEventListener {
+
+ public void preSave(User user, boolean isNew) throws Exception {
+ System.out.println("Before " + (isNew?"creating":"updating") + " user " + user.getUserName());
+ }
+
+ public void postSave(User user, boolean isNew) throws Exception {
+ System.out.println("After user " + user.getUserName() + (isNew?" created":" updated"));
+ }
+
+ public void preDelete(User user) throws Exception {
+ System.out.println("Before deleting user " + user.getUserName());
+ }
+
+ public void preDelete(User user) throws Exception {
+ System.out.println("After deleting user " + user.getUserName());
+ }
+
+}</programlisting>
+ </section>
+
+ <section>
+ <title>GroupEventListener</title>
+
+ <para>To listen to group changes, you need to extend
+ <>org.exoplatform.services.organization.GroupEventListener</>
+ :</para>
+
+ <programlisting>public class MyGroupListener extends GroupEventListener {
+
+ public void preSave(Group group, boolean isNew) throws Exception {
+ System.out.println("Before " + (isNew?"creating":"updating") + " group " + group.getName());
+ }
+
+ public void postSave(Group group, boolean isNew) throws Exception {
+ System.out.println("After group " + group.getName() + (isNew?" created":" updated"));
+ }
+
+ public void preDelete(Group group) throws Exception {
+ System.out.println("Before deleting group " + group.getName());
+ }
+
+ public void preDelete(Group group) throws Exception {
+ System.out.println("After deleting group " + group.getName());
+ }
+}</programlisting>
+ </section>
+
+ <section>
+ <title>MembershipEventListener</title>
+
+ <para>To listen to membership changes, you need to extend
+ <>org.exoplatform.services.organization.MembershipEventListener</>
+ :</para>
+
+ <programlisting>public class MyMembershipListener extends MembershipEventListener {
+
+ public void preSave(Membership membership, boolean isNew) throws Exception {
+ System.out.println("Before " + (isNew?"creating":"updating") + " membership.");
+ }
+
+ public void postSave(Membership membership, boolean isNew) throws Exception {
+ System.out.println("After membership " + (isNew?" created":" updated"));
+ }
+
+ public void preDelete(Membership membership) throws Exception {
+ System.out.println("Before deleting membership");
+ }
+
+ public void preDelete(Membership membership) throws Exception {
+ System.out.println("After deleting membership");
+ }
+}</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Registering your listeners</title>
+
+ <para>Registering the listeners is then achieved by using the ExoContainer
+ plugin mechanism. Learn more about it on the <link
+ linkend="KernelServiceConfigurationForBeginners">Service Configuration for
+ Beginners</link> article.</para>
+
+ <para>To effectively register organization service's listeners you simply
+ need to use the <>addListenerPlugin</> seer injector.</para>
+
+ <para>So, the easiest way to register your listeners is to pack them into
+ a .jar and create a configuration file into it under <emphasis
+ role="bold">mylisteners.jar!/conf/portal/configuration.xml</emphasis></para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration>
+ <external-component-plugins>
+ <target-component>org.exoplatform.services.organization.OrganizationService</target-component>
+ <component-plugin>
+ <name>myuserplugin</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.example.MyUserListener</type>
+ <description></description>
+ </component-plugin>
+ <component-plugin>
+ <name>mygroupplugin</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.example.MyGroupListener</type>
+ <description></description>
+ </component-plugin>
+ <component-plugin>
+ <name>mymembershipplugin</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.example.MyMembershipListener</type>
+ <description></description>
+ </component-plugin>
+ </external-component-plugins>
+<configuration></programlisting>
+
+ <para>Now, simply deploy the jar under $TOMCAT_HOME/lib and your listeners
+ are ready!</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreOrganizationService">
+ <title>Organization Service</title>
+
+ <section id="Overview">
+ <title>Overview</title>
+
+ <para>OrganizationService is the service that allows to access the
+ Organization model. This model is composed of :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Users</para>
+ </listitem>
+
+ <listitem>
+ <para>Groups</para>
+ </listitem>
+
+ <listitem>
+ <para>Memberships</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is the basis of eXo personalization and authorizations in eXo and
+ is used allover the platform. The model is abstract and does not rely on
+ any specific storage. Multiple implementations exist in exo :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>hibernate : for storage into a RDBMS</para>
+ </listitem>
+
+ <listitem>
+ <para>jndi : for storage into a directory such as an LDAP or MS Active
+ Directory</para>
+ </listitem>
+
+ <listitem>
+ <para>jcr : for storage inside a Java Content Repository</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Organizational Model</title>
+
+ <section>
+ <title>User</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>username used as the identified</para>
+ </listitem>
+
+ <listitem>
+ <para>Profile (identity and preferences)</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Group</title>
+
+ <para>Gather a set of users</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>applicative or business</para>
+ </listitem>
+
+ <listitem>
+ <para>tree structure</para>
+ </listitem>
+
+ <listitem>
+ <para>no inheritance</para>
+ </listitem>
+
+ <listitem>
+ <para>expressed as /group/subgroup/subsubgroup</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Membership</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>qualifies the group belonging</para>
+ </listitem>
+
+ <listitem>
+ <para>"Member of group as XXX"</para>
+ </listitem>
+
+ <listitem>
+ <para>expressed as : manager:/organization/hr, *:/partners</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>Related articles and how-tos</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink
+ url="http://wiki.exoplatform.org/xwiki/bin/view/JCR/Organization+Service">JCR
+ Organization Service</ulink></para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink
+ url="http://wiki.exoplatform.org/xwiki/bin/view/Core/Update+ConversationState+...'s+Membership+changed">Update
+ ConversationState when user's Membership changed</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="Organization Service Initializer">Organization
+ Service Initializer</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="http://wiki.exoplatform.org/xwiki/bin/view/Portal/Accessing+User+Profile">How
+ to Access User Profile in your code</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="CoreOrganizationListener">How to create your own
+ Organization Listener</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="How to manipulate Users and Memberships Programmatically">How to
+ manipulate Users and Memberships Programmatically</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/security-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/security-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/security-service.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreSecurityService">
+ <title>Security Service</title>
+
+ <section>
+ <title>1 Overview</title>
+
+ <para>The purpose is to make a simple, unified way for the authentication
+ and the storing/propagation of user sessions through all the eXo
+ components and J2EE containers. JAAS is supposed to be the primary login
+ mechanism but the Security Service framework should not prevent other
+ (custom or standard) mechanisms from being used. You can learn more about
+ JAAS in the <ulink
+ url="Java Tutorial>http://java.sun.com/j2se/1.5.0/docs/guide/security/jaas/tutor...">Java
+ Tutorial>http://java.sun.com/j2se/1.5.0/docs/guide/security/jaas/tutor...</ulink></para>
+ </section>
+
+ <section>
+ <title>1 Framework</title>
+
+ <para>The central point of this framework is the <emphasis
+ role="bold">ConversationState</emphasis> object which stores all
+ information about the state of the current user (very similar to the
+ Session concept). The same ConversationState also stores acquired
+ attributes of an <emphasis role="bold">Identity</emphasis> which is a set
+ of principals to identify a user.</para>
+
+ <para>The ConversationState has definite lifetime. This object should be
+ created when the user's identity becomes known by eXo (login procedure)
+ and destroyed when the user leaves an eXo based application (logout
+ procedure). Using JAAS it should happen in LoginModule's login() and
+ logout() methods respectively.</para>
+
+ <section>
+ <title>1.1 ConversationState and ConversationRegistry</title>
+
+ <para>The ConversationState can be stored</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>in a static <emphasis role="bold">local thread
+ variable</emphasis>, or</para>
+ </listitem>
+
+ <listitem>
+ <para>as a <emphasis role="bold">key-value pair</emphasis> in the
+ <emphasis role="bold">ConversationRegistry</emphasis>
+ component.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>One or the other, or both methods can be used to set/retrieve the
+ state at runtime. The most important thing is that they should be
+ complementary, i.e. make sure that the conversation state is set before
+ you try to use it.</para>
+
+ <para><emphasis role="bold">Local Thread Variable</emphasis> Storing the
+ ConversationState in a static local thread variable makes it possible to
+ represent it as a <emphasis role="bold">context</emphasis> (current
+ user's state).</para>
+
+ <programlisting>ConversationState.setCurrent(conversationState);
+....
+ConversationState.getCurrent();</programlisting>
+
+ <para><emphasis role="bold">Key-Value way</emphasis></para>
+
+ <para>If you store the ConversationState inside the <emphasis
+ role="bold">ConversationRegistry</emphasis> component as a set of
+ key-value pairs, the session key is an arbitrary String (user name,
+ ticket id, httpSessionId etc).</para>
+
+ <programlisting>conversationRegistry.register("key", conversationState);
+...
+conversationRegistry.getState("key");</programlisting>
+
+ <para><emphasis role="bold">ConversationRegistry</emphasis> The
+ ConversationRegistry is a mandatory component deployed into eXo
+ Container as following:</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.security.ConversationRegistry</type>
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>1.1 Authenticator</title>
+
+ <para>An Authenticator is responsible for Identity creating, it contains
+ two methods:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>validateUser() accepts an array of credentials and returns the
+ userId (which can be something different from the username).</para>
+ </listitem>
+
+ <listitem>
+ <para>createIdentity() accepts the userId and returns a newly
+ created Identity object.</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>public interface Authenticator {
+ /**
+ * Authenticate user and return userId which can be different to username.
+ * @param credentials - list of users credentials (such as name/password, X509 certificate etc)
+ * @return userId
+ * @throws LoginException
+ * @throws Exception
+ */
+ String validateUser(Credential[] credentials) throws LoginException, Exception;
+
+ /**
+ * @param credentials - userId.
+ * @return Identity
+ * @throws Exception
+ */
+ Identity createIdentity(String userId) throws Exception;
+
+}</programlisting>
+
+ <para>It is up to the application developer (and deployer) whether to
+ use the Authenticator component(s) and how many implementations of this
+ components should be deployed in eXo container. The developer is free to
+ create an Identity object using a different way, but the Authenticator
+ component is the highly recommended way from architectural
+ considerations.</para>
+
+ <para>Typical functionality of the validateUser(Credential\[]
+ credentials) method is the comparison of incoming credentials
+ (username/password, digest etc) with those credentials that are stored
+ in an implementation specific database. Then validateUser(Credential\[]
+ credentials) returns back the userId or throws a LoginException in a
+ case of wrong credentials.</para>
+
+ <para>Default Authenticator implementation is
+ org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl
+ which compares incoming username/password credentials with the ones
+ stored in OrganizationService. Configuration example:</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.security.Authenticator</key>
+ <type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
+</component></programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <section>
+ <title>JAAS login module</title>
+
+ <para>The framework described is not coupled with any authentication
+ mechanism but the most logical and implemented by default is the JAAS
+ Login module. The typical sequence looks as follows (see
+ org.exoplatform.services.security.jaas.DefaultLoginModule):</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>LoginModule.login() creates a list of credentials using
+ standard JAAS Callbacks features, obtains an Authenticator instance,
+ and creates an Identity object calling
+ Authenticator.authenticate(..) method</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>Authenticator authenticator = (Authenticator) container()
+ .getComponentInstanceOfType(Authenticator.class);
+// RolesExtractor can be null
+RolesExtractor rolesExtractor = (RolesExtractor) container().
+getComponentInstanceOfType(RolesExtractor.class);
+
+
+Credential[] credentials = new Credential[] {new UsernameCredential(username), new PasswordCredential(password) };
+String userId = authenticator.validateUser(credentials);
+identity = authenticator.createIdentity(userId);</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>LoginModule.commit() obtains the IdentityRegistry object, and
+ register the identity using userId as a key.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When initializing the login module you can set the option
+ parameter "singleLogin". With this option you can disallow the same
+ Identity to login for a second time.</para>
+
+ <para>By default singleLogin is disabled, so the same identity can be
+ registered more than one time. Parameter can be passed in this form
+ singleLogin=yes or singleLogin=true.</para>
+
+ <programlisting>IdentityRegistry identityRegistry = (IdentityRegistry) getContainer().getComponentInstanceOfType(IdentityRegistry.class);
+
+if (singleLogin && identityRegistry.getIdentity(identity.getUserId()) != null)
+ throw new LoginException("User " + identity.getUserId() + " already logined.");
+
+identity.setSubject(subject);
+identityRegistry.register(identity);</programlisting>
+
+ <para>In the case of using several LoginModules, JAAS allows to place
+ the login() and commit() methods in different REQUIRED modules.</para>
+
+ <para>After that, the web application must use SetCurrentIdentityFilter.
+ This filter obtains the ConversationRegistry object and tries to get the
+ ConversationState by sessionId (HttpSession). If there is no
+ ConversationState then SetCurrentIdentityFilter will create a new one,
+ register it and set it as current one using
+ ConversationState.setCurrent(state).</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>LoginModule.logout() can be called by
+ JAASConversationStateListener, it extends
+ ConversationStateListener.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This listener must be configured in web.xml. The method
+ sessionDestroyed(HttpSessionEvent)is called by the ServletContainer.
+ This method removes the ConversationState from the ConversationRegistry
+ ConversationRegistry.unregister(sesionId) and calls the method
+ LoginModule.logout().</para>
+
+ <programlisting>ConversationRegistry conversationRegistry = (ConversationRegistry) getContainer().getComponentInstanceOfType(ConversationRegistry.class);
+
+ConversationState conversationState = conversationRegistry.unregister(sesionId);
+
+if (conversationState != null) {
+ log.info("Remove conversation state " + sesionId);
+ if (conversationState.getAttribute(ConversationState.SUBJECT) != null) {
+ Subject subject = (Subject) conversationState.getAttribute(ConversationState.SUBJECT);
+ LoginContext ctx = new LoginContext("exo-domain", subject);
+ ctx.logout();
+} else {
+ log.warn("Subject was not found in ConversationState attributes.");
+}</programlisting>
+
+ <para></para>
+ </section>
+
+ <section>
+ <title>1.1 Predefinded JAAS login modules</title>
+
+ <para>There are several JAAS Login modules included in eXo Platform
+ sources:</para>
+
+ <para><emphasis
+ role="bold">org.exoplatform.services.security.jaas.DefaultLoginModule</emphasis>
+ which provides both authentication (using eXo Authenticator based
+ mechanism) and authorization, filling Conversation Registry as it
+ described in previous section. There are also several per-Application
+ Server extensions of this login module which can be found in
+ org.exoplatform.services.security.jaas package, which can be used in
+ appropriate AS. In particular, we have dedicated Login modules for
+ Tomcat, JBoss, Jonas and WebSphere.</para>
+
+ <para><emphasis role="bold">TODO: configuration examples for Tomcat,
+ JBoss, Jonas and WebSphere</emphasis></para>
+
+ <para>Besides that, for the case when third party authentication
+ mechanism required, we have <emphasis
+ role="bold">org.exoplatform.services.security.jaas.IdentitySetLoginModule</emphasis>,
+ which catches a login identity from third party "authenticating" login
+ module and preforms eXo specific authorization job. In this case third
+ party login module has to put login (user) name to the shared state map
+ under <emphasis role="bold">"javax.security.auth.login.name"</emphasis>
+ key and third party LM has to be configured before
+ IdentitySetLoginModule like:</para>
+
+ <programlisting>exo {
+ com.third.party.LoginModuleImpl required;
+ org.exoplatform.services.security.jaas.IdentitySetLoginModule required;
+};</programlisting>
+ </section>
+
+ <section>
+ <title>1.1 J2EE container authentication</title>
+
+ <para>As you know, when a user in JAAS is authenticated, a Subject is
+ created as a result. This Subject represents the authenticated user. It
+ is important to know and follow the rules regarding Subject filling
+ which are specific for each J2EE server, where eXo Platform is
+ deployed.</para>
+
+ <para>To make it workable for the particular J2EE server it is necessary
+ to add specific Principals/Credentials to the Subject to be propagated
+ into the specific J2EE container implementation. We extended the
+ DefaultLoginModule by overloading its commit() method with a dedicated
+ logic, presently available for Tomcat, JBOSS and JONAS application
+ servers.</para>
+
+ <para>Furthermore you can use the optional RolesExtractor which is
+ responsible for mapping primary Subject's principals (userId and a set
+ of groups) to J2EE Roles:</para>
+
+ <programlisting>public interface RolesExtractor {
+ Set <String> extractRoles(String userId, Set<MembershipEntry> memberships);
+}</programlisting>
+
+ <para>This component may be used by Authenticator to create the Identity
+ with a particular set of <emphasis role="bold">Roles</emphasis>.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/spring-security-integration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/spring-security-integration.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/spring-security-integration.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -0,0 +1,670 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="CoreSpringSecurityIntegration">
+ <title>Spring Security Integration</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>How to Integrate the spring security framework in the eXo
+ portal?</para>
+
+ <para>This tutorial will guide you through a few steps and show you how
+ easy it is to integrate spring security (or the Spring framework in
+ general) in eXo portal. We will create a login portlet example as a
+ support all along the document reading. The login portlet example has been
+ developed and deployed using the eXo WCM product running on the
+ application server JBoss 4.2.3. But it can easily be adapted to another
+ eXo product (such as ECM) and to other servers such as tomcat. Moreover,
+ the example, claiming to be a real world example, is implemented using JSF
+ 1.2, the JBoss portlet bridge and Spring and can serve as a example
+ project from where you can start your own portlet development targeting
+ the eXo platform.</para>
+ </section>
+
+ <section>
+ <title>Installation</title>
+
+ <para>This tutorial assumes that you have a working eXo WCM installation
+ running under JBoss 4.2.x.</para>
+
+ <para>Download the spring framework: <ulink
+ url="http://s3.amazonaws.com/dist.springframework.org/release/SPR/spring-frame...">http://s3.amazonaws.com/dist.springframework.org/release/SPR/spring-frame...</ulink></para>
+
+ <para>Download spring-security: <ulink
+ url="http://sourceforge.net/project/showfiles.php?group_id=73357&package_i...">http://sourceforge.net/project/showfiles.php?group_id=73357&package_i...</ulink></para>
+
+ <para>Unzip the 02portal.war file in the jboss
+ server/default/deploy/exoplatform.sar directory and copy the following
+ jars in WEB-INF/lib:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>spring.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>spring-security-core.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>aspectjrt-1.5.4.jar</para>
+ </listitem>
+
+ <listitem>
+ <para>exo-spring.jar (contains the filters and event handlers
+ described in this tutorial - see the attachment section of this
+ page)</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>To enable spring security in exo we need to go through a few
+ configuration steps:</para>
+
+ <section>
+ <title>JAAS disabling</title>
+
+ <para>First we need to disable the JAAS security which is the default
+ authentication mechanism in exo. Edit 02portal.war web.xml file and
+ comment out the JAAS configuration related lines:</para>
+
+ <programlisting>...
+ <session-config>
+ <session-timeout>15</session-timeout>
+ </session-config>
+
+ <!--
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>user authentication</web-resource-name>
+ <url-pattern>/private/*</url-pattern>
+ <http-method>POST</http-method>
+ <http-method>GET</http-method>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>users</role-name>
+ </auth-constraint>
+ <user-data-constraint>
+ <transport-guarantee>NONE</transport-guarantee>
+ </user-data-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>FORM</auth-method>
+ <realm-name>exo-domain</realm-name>
+ <form-login-config>
+ <form-login-page>/login/jsp/login.jsp</form-login-page>
+ <form-error-page>/login/jsp/login.jsp</form-error-page>
+ </form-login-config>
+ </login-config>
+ -->
+
+ <security-role>
+ <description>a simple user role</description>
+ <role-name>users</role-name>
+ </security-role>
+...</programlisting>
+ </section>
+
+ <section>
+ <title>Enabling spring security</title>
+
+ <para>To enable spring and set the spring security filter, add the
+ following lines:</para>
+
+ <programlisting>...
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>/WEB-INF/security-context.xml</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+
+ <filter>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+ </filter>
+...</programlisting>
+
+ <para>Activate the spring security filter at the right position, i.e.
+ just after the filter responsible of exo container
+ initialization.</para>
+
+ <programlisting>...
+ <filter-mapping>
+ <filter-name>PortalContainerInitializedFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>SetCurrentIdentityFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+...</programlisting>
+ </section>
+
+ <section>
+ <title>security-context.xml</title>
+
+ <para>We need to configure the spring security filter chain for our
+ purposes. Create a file named security-context.xml in 02portal.war
+ WEB-INF directory containing the following lines:</para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/security"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
+
+ <http auto-config="true">
+ <intercept-url pattern="/private/**" access="ROLE_USER" />
+ <form-login login-page='/public/classic/Login' default-target-url='/private/classic/home' />
+ </http>
+
+ <authentication-provider>
+ <user-service>
+ <user name="rod" password="koala" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
+ <user name="root" password="exo" authorities="ROLE_USER" />
+ </user-service>
+ </authentication-provider>
+
+</beans:beans></programlisting>
+
+ <para>The file contains two elements. The http node which is responsible
+ of configuring the filter chain. The auto-config mode set to true allows
+ us to do just a minimal configuration, everything else being smartly
+ initialized by default. We just set an intercept URL pointing to
+ '/private/**' with the ROLE_USER authority which corresponds to secured
+ resources in exo. In case of successful auhentication, the user will be
+ redirected to the specified default target URL.</para>
+
+ <para>The second element defines a simple authentication provider based
+ on the spring security InMemoryDaoImpl implementation of the
+ UserDetailsService. Note that we define the exo root user in the
+ configuration which will allow us to log in with admin privileges in the
+ exo portal.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Login portlet example</title>
+
+ <para>Now that we have successfully installed and configured spring
+ security in exo, we need a login portlet example to capture user
+ credentials and serve as an entry point in the authentication process. The
+ login portlet itself is based on JSF 1.2, Jboss portlet bridge and the
+ spring framework, but you can obviously use whatever web framework you
+ want to achieve the same.</para>
+
+ <section>
+ <title>Building the portlet</title>
+
+ <para>So we need a login form to capture user credentials inputs. The
+ portlet login form consists of the following lines of xml:</para>
+
+ <programlisting><f:view xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ice="http://www.icesoft.com/icefaces/component"
+ xmlns:liferay-faces="http://liferay.com/tld/faces"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:t="http://myfaces.apache.org/tomahawk">
+
+ <style type="text/css" media="screen">
+ @import "/loginportlet/css/starter.css";
+ @import "/loginportlet/css/uni-form.css";
+ </style>
+
+ <script src="/loginportlet/js/jquery.js" type="text/javascript"></script>
+ <script src="/loginportlet/js/uni-form.jquery.js" type="text/javascript"></script>
+
+ <h:form styleClass="uniForm" >
+ <fieldset class="inlineLabels">
+ <legend>Sign in</legend>
+
+ <div class="ctrlHolder">
+ <h:outputLabel for="login" style="width: 70px"><em>*</em>Login:</h:outputLabel>
+ <h:inputText id="login" value="#{loginBean.login}" required="true" styleClass="textInput" />
+ <h:message for="login" styleClass="portlet-msg-error" />
+ </div>
+ <div class="ctrlHolder">
+ <h:outputLabel for="password" style="width: 70px"><em>*</em>Password:</h:outputLabel>
+ <h:inputSecret id="password" value="#{loginBean.passwd}" required="true" styleClass="textInput" />
+ <h:message for="password" styleClass="portlet-msg-error" />
+ </div>
+ </fieldset>
+
+ <div class="buttonHolder" style="margin-top: 20px; margin-right: 20px">
+ <h:commandButton styleClass="primaryAction" value="Submit" action="#{loginBean.login}" />
+ </div>
+ </h:form>
+</f:view></programlisting>
+
+ <para>The interesting part resides in the backing bean which implements
+ the login action triggered when the user clicks the login form submit
+ button.</para>
+
+ <programlisting>package org.exoplatform.loginportlet;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Controller;
+
+@Controller
+@Scope("request")
+public class LoginBean {
+
+ String login;
+
+ String passwd;
+
+ public String login() throws Exception {
+ String redirect = "/portal/j_spring_security_check?j_username=" + login + "&j_password=" + passwd;
+ PortalUtils.sendRedirect(redirect);
+ return null;
+ }
+
+ ...
+}</programlisting>
+
+ <para>The login action simply sends a HTTP redirect to the spring
+ security login URL passing the user login and password as parameters.
+ This URL informs the filter to try to authenticate the supplied user
+ credentials. This is the Spring security authentication process entry
+ point.</para>
+ </section>
+
+ <section>
+ <title>Setting up the login portal page</title>
+
+ <para>Now that we have a login portlet available we need to set it up
+ into a portal page.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Log in as root in exo portal.</para>
+ </listitem>
+
+ <listitem>
+ <para>Go to application registry and import the loginportlet</para>
+ </listitem>
+
+ <listitem>
+ <para>Add a new hidden page named 'Login' under the portal classic's
+ navigation (read more on page creation <ulink
+ url="here>WCM.Tutorial">here>WCM.Tutorial</ulink>). Make sure
+ that the visible flag is unchecked to hide the page. Also declare
+ the page as public so that everyone can access it without being
+ authenticated for obvious reasons.</para>
+ </listitem>
+
+ <listitem>
+ <para>Finally, drag & drop the login portlet in the page with
+ the desired layout.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Customization of portal login and logout urls</title>
+
+ <para>In the portal header there is a login or logout action displayed
+ depending whether you are already logged in or not. We need to customize
+ those actions so that when the user clicks on it she or he will be
+ redirected either to our login page or to the spring security logout
+ url. Edit the article, go to the default.js tab and apply the following
+ changes to the code:</para>
+
+ <programlisting>function validateUser() {
+
+ var user = eXo.env.portal.userName;
+ var rootObj = document.getElementById("classic-access");
+ var loginContentObj = eXo.core.DOMUtil.findFirstDescendantByClass(rootObj, "div", "UIWCMLoginPortlet");
+ var welcomeObj = eXo.core.DOMUtil.findFirstDescendantByClass(rootObj, "span", "Welcome");
+ var userObj = eXo.core.DOMUtil.findFirstDescendantByClass(rootObj, "span", "LoggedUser");
+ var languageObj = eXo.core.DOMUtil.findFirstDescendantByClass(rootObj, "a", "LanguageIcon");
+ var logXXXObj = eXo.core.DOMUtil.findPreviousElementByTagName(languageObj, "a");
+
+ if (user != "null") {
+ welcomeObj.innerHTML = "Welcome: ";
+ userObj.innerHTML = user;
+ logXXXObj.innerHTML = "Logout";
+ if (eXo.core.DOMUtil.hasClass(logXXXObj, "LoginIcon")) {
+ eXo.core.DOMUtil.removeClass(logXXXObj, "LoginIcon");
+ eXo.core.DOMUtil.addClass(logXXXObj, "LogoutIcon");
+ }
+ logXXXObj.onclick = function() { document.location.href = '/portal/j_spring_security_logout' }
+ } else {
+ if (eXo.core.DOMUtil.hasClass(logXXXObj, "LogoutIcon")) {
+ eXo.core.DOMUtil.removeClass(logXXXObj, "LogoutIcon");
+ eXo.core.DOMUtil.addClass(logXXXObj, "LoginIcon");
+ }
+ logXXXObj.innerHTML = "Login";
+ logXXXObj.onclick = function() { document.location.href = '/portal/public/classic/Login' };
+ }
+
+ languageObj.onclick = function () { if(document.getElementById('UIMaskWorkspace')) ajaxGet(eXo.env.server.createPortalURL('UIPortal', 'ChangeLanguage', true)); }
+}
+
+eXo.core.Browser.addOnLoadCallback("validateUser", validateUser);</programlisting>
+
+ <para>As you can see, the two onclick event handler function bodies have
+ been changed to a simple redirect to the login page or the logout
+ URL.</para>
+ </section>
+
+ <section>
+ <title>A look at the login page</title>
+
+ <para>Once you are done with all this, just click on the login action
+ and you should be redirect to the login page looking something like
+ that:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/login-page.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+ </section>
+
+ <section>
+ <title>Integration strategies</title>
+
+ <para>Until now we haven't discussed about any integration strategies
+ concerning a potential existing security realm outside of the eXo
+ platform. To address this problem we have the choice between at least two
+ different strategies:</para>
+
+ <para>1.1.1 <emphasis role="bold">Direct integration</emphasis> We can
+ directly integrate eXo with the external realm. Everything related to
+ organisation and user management in exo is cleanly separated in its own
+ abstraction accessible through the OrganisationService. The authentication
+ process itself is encapsulated in the Authenticator abstraction which sits
+ on top of the organization service. eXo provides several implementations
+ of both. So whether your realm is based on LDAP or JDBC and because the
+ default implementations are generic enough, you will be able to use them
+ and fits them to your needs with a matter of a little configuration. You
+ can even develop a custom implementation to meet your more specific
+ needs.</para>
+
+ <section>
+ <title>Replication</title>
+
+ <para>Or we can go through a replication process between the external
+ realm and the eXo platform realm. This is the strategy that we are going
+ to use to build our login portlet example. Furthermore the replication
+ will occur dynamically on any user authentication attempt.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Integration with eXo portal</title>
+
+ <para>Being successfully authenticated against an external realm is not
+ sufficient by itself. We also need to propagate the newly created security
+ context to the portal own security mechanism. In eXo portal terminology,
+ it means we have to create an Identity object for the user and register it
+ into the Identity Registry.</para>
+
+ <para>Spring framework provides a simple notification model where a bean
+ can listen to application events published by other beans. Fortunately
+ spring security uses this mechanism and publishes an
+ InteractiveAuthenticationSuccessEvent in case of successful
+ authentication. That will allow us to hook up custom code to that
+ event.</para>
+
+ <para>Furthermore, we need to replicate the user details from the external
+ realm to the eXo portal one according to the integration strategy defined
+ above.</para>
+
+ <para>We create a SpringSecurityEventHandler bean that implements the
+ ApplicationListener interface and listens to the
+ InteractiveAuthenticationSuccessEvent event.</para>
+
+ <programlisting>package org.exoplatform.spring.security.web;
+
+...
+
+public class SpringSecurityEventHandler implements ApplicationListener {
+
+ private String portalContainerName = "portal";
+
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (event instanceof InteractiveAuthenticationSuccessEvent) {
+ try {
+ InteractiveAuthenticationSuccessEvent successEvent = (InteractiveAuthenticationSuccessEvent) event;
+ ExoContainer container = getContainer();
+
+ String login = successEvent.getAuthentication().getName();
+ String passwd = successEvent.getAuthentication().getCredentials().toString();
+
+ IdentityRegistry identityRegistry = (IdentityRegistry) container.getComponentInstanceOfType(IdentityRegistry.class);
+ Authenticator authenticator = (Authenticator) container.getComponentInstanceOfType(Authenticator.class);
+ OrganizationService orgService = (OrganizationService) container.getComponentInstanceOfType(OrganizationService.class);
+
+ User user = orgService.getUserHandler().findUserByName(login);
+ if (user == null) {
+ user = orgService.getUserHandler().createUserInstance(login);
+ user.setFirstName(login);
+ user.setLastName(login);
+ orgService.getUserHandler().createUser(user, false);
+ orgService.getUserHandler().saveUser(user, false);
+ //TODO: put some more integration code here
+ }
+
+ Identity identity = authenticator.createIdentity(login);
+
+ Subject subject = new Subject();
+ subject.getPrivateCredentials().add(passwd);
+ subject.getPublicCredentials().add(new UsernameCredential(login));
+
+ identity.setSubject(subject);
+ identityRegistry.register(identity);
+
+ } catch (Exception e) {
+ e.getMessage();
+ }
+ }
+ }
+
+ protected ExoContainer getContainer() {
+ // TODO set correct current container
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof RootContainer) {
+ container = RootContainer.getInstance().getPortalContainer(portalContainerName);
+ }
+ return container;
+ }
+
+...
+
+}</programlisting>
+
+ <para>Basically the bean retrieves user login and password from the
+ InteractiveAuthenticationSuccessEvent object and tries to get the user
+ from the organization service. In case he cannot find it in the
+ repository, he simply creates it on the fly. In this example the user is
+ created with just a few details, but you can put some custom integration
+ code with the external realm here, and create the user with all the
+ details (email, birth date, roles, etc.) it seems appropriate to you.
+ After that, the bean creates an Identity object with the help of the
+ authenticator service, populates it with a subject containing the user
+ credentials and registers it. That's all we have to do to make the portal
+ aware of the user logging in.</para>
+
+ <para>Registering our bean is done the usual way in security-context.xml
+ file:</para>
+
+ <programlisting>...
+<beans:bean id="myEventHandler" class="org.exoplatform.spring.security.web.SpringSecurityEventHandler" />
+...</programlisting>
+ </section>
+
+ <section>
+ <title>Security context propagation to portlets</title>
+
+ <para>Part of the problem is the question of security context propagation
+ between on one side the portal webapp and at the other side the portlets
+ webapps. This means that the security context has to be available in the
+ portlet side allowing the application logic to deal the with current user
+ principal and granted authorities. By default Spring security uses a
+ thread local variable to partially achieve this. But a problem may arise
+ due to the fact that the portal invokes the portlet through a webapp cross
+ context call. This means that it can lead to a class cast exceptions (two
+ different classloaders involved), or that the security context is simply
+ not propagated at all. To accommodate this we will need to set up two
+ request filters, one at the portal webapp side and the other at the
+ portlet webapp side and use the http request to propagate the context in
+ between.</para>
+
+ <section>
+ <title>Portal side filter</title>
+
+ <para>We will use the spring security extensible filter chain to plug in
+ our filter.</para>
+
+ <programlisting>package org.exoplatform.spring.security.web;
+
+...
+
+public class PortalSideSecurityContextFilter extends SpringSecurityFilter {
+
+ @Override
+ protected void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ //fill request with security context
+ SecurityContext context = SecurityContextHolder.getContext();
+ request.setAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY, context);
+
+ //fill request with security last exception
+ Object e = request.getSession().getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
+ request.setAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, e);
+
+ chain.doFilter(request, response);
+ }
+
+ public int getOrder() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+}</programlisting>
+
+ <para>The PortalSideSecurityContextFilter simply fills the request with
+ the security context and security last exception using the
+ HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY and
+ AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY attribute
+ names. The portlet can have a look to the
+ AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY attribute to
+ check if a security exception has occured.</para>
+
+ <para>The following lines in the security-context file register our
+ custom filter in the chain at the last position.</para>
+
+ <programlisting>...
+ <beans:bean id="myCustomFilter" class="org.exoplatform.spring.security.web.PortalSideSecurityContextFilter">
+ <custom-filter after="LAST" />
+ </beans:bean>
+...</programlisting>
+ </section>
+
+ <section>
+ <title>Portlet side filter</title>
+
+ <para>In the portlet webapp we create a regular filter named
+ PortletSideSecurityContextFilter.</para>
+
+ <programlisting>package org.exoplatform.spring.security.web;
+
+...
+
+public class PortletSideSecurityContextFilter implements Filter {
+
+ public void destroy() {
+
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+ Object object = request.getAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY);
+ SecurityContext context = (SecurityContext) serializeDeserialize(object);
+ if (context != null) {
+ SecurityContextHolder.setContext(context);
+ } else {
+ SecurityContextHolder.clearContext();
+ }
+
+ filterChain.doFilter(request, response);
+ }
+
+ public void init(FilterConfig arg0) throws ServletException {
+
+ }
+
+ private Object serializeDeserialize(Object obj) {
+ Object result = null;
+ try {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+
+ out.writeObject(obj);
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bin);
+
+ result = in.readObject();
+ } catch (Exception e) {
+ //TODO: handle exception
+ }
+ return result;
+ }
+
+}</programlisting>
+
+ <para>The PortletSideSecurityContextFilter retrieves the security
+ context from the request and proceeds to a serialization
+ de-serialization of it to avoid a potential class cast exception that
+ may occur when propagating an object across webapps. Then the context is
+ simply set or cleared whether the context is null or not.</para>
+
+ <para>To register your filter simply add the following lines to your
+ portlet webapp web.xml file.</para>
+
+ <programlisting>...
+ <filter>
+ <filter-name>portletSideSecurityContextFilter</filter-name>
+ <filter-class>org.exoplatform.spring.security.web.PortletSideSecurityContextFilter</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>portletSideSecurityContextFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ </filter-mapping>
+...</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Conclusion</title>
+
+ <para>We are done! Now we know how to integrate the spring security
+ framework in the eXo portal. Thanks to the the great integration
+ capabilities of both eXo portal and Spring framework. You can have a look
+ to the attachment section on this page and get the source code of this
+ tutorial.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core.xml 2010-07-30 13:29:37 UTC (rev 2845)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core.xml 2010-07-30 15:13:44 UTC (rev 2846)
@@ -8,8 +8,41 @@
<xi:include href="core/core.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+
<xi:include href="core/db-creator-service.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="core/security-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/spring-security-integration.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/organization-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/organization-service-initalizer.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/organization-service-listener.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/conversationstate-when-membership-changed.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/db-schema-creator-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/db-configuration-hibernate.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="core/ldap-configuration.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+
+
+
+
+
+
</part>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/login-page.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/login-page.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/organization-exo.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/organization-exo.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
13 years, 11 months
exo-jcr SVN: r2845 - jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-30 09:29:37 -0400 (Fri, 30 Jul 2010)
New Revision: 2845
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
Log:
EXOJCR-830: cleanup
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -43,7 +43,7 @@
* JBossCache.
*
* @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
- * @version $Id: BufferedJBossCache.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ * @version $Id$
*
*/
@SuppressWarnings("unchecked")
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -21,7 +21,7 @@
/**
*
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
- * @version $Id: CacheId.java 111 2010-11-11 11:11:11Z tolusha $
+ * @version $Id$
*/
public class CacheId extends CacheKey
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -28,7 +28,7 @@
* Date: 10.06.2008<br/>
*
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: CacheKey.java 34801 2009-07-31 15:44:50Z dkatayev $
+ * @version $Id$
*/
public abstract class CacheKey implements Serializable, Comparable<CacheKey>
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -26,7 +26,7 @@
* Cache record used to store item Id key.
*
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: CacheId.java 34801 2009-07-31 15:44:50Z dkatayev $
+ * @version $Id$
*/
public class CacheNodesId extends CacheKey
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -26,7 +26,7 @@
* Cache record used to store item Id key.
*
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: CacheId.java 34801 2009-07-31 15:44:50Z dkatayev $
+ * @version $Id$
*/
public class CachePropsId extends CacheKey
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -30,7 +30,7 @@
* 15.06.07
*
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: CacheQPath.java 13869 2008-05-05 08:40:10Z pnedonosko $
+ * @version $Id$
*/
class CacheQPath extends CacheKey
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -28,7 +28,7 @@
* Sorting cache modification
*
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
- * @version $Id: CompressedISPNChangesBuffer.java 111 2010-11-11 11:11:11Z tolusha $
+ * @version $Id$
*/
public class CompressedISPNChangesBuffer
{
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-07-30 13:14:37 UTC (rev 2844)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-07-30 13:29:37 UTC (rev 2845)
@@ -71,7 +71,7 @@
* </ul>
*
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
- * @version $Id: ISPNCacheWorkspaceStorageCache.java 111 2010-11-11 11:11:11Z tolusha $
+ * @version $Id$
*/
public class ISPNCacheWorkspaceStorageCache implements WorkspaceStorageCache
{
@@ -732,18 +732,6 @@
LOG.debug("Node not extists as a child but update asked " + node.getQPath().getAsString());
}
}
- // Fqn<String> prevFqn =
- // makeChildFqn(childNodes, node.getParentIdentifier(), prevNode.getQPath().getEntries()[prevNode.getQPath()
- // .getEntries().length - 1]);
- //
- // if (node.getIdentifier().equals(cache.getFromBuffer(prevFqn, ITEM_ID)))
- // {
- // // it's same-name siblings re-ordering, delete previous child
- // if (!cache.removeNode(prevFqn) && LOG.isDebugEnabled())
- // {
- // LOG.debug("Node not extists as a child but update asked " + node.getQPath().getAsString());
- // }
- // }
// update childs paths if index changed
int nodeIndex = node.getQPath().getEntries()[node.getQPath().getEntries().length - 1].getIndex();
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
___________________________________________________________________
Name: svn:keywords
+ Id
13 years, 11 months
exo-jcr SVN: r2844 - in jcr/branches/1.14-ISPN/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-30 09:14:37 -0400 (Fri, 30 Jul 2010)
New Revision: 2844
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
Log:
EXOJCR-830: bug fixed, 1 test failed
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml 2010-07-30 13:00:43 UTC (rev 2843)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml 2010-07-30 13:14:37 UTC (rev 2844)
@@ -404,11 +404,10 @@
</property-->
</systemProperties>
<includes>
- <!--include>org/exoplatform/services/jcr/api/**/Test*.java</include>
+ <include>org/exoplatform/services/jcr/api/**/Test*.java</include>
<include>org/exoplatform/services/jcr/usecases/**/Test*.java</include>
<include>org/exoplatform/services/jcr/usecases/**/*Test.java</include>
- <include>org/exoplatform/services/jcr/impl/**/Test*.java</include-->
-<include>**/**/TestOrderBefore.java</include>
+ <include>org/exoplatform/services/jcr/impl/**/Test*.java</include>
</includes>
<excludes>
<exclude>org/exoplatform/services/jcr/**/TestQueryUsecases.java</exclude>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-07-30 13:00:43 UTC (rev 2843)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-07-30 13:14:37 UTC (rev 2844)
@@ -724,6 +724,14 @@
*/
protected void updateInBuffer(final NodeData node, final NodeData prevNode)
{
+
+ if (node.getIdentifier().equals(prevNode.getIdentifier()))
+ {
+ if (cache.remove(new CacheQPath(prevNode.getParentIdentifier(), prevNode.getQPath())) != null)
+ {
+ LOG.debug("Node not extists as a child but update asked " + node.getQPath().getAsString());
+ }
+ }
// Fqn<String> prevFqn =
// makeChildFqn(childNodes, node.getParentIdentifier(), prevNode.getQPath().getEntries()[prevNode.getQPath()
// .getEntries().length - 1]);
13 years, 11 months
exo-jcr SVN: r2843 - in jcr/branches/1.14-ISPN/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan and 6 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-30 09:00:43 -0400 (Fri, 30 Jul 2010)
New Revision: 2843
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-config.xml
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
Removed:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestOrderBefore.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
Log:
EXOJCR-830: first step to impl. problems with SNS
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/pom.xml 2010-07-30 13:00:43 UTC (rev 2843)
@@ -404,10 +404,11 @@
</property-->
</systemProperties>
<includes>
- <include>org/exoplatform/services/jcr/api/**/Test*.java</include>
+ <!--include>org/exoplatform/services/jcr/api/**/Test*.java</include>
<include>org/exoplatform/services/jcr/usecases/**/Test*.java</include>
<include>org/exoplatform/services/jcr/usecases/**/*Test.java</include>
- <include>org/exoplatform/services/jcr/impl/**/Test*.java</include>
+ <include>org/exoplatform/services/jcr/impl/**/Test*.java</include-->
+<include>**/**/TestOrderBefore.java</include>
</includes>
<excludes>
<exclude>org/exoplatform/services/jcr/**/TestQueryUsecases.java</exclude>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -156,7 +156,7 @@
{
public Object execute(LockData newLockData) throws LockException
{
- Object oldValue = PrivilegedCacheHelper.putIfAbsent(cache, newLockData.getNodeIdentifier(), newLockData);
+ Object oldValue = PrivilegedCacheHelper.put(cache, newLockData.getNodeIdentifier(), newLockData);
if (oldValue == null)
{
throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
@@ -369,7 +369,7 @@
LockData lockData = session.getPendingLock(nodeIdentifier);
// this will return null if success. And old data if something exists...
- LockData oldLockData = (LockData)PrivilegedCacheHelper.putIfAbsent(cache, nodeIdentifier, lockData);
+ LockData oldLockData = (LockData)PrivilegedCacheHelper.put(cache, nodeIdentifier, lockData);
if (oldLockData != null)
{
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,1073 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.Flag;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.util.concurrent.NotifyingFuture;
+
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Decorator over the JBossCache that stores changes in buffer, then sorts and applies to
+ * JBossCache.
+ *
+ * @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
+ * @version $Id: BufferedJBossCache.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+@SuppressWarnings("unchecked")
+public class BufferedISPNCache implements Cache<Serializable, Object>
+{
+ /**
+ * Parent cache.
+ */
+ private final Cache<Serializable, Object> parentCache;
+
+ private final ThreadLocal<CompressedISPNChangesBuffer> changesList = new ThreadLocal<CompressedISPNChangesBuffer>();
+
+ private ThreadLocal<Boolean> local = new ThreadLocal<Boolean>();
+
+ private final boolean useExpiration;
+
+ private final long expirationTimeOut;
+
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.BufferedISPNCache");
+
+ public static enum ChangesType {
+ REMOVE, PUT;
+ }
+
+ /**
+ * Container for changes
+ */
+ public static abstract class ChangesContainer implements Comparable<ChangesContainer>
+ {
+ protected final CacheKey key;
+
+ protected final ChangesType changesType;
+
+ protected final Cache<Serializable, Object> cache;
+
+ protected final int historicalIndex;
+
+ protected final boolean localMode;
+
+ protected final boolean useExpiration;
+
+ protected final long timeOut;
+
+ public ChangesContainer(CacheKey key, ChangesType changesType, Cache<Serializable, Object> cache,
+ int historicalIndex, boolean localMode, boolean useExpiration, long timeOut)
+ {
+ super();
+ this.key = key;
+ this.changesType = changesType;
+ this.cache = cache;
+ this.historicalIndex = historicalIndex;
+ this.localMode = localMode;
+ this.useExpiration = useExpiration;
+ this.timeOut = timeOut;
+ }
+
+ /**
+ * @return the key
+ */
+ public CacheKey getKey()
+ {
+ return key;
+ }
+
+ /**
+ * @return the index of change in original sequence
+ */
+ public int getHistoricalIndex()
+ {
+ return historicalIndex;
+ }
+
+ /**
+ * @return the changesType
+ */
+ public ChangesType getChangesType()
+ {
+ return changesType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ return key.toString() + " type=" + changesType + " historyIndex=" + historicalIndex;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(ChangesContainer o)
+ {
+ int result = key.compareTo(o.getKey());
+ return result == 0 ? historicalIndex - o.getHistoricalIndex() : result;
+ }
+
+ protected void setCacheLocalMode()
+ {
+ if (localMode)
+ {
+ cache.getAdvancedCache().getInvocationContextContainer().getInvocationContext().setFlags(
+ Flag.CACHE_MODE_LOCAL);
+ }
+ else
+ {
+ Set<Flag> flags =
+ cache.getAdvancedCache().getInvocationContextContainer().getInvocationContext().getFlags();
+
+ if (flags != null)
+ {
+ flags.remove(Flag.CACHE_MODE_LOCAL);
+ cache.getAdvancedCache().getInvocationContextContainer().getInvocationContext().setFlags(flags);
+ }
+ }
+ }
+
+ public final void putExpiration(CacheKey key)
+ {
+ // setCacheLocalMode();
+ // // TODO
+ // cache.put(efqn, ExpirationAlgorithmConfig.EXPIRATION_KEY, new Long(System.currentTimeMillis() + timeOut));
+ }
+
+ public abstract void apply();
+ }
+
+ /**
+ * Put object container;
+ */
+ public static class PutObjectContainer extends ChangesContainer
+ {
+ private final Object value;
+
+ public PutObjectContainer(CacheKey key, Object value, Cache<Serializable, Object> cache, int historicalIndex,
+ boolean local, boolean useExpiration, long timeOut)
+ {
+ super(key, ChangesType.PUT, cache, historicalIndex, local, useExpiration, timeOut);
+
+ this.value = value;
+ }
+
+ @Override
+ public void apply()
+ {
+ setCacheLocalMode();
+ cache.put(key, value);
+
+ if (useExpiration)
+ {
+ putExpiration(key);
+ }
+ }
+ }
+
+ /**
+ * It tries to get Set by given key. If it is Set then adds new value and puts new set back. If
+ * null found, then new Set created (ordinary cache does).
+ */
+ public static class AddToListContainer extends ChangesContainer
+ {
+ private final Object value;
+
+ public AddToListContainer(CacheKey key, Object value, Cache<Serializable, Object> cache, int historicalIndex,
+ boolean local, boolean useExpiration, long timeOut)
+ {
+ super(key, ChangesType.PUT, cache, historicalIndex, local, useExpiration, timeOut);
+ this.value = value;
+ }
+
+ @Override
+ public void apply()
+ {
+ // force writeLock on next read
+ cache.getAdvancedCache().getInvocationContextContainer().getInvocationContext()
+ .setFlags(Flag.FORCE_WRITE_LOCK);
+
+ Object existingObject = cache.get(key);
+ Set<Object> newSet = new HashSet<Object>();
+
+ // if set found of null, perform add
+ if (existingObject instanceof Set || existingObject == null)
+ {
+ // set found
+ if (existingObject instanceof Set)
+ {
+ newSet.addAll((Set<Object>)existingObject);
+ }
+ newSet.add(value);
+
+ if (useExpiration)
+ {
+ putExpiration(key);
+ }
+
+ setCacheLocalMode();
+ cache.put(key, newSet);
+ }
+ else
+ {
+ LOG.error("Unexpected object found by key " + key.toString() + ". Expected Set, but found:"
+ + existingObject.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * It tries to get set by given key. If it is set then removes value and puts new modified set
+ * back.
+ */
+ public static class RemoveFromListContainer extends ChangesContainer
+ {
+ private final Object value;
+
+ public RemoveFromListContainer(CacheKey key, Object value, Cache<Serializable, Object> cache,
+ int historicalIndex, boolean local, boolean useExpiration, long timeOut)
+ {
+ super(key, ChangesType.REMOVE, cache, historicalIndex, local, useExpiration, timeOut);
+ this.value = value;
+ }
+
+ @Override
+ public void apply()
+ {
+ // force writeLock on next read
+ cache.getAdvancedCache().getInvocationContextContainer().getInvocationContext()
+ .setFlags(Flag.FORCE_WRITE_LOCK);
+
+ setCacheLocalMode();
+
+ Object existingObject = cache.get(key);
+
+ // if found value is really set! add to it.
+ if (existingObject instanceof Set)
+ {
+ Set<Object> newSet = new HashSet<Object>((Set<Object>)existingObject);
+ newSet.remove(value);
+
+ if (useExpiration)
+ {
+ putExpiration(key);
+ }
+
+ setCacheLocalMode();
+ cache.put(key, newSet);
+ }
+ }
+ }
+
+ /**
+ * Remove container.
+ */
+ public static class RemoveObjectContainer extends ChangesContainer
+ {
+ public RemoveObjectContainer(CacheKey key, Cache<Serializable, Object> cache, int historicalIndex, boolean local,
+ boolean useExpiration, long timeOut)
+ {
+ super(key, ChangesType.REMOVE, cache, historicalIndex, local, useExpiration, timeOut);
+ }
+
+ @Override
+ public void apply()
+ {
+ setCacheLocalMode();
+ cache.remove(key);
+ }
+ }
+
+ public BufferedISPNCache(Cache<Serializable, Object> parentCache, boolean useExpiration, long expirationTimeOut)
+ {
+ super();
+ this.parentCache = parentCache;
+ this.useExpiration = useExpiration;
+ this.expirationTimeOut = expirationTimeOut;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Void> clearAsync()
+ {
+ return parentCache.clearAsync();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void compact()
+ {
+ parentCache.compact();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void endBatch(boolean successful)
+ {
+ parentCache.endBatch(successful);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<java.util.Map.Entry<Serializable, Object>> entrySet()
+ {
+ return parentCache.entrySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void evict(Serializable key)
+ {
+ parentCache.evict(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AdvancedCache<Serializable, Object> getAdvancedCache()
+ {
+ return parentCache.getAdvancedCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CacheContainer getCacheManager()
+ {
+ return parentCache.getCacheManager();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Configuration getConfiguration()
+ {
+ return parentCache.getConfiguration();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getName()
+ {
+ return parentCache.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ComponentStatus getStatus()
+ {
+ return parentCache.getStatus();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getVersion()
+ {
+ return parentCache.getVersion();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Serializable> keySet()
+ {
+ return parentCache.keySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object put(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.put(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object put(Serializable key, Object value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime,
+ TimeUnit maxIdleTimeUnit)
+ {
+ return parentCache.put(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll(Map<? extends Serializable, ? extends Object> map, long lifespan, TimeUnit unit)
+ {
+ parentCache.putAll(map, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll(Map<? extends Serializable, ? extends Object> map, long lifespan, TimeUnit lifespanUnit,
+ long maxIdleTime, TimeUnit maxIdleTimeUnit)
+ {
+ parentCache.putAll(map, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Void> putAllAsync(Map<? extends Serializable, ? extends Object> data)
+ {
+ return parentCache.putAllAsync(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Void> putAllAsync(Map<? extends Serializable, ? extends Object> data, long lifespan,
+ TimeUnit unit)
+ {
+ return parentCache.putAllAsync(data, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Void> putAllAsync(Map<? extends Serializable, ? extends Object> data, long lifespan,
+ TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit)
+ {
+ return parentCache.putAllAsync(data, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putAsync(Serializable key, Object value)
+ {
+ return parentCache.putAsync(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putAsync(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.putAsync(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putAsync(Serializable key, Object value, long lifespan, TimeUnit lifespanUnit,
+ long maxIdle, TimeUnit maxIdleUnit)
+ {
+ return parentCache.putAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putForExternalRead(Serializable key, Object value)
+ {
+ parentCache.putForExternalRead(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object putIfAbsent(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.putIfAbsent(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object putIfAbsent(Serializable key, Object value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime,
+ TimeUnit maxIdleTimeUnit)
+ {
+ return parentCache.putIfAbsent(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putIfAbsentAsync(Serializable key, Object value)
+ {
+ return parentCache.putIfAbsentAsync(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putIfAbsentAsync(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.putIfAbsentAsync(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> putIfAbsentAsync(Serializable key, Object value, long lifespan,
+ TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit)
+ {
+ return parentCache.putIfAbsentAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> removeAsync(Object key)
+ {
+ return parentCache.removeAsync(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Boolean> removeAsync(Object key, Object value)
+ {
+ return parentCache.removeAsync(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object replace(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.replace(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean replace(Serializable key, Object oldValue, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.replace(key, oldValue, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object replace(Serializable key, Object value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime,
+ TimeUnit maxIdleTimeUnit)
+ {
+ return parentCache.replace(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean replace(Serializable key, Object oldValue, Object value, long lifespan, TimeUnit lifespanUnit,
+ long maxIdleTime, TimeUnit maxIdleTimeUnit)
+ {
+ return parentCache.replace(key, oldValue, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> replaceAsync(Serializable key, Object value)
+ {
+ return parentCache.replaceAsync(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Boolean> replaceAsync(Serializable key, Object oldValue, Object newValue)
+ {
+ return parentCache.replaceAsync(key, oldValue, newValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> replaceAsync(Serializable key, Object value, long lifespan, TimeUnit unit)
+ {
+ return parentCache.replaceAsync(key, value, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Boolean> replaceAsync(Serializable key, Object oldValue, Object newValue, long lifespan,
+ TimeUnit unit)
+ {
+ return parentCache.replaceAsync(key, oldValue, newValue, lifespan, unit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Object> replaceAsync(Serializable key, Object value, long lifespan, TimeUnit lifespanUnit,
+ long maxIdle, TimeUnit maxIdleUnit)
+ {
+ return parentCache.replaceAsync(key, value, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NotifyingFuture<Boolean> replaceAsync(Serializable key, Object oldValue, Object newValue, long lifespan,
+ TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit)
+ {
+ return parentCache.replaceAsync(key, oldValue, newValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean startBatch()
+ {
+ return parentCache.startBatch();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Object> values()
+ {
+ return parentCache.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object putIfAbsent(Serializable key, Object value)
+ {
+ return parentCache.putIfAbsent(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean remove(Object key, Object value)
+ {
+ return parentCache.remove(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object replace(Serializable key, Object value)
+ {
+ return parentCache.replace(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean replace(Serializable key, Object oldValue, Object newValue)
+ {
+ return parentCache.replace(key, oldValue, newValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clear()
+ {
+ parentCache.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsKey(Object key)
+ {
+ return parentCache.containsKey(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsValue(Object value)
+ {
+ return parentCache.containsValue(value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object get(Object key)
+ {
+ return parentCache.get(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isEmpty()
+ {
+ return parentCache.isEmpty();
+ }
+
+ /**
+ *
+ * @param key
+ * @param value
+ * @return
+ */
+ public Object put(CacheKey key, Object value)
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+ changesContainer.add(new PutObjectContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
+ .get(), useExpiration, expirationTimeOut));
+
+ return parentCache.get(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object put(Serializable key, Object value)
+ {
+ return parentCache.put(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll(Map<? extends Serializable, ? extends Object> m)
+ {
+ parentCache.putAll(m);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object remove(Object key)
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+ changesContainer.add(new RemoveObjectContainer((CacheKey)key, parentCache, changesContainer.getHistoryIndex(),
+ local.get(), useExpiration, expirationTimeOut));
+ return parentCache.get(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int size()
+ {
+ return parentCache.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start()
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ parentCache.start();
+ return null;
+ }
+ };
+ AccessController.doPrivileged(action);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop()
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ parentCache.stop();
+ return null;
+ }
+ };
+ AccessController.doPrivileged(action);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addListener(Object listener)
+ {
+ parentCache.addListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Object> getListeners()
+ {
+ return parentCache.getListeners();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeListener(Object listener)
+ {
+ parentCache.removeListener(listener);
+ }
+
+ /**
+ * Start buffering process.
+ */
+ public void beginTransaction()
+ {
+ changesList.set(new CompressedISPNChangesBuffer());
+ local.set(false);
+ }
+
+ /**
+ *
+ * @return status of the cache transaction
+ */
+ public boolean isTransactionActive()
+ {
+ return changesList.get() != null;
+ }
+
+ /**
+ * Sort changes and commit data to the cache.
+ */
+ public void commitTransaction()
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+ try
+ {
+ List<ChangesContainer> containers = changesContainer.getSortedList();
+ for (ChangesContainer cacheChange : containers)
+ {
+ cacheChange.apply();
+ }
+ }
+ finally
+ {
+ changesList.set(null);
+ changesContainer = null;
+ }
+ }
+
+ /**
+ * Forget about changes
+ */
+ public void rollbackTransaction()
+ {
+ changesList.set(null);
+ }
+
+ /**
+ * Creates all ChangesBuffers with given parameter
+ *
+ * @param local
+ */
+ public void setLocal(boolean local)
+ {
+ // start local transaction
+ if (local && changesList.get() == null)
+ {
+ beginTransaction();
+ }
+ if (!local && this.local.get())
+ {
+
+ }
+ this.local.set(local);
+ }
+
+ /**
+ * Tries to get buffer and if it is null throws an exception otherwise returns buffer.
+ *
+ * @return
+ */
+ private CompressedISPNChangesBuffer getChangesBufferSafe()
+ {
+ CompressedISPNChangesBuffer changesContainer = changesList.get();
+ if (changesContainer == null)
+ {
+ throw new IllegalStateException("changesContainer should not be empty");
+ }
+ return changesContainer;
+ }
+
+ /**
+ *
+ * @param key
+ * @param value
+ */
+ public void addToList(CacheKey key, Object value)
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+ changesContainer.add(new AddToListContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
+ .get(), useExpiration, expirationTimeOut));
+ }
+
+ /**
+ *
+ * @param string
+ * @param node
+ * @return
+ */
+ public Object putInBuffer(CacheKey key, Object value)
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+
+ // take Object from buffer for first
+ Object prevObject = getObjectFromChangesContainer(changesContainer, key);
+
+ changesContainer.add(new PutObjectContainer(key, value, parentCache, changesContainer.getHistoryIndex(), local
+ .get(), useExpiration, expirationTimeOut));
+
+ if (prevObject != null)
+ {
+ return prevObject;
+ }
+ else
+ {
+ return parentCache.get(key);
+ }
+ }
+
+ private Object getObjectFromChangesContainer(CompressedISPNChangesBuffer changesContainer, CacheKey key)
+ {
+ List<ChangesContainer> changes = changesContainer.getSortedList();
+ Object object = null;
+
+ for (ChangesContainer change : changes)
+ {
+ if (change.getChangesType().equals(ChangesType.PUT) && change.getKey().equals(key))
+ {
+ object = ((PutObjectContainer)change).value;
+ }
+ }
+
+ return object;
+ }
+
+ /**
+ *
+ * @param key
+ * @param value
+ */
+ public void removeFromList(CacheKey key, Object value)
+ {
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+ changesContainer.add(new RemoveFromListContainer(key, value, parentCache, changesContainer.getHistoryIndex(),
+ local.get(), useExpiration, expirationTimeOut));
+ }
+
+ public Object getFromBuffer(CacheKey key)
+ {
+ //look at buffer for first
+ CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
+
+ Object objectFromBuffer = getObjectFromChangesContainer(changesContainer, key);
+
+ if (objectFromBuffer != null)
+ {
+ return objectFromBuffer;
+ }
+ else
+ {
+ return parentCache.get(key);
+ }
+ }
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheId.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+/**
+ *
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
+ * @version $Id: CacheId.java 111 2010-11-11 11:11:11Z tolusha $
+ */
+public class CacheId extends CacheKey
+{
+
+ /**
+ * CacheId constructor.
+ *
+ * @param id
+ */
+ CacheId(String id)
+ {
+ super(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CacheId)
+ {
+ CacheId cacheId = (CacheId)obj;
+ return (cacheId.hash == hash && cacheId.id.equals(id));
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheKey.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+import java.io.Serializable;
+
+/**
+ * Created by The eXo Platform SAS. <br/>
+ *
+ * Base class for WorkspaceCache keys.<br/>
+ *
+ * Date: 10.06.2008<br/>
+ *
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id: CacheKey.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+public abstract class CacheKey implements Serializable, Comparable<CacheKey>
+{
+
+ protected final String id;
+
+ protected final int hash;
+
+ CacheKey(String id)
+ {
+ this.id = id;
+ this.hash = id.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+ return this.hash;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ return this.id.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(CacheKey o)
+ {
+ return id.compareTo(o.id);
+ }
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesId.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+/**
+ * Created by The eXo Platform SAS
+ *
+ * Date: 10.06.2008
+ *
+ * Cache record used to store item Id key.
+ *
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id: CacheId.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+public class CacheNodesId extends CacheKey
+{
+
+ public static final String PREFIX = "N";
+
+ CacheNodesId(String id)
+ {
+ super(PREFIX + id);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CacheNodesId)
+ {
+ CacheNodesId cacheNodesId = (CacheNodesId)obj;
+ return (cacheNodesId.hash == hash && cacheNodesId.id.equals(id));
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // check is this descendant of prevRootPath
+
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CachePropsId.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+/**
+ * Created by The eXo Platform SAS
+ *
+ * Date: 10.06.2008
+ *
+ * Cache record used to store item Id key.
+ *
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id: CacheId.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+public class CachePropsId extends CacheKey
+{
+
+ public static final String PREFIX = "P";
+
+ CachePropsId(String id)
+ {
+ super(PREFIX + id);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CachePropsId)
+ {
+ CachePropsId cachePropsId = (CachePropsId)obj;
+ return (cachePropsId.hash == hash && cachePropsId.id.equals(id));
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheQPath.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+
+/**
+ * Created by The eXo Platform SAS. <br/>
+ *
+ * Store QPath as key in cache.
+ *
+ * 15.06.07
+ *
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id: CacheQPath.java 13869 2008-05-05 08:40:10Z pnedonosko $
+ */
+class CacheQPath extends CacheKey
+{
+
+ private final String parentId;
+
+ private final QPath path;
+
+ CacheQPath(String parentId, QPath path)
+ {
+ super((parentId != null ? parentId : Constants.ROOT_PARENT_UUID)
+ + path.getEntries()[path.getEntries().length - 1].getAsString(true));
+
+ this.parentId = parentId;
+ this.path = path;
+ }
+
+ CacheQPath(String parentId, QPathEntry name)
+ {
+ super((parentId != null ? parentId : Constants.ROOT_PARENT_UUID) + name.getAsString(true));
+
+ this.parentId = parentId;
+ this.path = null;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CacheQPath)
+ {
+ CacheQPath cacheQPath = (CacheQPath)obj;
+ return (cacheQPath.hashCode() == hash && cacheQPath.id.equals(id));
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ final StringBuilder s = new StringBuilder();
+ s.append((this.parentId != null ? this.parentId : Constants.ROOT_PARENT_UUID));
+ s.append((path != null ? path.getEntries()[path.getEntries().length - 1] : "null"));
+ s.append(", ");
+ s.append(id);
+ return s.toString();
+ }
+
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CompressedISPNChangesBuffer.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+import org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.BufferedISPNCache.ChangesContainer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Sorting cache modification
+ *
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
+ * @version $Id: CompressedISPNChangesBuffer.java 111 2010-11-11 11:11:11Z tolusha $
+ */
+public class CompressedISPNChangesBuffer
+{
+ private int historyIndex = 0;
+
+ List<ChangesContainer> changes = new ArrayList<ChangesContainer>();
+
+ /**
+ * Adds new modification container to buffer and performs optimization if needed. Optimization doesn't iterate
+ * over lists and uses HashMaps. So each optimization duration doesn't depend on list size.
+ *
+ * @param container
+ */
+ public void add(ChangesContainer container)
+ {
+ changes.add(container);
+ }
+
+ /**
+ * After each invocation of the method increments internal field.
+ * Designed to be used as history order index in each {@link ChangesContainer}
+ * @return
+ */
+ public int getHistoryIndex()
+ {
+ historyIndex++;
+ return historyIndex;
+ }
+
+ /**
+ * Builds single list of modifications from internal structures and sorts it.
+ *
+ * @return
+ */
+ public List<ChangesContainer> getSortedList()
+ {
+ List<ChangesContainer> changesContainers = new ArrayList<ChangesContainer>(changes);
+ Collections.sort(changesContainers);
+ return changesContainers;
+ }
+
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
+
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
+import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
+import org.exoplatform.services.jcr.datamodel.IllegalPathException;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.infinispan.InfinispanCacheFactory;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.transaction.TransactionService;
+import org.infinispan.Cache;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.<p/>
+ *
+ * Cache based on Infinispan.<p/>
+ *
+ * TODO: structure
+ *
+ * <ul>
+ * <li>cache transparent: or item cached or not, we should not generate "not found" Exceptions </li>
+ *
+ * <p/>
+ * Current state notes (subject of change):
+ * <ul>
+ * <li>cache implements WorkspaceStorageCache, without any stuff about references and locks</li>
+ * <li>transaction style implemented via JBC barches, do with JTA (i.e. via exo's TransactionService + JBoss TM)</li>
+ * </ul>
+ *
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
+ * @version $Id: ISPNCacheWorkspaceStorageCache.java 111 2010-11-11 11:11:11Z tolusha $
+ */
+public class ISPNCacheWorkspaceStorageCache implements WorkspaceStorageCache
+{
+
+ private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ISPNCacheWorkspaceStorageCache");
+
+ public static final String JBOSSCACHE_CONFIG = "infinispan-configuration";
+
+ protected final BufferedISPNCache cache;
+
+ /**
+ * Node order comparator for getChildNodes().
+ */
+ class NodesOrderComparator<N extends NodeData> implements Comparator<NodeData>
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compare(NodeData n1, NodeData n2)
+ {
+ return n1.getOrderNumber() - n2.getOrderNumber();
+ }
+ }
+
+ class ChildItemsIterator<T extends ItemData> implements Iterator<T>
+ {
+
+ final Iterator<String> childs;
+
+ T next;
+
+ ChildItemsIterator(CacheKey key)
+ {
+ Set<String> set = (Set<String>)cache.get(key);
+ if (set != null)
+ {
+ childs = ((Set<String>)cache.get(key)).iterator();
+ fetchNext();
+ }
+ else
+ {
+ childs = null;
+ next = null;
+ }
+ }
+
+ protected void fetchNext()
+ {
+ if (childs.hasNext())
+ {
+ // traverse to the first existing or the end of children
+ T n = null;
+ do
+ {
+ n = (T)cache.get(new CacheId(childs.next()));
+ }
+ while (n == null && childs.hasNext());
+ next = n;
+ }
+ else
+ {
+ next = null;
+ }
+ }
+
+ public boolean hasNext()
+ {
+ return next != null;
+ }
+
+ public T next()
+ {
+ if (next == null)
+ {
+ throw new NoSuchElementException();
+ }
+
+ final T current = next;
+ fetchNext();
+ return current;
+ }
+
+ public void remove()
+ {
+ throw new IllegalArgumentException("Not implemented");
+ }
+ }
+
+ class ChildNodesIterator<N extends NodeData> extends ChildItemsIterator<N>
+ {
+ ChildNodesIterator(String parentId)
+ {
+ super(new CacheNodesId(parentId));
+ }
+
+ @Override
+ public N next()
+ {
+ return super.next();
+ }
+ }
+
+ class ChildPropertiesIterator<P extends PropertyData> extends ChildItemsIterator<P>
+ {
+
+ ChildPropertiesIterator(String parentId)
+ {
+ super(new CachePropsId(parentId));
+ }
+
+ @Override
+ public P next()
+ {
+ return super.next();
+ }
+ }
+
+ /**
+ * Cache constructor with eXo TransactionService support.
+ *
+ * @param wsConfig WorkspaceEntry workspace config
+ * @param transactionService TransactionService external transaction service
+ * @throws RepositoryException if error of initialization
+ * @throws RepositoryConfigurationException if error of configuration
+ */
+ public ISPNCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, TransactionService transactionService,
+ ConfigurationManager cfm) throws RepositoryException, RepositoryConfigurationException
+ {
+ if (wsConfig.getCache() == null)
+ {
+ throw new RepositoryConfigurationException("Cache configuration not found");
+ }
+
+ // create cache using custom factory
+ InfinispanCacheFactory<Serializable, Object> factory = new InfinispanCacheFactory<Serializable, Object>(cfm);
+
+ // create parent JBossCache instance
+ Cache<Serializable, Object> parentCache = factory.createCache(wsConfig.getCache());
+
+ // // get all eviction configurations
+ // List<EvictionRegionConfig> evictionConfigurations =
+ // parentCache.getConfiguration().getEvictionConfig().getEvictionRegionConfigs();
+ // // append and default eviction configuration, since it is not present in region configurations
+ // evictionConfigurations.add(parentCache.getConfiguration().getEvictionConfig().getDefaultEvictionRegionConfig());
+ //
+ // boolean useExpiration = false;
+ // // looking over all eviction configurations till the end or till some expiration algorithm subclass not found.
+ // for (EvictionRegionConfig evictionRegionConfig : evictionConfigurations)
+ // {
+ // if (evictionRegionConfig.getEvictionAlgorithmConfig() instanceof ExpirationAlgorithmConfig)
+ // {
+ // // force set expiration key to default value in all Expiration configurations (if any)
+ // ((ExpirationAlgorithmConfig)evictionRegionConfig.getEvictionAlgorithmConfig())
+ // .setExpirationKeyName(ExpirationAlgorithmConfig.EXPIRATION_KEY);
+ // useExpiration = true;
+ // }
+ // }
+
+ // if expiration is used, set appropriate factory with with timeout set via configuration (or default one 15minutes)
+ this.cache = new BufferedISPNCache(parentCache, false, -1);
+ }
+
+ /**
+ * Cache constructor with JBossCache JTA transaction support.
+ *
+ * @param wsConfig WorkspaceEntry workspace config
+ * @throws RepositoryException if error of initialization
+ * @throws RepositoryConfigurationException if error of configuration
+ */
+ public ISPNCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, ConfigurationManager cfm) throws RepositoryException,
+ RepositoryConfigurationException
+ {
+ this(wsConfig, null, cfm);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void put(ItemData item)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+ cache.setLocal(true);
+ if (item.isNode())
+ {
+ putNode((NodeData)item, ModifyChildOption.NOT_MODIFY);
+ }
+ else
+ {
+ putProperty((PropertyData)item, ModifyChildOption.NOT_MODIFY);
+ }
+ }
+ finally
+ {
+ cache.setLocal(false);
+ if (!inTransaction)
+ {
+ cache.commitTransaction();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void remove(ItemData item)
+ {
+ removeItem(item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onSaveItems(final ItemStateChangesLog itemStates)
+ {
+ // if something happen we will rollback changes
+ boolean rollback = true;
+ try
+ {
+ cache.beginTransaction();
+ for (ItemState state : itemStates.getAllStates())
+ {
+ if (state.isAdded())
+ {
+ if (state.isPersisted())
+ {
+ putItem(state.getData());
+ }
+ }
+ else if (state.isUpdated())
+ {
+ if (state.isPersisted())
+ {
+ // There was a problem with removing a list of samename siblings in on transaction,
+ // so putItemInBufferedCache(..) and updateInBufferedCache(..) used instead put(..) and update (..) methods.
+ ItemData prevItem = putItemInBufferedCache(state.getData());
+ if (prevItem != null && state.isNode())
+ {
+ // nodes reordered, if previous is null it's InvalidItemState case
+ updateInBuffer((NodeData)state.getData(), (NodeData)prevItem);
+ }
+ }
+ }
+ else if (state.isDeleted())
+ {
+ removeItem(state.getData());
+ }
+ else if (state.isRenamed())
+ {
+ putItem(state.getData());
+ }
+ else if (state.isMixinChanged())
+ {
+ if (state.isPersisted())
+ {
+ // update subtree ACLs
+ updateMixin((NodeData)state.getData());
+ }
+ }
+ }
+
+ cache.commitTransaction();
+ rollback = false;
+ }
+ finally
+ {
+ if (rollback)
+ {
+ cache.rollbackTransaction();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addChildNodes(NodeData parent, List<NodeData> childs)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+
+ cache.setLocal(true);
+
+ // remove previous all (to be sure about consistency)
+ cache.remove(new CacheNodesId(parent.getIdentifier()));
+
+ if (childs.size() > 0)
+ {
+ Set<Object> set = new HashSet<Object>();
+ for (NodeData child : childs)
+ {
+ putNode(child, ModifyChildOption.NOT_MODIFY);
+ set.add(child.getIdentifier());
+ }
+ cache.put(new CacheNodesId(parent.getIdentifier()), set);
+ }
+ else
+ {
+ // cache fact of empty childs list
+ cache.put(new CacheNodesId(parent.getIdentifier()), new HashSet<Object>());
+ }
+ }
+ finally
+ {
+ cache.setLocal(false);
+ if (!inTransaction)
+ {
+ cache.commitTransaction();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addChildProperties(NodeData parent, List<PropertyData> childs)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+ cache.setLocal(true);
+ // remove previous all (to be sure about consistency)
+ cache.remove(new CachePropsId(parent.getIdentifier()));
+ if (childs.size() > 0)
+ {
+ // add all new
+ Set<Object> set = new HashSet<Object>();
+ for (PropertyData child : childs)
+ {
+ putProperty(child, ModifyChildOption.NOT_MODIFY);
+ set.add(child.getIdentifier());
+ }
+ cache.put(new CachePropsId(parent.getIdentifier()), set);
+
+ }
+ else
+ {
+ LOG.warn("Empty properties list cached " + (parent != null ? parent.getQPath().getAsString() : parent));
+ }
+ }
+ finally
+ {
+ cache.setLocal(false);
+ if (!inTransaction)
+ {
+ cache.commitTransaction();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addChildPropertiesList(NodeData parent, List<PropertyData> childProperties)
+ {
+ // TODO not implemented, will force read from DB
+ // try
+ // {
+ // cache.beginTransaction();
+ // cache.setLocal(true);
+ //
+ // }
+ // finally
+ // {
+ // cache.setLocal(false);
+ // cache.commitTransaction();
+ // }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData get(String parentId, QPathEntry name)
+ {
+ return (ItemData)cache.get(new CacheQPath(parentId, name));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData get(String id)
+ {
+ return id == null ? null : (ItemData)cache.get(new CacheId(id));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<NodeData> getChildNodes(final NodeData parent)
+ {
+ // get list of children uuids
+ final Set<String> set = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
+
+ if (set != null)
+ {
+ final List<NodeData> childs = new ArrayList<NodeData>();
+
+ for (String childId : set)
+ {
+ NodeData child = (NodeData)cache.get(new CacheId(childId));
+ if (child == null)
+ {
+ return null;
+ }
+
+ childs.add(child);
+ }
+
+ // order children by orderNumber, as HashSet returns children in other order
+ Collections.sort(childs, new NodesOrderComparator<NodeData>());
+
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getChildNodesCount(NodeData parent)
+ {
+ Set<String> list = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
+ return list != null ? list.size() : -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> getChildProperties(NodeData parent)
+ {
+ return getChildProps(parent.getIdentifier(), true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> listChildProperties(NodeData parent)
+ {
+ return getChildProps(parent.getIdentifier(), false);
+ }
+
+ /**
+ * Internal get child properties.
+ *
+ * @param parentId String
+ * @param withValue boolean, if true only "full" Propeties can be returned
+ * @return List of PropertyData
+ */
+ protected List<PropertyData> getChildProps(String parentId, boolean withValue)
+ {
+ // get list of children uuids
+ final Set<String> set = (Set<String>)cache.get(new CachePropsId(parentId));
+ if (set != null)
+ {
+ final List<PropertyData> childs = new ArrayList<PropertyData>();
+
+ for (String childId : set)
+ {
+ PropertyData child = (PropertyData)cache.get(new CacheId(childId));
+
+ if (child == null)
+ {
+ return null;
+ }
+ if (withValue && child.getValues().size() <= 0)
+ {
+ return null;
+ }
+ childs.add(child);
+ }
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getSize()
+ {
+ return cache.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Internal put Item.
+ *
+ * @param item ItemData, new data to put in the cache
+ * @return ItemData, previous data or null
+ */
+ protected ItemData putItem(ItemData item)
+ {
+ if (item.isNode())
+ {
+ return putNode((NodeData)item, ModifyChildOption.MODIFY);
+ }
+ else
+ {
+ return putProperty((PropertyData)item, ModifyChildOption.MODIFY);
+ }
+ }
+
+ protected ItemData putItemInBufferedCache(ItemData item)
+ {
+ if (item.isNode())
+ {
+ return putNodeInBufferedCache((NodeData)item, ModifyChildOption.MODIFY);
+ }
+ else
+ {
+ return putProperty((PropertyData)item, ModifyChildOption.MODIFY);
+ }
+
+ }
+
+ /**
+ * Internal put Node.
+ *
+ * @param node, NodeData, new data to put in the cache
+ * @return NodeData, previous data or null
+ */
+ protected ItemData putNode(NodeData node, ModifyChildOption modifyListsOfChild)
+ {
+ if (node.getParentIdentifier() != null)
+ {
+ // if MODIFY and List present OR FORCE_MODIFY, then write
+ if ((modifyListsOfChild == ModifyChildOption.MODIFY && cache.get(new CacheNodesId(node.getParentIdentifier())) != null)
+ || modifyListsOfChild == ModifyChildOption.FORCE_MODIFY)
+ {
+ cache.addToList(new CacheNodesId(node.getParentIdentifier()), node.getIdentifier());
+ }
+ }
+
+ cache.put(new CacheQPath(node.getParentIdentifier(), node.getQPath()), node);
+ return (ItemData)cache.put(new CacheId(node.getIdentifier()), node);
+ }
+
+ protected ItemData putNodeInBufferedCache(NodeData node, ModifyChildOption modifyListsOfChild)
+ {
+ if (node.getParentIdentifier() != null)
+ {
+ // if MODIFY and List present OR FORCE_MODIFY, then write
+ if ((modifyListsOfChild == ModifyChildOption.MODIFY && cache.get(new CacheNodesId(node.getParentIdentifier())) != null)
+ || modifyListsOfChild == ModifyChildOption.FORCE_MODIFY)
+ {
+ cache.addToList(new CacheNodesId(node.getParentIdentifier()), node.getIdentifier());
+ }
+ }
+
+ cache.putInBuffer(new CacheQPath(node.getParentIdentifier(), node.getQPath()), node);
+ return (ItemData)cache.putInBuffer(new CacheId(node.getIdentifier()), node);
+ }
+
+ /**
+ * Internal put Property.
+ *
+ * @param node, PropertyData, new data to put in the cache
+ * @return PropertyData, previous data or null
+ */
+ protected PropertyData putProperty(PropertyData prop, ModifyChildOption modifyListsOfChild)
+ {
+ // if MODIFY and List present OR FORCE_MODIFY, then write
+ if ((modifyListsOfChild == ModifyChildOption.MODIFY && cache.get(new CachePropsId(prop.getParentIdentifier())) != null)
+ || modifyListsOfChild == ModifyChildOption.FORCE_MODIFY)
+ {
+ cache.addToList(new CachePropsId(prop.getParentIdentifier()), prop.getIdentifier());
+ }
+
+ cache.put(new CacheQPath(prop.getParentIdentifier(), prop.getQPath()), prop);
+ return (PropertyData)cache.put(new CacheId(prop.getIdentifier()), prop);
+ }
+
+ protected void removeItem(ItemData item)
+ {
+ cache.remove(new CacheId(item.getIdentifier()));
+ cache.remove(new CacheQPath(item.getParentIdentifier(), item.getQPath()));
+
+ if (item.getParentIdentifier() != null)
+ {
+ if (item.isNode())
+ {
+ cache.removeFromList(new CacheNodesId(item.getParentIdentifier()), item.getIdentifier());
+ }
+ else
+ {
+ cache.removeFromList(new CachePropsId(item.getParentIdentifier()), item.getIdentifier());
+ }
+ }
+ }
+
+ /**
+ * Update Node's mixin and ACL.
+ *
+ * @param node NodeData
+ */
+ protected void updateMixin(NodeData node)
+ {
+ NodeData prevData = (NodeData)cache.put(new CacheId(node.getIdentifier()), node);
+ cache.put(new CacheQPath(node.getParentIdentifier(), node.getQPath()), node);
+
+ if (prevData != null)
+ {
+ // do update ACL if needed
+ if (prevData.getACL() == null || !prevData.getACL().equals(node.getACL()))
+ {
+ updateChildsACL(node.getIdentifier(), node.getACL());
+ }
+ }
+ else if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Previous NodeData not found for mixin update " + node.getQPath().getAsString());
+ }
+ }
+
+ /**
+ * Update Node hierachy in case of same-name siblings reorder.
+ * Assumes the new (updated) nodes already putted in the cache. Previous name of updated nodes will be calculated
+ * and that node will be deleted (if has same id as the new node). Childs paths will be updated to a new node path.
+ *
+ * @param node NodeData
+ * @param prevNode NodeData
+ */
+ protected void updateInBuffer(final NodeData node, final NodeData prevNode)
+ {
+ // Fqn<String> prevFqn =
+ // makeChildFqn(childNodes, node.getParentIdentifier(), prevNode.getQPath().getEntries()[prevNode.getQPath()
+ // .getEntries().length - 1]);
+ //
+ // if (node.getIdentifier().equals(cache.getFromBuffer(prevFqn, ITEM_ID)))
+ // {
+ // // it's same-name siblings re-ordering, delete previous child
+ // if (!cache.removeNode(prevFqn) && LOG.isDebugEnabled())
+ // {
+ // LOG.debug("Node not extists as a child but update asked " + node.getQPath().getAsString());
+ // }
+ // }
+
+ // update childs paths if index changed
+ int nodeIndex = node.getQPath().getEntries()[node.getQPath().getEntries().length - 1].getIndex();
+ int prevNodeIndex = prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1].getIndex();
+ if (nodeIndex != prevNodeIndex)
+ {
+ // its a samename reordering
+ updateTreePath(prevNode.getQPath(), node.getQPath(), null); // don't change ACL, it's same parent
+ }
+ }
+
+ /**
+ * Check all items in cache - is it descendant of prevRootPath, and update path according newRootPath.
+ *
+ * @param prevRootPath
+ * @param newRootPath
+ * @param acl
+ */
+ protected void updateTreePath(final QPath prevRootPath, final QPath newRootPath, final AccessControlList acl)
+ {
+ boolean inheritACL = acl != null;
+
+ // check all ITEMS in cache
+ Iterator<Serializable> keys = cache.keySet().iterator();
+
+ while (keys.hasNext())
+ {
+ CacheKey key = (CacheKey)keys.next();
+ if (key instanceof CacheId || key instanceof CacheQPath)
+ {
+ ItemData data = (ItemData)cache.get(key);
+
+ if (data != null)
+ {
+ // check is this descendant of prevRootPath
+ QPath nodeQPath = data.getQPath();
+ if (nodeQPath.isDescendantOf(prevRootPath))
+ {
+
+ //make relative path
+ QPathEntry[] relativePath = null;
+ try
+ {
+ relativePath = nodeQPath.getRelPath(nodeQPath.getDepth() - prevRootPath.getDepth());
+ }
+ catch (IllegalPathException e)
+ {
+ // Do nothing. Never happens.
+ }
+
+ // make new path - no matter node or property
+ QPath newPath = QPath.makeChildPath(newRootPath, relativePath);
+
+ if (data.isNode())
+ {
+ // update node
+ NodeData prevNode = (NodeData)data;
+
+ TransientNodeData newNode =
+ new TransientNodeData(newPath, prevNode.getIdentifier(), prevNode.getPersistedVersion(),
+ prevNode.getPrimaryTypeName(), prevNode.getMixinTypeNames(), prevNode.getOrderNumber(),
+ prevNode.getParentIdentifier(), inheritACL ? acl : prevNode.getACL()); // TODO check ACL
+
+ // update this node
+ if (key instanceof CacheId)
+ {
+ cache.put(new CacheId(newNode.getIdentifier()), newNode);
+ }
+ else
+ {
+ cache.put(new CacheQPath(newNode.getParentIdentifier(), newNode.getQPath()), newNode);
+ }
+ }
+ else
+ {
+ //update property
+ PropertyData prevProp = (PropertyData)data;
+
+ if (inheritACL
+ && (prevProp.getQPath().getName().equals(Constants.EXO_PERMISSIONS) || prevProp.getQPath()
+ .getName().equals(Constants.EXO_OWNER)))
+ {
+ inheritACL = false;
+ }
+
+ TransientPropertyData newProp =
+ new TransientPropertyData(newPath, prevProp.getIdentifier(), prevProp.getPersistedVersion(),
+ prevProp.getType(), prevProp.getParentIdentifier(), prevProp.isMultiValued(), prevProp
+ .getValues());
+
+ // update this property
+ if (key instanceof CacheId)
+ {
+ cache.put(new CacheId(newProp.getIdentifier()), newProp);
+ }
+ else
+ {
+ cache.put(new CacheQPath(newProp.getParentIdentifier(), newProp.getQPath()), newProp);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Update child Nodes ACLs.
+ *
+ * @param parentId String - root node id of JCR subtree.
+ * @param acl AccessControlList
+ */
+ protected void updateChildsACL(final String parentId, final AccessControlList acl)
+ {
+ for (Iterator<NodeData> iter = new ChildNodesIterator<NodeData>(parentId); iter.hasNext();)
+ {
+ NodeData prevNode = iter.next();
+
+ // is ACL changes on this node (i.e. ACL inheritance brokes)
+ for (InternalQName mixin : prevNode.getMixinTypeNames())
+ {
+ if (mixin.equals(Constants.EXO_PRIVILEGEABLE) || mixin.equals(Constants.EXO_OWNEABLE))
+ {
+ continue;
+ }
+ }
+
+ // recreate with new path for child Nodes only
+ TransientNodeData newNode =
+ new TransientNodeData(prevNode.getQPath(), prevNode.getIdentifier(), prevNode.getPersistedVersion(),
+ prevNode.getPrimaryTypeName(), prevNode.getMixinTypeNames(), prevNode.getOrderNumber(), prevNode
+ .getParentIdentifier(), acl);
+
+ // update this node
+ cache.put(new CacheId(newNode.getIdentifier()), newNode);
+ cache.put(new CacheQPath(newNode.getIdentifier(), newNode.getQPath()), newNode);
+
+ // update childs recursive
+ updateChildsACL(newNode.getIdentifier(), acl);
+ }
+ }
+
+ public void beginTransaction()
+ {
+ cache.beginTransaction();
+ }
+
+ public void commitTransaction()
+ {
+ cache.commitTransaction();
+ }
+
+ public void rollbackTransaction()
+ {
+ cache.rollbackTransaction();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isTXAware()
+ {
+ return true;
+ }
+
+ /**
+ * <li>NOT_MODIFY - node(property) is not added to the parent's list (no persistent changes performed, cache used as cache)</li>
+ * <li>MODIFY - node(property) is added to the parent's list if parent in the cache (new item is added to persistent, add to list if it is present)</li>
+ * <li>FORCE_MODIFY - node(property) is added to the parent's list anyway (when list is read from DB, forcing write)</li>
+ */
+ private enum ModifyChildOption {
+ NOT_MODIFY, MODIFY, FORCE_MODIFY
+ }
+
+}
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -236,4 +236,42 @@
}
}
}
+
+ /**
+ * Put in Infinispan cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static Object put(final org.infinispan.Cache<Serializable, Object> cache, final Serializable key,
+ final Object value) throws CacheException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return cache.put(key, value);
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof CacheException)
+ {
+ throw (CacheException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
}
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -52,8 +52,6 @@
public static final String INFINISPAN_CONFIG = "infinispan-configuration";
- public static final String INFINISPAN_CACHE_NAME = "infinispan-cache-name";
-
public static final String JGROUPS_CONFIG = "jgroups-configuration";
public static final String JGROUPS_MUX_ENABLED = "jgroups-multiplexer-stack";
@@ -78,9 +76,8 @@
/**
* Factory that creates and starts pre-configured instances of Infinispan.
- * Path to Infinispan configuration or template and cache name should be
- * provided as "infinispan-configuration" and "infinispan-cache-name" properties
- * in parameterEntry instance respectively.
+ * Path to Infinispan configuration or template should be provided as
+ * "infinispan-configuration" property in parameterEntry instance.
* <br>
* If parameterEntry has "jgroups-multiplexer-stack" (=true) and
* "jgroups-configuration" parameters then Multiplexing stack is enabled
@@ -94,8 +91,7 @@
{
// get Infinispan configuration file path and cache name
final String configurationPath = parameterEntry.getParameterValue(INFINISPAN_CONFIG);
- final String cacheName = parameterEntry.getParameterValue(INFINISPAN_CACHE_NAME);
- log.info("Infinispan Cache configuration used: " + configurationPath + " cache name: " + cacheName);
+ log.info("Infinispan Cache configuration used: " + configurationPath);
// prepare configuration
InputStream configStream;
@@ -124,7 +120,7 @@
{
public Cache<K, V> run()
{
- return manager.getCache(cacheName);
+ return manager.getCache();
}
};
Cache<K, V> cache = AccessController.doPrivileged(action);
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestOrderBefore.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestOrderBefore.java 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestOrderBefore.java 2010-07-30 13:00:43 UTC (rev 2843)
@@ -25,7 +25,6 @@
import java.util.List;
import javax.jcr.ItemExistsException;
-import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
@@ -241,723 +240,723 @@
// -------------- Simple use-case: child nodes n1, n2, n3, n4 ---------------
- public void testOrderUp() throws Exception
- {
- initSimpleCase();
+ // public void testOrderUp() throws Exception
+ // {
+ // initSimpleCase();
+ //
+ // testBase.orderBefore("n4", "n3");
+ //
+ // String[] order = new String[]{"n1", "n2", "n4", "n3"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderUpStepOver() throws Exception
+ // {
+ // initSimpleCase5();
+ //
+ // // was n2,n3,n1,n4,n5
+ // testBase.orderBefore("n4", "n3");
+ //
+ // String[] order = new String[]{"n2", "n4", "n3", "n1", "n5"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderBegin() throws Exception
+ // {
+ // initSimpleCase();
+ //
+ // testBase.orderBefore("n3", "n1");
+ //
+ // String[] order = new String[]{"n3", "n1", "n2", "n4"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderDown() throws Exception
+ // {
+ // initSimpleCase();
+ //
+ // testBase.orderBefore("n2", "n4");
+ //
+ // String[] order = new String[]{"n1", "n3", "n2", "n4"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderEnd() throws Exception
+ // {
+ // initSimpleCase();
+ //
+ // testBase.orderBefore("n2", null);
+ //
+ // String[] order = new String[]{"n1", "n3", "n4", "n2"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // // ----- Same-name sibling use-case: child nodes n1, n2[1], n2[2], n3 -----
+ //
+ // public void testOrderUp_SNS1() throws Exception
+ // {
+ // initSNSCase1();
+ //
+ // testBase.orderBefore("n3", "n2");
+ //
+ // String[] order = new String[]{"n1", "n3", "n2", "n2[2]"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderBegin_SNS1() throws Exception
+ // {
+ // initSNSCase1();
+ //
+ // testBase.orderBefore("n2[2]", "n1");
+ //
+ // String[] order = new String[]{"n2", "n1", "n2[2]", "n3"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderDown_SNS1() throws Exception
+ // {
+ // initSNSCase1();
+ //
+ // testBase.orderBefore("n1", "n2[2]");
+ //
+ // String[] order = new String[]{"n2", "n1", "n2[2]", "n3"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // /**
+ // * A childs order map is unchanged after the order
+ // */
+ // public void testOrderDown1_SNS1() throws Exception
+ // {
+ // initSNSCase1();
+ //
+ // testBase.orderBefore("n2", "n3");
+ //
+ // String[] order = new String[]{"n1", "n2", "n2[2]", "n3"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // public void testOrderEnd_SNS1() throws Exception
+ // {
+ // initSNSCase1();
+ //
+ // testBase.orderBefore("n2[2]", null);
+ //
+ // String[] order = new String[]{"n1", "n2", "n3", "n2[2]"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ // }
+ //
+ // // ----- Same-name sibling use-case: child nodes n1, n1[2], n1[3], n1[4].
+ // // n1[3] -
+ // // mix:referenceable -----
+ //
+ // public void testOrderBegin_SNS2() throws Exception
+ // {
+ // initSNSCase2();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[3]", "n1");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
+ // // -> n1
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n1uuid = testBase.getNode("n1").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n1uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n1uuid = testBase.getNode("n1").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n1uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderUp_SNS2() throws Exception
+ // {
+ // initSNSCase2();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[4]", "n1[2]");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
+ // // ->
+ // // n1[4]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n4uuid = testBase.getNode("n1[4]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n4uuid = testBase.getNode("n1[4]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderDown_SNS2() throws Exception
+ // {
+ // initSNSCase2();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1", "n1[3]");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
+ // // is
+ // // unchanged
+ // // in
+ // // location
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // /**
+ // * A childs order map is unchanged after the order
+ // */
+ // public void testOrderDown1_SNS2() throws Exception
+ // {
+ // initSNSCase2();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[2]", "n1[4]");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
+ // // ->
+ // // n1[2]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderEnd_SNS2() throws Exception
+ // {
+ // initSNSCase2();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[2]", null);
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
+ // // ->
+ // // n1[2]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // // ----- Same-name sibling use-case: child nodes n1, n1[2], n1[3], n1[4], n2.
+ // // n1[3] -
+ // // mix:referenceable -----
+ //
+ // public void testOrderBegin_SNS3() throws Exception
+ // {
+ // initSNSCase3();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n2", "n1");
+ //
+ // String[] order = new String[]{"n2", "n1", "n1[2]", "n1[3]", "n1[4]"}; // n1
+ // // [
+ // // 3
+ // // ]
+ // // unchanged
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderUp_SNS3() throws Exception
+ // {
+ // initSNSCase3();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n2", "n1[3]");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n2", "n1[3]", "n1[4]"}; // n1
+ // // [
+ // // 3
+ // // ]
+ // // unchanged
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n3uuid_same = testBase.getNode("n1[3]").getUUID();
+ // assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderDown_SNS3() throws Exception
+ // {
+ // initSNSCase3();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1", "n2");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]", "n2"}; // n1
+ // // [
+ // // 3
+ // // ]
+ // // -
+ // // >
+ // // n1
+ // // [
+ // // 2
+ // // ]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // /**
+ // * A childs order map is unchanged after the order
+ // */
+ // public void testOrderDown1_SNS3() throws Exception
+ // {
+ // initSNSCase3();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[2]", "n1[4]");
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]", "n2"}; // n1
+ // // [
+ // // 3
+ // // ]
+ // // -
+ // // >
+ // // n1
+ // // [
+ // // 2
+ // // ]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n2uuid = testBase.getNode("n1[2]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // public void testOrderEnd_SNS3() throws Exception
+ // {
+ // initSNSCase3();
+ //
+ // String n3uuid = testBase.getNode("n1[3]").getUUID();
+ //
+ // testBase.orderBefore("n1[3]", null);
+ //
+ // String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n2", "n1[4]"}; // n1
+ // // [3]->n1[4]
+ //
+ // checkOrder(order);
+ //
+ // try
+ // {
+ // String n4uuid = testBase.getNode("n1[4]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
+ // + ". " + e);
+ // }
+ //
+ // testBase.save();
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // try
+ // {
+ // String n4uuid = testBase.getNode("n1[4]").getUUID();
+ // assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
+ // }
+ // catch (RepositoryException e)
+ // {
+ // fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
+ // + ". " + e);
+ // }
+ // }
+ //
+ // // ================= Large arrays of nodes ================
+ // /**
+ // * Test of case when an index text length in the item path is differs from one
+ // * new creted by reorder. E.g. n1[2] -> n1[100]
+ // */
+ // public void testLargeNodesArray() throws Exception
+ // {
+ // initSNSCaseLargeArray();
+ //
+ // // String n40uuid = testBase.getNode("n1[40]").getUUID();
+ //
+ // Node n1__2 = testBase.getNode("n1[2]");
+ // Node n_21 = testBase.getNode("n_21");
+ // Node n_24 = testBase.getNode("n_24");
+ //
+ // // === step 1 ===
+ //
+ // // n1[2] -> n1[100] pos:120; n_21 = pos:121; ... n1[3] -> pos:2; n1[99] ->
+ // // n1[98] pos:98;
+ // // n1[100] -> n1[99] pos:99
+ // testBase.orderBefore("n1[2]", "n_21");
+ //
+ // EntityCollection nodes = getEntityCollection(testBase.getNodes());
+ //
+ // assertEquals("Nodes must be equals ", n1__2, nodes.getList().get(119)); // pos
+ // // :
+ // // 120
+ // assertEquals("Nodes must be equals ", n1__2, testBase.getNode("n1[100]"));
+ //
+ // assertEquals("Nodes must be equals ", n_21, nodes.getList().get(120)); //pos:
+ // // 121
+ // assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
+ //
+ // assertTrue("Node must exists ", testBase.hasNode("n1[2]"));
+ //
+ // testBase.save();
+ //
+ // nodes = getEntityCollection(testBase.getNodes());
+ //
+ // assertEquals("Nodes must be equals ", n1__2, nodes.getList().get(119)); // pos
+ // // :
+ // // 120
+ // assertEquals("Nodes must be equals ", n1__2, testBase.getNode("n1[100]"));
+ //
+ // assertEquals("Nodes must be equals ", n_21, nodes.getList().get(120)); //pos:
+ // // 121
+ // assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
+ //
+ // assertTrue("Node must exists ", testBase.hasNode("n1[2]"));
+ //
+ // // === step 2 ===
+ //
+ // Node n1__100 = testBase.getNode("n1[100]");
+ //
+ // // n_24 -> pos:120; n1[100] -> pos:121;
+ // testBase.orderBefore("n_24", "n1[100]");
+ //
+ // nodes = getEntityCollection(testBase.getNodes());
+ //
+ // assertEquals("Nodes must be equals ", n1__100, nodes.getList().get(120)); // pos
+ // // :
+ // // 121
+ // assertEquals("Nodes must be equals ", n1__100, testBase.getNode("n1[100]"));
+ //
+ // assertEquals("Nodes must be equals ", n_24, nodes.getList().get(119)); //pos:
+ // // 120
+ // assertEquals("Nodes must be equals ", n_24, testBase.getNode("n_24"));
+ //
+ // assertEquals("Nodes must be equals ", n_21, nodes.getList().get(121)); //pos:
+ // // 122
+ // assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
+ //
+ // testBase.save();
+ //
+ // assertEquals("Nodes must be equals ", n1__100, nodes.getList().get(120)); // pos
+ // // :
+ // // 121
+ // assertEquals("Nodes must be equals ", n1__100, testBase.getNode("n1[100]"));
+ //
+ // assertEquals("Nodes must be equals ", n_24, nodes.getList().get(119)); //pos:
+ // // 120
+ // assertEquals("Nodes must be equals ", n_24, testBase.getNode("n_24"));
+ //
+ // assertEquals("Nodes must be equals ", n_21, nodes.getList().get(121)); //pos:
+ // // 122
+ // assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
+ // }
+ //
+ // public void testOrderTwice() throws Exception
+ // {
+ //
+ // String[] order = new String[]{"n1", "n2", "n3", "n4", "n5"};
+ // initCustom(order);
+ // checkOrder(testBase, order);
+ //
+ // testBase.orderBefore("n1", "n4");
+ //
+ // order = new String[]{"n2", "n3", "n1", "n4", "n5"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ //
+ // checkOrder(order);
+ //
+ // checkOrderAnotherSession(order);
+ //
+ // testBase.orderBefore("n4", "n3");
+ //
+ // order = new String[]{"n2", "n4", "n3", "n1", "n5"};
+ //
+ // checkOrder(order);
+ //
+ // testBase.save();
+ // checkOrder(order);
+ // checkOrderAnotherSession(order);
+ //
+ // }
- testBase.orderBefore("n4", "n3");
-
- String[] order = new String[]{"n1", "n2", "n4", "n3"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderUpStepOver() throws Exception
- {
- initSimpleCase5();
-
- // was n2,n3,n1,n4,n5
- testBase.orderBefore("n4", "n3");
-
- String[] order = new String[]{"n2", "n4", "n3", "n1", "n5"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderBegin() throws Exception
- {
- initSimpleCase();
-
- testBase.orderBefore("n3", "n1");
-
- String[] order = new String[]{"n3", "n1", "n2", "n4"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderDown() throws Exception
- {
- initSimpleCase();
-
- testBase.orderBefore("n2", "n4");
-
- String[] order = new String[]{"n1", "n3", "n2", "n4"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderEnd() throws Exception
- {
- initSimpleCase();
-
- testBase.orderBefore("n2", null);
-
- String[] order = new String[]{"n1", "n3", "n4", "n2"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- // ----- Same-name sibling use-case: child nodes n1, n2[1], n2[2], n3 -----
-
- public void testOrderUp_SNS1() throws Exception
- {
- initSNSCase1();
-
- testBase.orderBefore("n3", "n2");
-
- String[] order = new String[]{"n1", "n3", "n2", "n2[2]"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderBegin_SNS1() throws Exception
- {
- initSNSCase1();
-
- testBase.orderBefore("n2[2]", "n1");
-
- String[] order = new String[]{"n2", "n1", "n2[2]", "n3"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderDown_SNS1() throws Exception
- {
- initSNSCase1();
-
- testBase.orderBefore("n1", "n2[2]");
-
- String[] order = new String[]{"n2", "n1", "n2[2]", "n3"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- /**
- * A childs order map is unchanged after the order
- */
- public void testOrderDown1_SNS1() throws Exception
- {
- initSNSCase1();
-
- testBase.orderBefore("n2", "n3");
-
- String[] order = new String[]{"n1", "n2", "n2[2]", "n3"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- public void testOrderEnd_SNS1() throws Exception
- {
- initSNSCase1();
-
- testBase.orderBefore("n2[2]", null);
-
- String[] order = new String[]{"n1", "n2", "n3", "n2[2]"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrderAnotherSession(order);
- }
-
- // ----- Same-name sibling use-case: child nodes n1, n1[2], n1[3], n1[4].
- // n1[3] -
- // mix:referenceable -----
-
- public void testOrderBegin_SNS2() throws Exception
- {
- initSNSCase2();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[3]", "n1");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
- // -> n1
-
- checkOrder(order);
-
- try
- {
- String n1uuid = testBase.getNode("n1").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n1uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n1uuid = testBase.getNode("n1").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n1uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderUp_SNS2() throws Exception
- {
- initSNSCase2();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[4]", "n1[2]");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
- // ->
- // n1[4]
-
- checkOrder(order);
-
- try
- {
- String n4uuid = testBase.getNode("n1[4]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n4uuid = testBase.getNode("n1[4]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderDown_SNS2() throws Exception
- {
- initSNSCase2();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1", "n1[3]");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
- // is
- // unchanged
- // in
- // location
-
- checkOrder(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
- }
-
- /**
- * A childs order map is unchanged after the order
- */
- public void testOrderDown1_SNS2() throws Exception
- {
- initSNSCase2();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[2]", "n1[4]");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
- // ->
- // n1[2]
-
- checkOrder(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderEnd_SNS2() throws Exception
- {
- initSNSCase2();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[2]", null);
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]"}; // n1[3]
- // ->
- // n1[2]
-
- checkOrder(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
- }
-
- // ----- Same-name sibling use-case: child nodes n1, n1[2], n1[3], n1[4], n2.
- // n1[3] -
- // mix:referenceable -----
-
- public void testOrderBegin_SNS3() throws Exception
- {
- initSNSCase3();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n2", "n1");
-
- String[] order = new String[]{"n2", "n1", "n1[2]", "n1[3]", "n1[4]"}; // n1
- // [
- // 3
- // ]
- // unchanged
-
- checkOrder(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderUp_SNS3() throws Exception
- {
- initSNSCase3();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n2", "n1[3]");
-
- String[] order = new String[]{"n1", "n1[2]", "n2", "n1[3]", "n1[4]"}; // n1
- // [
- // 3
- // ]
- // unchanged
-
- checkOrder(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n3uuid_same = testBase.getNode("n1[3]").getUUID();
- assertEquals("A UUIDs must be unchanged after order an other node", n3uuid, n3uuid_same);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order of an other node, " + testBase.getNode("n1[3]").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderDown_SNS3() throws Exception
- {
- initSNSCase3();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1", "n2");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]", "n2"}; // n1
- // [
- // 3
- // ]
- // -
- // >
- // n1
- // [
- // 2
- // ]
-
- checkOrder(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
- }
-
- /**
- * A childs order map is unchanged after the order
- */
- public void testOrderDown1_SNS3() throws Exception
- {
- initSNSCase3();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[2]", "n1[4]");
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n1[4]", "n2"}; // n1
- // [
- // 3
- // ]
- // -
- // >
- // n1
- // [
- // 2
- // ]
-
- checkOrder(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n2uuid = testBase.getNode("n1[2]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n2uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[2]").getPath()
- + ". " + e);
- }
- }
-
- public void testOrderEnd_SNS3() throws Exception
- {
- initSNSCase3();
-
- String n3uuid = testBase.getNode("n1[3]").getUUID();
-
- testBase.orderBefore("n1[3]", null);
-
- String[] order = new String[]{"n1", "n1[2]", "n1[3]", "n2", "n1[4]"}; // n1
- // [3]->n1[4]
-
- checkOrder(order);
-
- try
- {
- String n4uuid = testBase.getNode("n1[4]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
- + ". " + e);
- }
-
- testBase.save();
-
- checkOrderAnotherSession(order);
-
- try
- {
- String n4uuid = testBase.getNode("n1[4]").getUUID();
- assertEquals("A UUIDs must be equals after order node to another position", n3uuid, n4uuid);
- }
- catch (RepositoryException e)
- {
- fail("A node is not mix:referenceable after order to another position, " + testBase.getNode("n1[4]").getPath()
- + ". " + e);
- }
- }
-
- // ================= Large arrays of nodes ================
- /**
- * Test of case when an index text length in the item path is differs from one
- * new creted by reorder. E.g. n1[2] -> n1[100]
- */
- public void testLargeNodesArray() throws Exception
- {
- initSNSCaseLargeArray();
-
- // String n40uuid = testBase.getNode("n1[40]").getUUID();
-
- Node n1__2 = testBase.getNode("n1[2]");
- Node n_21 = testBase.getNode("n_21");
- Node n_24 = testBase.getNode("n_24");
-
- // === step 1 ===
-
- // n1[2] -> n1[100] pos:120; n_21 = pos:121; ... n1[3] -> pos:2; n1[99] ->
- // n1[98] pos:98;
- // n1[100] -> n1[99] pos:99
- testBase.orderBefore("n1[2]", "n_21");
-
- EntityCollection nodes = getEntityCollection(testBase.getNodes());
-
- assertEquals("Nodes must be equals ", n1__2, nodes.getList().get(119)); // pos
- // :
- // 120
- assertEquals("Nodes must be equals ", n1__2, testBase.getNode("n1[100]"));
-
- assertEquals("Nodes must be equals ", n_21, nodes.getList().get(120)); //pos:
- // 121
- assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
-
- assertTrue("Node must exists ", testBase.hasNode("n1[2]"));
-
- testBase.save();
-
- nodes = getEntityCollection(testBase.getNodes());
-
- assertEquals("Nodes must be equals ", n1__2, nodes.getList().get(119)); // pos
- // :
- // 120
- assertEquals("Nodes must be equals ", n1__2, testBase.getNode("n1[100]"));
-
- assertEquals("Nodes must be equals ", n_21, nodes.getList().get(120)); //pos:
- // 121
- assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
-
- assertTrue("Node must exists ", testBase.hasNode("n1[2]"));
-
- // === step 2 ===
-
- Node n1__100 = testBase.getNode("n1[100]");
-
- // n_24 -> pos:120; n1[100] -> pos:121;
- testBase.orderBefore("n_24", "n1[100]");
-
- nodes = getEntityCollection(testBase.getNodes());
-
- assertEquals("Nodes must be equals ", n1__100, nodes.getList().get(120)); // pos
- // :
- // 121
- assertEquals("Nodes must be equals ", n1__100, testBase.getNode("n1[100]"));
-
- assertEquals("Nodes must be equals ", n_24, nodes.getList().get(119)); //pos:
- // 120
- assertEquals("Nodes must be equals ", n_24, testBase.getNode("n_24"));
-
- assertEquals("Nodes must be equals ", n_21, nodes.getList().get(121)); //pos:
- // 122
- assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
-
- testBase.save();
-
- assertEquals("Nodes must be equals ", n1__100, nodes.getList().get(120)); // pos
- // :
- // 121
- assertEquals("Nodes must be equals ", n1__100, testBase.getNode("n1[100]"));
-
- assertEquals("Nodes must be equals ", n_24, nodes.getList().get(119)); //pos:
- // 120
- assertEquals("Nodes must be equals ", n_24, testBase.getNode("n_24"));
-
- assertEquals("Nodes must be equals ", n_21, nodes.getList().get(121)); //pos:
- // 122
- assertEquals("Nodes must be equals ", n_21, testBase.getNode("n_21"));
- }
-
- public void testOrderTwice() throws Exception
- {
-
- String[] order = new String[]{"n1", "n2", "n3", "n4", "n5"};
- initCustom(order);
- checkOrder(testBase, order);
-
- testBase.orderBefore("n1", "n4");
-
- order = new String[]{"n2", "n3", "n1", "n4", "n5"};
-
- checkOrder(order);
-
- testBase.save();
-
- checkOrder(order);
-
- checkOrderAnotherSession(order);
-
- testBase.orderBefore("n4", "n3");
-
- order = new String[]{"n2", "n4", "n3", "n1", "n5"};
-
- checkOrder(order);
-
- testBase.save();
- checkOrder(order);
- checkOrderAnotherSession(order);
-
- }
-
public void testDeleteOrderBefore() throws Exception
{
Session session = repository.login(credentials, "ws");
@@ -990,48 +989,48 @@
session.save();
}
- public void testDeleteOrderBefore_SNS() throws Exception
- {
- Session session = repository.login(credentials, "ws");
- session.getRootNode().addNode("a");
- session.save();
- session.logout();
+ // public void testDeleteOrderBefore_SNS() throws Exception
+ // {
+ // Session session = repository.login(credentials, "ws");
+ // session.getRootNode().addNode("a");
+ // session.save();
+ // session.logout();
+ //
+ // session = repository.login(credentials, "ws");
+ // Node a = session.getRootNode().getNode("a"); // We suppose it already exist
+ // Node n1 = a.addNode("n");
+ // n1.addMixin("mix:referenceable");
+ // Node n2 = a.addNode("n");
+ // n2.addMixin("mix:referenceable");
+ // Node n3 = a.addNode("n");
+ // n3.addMixin("mix:referenceable");
+ // session.save();
+ // String n1id = n1.getUUID();
+ // String n2id = n2.getUUID();
+ // String n3id = n3.getUUID();
+ // session.logout();
+ //
+ // session = repository.login(credentials, "ws");
+ // a = session.getRootNode().getNode("a");
+ // a.getNode("n[2]").remove();
+ // a.save();
+ // session.save();
+ // session.logout();
+ //
+ // session = repository.login(credentials, "ws");
+ // a = session.getRootNode().getNode("a");
+ //
+ // try
+ // {
+ // session.getNodeByUUID(n2id);
+ // fail("Node with id " + n2id + " is deleted");
+ // }
+ // catch (ItemNotFoundException e)
+ // {
+ // // ok
+ // }
+ // }
- session = repository.login(credentials, "ws");
- Node a = session.getRootNode().getNode("a"); // We suppose it already exist
- Node n1 = a.addNode("n");
- n1.addMixin("mix:referenceable");
- Node n2 = a.addNode("n");
- n2.addMixin("mix:referenceable");
- Node n3 = a.addNode("n");
- n3.addMixin("mix:referenceable");
- session.save();
- String n1id = n1.getUUID();
- String n2id = n2.getUUID();
- String n3id = n3.getUUID();
- session.logout();
-
- session = repository.login(credentials, "ws");
- a = session.getRootNode().getNode("a");
- a.getNode("n[2]").remove();
- a.save();
- session.save();
- session.logout();
-
- session = repository.login(credentials, "ws");
- a = session.getRootNode().getNode("a");
-
- try
- {
- session.getNodeByUUID(n2id);
- fail("Node with id " + n2id + " is deleted");
- }
- catch (ItemNotFoundException e)
- {
- // ok
- }
- }
-
private EntityCollection getEntityCollection(NodeIterator nodes)
{
List result = new ArrayList();
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-config.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-config.xml 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<infinispan
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:infinispan:config:4.0 http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
+ xmlns="urn:infinispan:config:4.0">
+
+ <global>
+ <evictionScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+ <properties>
+ <property name="threadNamePrefix" value="EvictionThread"/>
+ </properties>
+ </evictionScheduledExecutor>
+
+ <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+ </global>
+
+ <default>
+ <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <deadlockDetection enabled="true" spinDuration="100"/>
+ <eviction strategy="LRU" wakeUpInterval="5000" threadPolicy="DEFAULT" maxEntries="5000"/>
+ </default>
+</infinispan>
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-07-30 13:00:43 UTC (rev 2843)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<infinispan
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:infinispan:config:4.0 http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
+ xmlns="urn:infinispan:config:4.0">
+
+ <global>
+ <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+ </global>
+
+ <default>
+ <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <deadlockDetection enabled="true" spinDuration="100"/>
+
+ <loaders passivation="false" shared="true" preload="true">
+ <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
+ <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
+ <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
+ <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
+ <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
+ <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
+ <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
+ <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
+ <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
+ <property name="connectionFactoryClass" value="${infinispan-cl-cache.jdbc.connectionFactory}"/>
+ <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
+ </properties>
+ <async enabled="false"/>
+ </loader>
+ </loaders>
+ </default>
+
+</infinispan>
Deleted: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml 2010-07-30 13:00:43 UTC (rev 2843)
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright (C) 2009 eXo Platform SAS.
-
- This is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this software; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-
--->
-<infinispan
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:infinispan:config:4.0 http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
- xmlns="urn:infinispan:config:4.0">
-
- <global>
- <evictionScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
- <properties>
- <property name="threadNamePrefix" value="EvictionThread"/>
- </properties>
- </evictionScheduledExecutor>
-
- <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
- </global>
-
- <default>
- <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
- <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
- <jmxStatistics enabled="true"/>
- <deadlockDetection enabled="true" spinDuration="100"/>
- </default>
-
- <namedCache name="lockCache">
- <loaders passivation="false" shared="true" preload="true">
- <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
- <properties>
- <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
- <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
- <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
- <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
- <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
- <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
- <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
- <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
- <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
- <property name="connectionFactoryClass" value="${infinispan-cl-cache.jdbc.connectionFactory}"/>
- <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
- </properties>
- <async enabled="false"/>
- </loader>
- </loaders>
- </namedCache>
-</infinispan>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-30 11:40:38 UTC (rev 2842)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-30 13:00:43 UTC (rev 2843)
@@ -65,9 +65,9 @@
<property name="restore-path" value="./src/test/resources/import-export/restore_db1_ws1.xml" />
</properties>
</initializer -->
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -81,8 +81,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -116,9 +115,9 @@
</value-storage>
</value-storages>
</container>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -135,8 +134,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws1" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -170,9 +168,9 @@
</value-storage>
</value-storages>
</container>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -189,8 +187,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws2" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -251,9 +248,9 @@
<property name="root-nodetype" value="nt:unstructured" />
</properties>
</initializer>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler
@@ -272,8 +269,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws3" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -323,9 +319,9 @@
<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" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -343,8 +339,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -384,9 +379,9 @@
<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" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -403,8 +398,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws1" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
@@ -444,9 +438,9 @@
<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" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan.ISPNCacheWorkspaceStorageCache">
<properties>
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
</properties>
</cache>
<query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
@@ -466,8 +460,7 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
- <property name="infinispan-cache-name" value="lockCache" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-config.xml" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws2" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
13 years, 11 months
exo-jcr SVN: r2842 - jcr/trunk/applications/product-patches/as/jetty.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-30 07:40:38 -0400 (Fri, 30 Jul 2010)
New Revision: 2842
Added:
jcr/trunk/applications/product-patches/as/jetty/eXo.bat
jcr/trunk/applications/product-patches/as/jetty/eXo.sh
Removed:
jcr/trunk/applications/product-patches/as/jetty/bin/
Log:
EXOJCR-771 launch scripts moved
Copied: jcr/trunk/applications/product-patches/as/jetty/eXo.bat (from rev 2841, jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat)
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/eXo.bat (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/eXo.bat 2010-07-30 11:40:38 UTC (rev 2842)
@@ -0,0 +1 @@
+java -Djava.security.auth.login.config=jaas.conf -jar start.jar
Copied: jcr/trunk/applications/product-patches/as/jetty/eXo.sh (from rev 2841, jcr/trunk/applications/product-patches/as/jetty/bin/eXo.sh)
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/eXo.sh (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/eXo.sh 2010-07-30 11:40:38 UTC (rev 2842)
@@ -0,0 +1 @@
+java -Djava.security.auth.login.config=jaas.conf -jar start.jar
13 years, 11 months
exo-jcr SVN: r2841 - in jcr/trunk/applications/product-patches/as/jetty: bin and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-30 02:35:11 -0400 (Fri, 30 Jul 2010)
New Revision: 2841
Added:
jcr/trunk/applications/product-patches/as/jetty/bin/
jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat
jcr/trunk/applications/product-patches/as/jetty/bin/eXo.sh
Removed:
jcr/trunk/applications/product-patches/as/jetty/eXo.sh
Log:
EXOJCR-771 launch files moved to bin folder
Added: jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat 2010-07-30 06:35:11 UTC (rev 2841)
@@ -0,0 +1 @@
+java -Djava.security.auth.login.config=jaas.conf -jar start.jar
Property changes on: jcr/trunk/applications/product-patches/as/jetty/bin/eXo.bat
___________________________________________________________________
Name: svn:executable
+ *
Copied: jcr/trunk/applications/product-patches/as/jetty/bin/eXo.sh (from rev 2838, jcr/trunk/applications/product-patches/as/jetty/eXo.sh)
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/bin/eXo.sh (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/bin/eXo.sh 2010-07-30 06:35:11 UTC (rev 2841)
@@ -0,0 +1 @@
+java -Djava.security.auth.login.config=jaas.conf -jar start.jar
Deleted: jcr/trunk/applications/product-patches/as/jetty/eXo.sh
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/eXo.sh 2010-07-29 14:46:27 UTC (rev 2840)
+++ jcr/trunk/applications/product-patches/as/jetty/eXo.sh 2010-07-30 06:35:11 UTC (rev 2841)
@@ -1 +0,0 @@
-java -Djava.security.auth.login.config=jaas.conf -jar start.jar
13 years, 11 months
exo-jcr SVN: r2840 - jcr/trunk/applications/exo.jcr.applications.jetty.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-29 10:46:27 -0400 (Thu, 29 Jul 2010)
New Revision: 2840
Modified:
jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml
Log:
EXOJCR-771 org.apache.taglibs.standard.glassfish which conflicts with jcr dependencies is now removed on build phase
Modified: jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml 2010-07-29 13:57:14 UTC (rev 2839)
+++ jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml 2010-07-29 14:46:27 UTC (rev 2840)
@@ -95,7 +95,8 @@
</copy>
<delete dir="${exo.projects.directory.working}/exo-jetty/etc" includeEmptyDirs="true" quiet="yes" />
<delete dir="${exo.projects.directory.working}/exo-jetty/contexts" includeEmptyDirs="true" quiet="yes" />
- <delete dir="${exo.projects.directory.working}/exo-jetty/webapps" includeEmptyDirs="true" quiet="yes" />
+ <delete dir="${exo.projects.directory.working}/exo-jetty/webapps" includeEmptyDirs="true" quiet="yes" />
+ <delete file="${exo.projects.directory.working}/exo-jetty/lib/jsp/org.apache.taglibs.standard.glassfish_1.2.0.v201004190952.jar" />
<copy todir="${exo.projects.directory.working}/exo-jetty/lib/ext/" verbose="true" overwrite="true">
<fileset dir="${basedir}/target/lib-binary.dir/" excludes="**/*.war" />
</copy>
13 years, 11 months
exo-jcr SVN: r2839 - in jcr/trunk/applications: exo.jcr.applications.jetty and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-29 09:57:14 -0400 (Thu, 29 Jul 2010)
New Revision: 2839
Added:
jcr/trunk/applications/exo.jcr.applications.jetty/
jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml
Modified:
jcr/trunk/applications/pom.xml
Log:
EXOJCR-771 Jetty bundle proposed
Added: jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml (rev 0)
+++ jcr/trunk/applications/exo.jcr.applications.jetty/pom.xml 2010-07-29 13:57:14 UTC (rev 2839)
@@ -0,0 +1,130 @@
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.exoplatform.jcr</groupId>
+ <artifactId>exo.jcr.applications.config</artifactId>
+ <version>1.14.0-CR1-SNAPSHOT</version>
+ <relativePath>exo.jcr.applications.config</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>exo.jcrapplications.jetty</artifactId>
+ <packaging>pom</packaging>
+ <name>eXo JCR :: Applications :: Jetty AS</name>
+ <url>http://www.exoplatform.org</url>
+ <description>eXo JCR Jetty Applications Server</description>
+
+ <properties>
+ <enforcer.skip>true</enforcer.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+
+ <profiles>
+ <profile>
+ <id>deploy</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>install</phase>
+ <goals>
+ <goal>assembly</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <descriptors>
+ <descriptor>../product-exo-jcr-as-descriptor.xml</descriptor>
+ </descriptors>
+ <finalName>lib</finalName>
+ <ignoreDirFormatExtensions>false</ignoreDirFormatExtensions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>install</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <tasks>
+ <delete dir="${exo.projects.directory.working}/exo-jetty" includeEmptyDirs="true" quiet="yes" />
+ <copy todir="${exo.projects.directory.working}/exo-jetty" verbose="false" overwrite="true">
+ <fileset dir="${exo.projects.directory.dependencies}/${exo.projects.app.jetty.version}" />
+ </copy>
+ <delete dir="${exo.projects.directory.working}/exo-jetty/etc" includeEmptyDirs="true" quiet="yes" />
+ <delete dir="${exo.projects.directory.working}/exo-jetty/contexts" includeEmptyDirs="true" quiet="yes" />
+ <delete dir="${exo.projects.directory.working}/exo-jetty/webapps" includeEmptyDirs="true" quiet="yes" />
+ <copy todir="${exo.projects.directory.working}/exo-jetty/lib/ext/" verbose="true" overwrite="true">
+ <fileset dir="${basedir}/target/lib-binary.dir/" excludes="**/*.war" />
+ </copy>
+ <copy todir="${exo.projects.directory.working}/exo-jetty/" verbose="true" overwrite="true">
+ <fileset dir="${basedir}/../product-patches/as/jetty/" />
+ </copy>
+ <chmod dir="${exo.projects.directory.working}/exo-jetty" perm="+x" includes="*.sh" />
+ <move todir="${basedir}/target/lib-binary.dir/">
+ <fileset dir="${basedir}/target/lib-binary.dir/">
+ <include name="**/*.war" />
+ </fileset>
+ <mapper>
+ <chainedmapper>
+ <flattenmapper />
+ <globmapper from="exo.jcr.applications.*-${project.version}.war" to="*.war" casesensitive="no" />
+ </chainedmapper>
+ </mapper>
+ </move>
+ <copy todir="${exo.projects.directory.working}/exo-jetty/webapps/" verbose="true" flatten="true" overwrite="true">
+ <fileset dir="${basedir}/target/lib-binary.dir/" casesensitive="yes">
+ <include name="**/*.war" />
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
Modified: jcr/trunk/applications/pom.xml
===================================================================
--- jcr/trunk/applications/pom.xml 2010-07-29 13:45:48 UTC (rev 2838)
+++ jcr/trunk/applications/pom.xml 2010-07-29 13:57:14 UTC (rev 2839)
@@ -44,5 +44,6 @@
<module>exo.jcr.applications.jboss</module>
<module>exo.jcr.applications.jonas</module>
<module>exo.jcr.applications.tomcat</module>
+ <module>exo.jcr.applications.jetty</module>
</modules>
</project>
13 years, 11 months
exo-jcr SVN: r2838 - in jcr/trunk/applications/product-patches/as: jetty and 2 other directories.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-29 09:45:48 -0400 (Thu, 29 Jul 2010)
New Revision: 2838
Added:
jcr/trunk/applications/product-patches/as/jetty/
jcr/trunk/applications/product-patches/as/jetty/contexts/
jcr/trunk/applications/product-patches/as/jetty/contexts/browser.xml
jcr/trunk/applications/product-patches/as/jetty/contexts/fckeditor.xml
jcr/trunk/applications/product-patches/as/jetty/contexts/rest.xml
jcr/trunk/applications/product-patches/as/jetty/eXo.sh
jcr/trunk/applications/product-patches/as/jetty/etc/
jcr/trunk/applications/product-patches/as/jetty/etc/exo-jetty.xml
jcr/trunk/applications/product-patches/as/jetty/etc/jetty-deploy.xml
jcr/trunk/applications/product-patches/as/jetty/etc/jetty.conf
jcr/trunk/applications/product-patches/as/jetty/etc/jetty.xml
jcr/trunk/applications/product-patches/as/jetty/etc/webdefault.xml
jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml
jcr/trunk/applications/product-patches/as/jetty/jaas.conf
jcr/trunk/applications/product-patches/as/jetty/start.ini
Log:
EXOJCR-771 Configuration files and scripts for jetty bundle added
Added: jcr/trunk/applications/product-patches/as/jetty/contexts/browser.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/contexts/browser.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/contexts/browser.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,24 @@
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/browser</Set>
+ <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/browser.war</Set>
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/contexts/fckeditor.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/contexts/fckeditor.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/contexts/fckeditor.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,24 @@
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/fckeditor</Set>
+ <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/fckeditor.war</Set>
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/contexts/rest.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/contexts/rest.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/contexts/rest.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,24 @@
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/rest</Set>
+ <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/rest.war</Set>
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/eXo.sh
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/eXo.sh (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/eXo.sh 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1 @@
+java -Djava.security.auth.login.config=jaas.conf -jar start.jar
Property changes on: jcr/trunk/applications/product-patches/as/jetty/eXo.sh
___________________________________________________________________
Name: svn:executable
+ *
Added: jcr/trunk/applications/product-patches/as/jetty/etc/exo-jetty.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/etc/exo-jetty.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/etc/exo-jetty.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- JAAS authentication options for exo-domain realm -->
+ <!-- =========================================================== -->
+ <Call name="addBean">
+ <Arg>
+ <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
+ <Set name="Name">exo-domain</Set>
+ <Set name="LoginModuleName">exo-domain</Set>
+ <Set name="roleClassNames">
+ <Array type="java.lang.String">
+ <Item>org.exoplatform.services.security.jaas.RolePrincipal</Item>
+ </Array>
+ </Set>
+ <!--Set name="userClassNames">
+ <Array type="java.lang.String">
+ <Item>org.exoplatform.services.security.jaas.UserPrincipal</Item>
+ </Array>
+ </Set-->
+ </New>
+ </Arg>
+ </Call>
+
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/etc/jetty-deploy.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/etc/jetty-deploy.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/etc/jetty-deploy.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Deployers -->
+<!-- =============================================================== -->
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Configure the deployment manager -->
+ <!-- -->
+ <!-- Sets up 2 monitored dir app providers that are configured -->
+ <!-- to behave in a similaraly to the legacy ContextDeployer -->
+ <!-- and WebAppDeployer from previous versions of Jetty. -->
+ <!-- =========================================================== -->
+ <Call name="addBean">
+ <Arg>
+ <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+ <Set name="contexts">
+ <Ref id="Contexts" />
+ </Set>
+ <Call name="setContextAttribute">
+ <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
+ <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
+ </Call>
+ <!-- Providers of Apps via Context XML files.
+ Configured to behave similar to the legacy ContextDeployer -->
+ <Call name="addAppProvider">
+ <Arg>
+ <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
+ <Set name="monitoredDir"><Property name="jetty.home" default="." />/contexts</Set>
+ <Set name="scanInterval">5</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- Providers of Apps via WAR file existence.
+ Configured to behave similar to the legacy WebAppDeployer -->
+ <Call name="addAppProvider">
+ <Arg>
+ <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+ <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
+ <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+ <Set name="scanInterval">5</Set>
+ <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
+ </New>
+ </Arg>
+ </Call>
+ </New>
+ </Arg>
+ </Call>
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/etc/jetty.conf
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/etc/jetty.conf (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/etc/jetty.conf 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,13 @@
+# ========================================================
+# jetty.conf Configuration for jetty.sh script
+# --------------------------------------------------------
+# This file is used by the jetty.sh script to provide
+# extra configuration arguments for the start.jar command
+# created by that script.
+#
+# Each line in this file becomes an arguement to start.jar
+# unless this file contains an --ini option, then these
+# arguments will be in addition to those found in the
+# start.ini file
+# =======================================================
+--pre=etc/jetty-logging.xml
Added: jcr/trunk/applications/product-patches/as/jetty/etc/jetty.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/etc/jetty.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/etc/jetty.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server -->
+<!-- -->
+<!-- Documentation of this file format can be found at: -->
+<!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax -->
+<!-- -->
+<!-- Additional configuration files are available in $JETTY_HOME/etc -->
+<!-- and can be mixed in. For example: -->
+<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
+<!-- -->
+<!-- See start.ini file for the default configuraton files -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Server Thread Pool -->
+ <!-- =========================================================== -->
+ <Set name="ThreadPool">
+ <!-- Default queued blocking threadpool -->
+ <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+ <Set name="minThreads">10</Set>
+ <Set name="maxThreads">200</Set>
+ </New>
+ </Set>
+
+ <!-- =========================================================== -->
+ <!-- Set connectors -->
+ <!-- =========================================================== -->
+
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+ <Set name="host"><Property name="jetty.host" /></Set>
+ <Set name="port"><Property name="jetty.port" default="8080"/></Set>
+ <Set name="maxIdleTime">300000</Set>
+ <Set name="Acceptors">2</Set>
+ <Set name="statsOn">false</Set>
+ <Set name="confidentialPort">8443</Set>
+ <Set name="lowResourcesConnections">20000</Set>
+ <Set name="lowResourcesMaxIdleTime">5000</Set>
+ </New>
+ </Arg>
+ </Call>
+
+ <!-- =========================================================== -->
+ <!-- Set handler Collection Structure -->
+ <!-- =========================================================== -->
+ <Set name="handler">
+ <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+ <Set name="handlers">
+ <Array type="org.eclipse.jetty.server.Handler">
+ <Item>
+ <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
+ </Item>
+ <Item>
+ <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
+ </Item>
+ </Array>
+ </Set>
+ </New>
+ </Set>
+
+ <!-- =========================================================== -->
+ <!-- extra options -->
+ <!-- =========================================================== -->
+ <Set name="stopAtShutdown">true</Set>
+ <Set name="sendServerVersion">true</Set>
+ <Set name="sendDateHeader">true</Set>
+ <Set name="gracefulShutdown">1000</Set>
+
+</Configure>
Added: jcr/trunk/applications/product-patches/as/jetty/etc/webdefault.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/etc/webdefault.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/etc/webdefault.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+ <!-- ===================================================================== -->
+ <!-- This file contains the default descriptor for web applications. -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- The intent of this descriptor is to include jetty specific or common -->
+ <!-- configuration for all webapps. If a context has a webdefault.xml -->
+ <!-- descriptor, it is applied before the contexts own web.xml file -->
+ <!-- -->
+ <!-- A context may be assigned a default descriptor by: -->
+ <!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
+ <!-- + Passed an arg to addWebApplications -->
+ <!-- -->
+ <!-- This file is used both as the resource within the jetty.jar (which is -->
+ <!-- used as the default if no explicit defaults descriptor is set) and it -->
+ <!-- is copied to the etc directory of the Jetty distro and explicitly -->
+ <!-- by the jetty.xml file. -->
+ <!-- -->
+ <!-- ===================================================================== -->
+<web-app
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ metadata-complete="true"
+ version="2.5"
+>
+
+ <description>
+ Default web.xml file.
+ This file is applied to a Web application before it's own WEB_INF/web.xml file
+ </description>
+
+
+ <!-- ==================================================================== -->
+ <!-- Context params to control Session Cookies -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!--
+ UNCOMMENT TO ACTIVATE <context-param> <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name> <param-value>127.0.0.1</param-value> </context-param> <context-param>
+ <param-name>org.eclipse.jetty.servlet.SessionPath</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
+ <param-value>-1</param-value> </context-param>
+ -->
+
+
+ <!-- ==================================================================== -->
+ <!-- The default servlet. -->
+ <!-- This servlet, normally mapped to /, provides the handling for static -->
+ <!-- content, OPTIONS and TRACE methods for the context. -->
+ <!-- The following initParameters are supported: -->
+ <!-- -->
+ <!-- aliases If true, aliases like symlinks are allowed. Note -->
+ <!-- that security constraints might be bypassed by -->
+ <!-- aliases static content. -->
+ <!-- -->
+ <!-- acceptRanges If true, range requests and responses are -->
+ <!-- supported -->
+ <!-- -->
+ <!-- dirAllowed If true, directory listings are returned if no -->
+ <!-- welcome file is found. Else 403 Forbidden. -->
+ <!-- -->
+ <!-- welcomeServlets If true, attempt to dispatch to welcome files -->
+ <!-- that are servlets, if no matching static -->
+ <!-- resources can be found. -->
+ <!-- -->
+ <!-- redirectWelcome If true, redirect welcome file requests -->
+ <!-- else use request dispatcher forwards -->
+ <!-- -->
+ <!-- gzip If set to true, then static content will be served-->
+ <!-- as gzip content encoded if a matching resource is -->
+ <!-- found ending with ".gz" -->
+ <!-- -->
+ <!-- resoureBase Can be set to replace the context resource base -->
+ <!-- -->
+ <!-- relativeResourceBase -->
+ <!-- Set with a pathname relative to the base of the -->
+ <!-- servlet context root. Useful for only serving -->
+ <!-- static content from only specific subdirectories. -->
+ <!-- -->
+ <!-- useFileMappedBuffer -->
+ <!-- If set to true (the default), a memory mapped -->
+ <!-- file buffer will be used to serve static content -->
+ <!-- when using an NIO connector. Setting this value -->
+ <!-- to false means that a direct buffer will be used -->
+ <!-- instead. If you are having trouble with Windows -->
+ <!-- file locking, set this to false. -->
+ <!-- -->
+ <!-- cacheControl If set, all static content will have this value -->
+ <!-- set as the cache-control header. -->
+ <!-- -->
+ <!-- maxCacheSize Maximum size of the static resource cache -->
+ <!-- -->
+ <!-- maxCachedFileSize Maximum size of any single file in the cache -->
+ <!-- -->
+ <!-- maxCachedFiles Maximum number of files in the cache -->
+ <!-- -->
+ <!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
+ <!-- of resource cache. A bio cached buffer may be used-->
+ <!-- by nio but is not as efficient as a nio buffer. -->
+ <!-- An nio cached buffer may not be used by bio. -->
+ <!-- -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+ <init-param>
+ <param-name>aliases</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>acceptRanges</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>dirAllowed</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>welcomeServlets</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>redirectWelcome</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>maxCacheSize</param-name>
+ <param-value>256000000</param-value>
+ </init-param>
+ <init-param>
+ <param-name>maxCachedFileSize</param-name>
+ <param-value>10000000</param-value>
+ </init-param>
+ <init-param>
+ <param-name>maxCachedFiles</param-name>
+ <param-value>1000</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cacheType</param-name>
+ <param-value>both</param-value>
+ </init-param>
+ <init-param>
+ <param-name>gzip</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>useFileMappedBuffer</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <!--
+ <init-param>
+ <param-name>cacheControl</param-name>
+ <param-value>max-age=3600,public</param-value>
+ </init-param>
+ -->
+ <load-on-startup>0</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+
+ <!-- ==================================================================== -->
+ <!-- JSP Servlet -->
+ <!-- This is the jasper JSP servlet from the jakarta project -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- The JSP page compiler and execution servlet, which is the mechanism -->
+ <!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
+ <!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- checkInterval If development is false and reloading is true, -->
+ <!-- background compiles are enabled. checkInterval -->
+ <!-- is the time in seconds between checks to see -->
+ <!-- if a JSP page needs to be recompiled. [300] -->
+ <!-- -->
+ <!-- compiler Which compiler Ant should use to compile JSP -->
+ <!-- pages. See the Ant documenation for more -->
+ <!-- information. [javac] -->
+ <!-- -->
+ <!-- classdebuginfo Should the class file be compiled with -->
+ <!-- debugging information? [true] -->
+ <!-- -->
+ <!-- classpath What class path should I use while compiling -->
+ <!-- generated servlets? [Created dynamically -->
+ <!-- based on the current web application] -->
+ <!-- Set to ? to make the container explicitly set -->
+ <!-- this parameter. -->
+ <!-- -->
+ <!-- development Is Jasper used in development mode (will check -->
+ <!-- for JSP modification on every access)? [true] -->
+ <!-- -->
+ <!-- enablePooling Determines whether tag handler pooling is -->
+ <!-- enabled [true] -->
+ <!-- -->
+ <!-- fork Tell Ant to fork compiles of JSP pages so that -->
+ <!-- a separate JVM is used for JSP page compiles -->
+ <!-- from the one Tomcat is running in. [true] -->
+ <!-- -->
+ <!-- ieClassId The class-id value to be sent to Internet -->
+ <!-- Explorer when using <jsp:plugin> tags. -->
+ <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
+ <!-- -->
+ <!-- javaEncoding Java file encoding to use for generating java -->
+ <!-- source files. [UTF-8] -->
+ <!-- -->
+ <!-- keepgenerated Should we keep the generated Java source code -->
+ <!-- for each page instead of deleting it? [true] -->
+ <!-- -->
+ <!-- logVerbosityLevel The level of detailed messages to be produced -->
+ <!-- by this servlet. Increasing levels cause the -->
+ <!-- generation of more messages. Valid values are -->
+ <!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
+ <!-- [WARNING] -->
+ <!-- -->
+ <!-- mappedfile Should we generate static content with one -->
+ <!-- print statement per input line, to ease -->
+ <!-- debugging? [false] -->
+ <!-- -->
+ <!-- -->
+ <!-- reloading Should Jasper check for modified JSPs? [true] -->
+ <!-- -->
+ <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
+ <!-- debugging be suppressed? [false] -->
+ <!-- -->
+ <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
+ <!-- dumped to a file? [false] -->
+ <!-- False if suppressSmap is true -->
+ <!-- -->
+ <!-- scratchdir What scratch directory should we use when -->
+ <!-- compiling JSP pages? [default work directory -->
+ <!-- for the current web application] -->
+ <!-- -->
+ <!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
+ <!-- -->
+ <!-- xpoweredBy Determines whether X-Powered-By response -->
+ <!-- header is added by generated servlet [false] -->
+ <!-- -->
+ <!-- If you wish to use Jikes to compile JSP pages: -->
+ <!-- Set the init parameter "compiler" to "jikes". Define -->
+ <!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
+ <!-- to cause Jikes to emit error messages in a format compatible with -->
+ <!-- Jasper. -->
+ <!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
+ <!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <servlet
+ id="jsp"
+ >
+ <servlet-name>jsp</servlet-name>
+ <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+ <init-param>
+ <param-name>logVerbosityLevel</param-name>
+ <param-value>DEBUG</param-value>
+ </init-param>
+ <init-param>
+ <param-name>fork</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>xpoweredBy</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <!--
+ <init-param>
+ <param-name>classpath</param-name>
+ <param-value>?</param-value>
+ </init-param>
+ -->
+ <load-on-startup>0</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jsp</url-pattern>
+ <url-pattern>*.jspf</url-pattern>
+ <url-pattern>*.jspx</url-pattern>
+ <url-pattern>*.xsp</url-pattern>
+ <url-pattern>*.JSP</url-pattern>
+ <url-pattern>*.JSPF</url-pattern>
+ <url-pattern>*.JSPX</url-pattern>
+ <url-pattern>*.XSP</url-pattern>
+ </servlet-mapping>
+
+ <!-- ==================================================================== -->
+ <!-- Dynamic Servlet Invoker. -->
+ <!-- This servlet invokes anonymous servlets that have not been defined -->
+ <!-- in the web.xml or by other means. The first element of the pathInfo -->
+ <!-- of a request passed to the envoker is treated as a servlet name for -->
+ <!-- an existing servlet, or as a class name of a new servlet. -->
+ <!-- This servlet is normally mapped to /servlet/* -->
+ <!-- This servlet support the following initParams: -->
+ <!-- -->
+ <!-- nonContextServlets If false, the invoker can only load -->
+ <!-- servlets from the contexts classloader. -->
+ <!-- This is false by default and setting this -->
+ <!-- to true may have security implications. -->
+ <!-- -->
+ <!-- verbose If true, log dynamic loads -->
+ <!-- -->
+ <!-- * All other parameters are copied to the -->
+ <!-- each dynamic servlet as init parameters -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!--
+ Uncomment for dynamic invocation <servlet> <servlet-name>invoker</servlet-name> <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class> <init-param> <param-name>verbose</param-name>
+ <param-value>false</param-value> </init-param> <init-param> <param-name>nonContextServlets</param-name> <param-value>false</param-value> </init-param> <init-param>
+ <param-name>dynamicParam</param-name> <param-value>anyValue</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>invoker</servlet-name>
+ <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
+ -->
+
+
+
+ <!-- ==================================================================== -->
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+ <!-- ==================================================================== -->
+ <!-- Default MIME mappings -->
+ <!-- The default MIME mappings are provided by the mime.properties -->
+ <!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
+ <!-- mappings may be specified here -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- UNCOMMENT TO ACTIVATE
+ <mime-mapping>
+ <extension>mysuffix</extension>
+ <mime-type>mymime/type</mime-type>
+ </mime-mapping>
+ -->
+
+ <!-- ==================================================================== -->
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <!-- ==================================================================== -->
+ <locale-encoding-mapping-list>
+ <locale-encoding-mapping>
+ <locale>ar</locale>
+ <encoding>ISO-8859-6</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>be</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>bg</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>ca</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>cs</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>da</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>de</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>el</locale>
+ <encoding>ISO-8859-7</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>en</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>es</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>et</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>fi</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>fr</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>hr</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>hu</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>is</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>it</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>iw</locale>
+ <encoding>ISO-8859-8</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>ja</locale>
+ <encoding>Shift_JIS</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>ko</locale>
+ <encoding>EUC-KR</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>lt</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>lv</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>mk</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>nl</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>no</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>pl</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>pt</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>ro</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>ru</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sh</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sk</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sl</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sq</locale>
+ <encoding>ISO-8859-2</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sr</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>sv</locale>
+ <encoding>ISO-8859-1</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>tr</locale>
+ <encoding>ISO-8859-9</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>uk</locale>
+ <encoding>ISO-8859-5</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>zh</locale>
+ <encoding>GB2312</encoding>
+ </locale-encoding-mapping>
+ <locale-encoding-mapping>
+ <locale>zh_TW</locale>
+ <encoding>Big5</encoding>
+ </locale-encoding-mapping>
+ </locale-encoding-mapping-list>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Disable TRACE</web-resource-name>
+ <url-pattern>/</url-pattern>
+ <http-method>TRACE</http-method>
+ </web-resource-collection>
+ <auth-constraint/>
+ </security-constraint>
+
+</web-app>
+
Added: jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<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.log.LogConfigurationInitializer</key>
+ <type>org.exoplatform.services.log.LogConfigurationInitializer</type>
+ <init-params>
+ <value-param>
+ <name>logger</name>
+ <value>org.slf4j.Logger</value>
+ </value-param>
+ <value-param>
+ <name>configurator</name>
+ <value>org.exoplatform.services.log.impl.Log4JConfigurator</value>
+ </value-param>
+ <properties-param>
+ <name>properties</name>
+ <description>Log4J properties</description>
+ <property name="log4j.rootLogger" value="INFO, stdout, file" />
+ <property name="log4j.appender.stdout" value="org.apache.log4j.ConsoleAppender" />
+ <property name="log4j.appender.stdout.threshold" value="DEBUG" />
+ <property name="log4j.appender.stdout.layout" value="org.apache.log4j.PatternLayout" />
+ <property name="log4j.appender.stdout.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n" />
+ <property name="log4j.appender.file" value="org.apache.log4j.FileAppender" />
+ <property name="log4j.appender.file.File" value="../logs/jcr.log" />
+ <property name="log4j.appender.file.layout" value="org.apache.log4j.PatternLayout" />
+ <property name="log4j.appender.file.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n" />
+ <!-- property name="log4j.category.jcr.FileCleaner" value="DEBUG" / -->
+ </properties-param>
+ </init-params>
+ </component>
+
+ <component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>jar:/conf/portal/exo-jcr-config.xml</value>
+ </value-param>
+ </init-params>
+ </component>
+
+ <component>
+ <key>org.exoplatform.services.jcr.RepositoryService</key>
+ <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
+ <component-plugins>
+ <component-plugin>
+ <name>add.namespaces</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.jcr.impl.AddNamespacesPlugin</type>
+ <init-params>
+ <properties-param>
+ <name>namespaces</name>
+ <property name="dc" value="http://purl.org/dc/elements/1.1/" />
+ <property name="webdav" value="http://www.exoplatform.org/jcr/webdav" />
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>add.nodeType</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.jcr.impl.AddNodeTypePlugin</type>
+ <init-params>
+ <values-param>
+ <name>autoCreatedInNewRepository</name>
+ <description>Node types configuration file</description>
+ <value>jar:/conf/ext-nodetypes-config.xml</value>
+ <value>jar:/conf/organization-nodetypes.xml</value>
+ <value>jar:/conf/webdav-nodetypes.xml</value>
+ </values-param>
+ </init-params>
+ </component-plugin>
+ </component-plugins>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog</type>
+ <component-plugins>
+ <component-plugin>
+ <name>addActions</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin</type>
+ <description>add actions plugin</description>
+ <init-params>
+ <object-param>
+ <name>actions</name>
+ <object type="org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin$ActionsConfig">
+ <field name="actions">
+ <collection type="java.util.ArrayList">
+ <value>
+ <object type="org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration">
+ <field name="eventTypes">
+ <string>addProperty,changeProperty</string>
+ </field>
+ <!--<field name="path"><string>/test</string></field>-->
+ <!--<field name="isDeep"><boolean>true</boolean></field>-->
+ <field name="nodeTypes">
+ <string>nt:resource</string>
+ </field>
+ <!-- field name="workspace"><string>production</string></field -->
+ <field name="actionClassName">
+ <string>org.exoplatform.services.jcr.ext.metadata.AddMetadataAction</string>
+ </field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </component-plugins>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.jcr.ext.registry.RegistryService</type>
+ <init-params>
+ <properties-param>
+ <name>locations</name>
+ <property name="repository" value="production" />
+ </properties-param>
+ </init-params>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.jcr.ext.registry.RESTRegistryService</type>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader</type>
+ <init-params>
+ <object-param>
+ <name>observation.config</name>
+ <object type="org.exoplatform.services.jcr.ext.script.groovy.ObservationListenerConfiguration">
+ <field name="repository">
+ <string>repository</string>
+ </field>
+ <field name="workspaces">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>production</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.rest.impl.method.MethodInvokerFilterComponentPlugin</type>
+ <init-params>
+ <value-param>
+ <name>method.access.filter</name>
+ <value>org.exoplatform.services.rest.ext.method.filter.MethodAccessFilter</value>
+ </value-param>
+ </init-params>
+ </component>
+
+ <!-- network services -->
+ <component>
+ <key>org.exoplatform.services.jcr.webdav.lnkproducer.LnkProducer</key>
+ <type>org.exoplatform.services.jcr.webdav.lnkproducer.LnkProducer</type>
+ </component>
+
+ <component>
+ <key>org.exoplatform.services.jcr.webdav.WebDavServiceImpl</key>
+ <type>org.exoplatform.services.jcr.webdav.WebDavServiceImpl</type>
+ <init-params>
+
+ <value-param>
+ <name>auto-mix-lockable</name>
+ <value>false</value>
+ </value-param>
+
+ <value-param>
+ <name>def-folder-node-type</name>
+ <value>nt:folder</value>
+ </value-param>
+
+ <value-param>
+ <name>def-file-node-type</name>
+ <value>nt:file</value>
+ </value-param>
+
+ <value-param>
+ <name>def-file-mimetype</name>
+ <value>text/plain</value>
+ </value-param>
+
+ <value-param>
+ <name>update-policy</name>
+ <value>create-version</value>
+ </value-param>
+ </init-params>
+ </component>
+
+ <component>
+ <key>org.exoplatform.services.ftp.FtpServiceImpl</key>
+ <type>org.exoplatform.services.ftp.FtpServiceImpl</type>
+ <init-params>
+ <value-param>
+ <name>command-port</name>
+ <value>2121</value>
+ </value-param>
+ <value-param>
+ <name>data-min-port</name>
+ <value>52000</value>
+ </value-param>
+ <value-param>
+ <name>data-max-port</name>
+ <value>53000</value>
+ </value-param>
+ <value-param>
+ <name>system</name>
+ <!-- value>Windows_NT</value -->
+ <value>UNIX Type: L8</value>
+ </value-param>
+ <value-param>
+ <name>client-side-encoding</name>
+ <value>windows-1251</value>
+ <!-- value>KOI8-R</value -->
+ </value-param>
+ <value-param>
+ <name>def-folder-node-type</name>
+ <value>nt:folder</value>
+ </value-param>
+ <value-param>
+ <name>def-file-node-type</name>
+ <value>nt:file</value>
+ </value-param>
+ <value-param>
+ <name>def-file-mime-type</name>
+ <value>application/octet-stream</value>
+ </value-param>
+ <value-param>
+ <name>cache-folder-name</name>
+ <value>../temp/ftp_cache</value>
+ </value-param>
+
+ <!-- bytes per second -->
+ <!-- value-param>
+ <name>upload-speed-limit</name>
+ <value>20480</value>
+ </value-param -->
+
+ <!-- bytes per second -->
+ <!-- value-param>
+ <name>download-speed-limit</name>
+ <value>20480</value>
+ </value-param -->
+
+ <!-- seconds -->
+ <!-- value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param -->
+ </init-params>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.organization.impl.mock.DummyOrganizationService</type>
+ </component>
+
+ <component>
+ <key>org.exoplatform.services.security.Authenticator</key>
+ <type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
+ </component>
+
+ <component>
+ <type>org.exoplatform.services.jcr.ext.resource.jcr.Handler</type>
+ </component>
+
+ <external-component-plugins>
+ <target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
+ <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</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:../temp/data/exodb" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.jcr</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>repository</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.jcr.Repository</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.exoplatform.services.jcr.impl.jndi.BindableRepositoryFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="repositoryName" value="repository" />
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>rmi.jcr</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>rmirepository</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.jcr.Repository</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.exoplatform.services.jcr.rmi.api.client.ClientRepositoryFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="url" value="//localhost:9999/repository" />
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins>
+
+</configuration>
Added: jcr/trunk/applications/product-patches/as/jetty/jaas.conf
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/jaas.conf (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/jaas.conf 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,3 @@
+exo-domain {
+ org.exoplatform.services.security.j2ee.JettyLoginModule required;
+ };
Added: jcr/trunk/applications/product-patches/as/jetty/start.ini
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/start.ini (rev 0)
+++ jcr/trunk/applications/product-patches/as/jetty/start.ini 2010-07-29 13:45:48 UTC (rev 2838)
@@ -0,0 +1,57 @@
+#===========================================================
+# Jetty start.jar arguments
+# Each line of this file is prepended to the command line
+# arguments # of a call to:
+# java -jar start.jar [arg...]
+#===========================================================
+
+
+
+#===========================================================
+# If the arguements in this file include JVM arguments
+# (eg -Xmx512m) or JVM System properties (eg com.sun.???),
+# then these will not take affect unless the --exec
+# parameter is included or if the output from --dry-run
+# is executed like:
+# eval $(java -jar start.jar --dry-run)
+#
+# Below are some recommended options for Sun's JRE
+#-----------------------------------------------------------
+# --exec
+# -Dcom.sun.management.jmxremote
+# -Xmx2000m
+# -Xmn512m
+# -verbose:gc
+# -XX:+PrintGCDateStamps
+# -XX:+PrintGCTimeStamps
+# -XX:+PrintGCDetails
+# -XX:+PrintTenuringDistribution
+# -XX:+PrintCommandLineFlags
+# -XX:+DisableExplicitGC
+# -XX:+UseConcMarkSweepGC
+# -XX:ParallelCMSThreads=2
+# -XX:+CMSClassUnloadingEnabled
+# -XX:+UseCMSCompactAtFullCollection
+# -XX:CMSInitiatingOccupancyFraction=80
+#-----------------------------------------------------------
+
+
+#===========================================================
+# Start classpath OPTIONS.
+# These control what classes are on the classpath
+# for a full listing do
+# java -jar start.jar --list-options
+#-----------------------------------------------------------
+OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus
+#-----------------------------------------------------------
+
+
+#===========================================================
+# Configuration files.
+# For a full list of available configuration files do
+# java -jar start.jar --help
+#-----------------------------------------------------------
+etc/jetty.xml
+etc/jetty-deploy.xml
+etc/exo-jetty.xml
+#===========================================================
13 years, 11 months
exo-jcr SVN: r2837 - core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-07-29 09:41:13 -0400 (Thu, 29 Jul 2010)
New Revision: 2837
Added:
core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee/JettyLoginModule.java
Log:
EXOJCR-771 Jetty login module foe jetty bundle added.
Added: core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee/JettyLoginModule.java
===================================================================
--- core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee/JettyLoginModule.java (rev 0)
+++ core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee/JettyLoginModule.java 2010-07-29 13:41:13 UTC (rev 2837)
@@ -0,0 +1,38 @@
+package org.exoplatform.services.security.j2ee;
+
+import org.exoplatform.services.security.jaas.DefaultLoginModule;
+import org.exoplatform.services.security.jaas.RolePrincipal;
+import org.exoplatform.services.security.jaas.UserPrincipal;
+
+import java.security.Principal;
+import java.util.Set;
+
+import javax.security.auth.login.LoginException;
+
+public class JettyLoginModule extends DefaultLoginModule
+{
+
+ @Override
+ public boolean commit() throws LoginException
+ {
+
+ if (super.commit())
+ {
+
+ Set<Principal> principals = subject.getPrincipals();
+
+ for (String role : identity.getRoles())
+ principals.add(new RolePrincipal(role));
+
+ // username principal
+ principals.add(new UserPrincipal(identity.getUserId()));
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+}
Property changes on: core/trunk/exo.core.component.security.core/src/main/java/org/exoplatform/services/security/j2ee/JettyLoginModule.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
13 years, 11 months