exo-jcr SVN: r2862 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-03 09:33:35 -0400 (Tue, 03 Aug 2010)
New Revision: 2862
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/cache.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/component-plugin-priority.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/exo-container.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/initialcontext-binder-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/inversion-of-control.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jmx-bean-server.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jndi-naming.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/job-scheduler-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/logging.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml
Log:
EXOJCR-867 target filenames and id's updated
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/cache.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/cache.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/cache.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
- <?dbhtml filename="ch-kernel-cache.html"?>
+<chapter id="Kernel.Cache">
+ <?dbhtml filename="ch-cache.html"?>
<title>eXo Cache</title>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/component-plugin-priority.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/component-plugin-priority.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/component-plugin-priority.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelComponentPluginPriority">
- <?dbhtml filename="ch-kernel-component-plugin-priority.html"?>
+<chapter id="Kernel.ComponentPluginPriority">
+ <?dbhtml filename="ch-component-plugin-priority.html"?>
<title>Component Plugin Priority</title>
<para>Since kernel version 2.0.6 it is possible to setup order of loading
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/configuration.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
+<chapter id = "Kernel.Configuration">
<?dbhtml filename="ch-configuration.html"?>
<title>Configuration</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/container-configuration.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="KernelContainerConfiguration">
+<chapter id="Kernel.ContainerConfiguration">
<?dbhtml filename="ch-kernel-container-configuration.html"?>
<title>Container Configuration</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/exo-container.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/exo-container.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/exo-container.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,6 +1,6 @@
<?xml version='1.0' ?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="KernelExoContainer">
- <?dbhtml filename="ch-kernel-exo_container.html"?>
+<chapter id="Kernel.ExoContainer">
+ <?dbhtml filename="ch-exo-container.html"?>
<title>ExoContainer info</title>
<para>ExoContainer is the main IoC kernel object. The container is responsible for loading services/components.</para>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/initialcontext-binder-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/initialcontext-binder-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/initialcontext-binder-service.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="InitialContextBinderservice">
- <?dbhtml filename="ch-kenel-initialcontext-binder-service.html"?>
+<chapter id="Kernel.InitialContextBinderservice">
+ <?dbhtml filename="ch-initialcontext-binder-service.html"?>
<title>Initial Context Binder service</title>
<para>Initial Context Binder is responsible for binding references at
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/inversion-of-control.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/inversion-of-control.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/inversion-of-control.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelInversionOfControl">
- <?dbhtml filename="ch-kenel-inversion-of-control.html"?>
+<chapter id="Kernel.InversionOfControl">
+ <?dbhtml filename="ch-inversion-of-control.html"?>
<title>Inversion Of Control</title>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jmx-bean-server.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jmx-bean-server.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jmx-bean-server.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelJMXMBeanServer">
- <?dbhtml filename="ch-kenel-jmxbeanserver.html"?>
+<chapter id="Kernel.JMXMBeanServer">
+ <?dbhtml filename="ch-jmxbean-server.html"?>
<title>JMX MBean Server</title>
<section>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jndi-naming.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jndi-naming.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/jndi-naming.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="KernelJNDINaming">
+<chapter id="Kernel.JNDINaming">
<?dbhtml filename="ch-jndi-naming.html"?>
<title>JNDI naming</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/job-scheduler-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/job-scheduler-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/job-scheduler-service.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelJobSchedulerService">
- <?dbhtml filename="ch-kenel-job-scheduler-service.html"?>
+<chapter id="Kernel.JobSchedulerService">
+ <?dbhtml filename="ch-job-scheduler-service.html"?>
<title>Job Scheduler Service</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/logging.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/logging.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/logging.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="KernleLogConfiguration">
- <?dbhtml filename="ch-log-configuration.html"?>
+<chapter id="Kernel.LogConfiguration">
+ <?dbhtml filename="ch-logging.html"?>
<title>Logs configuration</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-for-beginners.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelServiceConfigurationforBeginners">
- <?dbhtml filename="ch-kenel-service-configuration-for-beginners.html"?>
+<chapter id="Kernel.ServiceConfigurationforBeginners">
+ <?dbhtml filename="ch-service-configuration-for-beginners.html"?>
<title>Service Configuration for Beginners</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/service-configuration-in-detail.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelServiceConfigurationinDetail">
- <?dbhtml filename="ch-kenel-service-configuration-in-detail.html"?>
+<chapter id="Kernel.ServiceConfigurationinDetail">
+ <?dbhtml filename="ch-service-configuration-in-detail.html"?>
<title>Service Configuration in Detail</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/services-wiring.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelServicesWiring">
- <?dbhtml filename="ch-kenel-services-wiring.html"?>
+<chapter id="Kernel.ServicesWiring">
+ <?dbhtml filename="ch-services-wiring.html"?>
<title id="KernelServicesWiring.Title">Services Wiring</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="KernelTransactionService">
- <?dbhtml filename="ch-kernel-tranasction-service.html"?>
+<chapter id="Kernel.TransactionService">
+ <?dbhtml filename="ch-tranasction-service.html"?>
<title>TransactionService</title>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml 2010-08-03 13:16:29 UTC (rev 2861)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/kernel/understanding-listnerservice.xml 2010-08-03 13:33:35 UTC (rev 2862)
@@ -1,8 +1,8 @@
<?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="KernelUnderstandingtheListenerService">
- <?dbhtml filename="ch-kenel-understanding-listeners-service.html"?>
+<chapter id="Kernel.UnderstandingtheListenerService">
+ <?dbhtml filename="ch-understanding-listeners-service.html"?>
<title>Understanding the ListenerService</title>
15 years, 11 months
exo-jcr SVN: r2861 - jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-03 09:16:29 -0400 (Tue, 03 Aug 2010)
New Revision: 2861
Modified:
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
Log:
EXOJCR-868 target filenames updated
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/conversationstate-when-membership-changed.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.ConversationStateUserMembershipUpdated">
+ <?dbhtml filename="ch-conversationstate-when-membership-changed.html"?>
<title>Update ConversationState when user's Membership changed</title>
<para>When user logged in portal in ConversationRegistry added
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-configuration-hibernate.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.DatabaseConfigurationforHibernate">
+ <?dbhtml filename="ch-db-configuration-hibernate.html"?>
<title>Database Configuration for Hibernate</title>
<para>As usual, it is quite simple to use our configuration XML syntax to
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/db-schema-creator-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.DBSchemacreatorserviceJDBCimplementation">
+ <?dbhtml filename="ch-db-schema-creator-service.html"?>
<title>DB Schema creator service (JDBC implementation)</title>
<para>DB Schema Creator is responsible for database schema creating using a
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/ldap-configuration.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.LDAPConfiguration">
+ <?dbhtml filename="ch-ldap-configuration.html"?>
<title>LDAP Configuration</title>
<section>
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-initalizer.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.OrganizationServiceInitializer">
+ <?dbhtml filename="ch-organization-service-initalizer.html"?>
<title>Organization Service Initializer</title>
<para>Use the Organization Service Initializer to create users, groups and
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service-listener.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"hp://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.OrganizationListener">
+ <?dbhtml filename="ch-organization-service-listener.html"?>
<title>Organization Listener</title>
<section>
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/organization-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.OrganizationService">
+ <?dbhtml filename="ch-organization-service-listener.html"?>
<title>Organization Service</title>
<section id="Overview">
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/security-service.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.SecurityService">
+ <?dbhtml filename="ch-security-service.html"?>
<title>Security Service</title>
<section>
Modified: 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 2010-08-03 12:58:24 UTC (rev 2860)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/core/spring-security-integration.xml 2010-08-03 13:16:29 UTC (rev 2861)
@@ -2,6 +2,7 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="Core.SpringSecurityIntegration">
+ <?dbhtml filename="ch-spring-security-integration.html"?>
<title>Spring Security Integration</title>
<section>
15 years, 11 months
exo-jcr SVN: r2860 - in jcr/branches/1.12.x/docs/reference/en/src/main: docbook/en-US/modules/jcr and 3 other directories.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-03 08:58:24 -0400 (Tue, 03 Aug 2010)
New Revision: 2860
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-resources.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl-ext.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl.gif
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/binaryvalue.png
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer1.JPG
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer2.JPG
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer3.JPG
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer4.JPG
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-869 other documentation added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl-ext.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.AccessControlExtension">
+ <title>Access Control Extension</title>
+
+ <section>
+ <title>Prerequisites</title>
+
+ <para>This is an extension of eXo JCR Access Control features. Please read
+ <ulink url="Access Control">Access Control</ulink> and <ulink
+ url="JCR Extensions">JCR Extensions</ulink> topics before.</para>
+ </section>
+
+ <section>
+ <title>Overview</title>
+
+ <para>An extended Access Control system consists of: * Specifically
+ configured custom <emphasis role="bold">Extended Access Manager</emphasis>
+ which is called by eXo JCR internals to check if some user's Session
+ (user) has some privilege to perform some operation * The <emphasis
+ role="bold">Action</emphasis> which sets the thread local <emphasis
+ role="bold">Invocation Context</emphasis> at runtime. This invocation
+ context is used by the Extended Access Manager to make a decision about
+ the current Session's permission * <emphasis role="bold">Invocation
+ Context</emphasis> is a collection of properties which reflect the state
+ of a current Session. For the time being it contains: the type of the
+ current operation on Session (event), current Item (javax.jcr.Item) on
+ which this operation is performed and the current eXo Container</para>
+ </section>
+
+ <section>
+ <title>Access Context Action</title>
+
+ <para>SetAccessContextAction implements Action and may be called by
+ SessionActionInterceptor as a reaction of some event - usually before
+ writing methods and after reading (getNode(), getProperty() etc). This
+ SetAccessContextAction calls the
+ AccessManager.setContext(InvocationContext context) method which sets the
+ ThreadLocal invocation context for the current call.</para>
+
+ <para>Action's Configuration may look like the following:</para>
+
+ <programlisting><value>
+ <object type="org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration">
+ <field name="eventTypes"><string>addNode,read</string></field>
+ <field name="workspace"><string>production</string></field >
+ <field name="actionClassName"><string>org.exoplatform.services.jcr.ext.SetAccessContextAction</string></field>
+ </object>
+</value></programlisting>
+ </section>
+
+ <section>
+ <title>The Invocation Context</title>
+
+ <para>The <emphasis role="bold">InvocationContext</emphasis> contains the
+ current Item, the current ExoContainer and the current EventType like
+ below:</para>
+
+ <programlisting>public interface InvocationContext extends ContextBase {
+
+ Item getCurrentItem();
+
+ int getEventType();
+
+ ExoContainer getContainer();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Custom Extended Access Manager</title>
+
+ <para>By default all Workspaces share an AccessManager instance, created
+ by RepositoryService at the startup (DefaultAccessManagerImpl) which
+ supports default access control policy as described in the <emphasis
+ role="bold">Access Control</emphasis> chapter. Custom Access Control
+ policy can be applied to certain Workspace configuring <emphasis
+ role="bold">access-manager</emphasis> element inside <emphasis
+ role="bold">workspace</emphasis> as follows:</para>
+
+ <programlisting><workspace name="ws">
+ ...
+ <!-- after query-handler element -->
+ <access-manager class="org.exoplatform.services.jcr.CustomAccessManagerImpl">
+ <properties>
+ <property name="someProperty" value="value"/>
+ ...
+ </properties>
+ </access-manager>
+ ...
+</workspace></programlisting>
+
+ <para>For each interested AccessManager implementation overwrite the
+ hasPermission() method so it will use the current invocation context at
+ its discretion. For instance, it may get some current node's metadata and
+ make a decision if the current User has appropriate permissions. Use
+ Invocation Context's runtime properties to make a decision about current
+ Session's privileges (see the Example below)</para>
+
+ <para>Simplified Sequence diagram for the Session.getNode() method (as an
+ Example):</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/acl-ext.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Example of a custom Access Manager</title>
+
+ <para>The sample CustomAccessManagerImpl below extends the default access
+ manager and uses some DecisionMakingService in the overloaded
+ hasPermission method to find out if a current user has permission to use
+ current <emphasis role="bold">item, event type, userID</emphasis> and some
+ parameter of AccessManager. To make this Access manager work it is
+ necessary to configure it in jcr configuration as mentioned in <emphasis
+ role="bold">Custom Extended Access Manager</emphasis> as well as
+ SetAccessContextAction should be configured in the way mentioned in
+ <emphasis role="bold">Access Context Actio</emphasis></para>
+
+ <programlisting>public class CustomAccessManagerImpl extends AccessManager {
+
+ private String property;
+ private DecisionMakingService theService;
+
+ public CustomAccessManagerImpl (RepositoryEntry config, WorkspaceEntry wsConfig,
+ OrganizationService orgService, DecisionMakingService someService) throws RepositoryException {
+ super(config, wsConfig, orgService);
+ this.property = wsConfig.getAccessManager().getParameterValue("someParam");
+ this.theService = someService;
+ }
+
+ @Override
+ public boolean hasPermission(AccessControlList acl, String[] permission, String userId) {
+ // call the default permission check
+ if (super.hasPermission(acl, permission, userId)) {
+
+ Item curItem = context().getCurrentItem();
+ int eventType = context().getEventType();
+ ExoContainer container = context().getContainer();
+
+// call some service's method
+ return theService.makeDecision(curItem, eventType, userId, property);
+ } else {
+ return false;
+ }
+ }
+}
+</programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/acl.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.AccessControl">
+ <title>Access Control</title>
+
+ <para>eXo JCR is a complete implementation of the standard JSR 170: <ulink
+ url="Content Repository for Java TM Technology API > http://jcp.org/en/jsr/detail?id=170">Content
+ Repository for Java TM Technology API</ulink>, including <emphasis
+ role="bold">Level 1, Level 2 and Additional Features</emphasis> as is
+ specified in the JCR Specification.</para>
+
+ <section>
+ <title>Standard Action Permissions</title>
+
+ <para>The JCR specification (JSR 170), does not have many requirements
+ about Access Control. It only requires the implementation of the
+ Session.checkPermission(String absPath, String actions) method. This
+ method checks if a current session has permissions to perform some actions
+ on absPath:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>absPath : the string representation of a JCR absolute
+ path</para>
+ </listitem>
+
+ <listitem>
+ <para>actions : eXo JCR interprets this string as a comma separated
+ list of individual action names such as the 4 types defined in JSR 170
+ :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">add_node</emphasis> : Permission to
+ add a node</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">set_property</emphasis> : Permission
+ to set a property</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">remove</emphasis> : Permission to
+ remove an item (node or property)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">read</emphasis> : Permission to
+ retrieve a node or read a property value</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>Examples :</para>
+
+ <para>session.checkPermission("/Groups/organization",
+ "add_node,set_property") will check if the session is allowed to add a
+ child node to "organization" and to modify its properties. If one the two
+ permissions is denied an AccessDeniedException is thrown.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>session.checkPermission("/Groups/organization/exo:name",
+ "read,set_property") will check if the session is allowed to read and
+ change the "exo:name" property of the "organization" node.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>eXo Access Control</title>
+
+ <para>The JSR170 specification does not define how permissions are managed
+ or checked. So eXo JCR has implemented its own proprietary extension to
+ manage and check permissions on nodes. In essence, this extension uses an
+ <ulink url="http://en.wikipedia.org/wiki/Access_control_list">Access
+ Control List (ACL)</ulink> policy model applied to eXo Organization model
+ (see eXo Platform Organization Service).</para>
+
+ <section>
+ <title>Principal and Identity</title>
+
+ <para>At the heart of eXo Access Control, is the notion of the <emphasis
+ role="bold">identity</emphasis> concept. Access to JCR is made through
+ sessions acquired against a repository. Sessions can be authenticated
+ through the standard (but optional) repository login mechanism. Each
+ session is associated with a <emphasis role="bold">principal</emphasis>.
+ The principal is an authenticated user or group that may act on JCR
+ data. The identity is a string identifying this <emphasis
+ role="bold">group or user</emphasis>.</para>
+
+ <para>There are 3 reserved identities that have special meanings in eXo
+ JCR:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">any</emphasis> : represents any
+ authenticated session.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">anonim</emphasis> : represents a
+ principal for non authenticated sessions. (No error, it's really
+ "\_\_anonim".)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">system</emphasis> : represents a
+ principal for system sessions, typically used for administrative
+ purposes. System session have full access (all permissions) to all
+ nodes; therefore be careful when working with system
+ sessions.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>ACL</title>
+
+ <para>An access control list (ACL) is a list of permissions attached to
+ an object. An ACL specifies which users, groups or system processes are
+ granted access to JCR nodes, as well as what operations are allowed to
+ be performed on given objects.</para>
+
+ <para>eXo JCR Access Control is based on two facets applied to nodes
+ :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Privilegeable</emphasis> : Means that
+ the user or group (also called principal) needs the appropriate
+ privileges to access to this node. The privileges are defined as
+ (positive) permissions that are granted to users or groups.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Ownable</emphasis> : The node has an
+ <emphasis role="bold">owner</emphasis>. The owner has always
+ <emphasis role="bold">full access</emphasis> (all permissions) to
+ the node, independent of the privilegeable facet.</para>
+ </listitem>
+ </itemizedlist>
+
+ <section>
+ <title>Privilegeable</title>
+
+ <para>A privilegeable node defines the permissions required for
+ actions on this node. For this purpose it contains an ACL.</para>
+
+ <para>At JCR level, this is implemented by an <emphasis
+ role="bold">exo:privilegeable</emphasis> mixin.</para>
+
+ <programlisting><nodeType name="exo:privilegeable" isMixin="true" hasOrderableChildNodes="false" primaryItemName="">
+ <propertyDefinitions>
+ <propertyDefinition name="exo:permissions" requiredType="Permission" autoCreated="true" mandatory="true"
+ onParentVersion="COPY" protected="true" multiple="true">
+ <valueConstraints/>
+ </propertyDefinition>
+ </propertyDefinitions>
+</nodeType></programlisting>
+
+ <para>A privilegeable node can have multiple exo:permissions values.
+ The type of these values is the eXo JCR specific type Permission. The
+ Permission type contains a list of ACL.</para>
+
+ <para>The possible values are corresponding to JCR standard
+ actions:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">read</emphasis>: The node or its
+ properties can be read.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">remove</emphasis>: The node or its
+ properties can be removed.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">add_node</emphasis> : Child nodes can
+ be added to this node.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">set_property</emphasis> : The node's
+ properties can be modified, added or removed.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Ownable</title>
+
+ <para>An ownable node defines an owner identity. The <emphasis
+ role="bold">owner</emphasis> has always <emphasis role="bold">full
+ privileges</emphasis>. These privileges are independent of the
+ permissions set by exo:permissions. At JCR level, the ownership is
+ implemented by an <emphasis role="bold">exo:owneable</emphasis> mixin.
+ This mixin holds an owner property.</para>
+
+ <programlisting><nodeType name="exo:owneable" isMixin="true" hasOrderableChildNodes="false" primaryItemName="">
+ <propertyDefinitions>
+ <propertyDefinition name="exo:owner" requiredType="String" autoCreated="true" mandatory="true" onParentVersion="COPY"
+ protected="true" multiple="false">
+ <valueConstraints/>
+ </propertyDefinition>
+ </propertyDefinitions>
+</nodeType></programlisting>
+
+ <para>The exo:owner property value contains exactly one identity
+ string value. There might be a long list of different permissions for
+ different identities (user or groups). All permissions are always
+ positive permissions; denials are not possible. When checking for a
+ permission of an action it's therefore perfectly sufficient that the
+ principal of a session belongs to one the groups, to who the concerned
+ action is granted.</para>
+ </section>
+
+ <section>
+ <title>ACL Inheritance</title>
+
+ <para>In order to grant or deny access to a node, eXo JCR applies a
+ privilege resolving logic at node access time.</para>
+
+ <para>If a node is <emphasis role="bold">privilegeable</emphasis>, the
+ node's ACL is used exclusively. If the ACL does not match the
+ principal's identity the principal has no access (except if he is the
+ owner of the node).</para>
+
+ <para>Non-privilegeable nodes inherit permissions from their parent
+ node. If the parent node isn't privilegeable either, the resolving
+ logic looks further up the node hierarchy and stops with the first
+ privilegeable ancestor of the current node. All nodes potentially
+ inherit from the <emphasis role="bold">workspace</emphasis> root
+ node.</para>
+
+ <para>The owner of a node is inherited following the same logic: If
+ the node has no owner, the owner information of the closest owneable
+ ancestor is inherited.</para>
+
+ <para>This inheritance is implemented by browsing up the node's
+ hierarchy. At access time, if the node does not have owner or
+ permissions the system looks up into the node's ancestor hierarchy for
+ the <emphasis role="bold">first</emphasis> ACL.</para>
+ </section>
+
+ <section>
+ <title>Default ACL of the root node</title>
+
+ <para>When no matching ACL is found in the ancestor hierarchy, the
+ system may end up looking at the root node's ACL. As ACL are optional,
+ even for the root node, if the root node has no ACL, the following
+ rule is ultimately applied to resolve privileges :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">any</emphasis> identity (any
+ authenticated session) is granted all permissions</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>Notes</title>
+
+ <para><emphasis role="bold">Access Control nodetypes are not
+ extendible</emphasis> The access control mechanism works for <emphasis
+ role="bold">exo:owneable</emphasis> and <emphasis
+ role="bold">exo:privilegeable</emphasis> nodetypes only, not for their
+ subtypes! So you can NOT extend those nodetypes.</para>
+
+ <para><emphasis role="bold">Autocreation</emphasis> By default, newly
+ created nodes are neither <emphasis
+ role="bold">exo:privilegeable</emphasis> nor <emphasis
+ role="bold">exo:owneable</emphasis> but it is possible to configure the
+ repository to auto-create <emphasis
+ role="bold">exo:privilegeable</emphasis> or/and <emphasis
+ role="bold">exo:owneable</emphasis> thanks to eXo's JCR interceptors
+ extension (see <ulink
+ url="http://wiki.exoplatform.org/xwiki/bin/view/JCR/JCR+Extensions">http://wiki.exoplatform.org/xwiki/bin/view/JCR/JCR+Extensions</ulink>)</para>
+
+ <para><emphasis role="bold">OR-based Privilege Inheritance</emphasis>
+ Note, that eXo's Access Control implementation supports an privilege
+ inheritance that follows a strategy of either...or and has only an ALLOW
+ privilege mechanism (there is no DENY feature). This means that a
+ session is allowed to perform some operation on some node if its
+ identity has an appropriate permission assigned to this node. Only if
+ there is no exo:permission property assigned to the node itself, the
+ permissions of the node's ancestors are used.</para>
+ </section>
+
+ <section>
+ <title>Example</title>
+
+ <section>
+ <title>XML Example</title>
+
+ <para>In the following example, you see a node named "Politics" which
+ contains two nodes named "Cats" and "Dogs".</para>
+
+ <para>#info("These examples are exported from eXo DMS using the
+ \"document view\" representation of JCR. Each value of a multivalue
+ property is separated by a whitespace, each whitespace is escaped by
+ <emphasis>x0020</emphasis>.")</para>
+
+ <programlisting><Politics jcr:primaryType="nt:unstructured" jcr:mixinTypes="exo:owneable exo:datetime exo:privilegeable" exo:dateCreated="2009-10-08T18:02:43.687+02:00"
+exo:dateModified="2009-10-08T18:02:43.703+02:00"
+exo:owner="root"
+exo:permissions="any_x0020_read *:/platform/administrators_x0020_read *:/platform/administrators_x0020_add_node *:/platform/administrators_x0020_set_property *:/platform/administrators_x0020_remove">
+
+<Cats jcr:primaryType="exo:article"
+jcr:mixinTypes="exo:owneable"
+exo:owner="marry"
+exo:summary="The_x0020_secret_x0020_power_x0020_of_x0020_cats_x0020_influences_x0020_the_x0020_leaders_x0020_of_x0020_the_x0020_world."
+exo:text="" exo:title="Cats_x0020_rule_x0020_the_x0020_world" />
+
+<Dogs jcr:primaryType="exo:article"
+jcr:mixinTypes="exo:privilegeable"
+exo:permissions="manager:/organization_x0020_read manager:/organization_x0020_set_property"
+exo:summary="Dogs"
+exo:text="" exo:title="Dogs_x0020_are_x0020_friends" />
+
+</Politics></programlisting>
+
+ <para>The "Politics" node is <emphasis
+ role="bold">exo:owneable</emphasis> and <emphasis
+ role="bold">exo:privilegeable</emphasis>. It has both an <emphasis
+ role="bold">exo:owner</emphasis> property and also an <emphasis
+ role="bold">exo:permissions</emphasis> property. There is an <emphasis
+ role="bold">exo:owner="root"</emphasis> property so that the user root
+ is the owner. In the exo:permissions value you can see the ACL, a list
+ of access controls. In this example the group <emphasis
+ role="bold">\</emphasis>:/platform/administrators* has all rights on
+ this node (remember that the "\*" means any kind of membership/role).
+ Furthermore <emphasis role="bold">any</emphasis> has the read
+ permission.</para>
+
+ <para>As you can see in the jcr:mixinTypes property the "Cats" node is
+ <emphasis role="bold">exo:owneable</emphasis>; hence there is an
+ <emphasis role="bold">exo:owner="marry"</emphasis> property so that
+ the user marry is the owner. The "Cats" node is <emphasis
+ role="bold">not exo:privilegeable</emphasis> and has <emphasis
+ role="bold">no exo:permissions</emphasis>. In this case the <emphasis
+ role="bold">inheritance mechanism</emphasis> enters the game: The
+ "Cats" node has the same permissions as "Politics" node.</para>
+
+ <para>Finally the "Dogs" node is also a child node of "Politics". This
+ node is <emphasis role="bold">not exo:owneable</emphasis> and inherits
+ the owner of the "Politics" node (which is the user root). Otherwise
+ "Dogs" is <emphasis role="bold">exo:privilegeable</emphasis> and does
+ therefore have its own <emphasis
+ role="bold">exo:permissions</emphasis>. That means only the users
+ having a "manager" role in the group "/organization" and the user
+ "root" have the rights to access this node - all others have no access
+ rights.</para>
+ </section>
+
+ <section>
+ <title>Inheritance Examples</title>
+
+ <para>Here is an example showing the accessibility of two nodes (to
+ show inheritance) for two sample users named <emphasis
+ role="bold">manager</emphasis> and <emphasis
+ role="bold">user</emphasis>:</para>
+
+ <para>The "+" symbol means that there is a child node
+ "exo:owneable".</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other.acl.gif" />
+ </imageobject>
+ </mediaobject>
+ </section>
+ </section>
+
+ <section>
+ <title>Java API</title>
+
+ <para>eXo JCR's ExtendedNode interface which extends javax.jcr.Node
+ interface provides additional methods for Access Control
+ management.</para>
+
+ <para>{table} Method signature |Description void
+ setPermissions(Map\<String, String\ <ulink url="\">\</ulink>\>
+ permissions)| Assigns a set of Permissions to a node void
+ setPermission(String identity, String\ <ulink url="\">\</ulink>
+ permission)| Assigns some Identity's Permission to a node void
+ removePermission(String identity)| Remove Identity's Permission void
+ removePermission(String identity, String permission)|Remove the
+ specified permission for a particular identity void clearACL()| Clears
+ the current ACL so it becomes default AccessControlList getACL()|
+ Returns the current ACL void checkPermission(String actions)| Checks
+ Permission (AccessDeniedException will be thrown if denied)
+ {table}</para>
+
+ <para>The "identity" parameter is the user or group name. The
+ permissions are the literal strings of the standard action permissions
+ (add_node, set_property, remove, read.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/binary-values-processing.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.BinaryValuesProcessing">
+ <title>Binary Values Processing</title>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>Binary large object (BLOB) properties can be stored in two ways in
+ the eXo JCR: in the database with items information or in an external
+ storage on host file system. These options can be configured per workspace
+ in the repository configuration file (repository-configuration.xml in
+ portal and exo-jcr-config.xml in standalone mode). The database storage
+ can't be completely disabled.</para>
+
+ <para>The first case is optimal for most cases where you do not use very
+ large values or/and do not have too many BLOBs. The configuration of the
+ BLOBs size and BLOBs quantity in a repository depend on your database
+ features and hardware.</para>
+
+ <para>The second case is to use an external values storage. The storage
+ can be located on a built-in hard disk or on an attached storage. But in
+ any case you should have access to the storage as if it was a regular
+ file(s). The external value storage is optional and can be enabled in
+ addition to a database configuration.</para>
+
+ <note>
+ <para>eXo JCR Repository service configuration basics is discussed in
+ <ulink
+ url="Configuration>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Configura...">Configuration</ulink></para>
+
+ <para>Database and workspace persistence storage configuration is
+ discussed in <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/JCR/JDBC+Data+Container+config">JDBC
+ Data Container config</ulink></para>
+
+ <para>Configuration details for <ulink
+ url="http://wiki.exoplatform.com/xwiki/bin/view/JCR/External+Value+Storages">External
+ Value Storages</ulink>.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>In both cases a developer can set/update the binary Property via
+ Node.setProperty(String, InputStream), Property.setValue(InputStream) as
+ described in the spec JSR-170. Also there is the setter with a ready Value
+ object (obtainer from ValueFactory.createValue(InputStream)).</para>
+
+ <para>An example of a specification usage.</para>
+
+ <programlisting>// Set the property value with given stream content.
+Property binProp = node.setProperty("BinData", myDataStream);
+// Get the property value stream.
+InputStream binStream = binProp.getStream();
+
+// You may change the binary property value with a new Stream, all data will be replaced
+// with the content from the new stream.
+Property updatedBinProp = node.setProperty("BinData", newDataStream);
+// Or update an obtained property
+updatedBinProp.setValue(newDataStream);
+// Or update using a Value object
+updatedBinProp.setValue(ValueFactory.createValue(newDataStream));
+// Get the updated property value stream.
+InputStream newStream = updatedBinProp.getStream();</programlisting>
+
+ <para>But if you need to update the property sequentially and with partial
+ content you have no choice but to edit the whole data stream outside and
+ get it back to the repository each time. In case of really large sized
+ data the application will be stuck and the productivity will decrease a
+ lot. JCR stream setters will also check constraints and perform common
+ validation each time.</para>
+
+ <para>There is a feature of the eXo JCR extension that can be used for
+ binary values partial writing without frequent session level calls. The
+ main idea is to use during runtime a value object obtained from the
+ property as the storage of the property content during
+ writing/reading.</para>
+
+ <para>According to the spec JSR-170 Value interface provides the state of
+ property that can't be changed (edited). The eXo JCR core provides
+ ReadableBinaryValue and EditableBinaryValue interfaces which themselves
+ extend JCR Value. The interfaces allow the user to partially read and
+ change a value content.</para>
+
+ <para>ReadableBinaryValue value can be casted from any value, i.e. String,
+ Binary, Date etc.</para>
+
+ <programlisting>// get the property value of type PropertyType.STRING
+ReadableBinaryValue extValue = (ReadableBinaryValue) node.getProperty("LargeText").getValue();
+// read 200 bytes to a destStream from the position 1024 in the value content
+OutputStream destStream = new FileOutputStream("MyTextFile.txt");
+extValue.read(destStream, 200, 1024);</programlisting>
+
+ <para>But EditableBinaryValue can be applied only to properties of type
+ PropertyType.BINARY. In other cases a cast to EditableBinaryValue will
+ fail.</para>
+
+ <para>After the value has been edited the EditableBinaryValue value can be
+ applied to the property using the standard setters
+ (Property.setValue(Value), Property.setValues(Value),
+ Node.setProperty(String, Value) etc.). Only after the EditableBinaryValue
+ has been set to the property it can be obtained in this session by getters
+ (Property.getValue(), Node.getProperty(String) etc.).</para>
+
+ <para>The user can obtain an EditableBinaryValue instance and fill it with
+ data in an interaction manner (or any other appropriated to the targets)
+ and return (set) the value to the property after the content will be
+ done.</para>
+
+ <programlisting>// get the property value for PropertyType.BINARY Property
+EditableBinaryValue extValue = (EditableBinaryValue) node.getProperty("BinData").getValue();
+
+// update length bytes from the stream starting from the position 1024 in existing Value data
+extValue.update(dataInputStream, dataLength, 1024);
+
+// apply the edited EditableBinaryValue to the Property
+node.setProperty("BinData", extValue);
+
+// save the Property to persistence
+node.save();</programlisting>
+
+ <para>A practical example of the iterative usage. In this example the
+ value is updated with data from the sequence of streams and after the
+ update is done the value will be applied to the property and be visible
+ during the session.</para>
+
+ <programlisting>// update length bytes from the stream starting from the particular
+// position in the existing Value data
+int dpos = 1024;
+while (source.dataAvailable()) {
+ extValue.update(source.getInputStream(), source.getLength(), dpos);
+ dpos = dpos + source.getLength();
+}
+
+// apply the edited EditableBinaryValue to the Property
+node.setProperty("BinData", extValue);</programlisting>
+ </section>
+
+ <section>
+ <title>Value implementations</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/binaryvalue.png" />
+ </imageobject>
+ </mediaobject>
+
+ <para>ReadableBinaryValue has one method for Value reading.</para>
+
+ <para>Read length bytes from the binary value from the given position into
+ the stream.</para>
+
+ <programlisting>long read(OutputStream stream, long length, long position) throws IOException, RepositoryException ;</programlisting>
+
+ <para>EditableBinaryValue has two methods for value editing.</para>
+
+ <para>Update with length bytes from the specified stream to this value
+ data at a position. If the position is lower than 0 the IOException
+ exception will be thrown. If the position is higher than the current Value
+ length, the Value length will be increased at first to the size of
+ position and length bytes will be added after the position.</para>
+
+ <programlisting>void update(InputStream stream, long length, long position) throws IOException;</programlisting>
+
+ <para>Set the length of the Value in bytes to the specified size. If the
+ size is lower than 0 the IOException exception will be thrown. This
+ operation can be used both for extending and truncating the Value size.
+ This method is used internally in the update operation in case of
+ extending the size to the given position.</para>
+
+ <programlisting>void setLength(long size) throws IOException;</programlisting>
+
+ <para>An application can perform JCR binary operations more flexible and
+ will have less I/O and CPU usage using these methods.</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-organization-service.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.Organizationservice">
+ <title>JCR Organization service</title>
+
+ <para>This is an implementation of the exo.core.component.organization.api
+ API. The information will be stored in the root node /exo:organization of
+ the workspace. The workspace name has to be configured in the configuration
+ file (see below).</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>You need to comment out the previous initialization of the
+ organization service, e.g. DummyOrganizationService</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><!--component>
+ <type>org.exoplatform.services.organization.impl.mock.DummyOrganizationService</type>
+</component--></programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add jcr organization service</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.organization.OrganizationService</key>
+ <type>org.exoplatform.services.jcr.ext.organization.JCROrganizationServiceImpl</type>
+ <init-params>
+ <value-param>
+ <name>storage-workspace</name>
+ <description>Workspace in default repository where organization storage will be created</description>
+ <value>ws</value>
+ </value-param>
+ </init-params>
+</component></programlisting>
+
+ <para>where storage-workspace is the name of the workspace in the default
+ repository where the organization storage will be created.</para>
+
+ <para>Sice eXo JCR 1.11 you can add two new params:</para>
+
+ <programlisting><value-param>
+ <name>repository</name>
+ <description>The name of repository where organization storage will be created</description>
+ <value>db1</value>
+</value-param>
+<value-param>
+ <name>storage-path</name>
+ <description>The relative path where organization storage will be created</description>
+ <value>/exo:organization</value>
+</value-param></programlisting>
+
+ <para>where repository is the name of the repository where the organization
+ storage will be created<br> storage-path - the relative path to the
+ stored data<br></para>
+
+ <para>You should also read how to use the <ulink
+ url="Core.Organization Service Initializer">Core.Organization Service
+ Initializer</ulink>.</para>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-resources.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-resources.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/jcr-resources.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.Resources">
+ <title>JCR Resources:</title>
+
+ <para>* Java Community Process: <ulink
+ url="http://jcp.org/en/jsr/detail?id=170">JSR 170 </ulink> and <ulink
+ url="http://jcp.org/en/jsr/detail?id=283">JSR 283</ulink></para>
+
+ <para>* Tom Wheeler, <ulink
+ url="http://www.tomwheeler.com/java_content_repository_tomwheeler_20071007.pdf">The
+ Java Content Repository</ulink> (2007)</para>
+
+ <para>* Roy T. Fielding, <ulink
+ url="http://www.day.com/content/dam/day/whitepapers/JSR_170_White_Paper.pdf">JSR
+ 170 Overview: Standardizing the Content Repository Interface</ulink> (March
+ 13, 2005)</para>
+
+ <para>* David Nuescheler and Janus Boye, <ulink
+ url="http://www.cmswatch.com/Feature/123">JSR-170 What's in it for
+ me?</ulink> (April 20, 2005)</para>
+
+ <para>* Benjamin Mestrallet, Tuan Nguyen, Gennady Azarenkov, Francois Moron
+ and Brice Revenant <ulink
+ url="http://www.theserverside.com/tt/articles/article.tss?l=eXoPlatform2">eXo
+ Platform v2, Portal, JCR, ECM, Groupware and Business Intelligence</ulink>
+ (January 2006)</para>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/other/link-producer.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.LinkProducerService">
+ <title>Link Producer Service</title>
+
+ <para>Link Producer Service - a simple service, which generates an .lnk
+ file, that is compatible with the Microsoft link file format. It is an
+ extension of the REST Framework library and is included into the WebDav
+ service. On dispatching a GET request the service generates the content of
+ an .lnk file, which points to a JCR resource via WebDav.</para>
+
+ <para>Link Producer has a simple configuration like described below:</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.webdav.lnkproducer.LnkProducer</key>
+ <type>org.exoplatform.services.webdav.lnkproducer.LnkProducer</type>
+</component></programlisting>
+
+ <para>When using JCR the resource can be addressed by WebDav reference
+ (href) like <emphasis role="bold"> <ulink
+ url="http://host:port/rest/jcr/repository/workspace/somenode/somefile.extention">http://host:port/rest/jcr/repository/workspace/somenode/somefile.extention</ulink>
+ </emphasis>, the link servlet must be called for this resource by several
+ hrefs, like <emphasis role="bold"> <ulink
+ url="http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...">http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...</ulink>
+ </emphasis></para>
+
+ <para>Please note, that when using the portal mode the REST servlet is
+ available using a reference (href) like <emphasis role="bold"> <ulink
+ url="http://localhost:8080/portal/rest/">http://localhost:8080/portal/rest/</ulink>...
+ </emphasis></para>
+
+ <para>The name of the .lnk file can be any. But for the best compatibility
+ it must be the same as the name of the JCR resource.</para>
+
+ <para>Here is a step by step sample of a use case of the link producer... At
+ first, type valid reference to the resource, using the link producer in your
+ browser's adress field:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/lnkproducer1.JPG" />
+ </imageobject>
+ </mediaobject>
+
+ <para>Internet Explorer will give a dialog window requesting to Open a file
+ or to Save it. Click on the Open button</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/lnkproducer2.JPG" />
+ </imageobject>
+ </mediaobject>
+
+ <para>In Windows system an .lnk file will be downloaded and opened with the
+ application which is registered to open the files, which are pointed to by
+ the .lnk file. In case of a .doc file, Windows opens Microsoft Office Word
+ which will try to open a remote file (test0000.doc). Maybe it will be
+ necessary to enter USERNAME and PASSWORD.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/lnkproducer3.JPG" />
+ </imageobject>
+ </mediaobject>
+
+ <para>Next, you will be able to edit the file in Microsoft Word.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/other/lnkproducer4.JPG" />
+ </imageobject>
+ </mediaobject>
+
+ <para>The Link Producer is necessary for opening/editing and then saving the
+ remote files in Microsoft Office Word, without any further updates.</para>
+
+ <para>Also the Link Producer can be referenced to from an HTML page. If page
+ contains code like</para>
+
+ <programlisting><a href="http://localhost:8080/rest/lnkproducer/openit.lnk?path=/repository/worksp...">somefile.extention</a></programlisting>
+
+ <para>the file "somefile.extention" will open directly.</para>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 09:43:46 UTC (rev 2859)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 12:58:24 UTC (rev 2860)
@@ -115,12 +115,32 @@
<xi:include href="jcr/backup/search-index-backup.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-
<!-- other -->
<xi:include href="jcr/statistics.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/other/acl.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/other/acl-ext.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/other/link-producer.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/other/binary-values-processing.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/other/jcr-organization-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+
+
+
+
+ <xi:include href="jcr/other/jcr-resources.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
<!-- data container configs -->
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl-ext.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl-ext.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/acl.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/binaryvalue.png
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/binaryvalue.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer1.JPG
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer1.JPG
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer2.JPG
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer2.JPG
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer3.JPG
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer3.JPG
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer4.JPG
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/other/lnkproducer4.JPG
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
15 years, 11 months
exo-jcr SVN: r2859 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules: jcr/backup and 1 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-03 05:43:46 -0400 (Tue, 03 Aug 2010)
New Revision: 2859
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/search-index-backup.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
Log:
EXOJCR-869: backup documents ported
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/backup-client.xml 2010-08-03 09:43:46 UTC (rev 2859)
@@ -0,0 +1,1321 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.BackupClient">
+ <?dbhtml filename="ch-backup-client.html"?>
+
+ <title>HTTPBackupAgent and backup client</title>
+
+ <warning>
+ <para>For this service you should configure the <emphasis
+ role="bold">org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister</emphasis>
+ in order to save the changes of the repository configuration. See the
+ <link
+ linkend="JCR.eXoJCRconfiguration.PortalAndStandaloneConfiguration">eXo JCR
+ Configuration article at chapter '2 Portal and Standalone
+ configuration'</link> .</para>
+ </warning>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The service
+ org.exoplatform.services.jcr.ext.backup.server.HTTPBackupAgent is
+ REST-based front-end to service
+ org.exoplatform.services.jcr.ext.backup.BackupManager. HTTPBackupAgent is
+ representation BackupManager to creation backup, restore, getting status
+ of current or completed backup/restore, etc.</para>
+
+ <para>The backup client is http client for HTTPBackupAgent.</para>
+ </section>
+
+ <section>
+ <title>HTTPBackupAgent</title>
+
+ <para>The HTTPBackupAgent is based on REST (see details about the <link
+ linkend="WS.RestFramework">REST Framework</link>).</para>
+
+ <para>HTTPBackupAgent is using POST and GET methods for request.</para>
+
+ <para>The HTTPBackupAgent allows :<itemizedlist>
+ <listitem>
+ <para>start backup</para>
+ </listitem>
+
+ <listitem>
+ <para>stop backup</para>
+ </listitem>
+
+ <listitem>
+ <para>restore from backup</para>
+ </listitem>
+
+ <listitem>
+ <para>delete the workspace</para>
+ </listitem>
+
+ <listitem>
+ <para>getting information about backup service
+ (BackupManager)</para>
+ </listitem>
+
+ <listitem>
+ <para>getting information about current backup / restores /
+ completed backups</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <section>
+ <title>HTTPBackupAgent methods</title>
+
+ <section>
+ <title>Start Backup Service</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/start/{repo}/{ws}</emphasis></para>
+
+ <para>Start backup on specific workspace</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/start/{repo}/{ws}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json.</para>
+
+ <para><emphasis role="bold">Method</emphasis>: POST</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{repo} - the repository name;</para>
+ </listitem>
+
+ <listitem>
+ <para>{ws} - the workspace name;</para>
+ </listitem>
+
+ <listitem>
+ <para>BackupConfigBean - the JSON to BackupConfigBean.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The BackupConfigBean:</para>
+
+ <programlisting>header :
+"Content-Type" = "application/json; charset=UTF-8"
+
+body:
+<JSON to BackupConfigBean></programlisting>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.BackupConfigBean
+ :</para>
+
+ <programlisting>{"incrementalRepetitionNumber":<Integer>,"incrementalBackupJobConfig":<JSON to BackupJobConfig>,
+"backupType":<Integer>,"fullBackupJobConfig":<JSON to BackupJobConfig>,
+"incrementalJobPeriod":<Long>,"backupDir":"<String>"}</programlisting>
+
+ <para>Where :</para>
+
+ <programlisting>backupType - the type of backup:
+ 0 - full backup only;
+ 1 - full and incremental backup.
+backupDir - the path to backup folder;
+incrementalJobPeriod - the incremental job period;
+incrementalRepetitionNumber - the incremental repetition number;
+fullBackupJobConfig - the configuration to full backup, JSON to BackupJobConfig;
+incrementalJobPeriod - the configuration to incremental backup, JSON to BackupJobConfig.</programlisting>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.BackupJobConfig
+ :</para>
+
+ <programlisting>{"parameters":[<JSON to Pair>, ..., <JSON to pair> ],"backupJob":"<String>"}</programlisting>
+
+ <para>Where:</para>
+
+ <programlisting>backupJob - the FQN (fully qualified name) to BackupJob class;
+parameters - the list of JSON of Pair.</programlisting>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.Pair
+ :</para>
+
+ <programlisting>{"name":"<String>","value":"<String>"}</programlisting>
+
+ <para>Where:</para>
+
+ <programlisting>name - the name of parameter;
+value - the value of parameter.</programlisting>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful<programlisting>status code = 200</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure<programlisting>status code = 404 - the not found repositry '{repo}' or workspace '{ws}'
+status code = 500 - the other unknown errors
+failure message in response - the description of failure</programlisting></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Stop Backup Service</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/stop/{id}</emphasis></para>
+
+ <para>Stop backup with identifier {id}.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/stop/{id}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> plain text</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{id} - the identifier of backup</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful<programlisting>status code = 200</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure<programlisting>status code = 404 - the no active backup with identifier {id}
+status code = 500 - the other unknown errors
+failure message in response - the description of failure</programlisting></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Backup Info Service</title>
+
+ <para><emphasis role="bold">/rest/jcr-backup/info</emphasis></para>
+
+ <para>Information about the backup service.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>Return the JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.BackupServiceInfoBean
+ :<programlisting>{"backupLogDir":"<String>","defaultIncrementalJobPeriod":<Long>,"fullBackupType":"<String>","incrementalBackupType":"<String>"}</programlisting>Where:<programlisting>fullBackupType - the FQN (fully qualified name) of BackupJob class for full backup type;
+incrementalBackupType - the FQN (fully qualified name) of BackupJob class for incremental backup type;
+backupLogDir - path to backup folder;
+defaultIncrementalJobPeriod - the default incremental job period.</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure<programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Drop Workspace Service</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/drop-workspace/{repo}/{ws}/{force-session-close}</emphasis></para>
+
+ <para>Delete the workspace from repository /{repo}/{ws}. With this
+ service you can delete any workspace, completly independant of the
+ fact if the workspace is a backup or has been copied to a
+ backup.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/drop-workspace/{repo}/{ws}/{force-sessio...</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> plain text</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{repo} - the repository name;</para>
+ </listitem>
+
+ <listitem>
+ <para>{ws} - the workspace name;</para>
+ </listitem>
+
+ <listitem>
+ <para> {force-session-close} - the boolean value : <emphasis
+ role="bold">true</emphasis> - the open sessions on workspace
+ will be closed; <emphasis role="bold">false</emphasis> - will
+ not close open sessions.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful<programlisting>status code = 200</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure<programlisting>status code = 500 - the other unknown errors;
+ - not found repositry '{repo}' or workspace '{ws}'
+failure message in response - the description of failure</programlisting></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Backup Info</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis></para>
+
+ <para>Information about the current and completed backups</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/backup</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfoList
+ :<programlisting>{"backups":[<JSON to ShortInfo>,<JSON to ShortInfo>,...,<JSON to ShortInfo>]}</programlisting>The
+ JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfo
+ :<programlisting>{"startedTime":"<String>","backupId":"<String>","type":<Integer>,"state":<Integer>,"backupType":<Integer>,
+"workspaceName":"<String>","finishedTime":"<String>","repositoryName":"<String>"}</programlisting></para>
+
+ <para>Where:<programlisting>type - the type of ShortInfo :
+ 0 - the ShorInfo to completed backup;
+ -1 - the ShorInfo to current (active) backup.
+ 1 - the ShorInfo to current restore.
+backupType - the type of backup:
+ 0 - full backup only;
+ 1 - full and incremental backup.
+backupId - the identifier of backup;
+workspaceName - the name of workspace;
+repositoryName - the name of repository.
+startedTime - the date of started backup. The date in format RFC 1123 (for examle "Thu, 16 Apr 2009 14:56:49 EEST").
+
+The ShorInfo to current (active) backup :
+ finishedTime - no applicable, always an empty string ("");
+ state - the state of full backup :
+ 0 - starting;
+ 1 - waiting;
+ 2 - working;
+ 4 - finished.
+
+The ShorInfo to completed backup :
+ finishedTime - the date of finished backup. The date in format RFC 1123;
+ state - no applicable, always zero (0).
+
+The ShorInfo to current restore :
+ finishedTime - the date of finished backup. The date in format RFC 1123;
+ state - the state of restore :
+ 1 - started;
+ 2 - successful;
+ 3 - failure;
+ 4 - initialized.</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure<programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Current Backups Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/backup/current</emphasis>
+ Information about the current backups</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/backup/current</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfoList
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Completed Backups Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/backup/completed</emphasis>
+ Information about the completed backups.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/backup/completed</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfoList
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Workspace-specific Backup Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/backup/{repo}/{ws}</emphasis>
+ Information about the current and completed backups for specific
+ workspace.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/backup/{repo}/{ws}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{repo} - the repository name</para>
+ </listitem>
+
+ <listitem>
+ <para>{ws} - the workspace name</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfoList
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Single Backup Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/backup/{id}</emphasis> Detailed
+ information about a current or completed backup with identifier
+ '{id}'.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/backup/{id}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{id} - the identifier of backup</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.DetailedInfo
+ :<programlisting>{"backupConfig":<JSON to BackupConfigBean>,"startedTime":"<String>","backupId":"<String>","type":<Integer>,
+"state":<Integer>,"backupType":<Integer>,"workspaceName":"<String>","finishedTime":"<String>",
+"repositoryName":"<String>"}</programlisting></para>
+
+ <para>Where:<programlisting>type - the type of DetailedInfo :
+ 0 - the DetailedInfo to completed backup;
+ -1 - the DetailedInfo to current (active) backup;
+ 1 - the DetailedInfo to restore.
+backupType - the type of backup:
+ 0 - full backup only;
+ 1 - full and incremental backup.
+backupId - the identifier of backup;
+workspaceName - the name of workspace;
+repositoryName - the name of repository;
+backupConfig - the JSON to BackupConfigBean.
+
+The DetailedInfo to current (active) backup :
+ startedTime - the date of started backup. The date in format RFC 1123 (for examle "Thu, 16 Apr 2009 14:56:49 EEST");
+ finishedTime - no applicable, always an empty string ("");
+ state - the state of full backup :
+ 0 - starting;
+ 1 - waiting;
+ 2 - working;
+ 4 - finished.
+The DetailedInfo to completed backup :
+ startedTime - the date of started backup. The date in format RFC 1123 (for examle "Thu, 16 Apr 2009 14:56:49 EEST");
+ finishedTime - the date of finished backup. The date in format RFC 1123;
+ state - no applicable, always zero (0).
+
+The DetailedInfo to restore :
+ startedTime - the date of started restore. The date in format RFC 1123 (for examle "Thu, 16 Apr 2009 14:56:49 EEST");
+ finishedTime - the date of finished restore;
+ state - the state of restore :
+ 1 - started;
+ 2 - successful;
+ 3 - failure;
+ 4 - initialized.</programlisting></para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.BackupConfigBean
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/start/{repo}/{ws}</emphasis>).</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 404 - not found the backup with {id}
+status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Restores on a Workspace Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/restore/{repo}/{ws}</emphasis> The
+ information about the last restore on a specific workspace
+ /{repo}/{ws}.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/restore/{repo}/{ws}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{repo} - the repository name</para>
+ </listitem>
+
+ <listitem>
+ <para>{ws} - the workspace name</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.DetailedInfo
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup/{id}</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 404 - the not found the restore for workspace /{repo}/{ws}
+status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Restores Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/restores</emphasis></para>
+
+ <para>The information about the last restores.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/restores</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean of
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfoList
+ (see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis>)</para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Restore Service</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/restore/{repo}/{id}</emphasis></para>
+
+ <para>Restore the workspace from specific backup.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/restore/{repo}/{id}</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json.</para>
+
+ <para><emphasis role="bold">Method</emphasis>: POST</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis><itemizedlist>
+ <listitem>
+ <para>{repo} - the repository name;</para>
+ </listitem>
+
+ <listitem>
+ <para>{id} - the identifier to backup; * WorkspaceEntry - the
+ JSON to WorkspaceEntry.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The RestoreBean:</para>
+
+ <programlisting>header :
+"Content-Type" = "application/json; charset=UTF-8"
+
+body:
+<JSON to WorkspaceEntry></programlisting>
+
+ <para>The example of JSON bean to
+ org.exoplatform.services.jcr.config.WorkspaceEntry :</para>
+
+ <programlisting>{ "accessManager" : null,
+ "autoInitPermissions" : null,
+ "autoInitializedRootNt" : null,
+ "cache" : { "parameters" : [ { "name" : "max-size",
+ "value" : "10k"
+ },
+ { "name" : "live-time",
+ "value" : "1h"
+ }
+ ],
+ "type" : "org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl"
+ },
+ "container" : { "parameters" : [ { "name" : "source-name",
+ "value" : "jdbcjcr"
+ },
+ { "name" : "dialect",
+ "value" : "hsqldb"
+ },
+ { "name" : "multi-db",
+ "value" : "false"
+ },
+ { "name" : "update-storage",
+ "value" : "false"
+ },
+ { "name" : "max-buffer-size",
+ "value" : "200k"
+ },
+ { "name" : "swap-directory",
+ "value" : "../temp/swap/production"
+ }
+ ],
+ "type" : "org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer",
+ "valueStorages" : [ { "filters" : [ { "ancestorPath" : null,
+ "minValueSize" : 0,
+ "propertyName" : null,
+ "propertyType" : "Binary"
+ } ],
+ "id" : "system",
+ "parameters" : [ { "name" : "path",
+ "value" : "../temp/values/production"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage"
+ } ]
+ },
+ "initializer" : { "parameters" : [ { "name" : "root-nodetype",
+ "value" : "nt:unstructured"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer"
+ },
+ "lockManager" : { "persister" : { "parameters" : [ { "name" : "path",
+ "value" : "../temp/lock/system"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister"
+ },
+ "timeout" : 15728640
+ },
+ "name" : "production",
+ "queryHandler" : { "analyzer" : { },
+ "autoRepair" : true,
+ "bufferSize" : 10,
+ "cacheSize" : 1000,
+ "documentOrder" : true,
+ "errorLogSize" : 50,
+ "excerptProviderClass" : "org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt",
+ "excludedNodeIdentifers" : null,
+ "extractorBackLogSize" : 100,
+ "extractorPoolSize" : 0,
+ "extractorTimeout" : 100,
+ "indexDir" : "../temp/jcrlucenedb/production",
+ "indexingConfigurationClass" : "org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfigurationImpl",
+ "indexingConfigurationPath" : null,
+ "maxFieldLength" : 10000,
+ "maxMergeDocs" : 2147483647,
+ "mergeFactor" : 10,
+ "minMergeDocs" : 100,
+ "parameters" : [ { "name" : "index-dir",
+ "value" : "../temp/jcrlucenedb/production"
+ } ],
+ "queryClass" : "org.exoplatform.services.jcr.impl.core.query.QueryImpl",
+ "queryHandler" : null,
+ "resultFetchSize" : 2147483647,
+ "rootNodeIdentifer" : "00exo0jcr0root0uuid0000000000000",
+ "spellCheckerClass" : null,
+ "supportHighlighting" : false,
+ "synonymProviderClass" : null,
+ "synonymProviderConfigPath" : null,
+ "type" : "org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex",
+ "useCompoundFile" : false,
+ "volatileIdleTime" : 3
+ },
+ "uniqueName" : "repository_production"
+}</programlisting>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <programlisting>status code = 200</programlisting>
+
+ <para>Return the JSON bean
+ org.exoplatform.services.jcr.ext.backup.server.bean.response.ShortInfo
+ of just started restore. For JSON description see item <emphasis
+ role="bold">/rest/jcr-backup/info/backup</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 403 - the already was restore to workspace /{repo}/{ws}
+status code = 404 - the not found repositry '{repo}' or unsupported encoding to workspaceConfig
+status code = 500 - the other unknown errors
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Default Workspace Information</title>
+
+ <para><emphasis
+ role="bold">/rest/jcr-backup/info/default-ws-config</emphasis> Will be
+ returned the JSON bean to WorkspaceEntry for default workspace.</para>
+
+ <para><emphasis role="bold">URL:</emphasis>
+ <uri>http://host:port/rest/jcr-backup/info/default-ws-config</uri></para>
+
+ <para><emphasis role="bold">Formats:</emphasis> json</para>
+
+ <para><emphasis role="bold">Method</emphasis>: GET</para>
+
+ <para><emphasis role="bold">Parameters:</emphasis> no</para>
+
+ <para><emphasis role="bold">Returns:</emphasis><itemizedlist>
+ <listitem>
+ <para>return when successful</para>
+
+ <para>The JSON bean to
+ org.exoplatform.services.jcr.config.WorkspaceEntry
+ :<programlisting>{ "accessManager" : null,
+ "autoInitPermissions" : null,
+ "autoInitializedRootNt" : null,
+ "cache" : { "parameters" : [ { "name" : "max-size",
+ "value" : "10k"
+ },
+ { "name" : "live-time",
+ "value" : "1h"
+ }
+ ],
+ "type" : "org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl"
+ },
+ "container" : { "parameters" : [ { "name" : "source-name",
+ "value" : "jdbcjcr"
+ },
+ { "name" : "dialect",
+ "value" : "hsqldb"
+ },
+ { "name" : "multi-db",
+ "value" : "false"
+ },
+ { "name" : "update-storage",
+ "value" : "false"
+ },
+ { "name" : "max-buffer-size",
+ "value" : "200k"
+ },
+ { "name" : "swap-directory",
+ "value" : "../temp/swap/production"
+ }
+ ],
+ "type" : "org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer",
+ "valueStorages" : [ { "filters" : [ { "ancestorPath" : null,
+ "minValueSize" : 0,
+ "propertyName" : null,
+ "propertyType" : "Binary"
+ } ],
+ "id" : "system",
+ "parameters" : [ { "name" : "path",
+ "value" : "../temp/values/production"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage"
+ } ]
+ },
+ "initializer" : { "parameters" : [ { "name" : "root-nodetype",
+ "value" : "nt:unstructured"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer"
+ },
+ "lockManager" : { "persister" : { "parameters" : [ { "name" : "path",
+ "value" : "../temp/lock/system"
+ } ],
+ "type" : "org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister"
+ },
+ "timeout" : 15728640
+ },
+ "name" : "production",
+ "queryHandler" : { "analyzer" : { },
+ "autoRepair" : true,
+ "bufferSize" : 10,
+ "cacheSize" : 1000,
+ "documentOrder" : true,
+ "errorLogSize" : 50,
+ "excerptProviderClass" : "org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt",
+ "excludedNodeIdentifers" : null,
+ "extractorBackLogSize" : 100,
+ "extractorPoolSize" : 0,
+ "extractorTimeout" : 100,
+ "indexDir" : "../temp/jcrlucenedb/production",
+ "indexingConfigurationClass" : "org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfigurationImpl",
+ "indexingConfigurationPath" : null,
+ "maxFieldLength" : 10000,
+ "maxMergeDocs" : 2147483647,
+ "mergeFactor" : 10,
+ "minMergeDocs" : 100,
+ "parameters" : [ { "name" : "index-dir",
+ "value" : "../temp/jcrlucenedb/production"
+ } ],
+ "queryClass" : "org.exoplatform.services.jcr.impl.core.query.QueryImpl",
+ "queryHandler" : null,
+ "resultFetchSize" : 2147483647,
+ "rootNodeIdentifer" : "00exo0jcr0root0uuid0000000000000",
+ "spellCheckerClass" : null,
+ "supportHighlighting" : false,
+ "synonymProviderClass" : null,
+ "synonymProviderConfigPath" : null,
+ "type" : "org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex",
+ "useCompoundFile" : false,
+ "volatileIdleTime" : 3
+ },
+ "uniqueName" : "repository_production"
+}</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>return when failure</para>
+
+ <programlisting>status code = 500 - the unknown error
+failure message in response - the description of failure</programlisting>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
+
+ <section>
+ <title>HTTPBackupAgent Configuration</title>
+
+ <para>Add the components
+ org.exoplatform.services.jcr.ext.backup.server.HTTPBackupAgent and
+ org.exoplatform.services.jcr.ext.backup.BackupManager to services
+ configuration :</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.jcr.ext.backup.server.HTTPBackupAgent</type>
+</component>
+
+<component>
+ <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
+ <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
+ <init-params>
+ <properties-param>
+ <name>backup-properties</name>
+ <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental periond = 60 minutes -->
+ <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
+ <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
+ <property name="backup-dir" value="../temp/backup" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Backup Client</title>
+
+ <para>Backup client is console application.</para>
+
+ <para>The backup client is http client for HTTPBackupAgent.</para>
+
+ <para>Command signature:</para>
+
+ <programlisting>Help info:
+ <url> <cmd>
+ <url> : http(s)//login:password@host:port/<context>
+ <cmd> : start <repo/ws> <backup_dir> [<incr>]
+ stop <backup_id>
+ status <backup_id>
+ restores <repo/ws>
+ restore <repo/ws> <backup_id> <pathToConfigFile>
+ list [completed]
+ info
+ drop [force-close-session] <repo/ws>
+ help
+
+ start - start backup
+ stop - stop backup
+ status - information about the current or completed backup by 'backup_id'
+ restores - information about the last restore on specific workspace
+ restore - restore the workspace from specific backup
+ list - information about the current backups (in progress)
+ list completed - information about the completed (ready to restore) backups
+ info - information about the service backup
+ drop - delete the workspace
+ help - print help information about backup console
+
+ <repo/ws> - /<reponsitory-name>/<workspace-name> the workspace
+ <backup_dir> - path to folder for backup on remote server
+ <backup_id> - the identifier for backup
+ <incr> - incemental job period
+ <pathToConfigFile> - path (local) to workspace configuration
+ force-close-session - close opened sessions on workspace.</programlisting>
+ </section>
+
+ <section>
+ <title>Backup Client Usage</title>
+
+ <section>
+ <title>Build application</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>go to folder of "backup client" <emphasis
+ role="bold">../jcr/trunk/applications/java/standalone/backupconsole</emphasis>
+ . - build the application :<programlisting>
+ mvn clean install
+
+</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>go to <emphasis
+ role="bold">../jcr/trunk/applications/java/standalone/backupconsole/target/backupconsole-binary</emphasis>
+ and use it.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Run application</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>run jar<programlisting>java -jar exo.jcr.applications.backupconsole-1.11.1-SNAPSHOT.jar <command>
+</programlisting>or use jcrbackup.cmd (or .sh);</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Get information about backup service</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 info</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>The backup service information :
+ full backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob
+ incremetal backup type : org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob
+ backup log folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ default incremental job period : 3600</programlisting>
+ </section>
+
+ <section>
+ <title>Start full backup</title>
+
+ <para>Start full backup only on workspace "backup", the parameter
+ <bakcup_dir> (../temp/backup) should be exists:</para>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 start /repository/backup ../temp/backup</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Start full and incremental backup on a single workspace</title>
+
+ <para>Start full and incremental backup on workspace
+ "production":</para>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 start /repository/production ../temp/backup 10000</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>Successful :
+ tatus code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Get information about the current backups (in progress)</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 list</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>The current backups information :
+ 1) Backup with id b46370107f000101014b03ea5fbe8d54 :
+ repository name : repository
+ workspace name : production
+ backup type : full + incremetal
+ full backup state : finished
+ incremental backup state : working
+ started time : Fri, 17 Apr 2009 17:03:16 EEST
+ 2) Backup with id b462e4427f00010101cf243b4c6015bb :
+ repository name : repository
+ workspace name : backup
+ backup type : full only
+ full backup state : finished
+ started time : Fri, 17 Apr 2009 17:02:41 EEST</programlisting>
+ </section>
+
+ <section>
+ <title>Get information about the current backup by 'backup_id'</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 status b46370107f000101014b03ea5fbe8d54</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>The current backup information :
+ backup id : b46370107f000101014b03ea5fbe8d54
+ backup folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ repository name : repository
+ workspace name : production
+ backup type : full + incremetal
+ full backup state : finished
+ incremental backup state : working
+ started time : Fri, 17 Apr 2009 17:03:16 EEST</programlisting>
+ </section>
+
+ <section>
+ <title>Stop backup by "backup_id"</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 stop 6c302adc7f00010100df88d29535c6ee</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Get information about the completed (ready to restore)
+ backups</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 list completed</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>The completed (ready to restore) backups information :
+ 1) Backup with id adf6fadc7f00010100053b2cba43513c :
+ repository name : repository
+ workspace name : backup
+ backup type : full only
+ started time : Thu, 16 Apr 2009 11:07:05 EEST
+
+ 2) Backup with id b46370107f000101014b03ea5fbe8d54 :
+ repository name : repository
+ workspace name : production
+ backup type : full + incremetal
+ started time : Fri, 17 Apr 2009 17:03:16 EEST
+
+ 3) Backup with id aec419cc7f000101004aca277b2b4e9f :
+ repository name : repository
+ workspace name : backup8
+ backup type : full only
+ started time : Thu, 16 Apr 2009 14:51:08 EEST</programlisting>
+ </section>
+
+ <section>
+ <title>Restore to workspace</title>
+
+ <para>Restore to workspace "backup3", for restore need the
+ <backup_id> of completed backup and path to file with workspace
+ configuration:</para>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 restore /repository/backup3 6c302adc7f00010100df88d29535c6ee /home/rainf0x/java/exo-working/JCR-839/exo-jcr-config_backup3.xml</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Get information about the current restore</title>
+
+ <para>Get information about the current restore for workspace
+ /repository/backup3:</para>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 restores</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>The current restores information :
+1) Restore with id 6c302adc7f00010100df88d29535c6ee:
+ full backup date : 2009-04-03T16:34:37.394+03:00
+ backup log file : /home/rainf0x/java/exo-working/JCR-839/exo-tomcat/bin/../temp/backup/backup-6c302adc7f00010100df88d29535c6ee.xml
+ repository name : repository
+ workspace name : backup3
+ backup type : full only
+ path to backup folder : /home/rainf0x/java/exo-working/JCR-839/exo-tomcat/bin/../temp/backup
+ restore state : successful</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Full Example for create backup and restore it for workspace
+ 'backup'</title>
+
+ <section>
+ <title>Create backup</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 start /repository/backup ../temp/backup 10000</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Get information about current backups</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 list</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>The current backups information :
+ 1) Backup with id b469ba957f0001010178febaedf20eb7 :
+ repository name : repository
+ workspace name : backup
+ backup type : full + incremetal
+ full backup state : finished
+ incremental backup state : working
+ started time : Fri, 17 Apr 2009 17:10:09 EEST</programlisting>
+ </section>
+
+ <section>
+ <title>Stop backup by id</title>
+
+ <para>Stop backup with id b469ba957f0001010178febaedf20eb7 :</para>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 stop b469ba957f0001010178febaedf20eb7</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Delete the workspace "backup" and close opened sessions on this
+ workspace</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 drop force-close-session /repository/backup</programlisting>
+
+ <para>return :</para>
+
+ <programlisting>Successful :
+ status code = 200</programlisting>
+ </section>
+
+ <section>
+ <title>Restore the workspace "backup"</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>delete/clean the database for workspace <emphasis
+ role="bold">"backup"</emphasis> : When we use "single-db", then we
+ will run the SQL queries for clean database :<programlisting>
+ delete from JCR_SREF where NODE_ID in (select ID from JCR_SITEM where CONTAINER_NAME = 'backup')
+ delete from JCR_SVALUE where PROPERTY_ID in (select ID from JCR_SITEM where CONTAINER_NAME = 'backup')
+ delete from JCR_SITEM where CONTAINER_NAME='backup'
+
+</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>delete the value storage for workspace <emphasis
+ role="bold">"backup"</emphasis>; - delete the index data for
+ workspace <emphasis role="bold">"backup"</emphasis>; - restore
+ :<programlisting>jcrbackup http://root:exo@127.0.0.1:8080 restore /repository/backup b469ba957f0001010178febaedf20eb7 /home/rainf0x/java/exo-working/JCR-839/exo-jcr-config_backup.xml
+</programlisting>return :<programlisting>Successful :
+ status code = 200</programlisting>The
+ /home/rainf0x/java/exo-working/JCR-839/exo-jcr-config_backup.xml
+ content the configuration for restored workspace <emphasis
+ role="bold">"backup"</emphasis> :<programlisting>
+<repository-service default-repository="repository">
+ <repositories>
+ <repository name="repository" system-workspace="production" default-workspace="production">
+ <security-domain>exo-domain</security-domain>
+ <access-control>optional</access-control>
+ <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+ <workspaces>
+
+ <workspace name="backup">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="pgsql" />
+ <property name="multi-db" value="false" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="../temp/swap/backup" />
+ </properties>
+ <value-storages>
+ <value-storage id="draft" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="../temp/values/backup" />
+ </properties>
+ <filters>
+ <filter property-type="Binary"/>
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+ <properties>
+ <property name="max-size" value="10k" />
+ <property name="live-time" value="1h" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="../temp/jcrlucenedb/backup" />
+ </properties>
+ </query-handler>
+ </workspace>
+ </workspaces>
+ </repository>
+ </repositories>
+</repository-service></programlisting></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Get information about restore for workspace
+ /repository/backup</title>
+
+ <programlisting>jcrbackup http://root:exo@127.0.0.1:8080 restores /repository/backup</programlisting>
+
+ <para>return:</para>
+
+ <programlisting>The current restores information :
+ Restore with id b469ba957f0001010178febaedf20eb7:
+ backup folder : /home/rainf0x/java/exo-working/JCR-839/new_JCR/exo-tomcat/bin/../temp/backup
+ repository name : repository
+ workspace name : backup
+ backup type : full + incremetal
+ restore state : successful
+ started time : Fri, 17 Apr 2009 16:38:00 EEST
+ finished time : Fri, 17 Apr 2009 16:38:00 EEST</programlisting>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-03 08:22:26 UTC (rev 2858)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-03 09:43:46 UTC (rev 2859)
@@ -1,480 +1,480 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="JCR.eXoJCRBackupService">
- <?dbhtml filename="ch-exojcr-backup-service.html"?>
-
- <title>eXo JCR Backup Service</title>
-
- <section id="Concept">
- <title>Concept</title>
-
- <para>The main purpose of that feature is to restore data in case of
- system faults and repository crashes. Also the backup results may be used
- as a content history.</para>
-
- <para>The eXo JCR backup service was developed from the JCR 1.8
- implementation. It's an independent service available as an eXo JCR
- Extensions project.</para>
-
- <para>The concept is based on the export of a workspace unit in the Full,
- or Full + Incrementals model. A repository workspace can be backup and
- restored using a combination of these modes. In all cases, at least one
- Full (initial) backup must be executed to mark a starting point of the
- backup history. An Incremental backup is not a complete image of the
- workspace. It contains only changes for some period. So it is not possible
- to perform an Incremental backup without an initial Full backup.</para>
-
- <para>The Backup service may operate as a hot-backup process at runtime on
- an in-use workspace. It's a case when the Full + Incrementals model should
- be used to have a guaranty of data consistency during restoration. An
- Incremental will be run starting from the start point of the Full backup
- and will contain changes that have occured during the Full backup
- too.</para>
-
- <para>A <emphasis role="bold">restore</emphasis> operation is a mirror of
- a backup one. At least one Full backup should be restored to obtain a
- workspace corresponding to some point in time. On the other hand,
- Incrementals may be restored in the order of creation to reach a required
- state of a content. If the Incremental contains the same data as the Full
- backup (hot-backup), the changes will be applied again as if they were
- made in a normal way via API calls.</para>
-
- <para>According to the model there are several modes for backup
- logic:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">Full backup only</emphasis> : single
- operation, runs once</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">Full + Incrementals</emphasis> : Start
- with an initial Full backup and then keep incrementals changes in one
- file. Runs until it is stopped.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">Full + Incrementals(periodic)</emphasis> :
- Start with an initial Full backup and then keep incrementals with
- periodic result file rotation. Runs until it is stopped.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>How it works</title>
-
- <section>
- <title>Implementation details</title>
-
- <para>Full backup/restore is implemented using the JCR SysView
- Export/Import. Workspace data will be exported into Sysview XML data
- from root node.</para>
-
- <para>Restore is implemented using the special eXo JCR API feature: a
- dynamic workspace creation. Restoring of the workspace Full backup will
- create one new workspace in the repository. Then the SysView XML data
- will be imported as the root node.</para>
-
- <para>Incremental backup is implemented using the eXo JCR ChangesLog
- API. This API allows to record each JCR API call as atomic entries in a
- changelog. Hence, the Incremental backup uses a listener that collects
- these logs and stores them in a file.</para>
-
- <para>Restoring an incremental backup consists in applying the collected
- set of ChangesLogs to a workspace in the correct order.</para>
- </section>
-
- <section>
- <title>Work basics</title>
-
- <para>The work of Backup is based on the BackupConfig configuration and
- the BackupChain logical unit.</para>
-
- <para>BackupConfig describes the backup operation chain that will be
- performed by the service. When you intend to work with it, the
- configuration should be prepared before the backup is started.</para>
-
- <para>The configuration contains such values as:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="bold">types of full and incremental
- backup</emphasis> ? (fullBackupType, incrementalBackupType) Strings
- with full names of classes which will cover the type
- functional.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">incremental period</emphasis> - a period
- after that a current backup will be stopped and a new one will be
- started, in seconds (long).</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">target repository and workspace
- names</emphasis> ? Strings with described names</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">destination directory</emphasis> for
- result files ? String with a path to a folder where operation result
- files will be stored.</para>
- </listitem>
- </itemizedlist>
-
- <para>BackupChain is a unit performing the backup process and it covers
- the principle of initial Full backup execution and manages Incrementals
- operations. BackupChain is used as a key object for accessing current
- backups during runtime via BackupManager. Each BackupJob performs a
- single atomic operation ? a Full or Incremental process. The result of
- that operation is data for a Restore. BackupChain can contain one or
- more BackupJobs. But at least the initial Full job is always there. Each
- BackupJobs has its own unique number which means its Job order in the
- chain, the initial Full job always has the number 0.</para>
-
- <para><emphasis role="bold">Backup process, result data and file
- location</emphasis></para>
-
- <para>To start the backup process it's necessary to create the
- BackupConfig and call the BackupManager.startBackup(BackupConfig)
- method. This method will return BackupChain created according to the
- configuration. At the same time the chain creates a BackupChainLog which
- persists BackupConfig content and BackupChain operation states to the
- file in the service working directory (see Configuration).</para>
-
- <para>When the chain starts the work and the initial BackupJob starts,
- the job will create a result data file using the destination directory
- path from BackupConfig. The destination directory will contain a
- directory with an automatically created name using the pattern
- repository_workspace-timestamp where timestamp is current time in the
- format of yyyyMMdd_hhmmss (E.g. db1_ws1-20080306_055404). The directory
- will contain the results of all Jobs configured for execution. Each Job
- stores the backup result in its own file with the name
- repository_workspace-timestamp.jobNumber. BackupChain saves each state
- (STARTING, WAITING, WORKING, FINISHED) of its Jobs in the
- BackupChainLog, which has a current result full file path.</para>
-
- <para>BackupChain log file and job result files are a whole and
- consistent unit, that is a source for a Restore.</para>
-
- <note>
- <para>BackupChain log contains absolute paths to job result files.
- Don't move these files to another location.</para>
- </note>
-
- <para><emphasis role="bold">Restore requirements</emphasis></para>
-
- <para>As mentioned before a Restore operation is a mirror of a Backup.
- The process is a Full restore of a root node with restoring an
- additional Incremental backup to reach a desired workspace state.
- Restoring of the workspace Full backup will create a new workspace in
- the repository using given RepositoyEntry of existing repository and
- given (preconfigured) WorkspaceEntry for a new target workspace. A
- Restore process will restore a root node there from the SysView XML
- data.</para>
-
- <note>
- <para>The target workspace should not be in the repository. Otherwise
- a BackupConfigurationException exception will be thrown.</para>
- </note>
-
- <para>For creation and manipulation with Workspaces check the article
- <link linkend="TODO">Repository and Workspace management</link>.</para>
-
- <para>Finally we may say that a Restore is a process of a new Workspace
- creation and filling it with a Backup content. In case you already have
- a target Workspace (with the same name) in a Repository, you have to
- configure a new name for it. If no target workspace exists in the
- Repository you may use the same name as the Backup one.</para>
- </section>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <para>As an optional extension, the Backup service is not enabled by
- default. <emphasis role="bold">You need to enable it via
- configuration</emphasis>.</para>
-
- <para>Below is an example configuration compatible with JCR 1.9.3 and
- later :</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
- <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
- <init-params>
- <properties-param>
- <name>backup-properties</name>
- <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
- <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
- <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
- <property name="backup-dir" value="target/backup" />
- </properties-param>
- </init-params>
-</component></programlisting>
-
- <para>Where:<itemizedlist>
- <listitem>
- <para><emphasis role="bold">incremental-backup-type</emphasis>
- (since 1.9.3) : the FQN of incremental job class. Must implement
- org.exoplatform.services.jcr.ext.backup.BackupJob</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">full-backup-type</emphasis> (since
- 1.9.3) : the FQN of the full backup job class; Must implement
- org.exoplatform.services.jcr.ext.backup.BackupJob</para>
- </listitem>
-
- <listitem>
- <para><emphasis
- role="bold">default-incremental-job-period</emphasis> (since 1.9.3)
- :the period between incremetal flushes (in seconds)</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="bold">backup-dir</emphasis> : the path to a
- working directory where the service will store internal files and
- chain logs.</para>
- </listitem>
- </itemizedlist></para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <section>
- <title>Perform a Backup</title>
-
- <para>In following example we create a BackupConfig bean for the Full +
- Incrementals mode, then we ask the BackupManager to start the backup
- process.</para>
-
- <programlisting>// Obtaining the backup service from the eXo container.
-BackupManager backup = (BackupManager) container.getComponentInstanceOfType(BackupManager.class);
-
-// And prepare the BackupConfig instance with custom parameters.
-// full backup & incremental
-File backDir = new File("/backup/ws1"); // the destination path for result files
-backDir.mkdirs();
-
-BackupConfig config = new BackupConfig();
-config.setRepository(repository.getName());
-config.setWorkspace("ws1");
-config.setBackupDir(backDir);
-
-// Before 1.9.3, you also need to indicate the backupjobs class FDNs
-// config.setFullBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob");
-// config.setIncrementalBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob");
-
-// start backup using the service manager
-BackupChain chain = backup.startBackup(config);</programlisting>
-
- <para>To stop the backup operation you have to use the BackupChain
- instance.</para>
-
- <programlisting>// stop backup
-backup.stopBackup(chain);</programlisting>
- </section>
-
- <section>
- <title>Perform a Restore</title>
-
- <para>Restoration involves the reloading the backup file into a
- BackupChainLog and applying appropriate workspace initialization. The
- following snippet shows the typical sequence for restoring a workspace
- :</para>
-
- <programlisting>// find BackupChain using the repository and workspace names (return null if not found)
-BackupChain chain = backup.findBackup("db1", "ws1");
-
-// Get the RepositoryEntry and WorkspaceEntry
-ManageableRepository repo = repositoryService.getRepository(repository);
-RepositoryEntry repoconf = repo.getConfiguration();
-List<WorkspaceEntry> entries = repoconf.getWorkspaceEntries();
-WorkspaceEntry = getNewEntry(entries, workspace); // create a copy entry from an existing one
-
-// restore backup log using ready RepositoryEntry and WorkspaceEntry
-File backLog = new File(chain.getLogFilePath());
-BackupChainLog bchLog = new BackupChainLog(backLog);
-
-// initialize the workspace
-repository.configWorkspace(workspaceEntry);
-
-// run restoration
-backup.restore(bchLog, repositoryEntry, workspaceEntry);</programlisting>
-
- <section>
- <title>Restoring into an existing workspace</title>
-
- <note>
- <para>These instructions only applies to regular workspace. Special
- instructions are provided for System workspace below.</para>
- </note>
-
- <para>To restore a backup over an existing workspace, you are required
- to clear its data. Your backup process should follow these steps :
- <itemizedlist>
- <listitem>
- <para>remove workspace<programlisting>ManageableRepository repo = repositoryService.getRepository(repository);
-repo.removeWorkspace(workspace);</programlisting></para>
- </listitem>
-
- <listitem>
- <para>clean database, value storage, index</para>
- </listitem>
-
- <listitem>
- <para>restore (see snippet above)</para>
- </listitem>
- </itemizedlist></para>
- </section>
-
- <section>
- <title>System workspace</title>
-
- <note>
- <para>The BackupWorkspaceInitializer is available in JCR 1.9 and
- later.</para>
- </note>
-
- <para>Restoring the JCR System workspace requires to shutdown the
- system and use of a special initializer.</para>
-
- <para>Follow these steps (this will also work for normal workspaces) :
- <itemizedlist>
- <listitem>
- <para>Stop repository (or portal)</para>
- </listitem>
-
- <listitem>
- <para>clean database, value storage, index; </para>
- </listitem>
-
- <listitem>
- <para>In configuration the workspace set
- BackupWorkspaceInitializer to reference your backup.</para>
-
- <para>For example :<programlisting><workspaces>
- <workspace name="production" ... >
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- ...
- </container>
- <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
- <properties>
- <property name="restore-path" value="D:\java\exo-working\backup\repository_production-20090527_030434"/>
- </properties>
- </initializer>
- ...
-</workspace></programlisting></para>
- </listitem>
-
- <listitem>
- <para>Start repository (or portal).</para>
- </listitem>
- </itemizedlist></para>
- </section>
- </section>
- </section>
-
- <section>
- <title>Scheduling (experimental)</title>
-
- <para>The Backup service has an additional feature that can be useful for
- a production level backup implementation. When you need to organize a
- backup of a repository it's necessary to have a tool which will be able to
- create and manage a cycle of Full and Incremental backups in periodic
- manner.</para>
-
- <para>The service has internal BackupScheduler which can run a
- configurable cycle of BackupChains as if they have been executed by a user
- during some period of time. I.e. BackupScheduler is a user-like daemon
- which asks the BackupManager to start or stop backup operations.</para>
-
- <para>For that purpose BackupScheduler has the method</para>
-
- <para>BackupScheduler.schedule(backupConfig, startDate, stopDate,
- chainPeriod, incrementalPeriod)</para>
-
- <para>where</para>
-
- <itemizedlist>
- <listitem>
- <para>backupConfig - a ready configuration which will be given to the
- BackupManager.startBackup() method</para>
- </listitem>
-
- <listitem>
- <para>startDate - a date and time of the backup start</para>
- </listitem>
-
- <listitem>
- <para>stopDate - a date and time of the backup stop</para>
- </listitem>
-
- <listitem>
- <para>chainPeriod - a period after which a current BackupChain will be
- stopped and a new one will be started, in seconds</para>
- </listitem>
-
- <listitem>
- <para>incrementalPeriod - if it is greater than 0 it will be used to
- override the same value in backupConfig.</para>
- </listitem>
- </itemizedlist>
-
- <programlisting>// geting the scheduler from the BackupManager
- BackupScheduler scheduler = backup.getScheduler();
-
-// schedule backup using a ready configuration (Full + Incrementals) to run from startTime
-// to stopTime. Full backuop will be performed every 24 hours (BackupChain lifecycle),
-// incremental will rotate result files every 3 hours.
- scheduler.schedule(config, startTime, stopTime, 3600 * 24, 3600 * 3);
-
-// it's possible to run the scheduler for an uncertain period of time (i.e. without stop time).
-// schedule backup to run from startTime till it will be stopped manually
-// also there, the incremental will rotate result files as it configured in BackupConfig
- scheduler.schedule(config, startTime, null, 3600 * 24, 0);
-
-// to unschedule backup simply call the scheduler with the configuration describing the
-// already planned backup cycle.
-// the scheduler will search in internal tasks list for task with repository and
-// workspace name from the configuration and will stop that task.
- scheduler.unschedule(config);</programlisting>
-
- <para>When the BackupScheduler starts the scheduling, it uses the internal
- Timer with startDate for the first (or just once) execution. If
- chainPeriod is greater than 0 then the task is repeated with this value
- used as a period starting from startDate. Otherwise the task will be
- executed once at startDate time. If the scheduler has stopDate it will
- stop the task ( the chain cycle) after stopDate. And the last parameter
- incrementalPeriod will be used instead of the same from BackupConfig if
- its values are greater than 0.</para>
-
- <para>Starting each task (BackupScheduler.schedule(...)), the scheduler
- creates a task file in the service working directory (see <emphasis
- role="bold">Configuration</emphasis>, backup-dir) which describes the task
- backup configuration and periodic values. These files will be used at the
- backup service start (JVM start) to reinitialize BackupScheduler for
- continuous task scheduling. Only tasks that don't have a stopDate or a
- stopDate not expired will be reinitialized.</para>
-
- <para>There is one notice about BackupScheduler task reinitialization in
- the current implementation. It comes from the BackupScheduler nature and
- its implemented behaviour. As the scheduler is just a virtual user which
- asks the BackupManager to start or stop backup operations, it isn't able
- to reinitialize each existing BackupChain before the service (JVM) is
- stopped. But it's possible to start a new operation with the same
- configuration via BackupManager (that was configured before and stored in
- a task file).</para>
-
- <para>This is a main detail of the BackupScheduler which should be taken
- into suggestion of a backup operation design now. In case of
- reinitialization the task will have new time values for the backup
- operation cycle as the chainPeriod and incrementalPeriod will be applied
- again. That behaviour may be changed in the future.</para>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.BackupService">
+ <?dbhtml filename="ch-exojcr-backup-service.html"?>
+
+ <title>eXo JCR Backup Service</title>
+
+ <section id="Concept">
+ <title>Concept</title>
+
+ <para>The main purpose of that feature is to restore data in case of
+ system faults and repository crashes. Also the backup results may be used
+ as a content history.</para>
+
+ <para>The eXo JCR backup service was developed from the JCR 1.8
+ implementation. It's an independent service available as an eXo JCR
+ Extensions project.</para>
+
+ <para>The concept is based on the export of a workspace unit in the Full,
+ or Full + Incrementals model. A repository workspace can be backup and
+ restored using a combination of these modes. In all cases, at least one
+ Full (initial) backup must be executed to mark a starting point of the
+ backup history. An Incremental backup is not a complete image of the
+ workspace. It contains only changes for some period. So it is not possible
+ to perform an Incremental backup without an initial Full backup.</para>
+
+ <para>The Backup service may operate as a hot-backup process at runtime on
+ an in-use workspace. It's a case when the Full + Incrementals model should
+ be used to have a guaranty of data consistency during restoration. An
+ Incremental will be run starting from the start point of the Full backup
+ and will contain changes that have occured during the Full backup
+ too.</para>
+
+ <para>A <emphasis role="bold">restore</emphasis> operation is a mirror of
+ a backup one. At least one Full backup should be restored to obtain a
+ workspace corresponding to some point in time. On the other hand,
+ Incrementals may be restored in the order of creation to reach a required
+ state of a content. If the Incremental contains the same data as the Full
+ backup (hot-backup), the changes will be applied again as if they were
+ made in a normal way via API calls.</para>
+
+ <para>According to the model there are several modes for backup
+ logic:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Full backup only</emphasis> : single
+ operation, runs once</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals</emphasis> : Start
+ with an initial Full backup and then keep incrementals changes in one
+ file. Runs until it is stopped.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals(periodic)</emphasis> :
+ Start with an initial Full backup and then keep incrementals with
+ periodic result file rotation. Runs until it is stopped.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How it works</title>
+
+ <section>
+ <title>Implementation details</title>
+
+ <para>Full backup/restore is implemented using the JCR SysView
+ Export/Import. Workspace data will be exported into Sysview XML data
+ from root node.</para>
+
+ <para>Restore is implemented using the special eXo JCR API feature: a
+ dynamic workspace creation. Restoring of the workspace Full backup will
+ create one new workspace in the repository. Then the SysView XML data
+ will be imported as the root node.</para>
+
+ <para>Incremental backup is implemented using the eXo JCR ChangesLog
+ API. This API allows to record each JCR API call as atomic entries in a
+ changelog. Hence, the Incremental backup uses a listener that collects
+ these logs and stores them in a file.</para>
+
+ <para>Restoring an incremental backup consists in applying the collected
+ set of ChangesLogs to a workspace in the correct order.</para>
+ </section>
+
+ <section>
+ <title>Work basics</title>
+
+ <para>The work of Backup is based on the BackupConfig configuration and
+ the BackupChain logical unit.</para>
+
+ <para>BackupConfig describes the backup operation chain that will be
+ performed by the service. When you intend to work with it, the
+ configuration should be prepared before the backup is started.</para>
+
+ <para>The configuration contains such values as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">types of full and incremental
+ backup</emphasis> ? (fullBackupType, incrementalBackupType) Strings
+ with full names of classes which will cover the type
+ functional.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">incremental period</emphasis> - a period
+ after that a current backup will be stopped and a new one will be
+ started, in seconds (long).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">target repository and workspace
+ names</emphasis> ? Strings with described names</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">destination directory</emphasis> for
+ result files ? String with a path to a folder where operation result
+ files will be stored.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>BackupChain is a unit performing the backup process and it covers
+ the principle of initial Full backup execution and manages Incrementals
+ operations. BackupChain is used as a key object for accessing current
+ backups during runtime via BackupManager. Each BackupJob performs a
+ single atomic operation ? a Full or Incremental process. The result of
+ that operation is data for a Restore. BackupChain can contain one or
+ more BackupJobs. But at least the initial Full job is always there. Each
+ BackupJobs has its own unique number which means its Job order in the
+ chain, the initial Full job always has the number 0.</para>
+
+ <para><emphasis role="bold">Backup process, result data and file
+ location</emphasis></para>
+
+ <para>To start the backup process it's necessary to create the
+ BackupConfig and call the BackupManager.startBackup(BackupConfig)
+ method. This method will return BackupChain created according to the
+ configuration. At the same time the chain creates a BackupChainLog which
+ persists BackupConfig content and BackupChain operation states to the
+ file in the service working directory (see Configuration).</para>
+
+ <para>When the chain starts the work and the initial BackupJob starts,
+ the job will create a result data file using the destination directory
+ path from BackupConfig. The destination directory will contain a
+ directory with an automatically created name using the pattern
+ repository_workspace-timestamp where timestamp is current time in the
+ format of yyyyMMdd_hhmmss (E.g. db1_ws1-20080306_055404). The directory
+ will contain the results of all Jobs configured for execution. Each Job
+ stores the backup result in its own file with the name
+ repository_workspace-timestamp.jobNumber. BackupChain saves each state
+ (STARTING, WAITING, WORKING, FINISHED) of its Jobs in the
+ BackupChainLog, which has a current result full file path.</para>
+
+ <para>BackupChain log file and job result files are a whole and
+ consistent unit, that is a source for a Restore.</para>
+
+ <note>
+ <para>BackupChain log contains absolute paths to job result files.
+ Don't move these files to another location.</para>
+ </note>
+
+ <para><emphasis role="bold">Restore requirements</emphasis></para>
+
+ <para>As mentioned before a Restore operation is a mirror of a Backup.
+ The process is a Full restore of a root node with restoring an
+ additional Incremental backup to reach a desired workspace state.
+ Restoring of the workspace Full backup will create a new workspace in
+ the repository using given RepositoyEntry of existing repository and
+ given (preconfigured) WorkspaceEntry for a new target workspace. A
+ Restore process will restore a root node there from the SysView XML
+ data.</para>
+
+ <note>
+ <para>The target workspace should not be in the repository. Otherwise
+ a BackupConfigurationException exception will be thrown.</para>
+ </note>
+
+ <para>For creation and manipulation with Workspaces check the article
+ <link linkend="TODO">Repository and Workspace management</link>.</para>
+
+ <para>Finally we may say that a Restore is a process of a new Workspace
+ creation and filling it with a Backup content. In case you already have
+ a target Workspace (with the same name) in a Repository, you have to
+ configure a new name for it. If no target workspace exists in the
+ Repository you may use the same name as the Backup one.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>As an optional extension, the Backup service is not enabled by
+ default. <emphasis role="bold">You need to enable it via
+ configuration</emphasis>.</para>
+
+ <para>Below is an example configuration compatible with JCR 1.9.3 and
+ later :</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
+ <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
+ <init-params>
+ <properties-param>
+ <name>backup-properties</name>
+ <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
+ <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
+ <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
+ <property name="backup-dir" value="target/backup" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para>Where:<itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">incremental-backup-type</emphasis>
+ (since 1.9.3) : the FQN of incremental job class. Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">full-backup-type</emphasis> (since
+ 1.9.3) : the FQN of the full backup job class; Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis
+ role="bold">default-incremental-job-period</emphasis> (since 1.9.3)
+ :the period between incremetal flushes (in seconds)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">backup-dir</emphasis> : the path to a
+ working directory where the service will store internal files and
+ chain logs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <section>
+ <title>Perform a Backup</title>
+
+ <para>In following example we create a BackupConfig bean for the Full +
+ Incrementals mode, then we ask the BackupManager to start the backup
+ process.</para>
+
+ <programlisting>// Obtaining the backup service from the eXo container.
+BackupManager backup = (BackupManager) container.getComponentInstanceOfType(BackupManager.class);
+
+// And prepare the BackupConfig instance with custom parameters.
+// full backup & incremental
+File backDir = new File("/backup/ws1"); // the destination path for result files
+backDir.mkdirs();
+
+BackupConfig config = new BackupConfig();
+config.setRepository(repository.getName());
+config.setWorkspace("ws1");
+config.setBackupDir(backDir);
+
+// Before 1.9.3, you also need to indicate the backupjobs class FDNs
+// config.setFullBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob");
+// config.setIncrementalBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob");
+
+// start backup using the service manager
+BackupChain chain = backup.startBackup(config);</programlisting>
+
+ <para>To stop the backup operation you have to use the BackupChain
+ instance.</para>
+
+ <programlisting>// stop backup
+backup.stopBackup(chain);</programlisting>
+ </section>
+
+ <section>
+ <title>Perform a Restore</title>
+
+ <para>Restoration involves the reloading the backup file into a
+ BackupChainLog and applying appropriate workspace initialization. The
+ following snippet shows the typical sequence for restoring a workspace
+ :</para>
+
+ <programlisting>// find BackupChain using the repository and workspace names (return null if not found)
+BackupChain chain = backup.findBackup("db1", "ws1");
+
+// Get the RepositoryEntry and WorkspaceEntry
+ManageableRepository repo = repositoryService.getRepository(repository);
+RepositoryEntry repoconf = repo.getConfiguration();
+List<WorkspaceEntry> entries = repoconf.getWorkspaceEntries();
+WorkspaceEntry = getNewEntry(entries, workspace); // create a copy entry from an existing one
+
+// restore backup log using ready RepositoryEntry and WorkspaceEntry
+File backLog = new File(chain.getLogFilePath());
+BackupChainLog bchLog = new BackupChainLog(backLog);
+
+// initialize the workspace
+repository.configWorkspace(workspaceEntry);
+
+// run restoration
+backup.restore(bchLog, repositoryEntry, workspaceEntry);</programlisting>
+
+ <section>
+ <title>Restoring into an existing workspace</title>
+
+ <note>
+ <para>These instructions only applies to regular workspace. Special
+ instructions are provided for System workspace below.</para>
+ </note>
+
+ <para>To restore a backup over an existing workspace, you are required
+ to clear its data. Your backup process should follow these steps :
+ <itemizedlist>
+ <listitem>
+ <para>remove workspace<programlisting>ManageableRepository repo = repositoryService.getRepository(repository);
+repo.removeWorkspace(workspace);</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index</para>
+ </listitem>
+
+ <listitem>
+ <para>restore (see snippet above)</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>System workspace</title>
+
+ <note>
+ <para>The BackupWorkspaceInitializer is available in JCR 1.9 and
+ later.</para>
+ </note>
+
+ <para>Restoring the JCR System workspace requires to shutdown the
+ system and use of a special initializer.</para>
+
+ <para>Follow these steps (this will also work for normal workspaces) :
+ <itemizedlist>
+ <listitem>
+ <para>Stop repository (or portal)</para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index; </para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration the workspace set
+ BackupWorkspaceInitializer to reference your backup.</para>
+
+ <para>For example :<programlisting><workspaces>
+ <workspace name="production" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_production-20090527_030434"/>
+ </properties>
+ </initializer>
+ ...
+</workspace></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository (or portal).</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Scheduling (experimental)</title>
+
+ <para>The Backup service has an additional feature that can be useful for
+ a production level backup implementation. When you need to organize a
+ backup of a repository it's necessary to have a tool which will be able to
+ create and manage a cycle of Full and Incremental backups in periodic
+ manner.</para>
+
+ <para>The service has internal BackupScheduler which can run a
+ configurable cycle of BackupChains as if they have been executed by a user
+ during some period of time. I.e. BackupScheduler is a user-like daemon
+ which asks the BackupManager to start or stop backup operations.</para>
+
+ <para>For that purpose BackupScheduler has the method</para>
+
+ <para>BackupScheduler.schedule(backupConfig, startDate, stopDate,
+ chainPeriod, incrementalPeriod)</para>
+
+ <para>where</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>backupConfig - a ready configuration which will be given to the
+ BackupManager.startBackup() method</para>
+ </listitem>
+
+ <listitem>
+ <para>startDate - a date and time of the backup start</para>
+ </listitem>
+
+ <listitem>
+ <para>stopDate - a date and time of the backup stop</para>
+ </listitem>
+
+ <listitem>
+ <para>chainPeriod - a period after which a current BackupChain will be
+ stopped and a new one will be started, in seconds</para>
+ </listitem>
+
+ <listitem>
+ <para>incrementalPeriod - if it is greater than 0 it will be used to
+ override the same value in backupConfig.</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>// geting the scheduler from the BackupManager
+ BackupScheduler scheduler = backup.getScheduler();
+
+// schedule backup using a ready configuration (Full + Incrementals) to run from startTime
+// to stopTime. Full backuop will be performed every 24 hours (BackupChain lifecycle),
+// incremental will rotate result files every 3 hours.
+ scheduler.schedule(config, startTime, stopTime, 3600 * 24, 3600 * 3);
+
+// it's possible to run the scheduler for an uncertain period of time (i.e. without stop time).
+// schedule backup to run from startTime till it will be stopped manually
+// also there, the incremental will rotate result files as it configured in BackupConfig
+ scheduler.schedule(config, startTime, null, 3600 * 24, 0);
+
+// to unschedule backup simply call the scheduler with the configuration describing the
+// already planned backup cycle.
+// the scheduler will search in internal tasks list for task with repository and
+// workspace name from the configuration and will stop that task.
+ scheduler.unschedule(config);</programlisting>
+
+ <para>When the BackupScheduler starts the scheduling, it uses the internal
+ Timer with startDate for the first (or just once) execution. If
+ chainPeriod is greater than 0 then the task is repeated with this value
+ used as a period starting from startDate. Otherwise the task will be
+ executed once at startDate time. If the scheduler has stopDate it will
+ stop the task ( the chain cycle) after stopDate. And the last parameter
+ incrementalPeriod will be used instead of the same from BackupConfig if
+ its values are greater than 0.</para>
+
+ <para>Starting each task (BackupScheduler.schedule(...)), the scheduler
+ creates a task file in the service working directory (see <emphasis
+ role="bold">Configuration</emphasis>, backup-dir) which describes the task
+ backup configuration and periodic values. These files will be used at the
+ backup service start (JVM start) to reinitialize BackupScheduler for
+ continuous task scheduling. Only tasks that don't have a stopDate or a
+ stopDate not expired will be reinitialized.</para>
+
+ <para>There is one notice about BackupScheduler task reinitialization in
+ the current implementation. It comes from the BackupScheduler nature and
+ its implemented behaviour. As the scheduler is just a virtual user which
+ asks the BackupManager to start or stop backup operations, it isn't able
+ to reinitialize each existing BackupChain before the service (JVM) is
+ stopped. But it's possible to start a new operation with the same
+ configuration via BackupManager (that was configured before and stored in
+ a task file).</para>
+
+ <para>This is a main detail of the BackupScheduler which should be taken
+ into suggestion of a backup operation design now. In case of
+ reinitialization the task will have new time values for the backup
+ operation cycle as the chainPeriod and incrementalPeriod will be applied
+ again. That behaviour may be changed in the future.</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/search-index-backup.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/search-index-backup.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/search-index-backup.xml 2010-08-03 09:43:46 UTC (rev 2859)
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.SearchIndexBackup">
+ <?dbhtml filename="ch-search-index-backup.html"?>
+
+ <title>Search index backup</title>
+
+ <section>
+ <title>Manual backup (file copy)</title>
+
+ <para>It can be useful for some reason. The backup may be performed
+ manually or using third part software.</para>
+
+ <para>You can make a copy of the search index ($AS_HOME/temp/jcrlucenedb).
+ And use it to replace the current index by this copy in case of an index
+ damage or lost.</para>
+
+ <para>All repository changes that are applied between the index backup and
+ the point of time when the backup index is restored, are not in the index
+ and those modifications will not be found when searching. The
+ modifications exist in the repository, but do not exist in the search
+ index. <emphasis role="bold">And those changes will not be automatically
+ reindexed.</emphasis></para>
+
+ <para>For example: You have configured the workspace index to be in the
+ "/index/workspace" directory.<itemizedlist>
+ <listitem>
+ <para>make a backup of the search index - copy the content of the
+ "/index" directory;</para>
+ </listitem>
+
+ <listitem>
+ <para>add the node "/anynode" to the workspace. Now this node exists
+ in the workspace database and the search index has information about
+ this node, so you can find it using query <code>select * from
+ nt:base where jcr:path="/anynode"</code>;</para>
+ </listitem>
+
+ <listitem>
+ <para>rollback to the last backup - replace current
+ "/index/workspace" directory by the backup;</para>
+ </listitem>
+
+ <listitem>
+ <para>node "/anynode" still exists and is accessible in the
+ workspace (Session.getItem("/anynode")), but you can't find it via
+ the search query<code> select * from nt:base where
+ jcr:path="/anynode"</code>;</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>If you want to find changes made after update you have to reindex
+ whole workspace content. One way to do this is to stop the repository
+ container and delete the "/index/workspace" folder. The workspace database
+ content will be reindexed on repository startup.</para>
+ </section>
+
+ <section>
+ <title>Consistency Requirements</title>
+
+ <para>To have the workspace content consistent with the search index, the
+ workspace database and the index directory should correspond to the same
+ state. In case of an external (manual) backup <emphasis>the database
+ backup and the index directory backup should be performed on a
+ stopped/unmodifiable repository</emphasis>.</para>
+
+ <para><emphasis role="bold">Only in that case the repository content and
+ the search index will be consistent.</emphasis></para>
+ </section>
+
+ <section>
+ <title>JCR Backup Service</title>
+
+ <para>To get a hot-backup, which is executed on the fly, it's possible to
+ use the <link linkend="JCR.BackupService">Backup service</link> which is
+ available as a JCR Extension.</para>
+
+ <note>
+ <para>Backup service supports full and incremental backup types. A
+ Scheduler is available.</para>
+ </note>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-03 08:22:26 UTC (rev 2858)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-03 09:43:46 UTC (rev 2859)
@@ -38,7 +38,7 @@
</itemizedlist>
</section>
- <section>
+ <section id ="JCR.eXoJCRconfiguration.PortalAndStandaloneConfiguration">
<title>Portal and Standalone configuration</title>
<para>Like other eXo services eXo JCR can be configured and used in portal
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 08:22:26 UTC (rev 2858)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 09:43:46 UTC (rev 2859)
@@ -110,8 +110,10 @@
<!-- backup -->
<xi:include href="jcr/backup/exojcr-backup-service.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <!--xi:include href="jcr/backup/backup-client.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" /-->
+ <xi:include href="jcr/backup/backup-client.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="jcr/backup/search-index-backup.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
15 years, 11 months
exo-jcr SVN: r2858 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules: jcr and 1 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-03 04:22:26 -0400 (Tue, 03 Aug 2010)
New Revision: 2858
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-869: backup documents ported
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2010-08-03 08:22:26 UTC (rev 2858)
@@ -0,0 +1,480 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.eXoJCRBackupService">
+ <?dbhtml filename="ch-exojcr-backup-service.html"?>
+
+ <title>eXo JCR Backup Service</title>
+
+ <section id="Concept">
+ <title>Concept</title>
+
+ <para>The main purpose of that feature is to restore data in case of
+ system faults and repository crashes. Also the backup results may be used
+ as a content history.</para>
+
+ <para>The eXo JCR backup service was developed from the JCR 1.8
+ implementation. It's an independent service available as an eXo JCR
+ Extensions project.</para>
+
+ <para>The concept is based on the export of a workspace unit in the Full,
+ or Full + Incrementals model. A repository workspace can be backup and
+ restored using a combination of these modes. In all cases, at least one
+ Full (initial) backup must be executed to mark a starting point of the
+ backup history. An Incremental backup is not a complete image of the
+ workspace. It contains only changes for some period. So it is not possible
+ to perform an Incremental backup without an initial Full backup.</para>
+
+ <para>The Backup service may operate as a hot-backup process at runtime on
+ an in-use workspace. It's a case when the Full + Incrementals model should
+ be used to have a guaranty of data consistency during restoration. An
+ Incremental will be run starting from the start point of the Full backup
+ and will contain changes that have occured during the Full backup
+ too.</para>
+
+ <para>A <emphasis role="bold">restore</emphasis> operation is a mirror of
+ a backup one. At least one Full backup should be restored to obtain a
+ workspace corresponding to some point in time. On the other hand,
+ Incrementals may be restored in the order of creation to reach a required
+ state of a content. If the Incremental contains the same data as the Full
+ backup (hot-backup), the changes will be applied again as if they were
+ made in a normal way via API calls.</para>
+
+ <para>According to the model there are several modes for backup
+ logic:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Full backup only</emphasis> : single
+ operation, runs once</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals</emphasis> : Start
+ with an initial Full backup and then keep incrementals changes in one
+ file. Runs until it is stopped.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">Full + Incrementals(periodic)</emphasis> :
+ Start with an initial Full backup and then keep incrementals with
+ periodic result file rotation. Runs until it is stopped.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>How it works</title>
+
+ <section>
+ <title>Implementation details</title>
+
+ <para>Full backup/restore is implemented using the JCR SysView
+ Export/Import. Workspace data will be exported into Sysview XML data
+ from root node.</para>
+
+ <para>Restore is implemented using the special eXo JCR API feature: a
+ dynamic workspace creation. Restoring of the workspace Full backup will
+ create one new workspace in the repository. Then the SysView XML data
+ will be imported as the root node.</para>
+
+ <para>Incremental backup is implemented using the eXo JCR ChangesLog
+ API. This API allows to record each JCR API call as atomic entries in a
+ changelog. Hence, the Incremental backup uses a listener that collects
+ these logs and stores them in a file.</para>
+
+ <para>Restoring an incremental backup consists in applying the collected
+ set of ChangesLogs to a workspace in the correct order.</para>
+ </section>
+
+ <section>
+ <title>Work basics</title>
+
+ <para>The work of Backup is based on the BackupConfig configuration and
+ the BackupChain logical unit.</para>
+
+ <para>BackupConfig describes the backup operation chain that will be
+ performed by the service. When you intend to work with it, the
+ configuration should be prepared before the backup is started.</para>
+
+ <para>The configuration contains such values as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">types of full and incremental
+ backup</emphasis> ? (fullBackupType, incrementalBackupType) Strings
+ with full names of classes which will cover the type
+ functional.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">incremental period</emphasis> - a period
+ after that a current backup will be stopped and a new one will be
+ started, in seconds (long).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">target repository and workspace
+ names</emphasis> ? Strings with described names</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">destination directory</emphasis> for
+ result files ? String with a path to a folder where operation result
+ files will be stored.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>BackupChain is a unit performing the backup process and it covers
+ the principle of initial Full backup execution and manages Incrementals
+ operations. BackupChain is used as a key object for accessing current
+ backups during runtime via BackupManager. Each BackupJob performs a
+ single atomic operation ? a Full or Incremental process. The result of
+ that operation is data for a Restore. BackupChain can contain one or
+ more BackupJobs. But at least the initial Full job is always there. Each
+ BackupJobs has its own unique number which means its Job order in the
+ chain, the initial Full job always has the number 0.</para>
+
+ <para><emphasis role="bold">Backup process, result data and file
+ location</emphasis></para>
+
+ <para>To start the backup process it's necessary to create the
+ BackupConfig and call the BackupManager.startBackup(BackupConfig)
+ method. This method will return BackupChain created according to the
+ configuration. At the same time the chain creates a BackupChainLog which
+ persists BackupConfig content and BackupChain operation states to the
+ file in the service working directory (see Configuration).</para>
+
+ <para>When the chain starts the work and the initial BackupJob starts,
+ the job will create a result data file using the destination directory
+ path from BackupConfig. The destination directory will contain a
+ directory with an automatically created name using the pattern
+ repository_workspace-timestamp where timestamp is current time in the
+ format of yyyyMMdd_hhmmss (E.g. db1_ws1-20080306_055404). The directory
+ will contain the results of all Jobs configured for execution. Each Job
+ stores the backup result in its own file with the name
+ repository_workspace-timestamp.jobNumber. BackupChain saves each state
+ (STARTING, WAITING, WORKING, FINISHED) of its Jobs in the
+ BackupChainLog, which has a current result full file path.</para>
+
+ <para>BackupChain log file and job result files are a whole and
+ consistent unit, that is a source for a Restore.</para>
+
+ <note>
+ <para>BackupChain log contains absolute paths to job result files.
+ Don't move these files to another location.</para>
+ </note>
+
+ <para><emphasis role="bold">Restore requirements</emphasis></para>
+
+ <para>As mentioned before a Restore operation is a mirror of a Backup.
+ The process is a Full restore of a root node with restoring an
+ additional Incremental backup to reach a desired workspace state.
+ Restoring of the workspace Full backup will create a new workspace in
+ the repository using given RepositoyEntry of existing repository and
+ given (preconfigured) WorkspaceEntry for a new target workspace. A
+ Restore process will restore a root node there from the SysView XML
+ data.</para>
+
+ <note>
+ <para>The target workspace should not be in the repository. Otherwise
+ a BackupConfigurationException exception will be thrown.</para>
+ </note>
+
+ <para>For creation and manipulation with Workspaces check the article
+ <link linkend="TODO">Repository and Workspace management</link>.</para>
+
+ <para>Finally we may say that a Restore is a process of a new Workspace
+ creation and filling it with a Backup content. In case you already have
+ a target Workspace (with the same name) in a Repository, you have to
+ configure a new name for it. If no target workspace exists in the
+ Repository you may use the same name as the Backup one.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>As an optional extension, the Backup service is not enabled by
+ default. <emphasis role="bold">You need to enable it via
+ configuration</emphasis>.</para>
+
+ <para>Below is an example configuration compatible with JCR 1.9.3 and
+ later :</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>
+ <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>
+ <init-params>
+ <properties-param>
+ <name>backup-properties</name>
+ <property name="default-incremental-job-period" value="3600" /> <!-- set default incremental period = 60 minutes -->
+ <property name="full-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob" />
+ <property name="incremental-backup-type" value="org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob" />
+ <property name="backup-dir" value="target/backup" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para>Where:<itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">incremental-backup-type</emphasis>
+ (since 1.9.3) : the FQN of incremental job class. Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">full-backup-type</emphasis> (since
+ 1.9.3) : the FQN of the full backup job class; Must implement
+ org.exoplatform.services.jcr.ext.backup.BackupJob</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis
+ role="bold">default-incremental-job-period</emphasis> (since 1.9.3)
+ :the period between incremetal flushes (in seconds)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="bold">backup-dir</emphasis> : the path to a
+ working directory where the service will store internal files and
+ chain logs.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <section>
+ <title>Perform a Backup</title>
+
+ <para>In following example we create a BackupConfig bean for the Full +
+ Incrementals mode, then we ask the BackupManager to start the backup
+ process.</para>
+
+ <programlisting>// Obtaining the backup service from the eXo container.
+BackupManager backup = (BackupManager) container.getComponentInstanceOfType(BackupManager.class);
+
+// And prepare the BackupConfig instance with custom parameters.
+// full backup & incremental
+File backDir = new File("/backup/ws1"); // the destination path for result files
+backDir.mkdirs();
+
+BackupConfig config = new BackupConfig();
+config.setRepository(repository.getName());
+config.setWorkspace("ws1");
+config.setBackupDir(backDir);
+
+// Before 1.9.3, you also need to indicate the backupjobs class FDNs
+// config.setFullBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob");
+// config.setIncrementalBackupType("org.exoplatform.services.jcr.ext.backup.impl.fs.IncrementalBackupJob");
+
+// start backup using the service manager
+BackupChain chain = backup.startBackup(config);</programlisting>
+
+ <para>To stop the backup operation you have to use the BackupChain
+ instance.</para>
+
+ <programlisting>// stop backup
+backup.stopBackup(chain);</programlisting>
+ </section>
+
+ <section>
+ <title>Perform a Restore</title>
+
+ <para>Restoration involves the reloading the backup file into a
+ BackupChainLog and applying appropriate workspace initialization. The
+ following snippet shows the typical sequence for restoring a workspace
+ :</para>
+
+ <programlisting>// find BackupChain using the repository and workspace names (return null if not found)
+BackupChain chain = backup.findBackup("db1", "ws1");
+
+// Get the RepositoryEntry and WorkspaceEntry
+ManageableRepository repo = repositoryService.getRepository(repository);
+RepositoryEntry repoconf = repo.getConfiguration();
+List<WorkspaceEntry> entries = repoconf.getWorkspaceEntries();
+WorkspaceEntry = getNewEntry(entries, workspace); // create a copy entry from an existing one
+
+// restore backup log using ready RepositoryEntry and WorkspaceEntry
+File backLog = new File(chain.getLogFilePath());
+BackupChainLog bchLog = new BackupChainLog(backLog);
+
+// initialize the workspace
+repository.configWorkspace(workspaceEntry);
+
+// run restoration
+backup.restore(bchLog, repositoryEntry, workspaceEntry);</programlisting>
+
+ <section>
+ <title>Restoring into an existing workspace</title>
+
+ <note>
+ <para>These instructions only applies to regular workspace. Special
+ instructions are provided for System workspace below.</para>
+ </note>
+
+ <para>To restore a backup over an existing workspace, you are required
+ to clear its data. Your backup process should follow these steps :
+ <itemizedlist>
+ <listitem>
+ <para>remove workspace<programlisting>ManageableRepository repo = repositoryService.getRepository(repository);
+repo.removeWorkspace(workspace);</programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index</para>
+ </listitem>
+
+ <listitem>
+ <para>restore (see snippet above)</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>System workspace</title>
+
+ <note>
+ <para>The BackupWorkspaceInitializer is available in JCR 1.9 and
+ later.</para>
+ </note>
+
+ <para>Restoring the JCR System workspace requires to shutdown the
+ system and use of a special initializer.</para>
+
+ <para>Follow these steps (this will also work for normal workspaces) :
+ <itemizedlist>
+ <listitem>
+ <para>Stop repository (or portal)</para>
+ </listitem>
+
+ <listitem>
+ <para>clean database, value storage, index; </para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration the workspace set
+ BackupWorkspaceInitializer to reference your backup.</para>
+
+ <para>For example :<programlisting><workspaces>
+ <workspace name="production" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_production-20090527_030434"/>
+ </properties>
+ </initializer>
+ ...
+</workspace></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository (or portal).</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Scheduling (experimental)</title>
+
+ <para>The Backup service has an additional feature that can be useful for
+ a production level backup implementation. When you need to organize a
+ backup of a repository it's necessary to have a tool which will be able to
+ create and manage a cycle of Full and Incremental backups in periodic
+ manner.</para>
+
+ <para>The service has internal BackupScheduler which can run a
+ configurable cycle of BackupChains as if they have been executed by a user
+ during some period of time. I.e. BackupScheduler is a user-like daemon
+ which asks the BackupManager to start or stop backup operations.</para>
+
+ <para>For that purpose BackupScheduler has the method</para>
+
+ <para>BackupScheduler.schedule(backupConfig, startDate, stopDate,
+ chainPeriod, incrementalPeriod)</para>
+
+ <para>where</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>backupConfig - a ready configuration which will be given to the
+ BackupManager.startBackup() method</para>
+ </listitem>
+
+ <listitem>
+ <para>startDate - a date and time of the backup start</para>
+ </listitem>
+
+ <listitem>
+ <para>stopDate - a date and time of the backup stop</para>
+ </listitem>
+
+ <listitem>
+ <para>chainPeriod - a period after which a current BackupChain will be
+ stopped and a new one will be started, in seconds</para>
+ </listitem>
+
+ <listitem>
+ <para>incrementalPeriod - if it is greater than 0 it will be used to
+ override the same value in backupConfig.</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>// geting the scheduler from the BackupManager
+ BackupScheduler scheduler = backup.getScheduler();
+
+// schedule backup using a ready configuration (Full + Incrementals) to run from startTime
+// to stopTime. Full backuop will be performed every 24 hours (BackupChain lifecycle),
+// incremental will rotate result files every 3 hours.
+ scheduler.schedule(config, startTime, stopTime, 3600 * 24, 3600 * 3);
+
+// it's possible to run the scheduler for an uncertain period of time (i.e. without stop time).
+// schedule backup to run from startTime till it will be stopped manually
+// also there, the incremental will rotate result files as it configured in BackupConfig
+ scheduler.schedule(config, startTime, null, 3600 * 24, 0);
+
+// to unschedule backup simply call the scheduler with the configuration describing the
+// already planned backup cycle.
+// the scheduler will search in internal tasks list for task with repository and
+// workspace name from the configuration and will stop that task.
+ scheduler.unschedule(config);</programlisting>
+
+ <para>When the BackupScheduler starts the scheduling, it uses the internal
+ Timer with startDate for the first (or just once) execution. If
+ chainPeriod is greater than 0 then the task is repeated with this value
+ used as a period starting from startDate. Otherwise the task will be
+ executed once at startDate time. If the scheduler has stopDate it will
+ stop the task ( the chain cycle) after stopDate. And the last parameter
+ incrementalPeriod will be used instead of the same from BackupConfig if
+ its values are greater than 0.</para>
+
+ <para>Starting each task (BackupScheduler.schedule(...)), the scheduler
+ creates a task file in the service working directory (see <emphasis
+ role="bold">Configuration</emphasis>, backup-dir) which describes the task
+ backup configuration and periodic values. These files will be used at the
+ backup service start (JVM start) to reinitialize BackupScheduler for
+ continuous task scheduling. Only tasks that don't have a stopDate or a
+ stopDate not expired will be reinitialized.</para>
+
+ <para>There is one notice about BackupScheduler task reinitialization in
+ the current implementation. It comes from the BackupScheduler nature and
+ its implemented behaviour. As the scheduler is just a virtual user which
+ asks the BackupManager to start or stop backup operations, it isn't able
+ to reinitialize each existing BackupChain before the service (JVM) is
+ stopped. But it's possible to start a new operation with the same
+ configuration via BackupManager (that was configured before and stored in
+ a task file).</para>
+
+ <para>This is a main detail of the BackupScheduler which should be taken
+ into suggestion of a backup operation design now. In case of
+ reinitialization the task will have new time values for the backup
+ operation cycle as the chainPeriod and incrementalPeriod will be applied
+ again. That behaviour may be changed in the future.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 08:16:25 UTC (rev 2857)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 08:22:26 UTC (rev 2858)
@@ -96,16 +96,25 @@
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="jcr/searching/searching-repository-content.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <!-- protocols -->
-
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!-- protocols -->
+
<xi:include href="jcr/protocols/webdav.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<xi:include href="jcr/protocols/ftp.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!-- backup -->
+ <xi:include href="jcr/backup/exojcr-backup-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <!--xi:include href="jcr/backup/backup-client.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" /-->
+
+
+
<!-- other -->
<xi:include href="jcr/statistics.xml"
15 years, 11 months
exo-jcr SVN: r2857 - in jcr/branches/1.12.x/docs/reference/en/src/main: docbook/en-US/modules/jcr and 3 other directories.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-03 04:16:25 -0400 (Tue, 03 Aug 2010)
New Revision: 2857
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/ftp.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_davexplorer.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_explorer.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_msoffice2003.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_ubuntulinux.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_xythosdrive.jpg
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-869 protocols documentation added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/ftp.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/ftp.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/ftp.xml 2010-08-03 08:16:25 UTC (rev 2857)
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.FTP">
+ <title>FTP</title>
+
+ <section>
+ <title>Introdution</title>
+
+ <para>The JCR-FTP Server represents the standard eXo service, operates as
+ an FTP server with an access to a content stored in JCR repositories in
+ the form of <emphasis role="bold">nt:file/nt:folder</emphasis> nodes or
+ their successors. The client of an executed Server can be any FTP client.
+ The FTP server is supported by a standard configuration which can be
+ changed as required.</para>
+ </section>
+
+ <section>
+ <title>Configuration Parameters</title>
+
+ <section>
+ <title>command-port:</title>
+
+ <programlisting><value-param>
+ <name>command-port</name>
+ <value>21</value>
+</value-param></programlisting>
+
+ <para>The value of the command channel port. The value '21' is
+ default.</para>
+
+ <para>When you have already some FTP server installed in your system ,
+ this parameter needs to be changed (2121 for example) to avoid conflicts
+ or if the port is protected.</para>
+ </section>
+
+ <section>
+ <title>data-min-port & data-max-port</title>
+
+ <programlisting><value-param>
+ <name>data-min-port</name>
+ <value>52000</value>
+</value-param></programlisting>
+
+ <programlisting><value-param>
+ <name>data-max-port</name>
+ <value>53000</value>
+</value-param></programlisting>
+
+ <para>These two parameters indicate the minimal and maximal values of
+ the range of ports, used by the server. The usage of the additional data
+ channel is required by the FTP - protocol, which is used to transfer the
+ contents of files and the listing of catalogues. This range of ports
+ should be free from listening by other server-programs.</para>
+ </section>
+
+ <section>
+ <title>system</title>
+
+ <programlisting><value-param>
+ <name>system</name>
+
+ <value>Windows_NT</value>
+ or
+ <value>UNIX Type: L8</value>
+</value-param></programlisting>
+
+ <para>Types of formats of listing of catalogues which are
+ supported.</para>
+ </section>
+
+ <section>
+ <title>client-side-encoding</title>
+
+ <programlisting><value-param>
+ <name>client-side-encoding</name>
+
+ <value>windows-1251</value>
+ or
+ <value>KOI8-R</value>
+
+</value-param></programlisting>
+
+ <para>This parameter specifies the coding which is used for dialogue
+ with the client.</para>
+ </section>
+
+ <section>
+ <title>def-folder-node-type</title>
+
+ <programlisting><value-param>
+ <name>def-folder-node-type</name>
+ <value>nt:folder</value>
+</value-param></programlisting>
+
+ <para>This parameter specifies the type of a node, when an FTP-folder is
+ created.</para>
+ </section>
+
+ <section>
+ <title>def-file-node-type</title>
+
+ <programlisting><value-param>
+ <name>def-file-node-type</name>
+ <value>nt:file</value>
+</value-param></programlisting>
+
+ <para>This parameter specifies the type of a node, when an FTP - file is
+ created.</para>
+ </section>
+
+ <section>
+ <title>def-file-mime-type</title>
+
+ <programlisting><value-param>
+ <name>def-file-mime-type</name>
+ <value>application/zip</value>
+</value-param></programlisting>
+
+ <para>The mime type of a created file is chosen using its file
+ extention. In case a server cannot find the corresponding mime type,
+ this value is used.</para>
+ </section>
+
+ <section>
+ <title>cache-folder-name</title>
+
+ <programlisting><value-param>
+ <name>cache-folder-name</name>
+ <value>../temp/ftp_cache</value>
+</value-param></programlisting>
+
+ <para>The Path of the cache folder.</para>
+ </section>
+
+ <section>
+ <title>upload-speed-limit</title>
+
+ <programlisting><value-param>
+ <name>upload-speed-limit</name>
+ <value>20480</value>
+</value-param></programlisting>
+
+ <para>Restriction of the upload speed. It is measured in bytes.</para>
+ </section>
+
+ <section>
+ <title>download-speed-limit</title>
+
+ <programlisting><value-param>
+ <name>download-speed-limit</name>
+ <value>20480</value>
+</value-param></programlisting>
+
+ <para>Restriction of the download speed. It is measured in bytes.</para>
+ </section>
+
+ <section>
+ <title>timeout</title>
+
+ <programlisting><value-param>
+ <name>timeout</name>
+ <value>60</value>
+</value-param></programlisting>
+
+ <para>Defines the value of a timeout.</para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml 2010-08-03 08:16:25 UTC (rev 2857)
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.WebDAV">
+ <title>WebDAV</title>
+
+ <section>
+ <title>Related documents</title>
+
+ <para>* Link Producer * Microsoft Office plugin * Open Office Add-On *
+ WebDav Client Libraries</para>
+ </section>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The WebDAV protocol allows you to use third party tools to
+ communicate with hierarchical content servers via HTTP. It is possible to
+ add and remove documents or a set of documents from a path on the server.
+ DeltaV is an extension of the WebDav protocol that allows to manage
+ document versioning. Locking guarantees protection against multiple access
+ when writing resources. The ordering support allows to change the position
+ of the resource in the list, sorting the directory for the convenience of
+ viewing the directory tree. The full-text search makes it easy to find the
+ necessary documents. You can search using two languages: SQL and XPATH is
+ supported.</para>
+
+ <para>In eXo JCR we plug in the WebDAV layer - based on the code taken
+ from the extension modules of the reference implementation - on top of our
+ JCR implementation so that it is possible to browse a workspace using the
+ third party tools (it can be Windows folders or Mac ones as well as a Java
+ WebDAV client such as DAVExplorer or IE using File->Open as a Web
+ Folder).</para>
+
+ <para>Now WebDav is an extension of the REST service. To get the WebDav
+ server ready you must deploy the REST application. Then you can access any
+ workspace of your repository using the following URL:</para>
+
+ <para>Standalone mode:</para>
+
+ <para><ulink
+ url="http://host:port/rest/jcr/">http://host:port/rest/jcr/</ulink>{RepositoryName}/{WorkspaceName}/{Path}</para>
+
+ <para>Portal mode:</para>
+
+ <para><ulink
+ url="http://host:port/portal/rest/private/jcr/">http://host:port/portal/rest/private/jcr/</ulink>{RepositoryName}/{WorkspaceName}/{Path}</para>
+
+ <para>When accessing the WebDAV server - here URL is <ulink
+ url="http://localhost:8080/rest/jcr/repository/production">http://localhost:8080/rest/jcr/repository/production</ulink>,
+ you might also use "collaboration" (instead of "production") which is the
+ default workspace in eXo products - the user will be asked to enter his
+ login and password. Those will then be checked using the organization
+ service (that can be implemented thanks to an Inmemory(dummy) module or DB
+ module or LDAP one) and the JCR user session will be created with the
+ correct JCR Credentials.</para>
+
+ <para><emphasis role="bold">NOTE:</emphasis> If you try the "in ECM"
+ option, add "@ecm" to the user's password. Alternatively, you may modify
+ jaas.conf adding the <emphasis role="bold">domain=ecm</emphasis> option
+ like:</para>
+
+ <programlisting>exo-domain {
+ org.exoplatform.services.security.jaas.BasicLoginModule required domain=ecm;
+};</programlisting>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.webdav.WebDavServiceImpl</key>
+ <type>org.exoplatform.services.webdav.WebDavServiceImpl</type>
+ <init-params>
+
+ <!-- this parameter indicates the default login and password values
+ used as credentials for accessing the repository -->
+ <!-- value-param>
+ <name>default-identity</name>
+ <value>admin:admin</value>
+ </value-param -->
+
+ <!-- this is the value of WWW-Authenticate header -->
+ <value-param>
+ <name>auth-header</name>
+ <value>Basic realm="eXo-Platform Webdav Server 1.6.1"</value>
+ </value-param>
+
+ <!-- default node type which is used for the creation of collections -->
+ <value-param>
+ <name>def-folder-node-type</name>
+ <value>nt:folder</value>
+ </value-param>
+
+ <!-- default node type which is used for the creation of files -->
+ <value-param>
+ <name>def-file-node-type</name>
+ <value>nt:file</value>
+ </value-param>
+
+ <!-- if MimeTypeResolver can't find the required mime type,
+ which conforms with the file extension, and the mimeType header is absent
+ in the HTTP request header, this parameter is used
+ as the default mime type-->
+ <value-param>
+ <name>def-file-mimetype</name>
+ <value>application/octet-stream</value>
+ </value-param>
+
+ <!-- This parameter indicates one of the three cases when you update the content of the resource by PUT command.
+ In case of "create-version", PUT command creates the new version of the resource if this resource exists.
+ In case of "replace" - if the resource exists, PUT command updates the content of the resource and its last modification date.
+ In case of "add", the PUT command tries to create the new resource with the same name (if the parent node allows same-name siblings).-->
+
+ <value-param>
+ <name>update-policy</name>
+ <value>create-version</value>
+ <!--value>replace</value -->
+ <!-- value>add</value -->
+ </value-param>
+
+ <!--
+ This parameter determines how service responds to a method that attempts to modify file content.
+ In case of "checkout-checkin" value, when a modification request is applied to a checked-in version-controlled resource, the request is automatically preceded by a checkout and followed by a checkin operation.
+ In case of "checkout" value, when a modification request is applied to a checked-in version-controlled resource, the request is automatically preceded by a checkout operation.
+ -->
+ <value-param>
+ <name>auto-version</name>
+ <value>checkout-checkin</value>
+ <!--value>checkout</value -->
+ </value-param>
+
+ <!--
+ This parameter is responsible for managing Cache-Control header value which will be returned to the client.
+ You can use patterns like "text/*", "image/*" or wildcard to define the type of content.
+ -->
+ <value-param>
+ <name>cache-control</name>
+ <value>text/xml,text/html:max-age=3600;image/png,image/jpg:max-age=1800;*/*:no-cache;</value>
+ </value-param>
+
+ </init-params
+</component></programlisting>
+ </section>
+
+ <section>
+ <title>Screenshots</title>
+
+ <para>For the time being eXo JCR WebDav server was tested using MS
+ Internet Explorer, <ulink url="http://www.ics.uci.edu/~webdav">Dav
+ Explorer</ulink>, <ulink
+ url="http://www.xythos.com/home/xythos/products/xythos_drive.html">Xythos
+ Drive</ulink>, Microsoft Office 2003 (as client), and Ubuntu Linux.</para>
+
+ <section>
+ <title>MS Internet Explorer</title>
+
+ <para>(File -> Open as Web Folder)</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/protocols/webdav_explorer.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Dav Explorer</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/protocols/webdav_davexplorer.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Xythos Drive</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/protocols/webdav_xythosdrive.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Microsoft Office 2003</title>
+
+ <para>(as client) (File->Open with typing http://... href in the file
+ name box)</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/protocols/webdav_msoffice2003.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Ubuntu Linux</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/protocols/webdav_ubuntulinux.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+ </section>
+
+ <section>
+ <title>Comparison table of WebDav and JCR commands</title>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>WebDav</entry>
+
+ <entry>JCR</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>COPY</entry>
+
+ <entry>Workspace.copy(...)</entry>
+ </row>
+
+ <row>
+ <entry>DELETE</entry>
+
+ <entry>Node.remove()</entry>
+ </row>
+
+ <row>
+ <entry>GET</entry>
+
+ <entry>Node.getProperty(...); Property.getValue()</entry>
+ </row>
+
+ <row>
+ <entry>HEAD</entry>
+
+ <entry>Node.getProperty(...); Property.getLength()</entry>
+ </row>
+
+ <row>
+ <entry>MKCOL</entry>
+
+ <entry>Node.addNode(...)</entry>
+ </row>
+
+ <row>
+ <entry>MOVE</entry>
+
+ <entry>Session.move(...) or Workspace.move(...)</entry>
+ </row>
+
+ <row>
+ <entry>PROPFIND</entry>
+
+ <entry>Session.getNode(...); Node.getNode(...);
+ Node.getNodes(...); Node.getProperties()</entry>
+ </row>
+
+ <row>
+ <entry>PROPPATCH</entry>
+
+ <entry>Node.setProperty(...);
+ Node.getProperty(...).remove()</entry>
+ </row>
+
+ <row>
+ <entry>PUT</entry>
+
+ <entry>Node.addNode("node","nt:file");
+ Node.setProperty("jcr:data", "data")</entry>
+ </row>
+
+ <row>
+ <entry>CHECKIN</entry>
+
+ <entry>Node.checkin()</entry>
+ </row>
+
+ <row>
+ <entry>CHECKOUT</entry>
+
+ <entry>Node.checkout()</entry>
+ </row>
+
+ <row>
+ <entry>REPORT</entry>
+
+ <entry>Node.getVersionHistory(); VersionHistory.getAllVersions();
+ Version.getProperties()</entry>
+ </row>
+
+ <row>
+ <entry>RESTORE</entry>
+
+ <entry>Node.restore(...)</entry>
+ </row>
+
+ <row>
+ <entry>UNCHECKOUT</entry>
+
+ <entry>Node.restore(...)</entry>
+ </row>
+
+ <row>
+ <entry>VERSION-CONTROL</entry>
+
+ <entry>Node.addMixin("mix:versionable")</entry>
+ </row>
+
+ <row>
+ <entry>LOCK</entry>
+
+ <entry>Node.lock(...)</entry>
+ </row>
+
+ <row>
+ <entry>UNLOCK</entry>
+
+ <entry>Node.unlock()</entry>
+ </row>
+
+ <row>
+ <entry>ORDERPATCH</entry>
+
+ <entry>Node.orderBefore(...)</entry>
+ </row>
+
+ <row>
+ <entry>SEARCH</entry>
+
+ <entry>Workspace.getQueryManager(); QueryManager.createQuery();
+ Query.execute()</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 07:16:23 UTC (rev 2856)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 08:16:25 UTC (rev 2857)
@@ -96,7 +96,15 @@
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="jcr/searching/searching-repository-content.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!-- protocols -->
+
+ <xi:include href="jcr/protocols/webdav.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/protocols/ftp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
<!-- other -->
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_davexplorer.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_davexplorer.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_explorer.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_explorer.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_msoffice2003.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_msoffice2003.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_ubuntulinux.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_ubuntulinux.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_xythosdrive.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/protocols/webdav_xythosdrive.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
15 years, 11 months
exo-jcr SVN: r2856 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules: jcr and 3 other directories.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-08-03 03:16:23 -0400 (Tue, 03 Aug 2010)
New Revision: 2856
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/rest-services-on-groovy.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/offset-and-limit.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
Removed:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration-persister.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/external-value-storages.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jdbc-data-container-config.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/multilanguage-support.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/search-configuration.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml
Log:
EXOJCR-869: configuration and search documents ported
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/configuration-persister.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.ConfigurationPersister">
+ <?dbhtml filename="ch-jcr-configuration-persister.html"?>
+ <title>JCR Configuration persister</title>
+
+ <section>
+ <title>Idea</title>
+
+ <para>JCR Repository Service uses
+ <classname>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</classname>
+ component to read its configuration.</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ </init-params>
+ </component></programlisting>
+
+ <para>In the example Repository Service will read the configuration from
+ the file <filename>/conf/standalone/exo-jcr-config.xml</filename>.</para>
+
+ <para>But in some cases it's required to change the configuration on the
+ fly. And know that the new one will be used. Additionally we wish not to
+ modify the original file.</para>
+
+ <para>In this case we have to use the configuration persister feature
+ which allows to store the configuration in different locations.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>On startup <classname>RepositoryServiceConfiguration</classname>
+ component checks if a configuration persister was configured. In that case
+ it uses the provided <classname>ConfigurationPersister</classname>
+ implementation class to instantiate the persister object.</para>
+
+ <para>Configuration with persister:<programlisting><component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR configuration file</description>
+ <value>/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ <properties-param>
+ <name>working-conf</name>
+ <description>working-conf</description>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="mysql" />
+ <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
+ </properties-param>
+ </init-params>
+ </component></programlisting></para>
+
+ <para>Where:<itemizedlist>
+ <listitem>
+ <para><parameter>source-name</parameter> - JNDI source name
+ configured in <classname>InitialContextInitializer</classname>
+ component. (<parameter>sourceName</parameter> prior v.1.9.) Find
+ more in <link linkend="ch_configuration">database
+ configuration</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>dialect</parameter> - SQL dialect which will be
+ used with database from <parameter>source-name</parameter>. Find
+ more in <link linkend="ch_configuration">database
+ configuration</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>persister-class-name</parameter> - class name of
+ <classname>ConfigurationPersister</classname> interface
+ implementation. (<parameter>persisterClassName</parameter> prior
+ v.1.9.)</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>ConfigurationPersister interface:<programlisting>/**
+ * Init persister.
+ * Used by RepositoryServiceConfiguration on init.
+ * @return - config data stream
+ */
+ void init(PropertiesParam params) throws RepositoryConfigurationException;
+
+ /**
+ * Read config data.
+ * @return - config data stream
+ */
+ InputStream read() throws RepositoryConfigurationException;
+
+ /**
+ * Create table, write data.
+ * @param confData - config data stream
+ */
+ void write(InputStream confData) throws RepositoryConfigurationException;
+
+ /**
+ * Tell if the config exists.
+ * @return - flag
+ */
+ boolean hasConfig() throws RepositoryConfigurationException;</programlisting></para>
+
+ <para>JCR Core implementation contains a persister which stores the
+ repository configuration in the relational database using JDBC calls -
+ <classname>org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister</classname>.</para>
+
+ <para>The implementation will crate and use table JCR_CONFIG in the
+ provided database.</para>
+
+ <para>But the developer can implement his own persister for his particular
+ usecase.</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.eXoJCRconfiguration">
+ <?dbhtml filename="ch-jcr-configuration.html"?>
+ <title>eXo JCR configuration</title>
+ <section>
+ <title>Related documents</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.ConfigurationPersister">Configuration
+ persister</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="JCR.SearchConfiguration">Search
+ Configuration</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="ch_jdbc_data_container">JDBC Data Container
+ config</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="ch_external_value_storages">External Value
+ Storages</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="none">Workspace SimpleDB storage</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="none">Workspace Persistence Storage</link></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Portal and Standalone configuration</title>
+
+ <para>Like other eXo services eXo JCR can be configured and used in portal
+ or embedded mode (as a service embedded in eXo Portal) and in standalone
+ mode.</para>
+
+ <para>In Embedded mode, JCR services are registered in the Portal
+ container and the second option is to use a Standalone container. The main
+ difference between these container types is that the first one is intended
+ to be used in a Portal (Web) environment, while the second one can be used
+ standalone (see the comprehensive page <link
+ linkend="Kernel.ServiceConfigurationForBeginners">Service Configuration
+ for Beginners</link> for more details).</para>
+
+ <para>The following setup procedure is used to obtain a Standalone
+ configuration (find more in <link
+ linkend="Kernel.ContainerConfiguration">Container
+ configuration</link>):</para>
+
+ <para>* Configuration that is set explicitly using
+ StandaloneContainer.addConfigurationURL(String url) or
+ StandaloneContainer.addConfigurationPath(String path) before
+ getInstance()</para>
+
+ <para>* Configuration from $base:directory/exo-configuration.xml or
+ $base:directory/conf/exo-configuration.xml file. Where $base:directory is
+ either AS's home directory in case of J2EE AS environment or just the
+ current directory in case of a standalone application.</para>
+
+ <para>* /conf/exo-configuration.xml in the current classloader (e.g. war,
+ ear archive)</para>
+
+ <para>* Configuration from
+ $service_jar_file/conf/portal/configuration.xml. WARNING: do not rely on
+ some concrete jar's configuration if you have more than one jar containing
+ conf/portal/configuration.xml file. In this case choosing a configuration
+ is unpredictable.</para>
+
+ <para>JCR service configuration looks like:</para>
+
+ <programlisting><component>
+ <key>org.exoplatform.services.jcr.RepositoryService</key>
+ <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
+</component>
+<component>
+ <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+ <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+ <init-params>
+ <value-param>
+ <name>conf-path</name>
+ <description>JCR repositories configuration file</description>
+ <value>jar:/conf/standalone/exo-jcr-config.xml</value>
+ </value-param>
+ <properties-param>
+ <name>working-conf</name>
+ <description>working-conf</description>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="hsqldb" />
+ <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para><emphasis role="bold">conf-path</emphasis> : a path to a
+ RepositoryService JCR Configuration.</para>
+
+ <para><emphasis role="bold">working-conf</emphasis> : optional; <link
+ linkend="JCR.ConfigurationPersister">JCR configuration persister</link>
+ configuration. If there isn't a working-conf the persister will be
+ disabled.</para>
+ </section>
+
+ <section>
+ <title>JCR Configuration</title>
+
+ <para>The Configuration is defined in an XML file (see DTD below)</para>
+
+ <para>JCR Service can use multiple <emphasis
+ role="bold">Repositories</emphasis> and each repository can have multiple
+ <emphasis role="bold">Workspaces</emphasis>.</para>
+
+ <para>From v.1.9 JCR repositories configuration parameters support
+ human-readable formats of values. They are all case-insensitive:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Numbers formats: K,KB - kilobytes, M,MB - megabytes, G,GB -
+ gigabytes, T,TB - terabytes. Examples: 100.5 - digit 100.5, 200k - 200
+ Kbytes, 4m - 4 Mbytes, 1.4G - 1.4 Gbytes, 10T - 10 Tbytes</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>Time format endings: ms - milliseconds, m - minutes, h - hours,
+ d - days, w - weeks, if no ending - seconds. Examples: 500ms - 500
+ milliseconds, 20 - 20 seconds, 30m - 30 minutes, 12h - 12 hours, 5d -
+ 5 days, 4w - 4 weeks.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Repository service configuration (JCR repositories
+ configuration)</title>
+
+ <para>Service configuration may be placed in
+ jar:/conf/standalone/exo-jcr-config.xml for standalone mode. For portal
+ mode it is located in the portal web application
+ portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
+
+ <para><emphasis role="bold">default-repository</emphasis> - the name of a
+ default repository (one returned by
+ RepositoryService.getRepository())</para>
+
+ <para><emphasis role="bold">repositories</emphasis> - the list of
+ repositories</para>
+ </section>
+
+ <section>
+ <title>Repository configuration:</title>
+
+ <para><emphasis role="bold">name</emphasis> - the name of a
+ repository</para>
+
+ <para><emphasis role="bold">default-workspace</emphasis> - the name of a
+ workspace obtained using Session's login() or login(Credentials) methods
+ (ones without an explicit workspace name)</para>
+
+ <para><emphasis role="bold">system-workspace</emphasis> - name of
+ workspace where <emphasis role="bold">/jcr:system</emphasis> node is
+ placed</para>
+
+ <para><emphasis role="bold">security-domain</emphasis> - the name of a
+ security domain for JAAS authentication</para>
+
+ <para><emphasis role="bold">access-control</emphasis> - the name of an
+ access control policy. There can be 3 types: optional - ACL is created
+ on-demand(default), disable - no access control, mandatory - an ACL is
+ created for each added node(not supported yet)</para>
+
+ <para><emphasis role="bold">authentication-policy</emphasis> - the name of
+ an authentication policy class</para>
+
+ <para><emphasis role="bold">workspaces</emphasis> - the list of
+ workspaces</para>
+
+ <para><emphasis role="bold">session-max-age</emphasis> - the time after
+ which an idle session will be removed (called logout). If not set, the
+ idle session will never be removed.</para>
+ </section>
+
+ <section>
+ <title>Workspace configuration:</title>
+
+ <para><emphasis role="bold">name</emphasis> - the name of a
+ workspace</para>
+
+ <para><emphasis role="bold">auto-init-root-nodetype</emphasis> -
+ DEPRECATED in JCR 1.9 (use initializer). The node type for root node
+ initialization</para>
+
+ <para><emphasis role="bold">container</emphasis> - workspace data
+ container (physical storage) configuration</para>
+
+ <para><emphasis role="bold">initializer</emphasis> - workspace initializer
+ configuration</para>
+
+ <para><emphasis role="bold">cache</emphasis> - workspace storage cache
+ configuration</para>
+
+ <para><emphasis role="bold">query-handler</emphasis> - query handler
+ configuration</para>
+
+ <para><emphasis role="bold">auto-init-permissions</emphasis> - DEPRECATED
+ in JCR 1.9 (use initializer). Default permissions of the root node. It is
+ defined as a set of semicolon-delimited permissions containing a group of
+ space-delimited identities (user, group etc, see Organization service
+ documentation for details) and the type of permission. For example any
+ read; <emphasis role="bold">:/admin read;</emphasis>:/admin add_node;
+ <emphasis role="bold">:/admin set_property;</emphasis>:/admin remove means
+ that users from group <emphasis role="bold">admin</emphasis> have all
+ permissions and other users have only a 'read' permission.</para>
+ </section>
+
+ <section>
+ <title>Workspace data container configuration:</title>
+
+ <para><emphasis role="bold">class</emphasis> - A workspace data container
+ class name</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for the concrete Workspace data container</para>
+
+ <para><emphasis role="bold">value-storages</emphasis> - the list of value
+ storage plugins</para>
+ </section>
+
+ <section id="JCR.ConfigurationPersister.ValueStoragePlugin">
+ <title>Value Storage plugin configuration (for data container):</title>
+
+ <note>
+ <para>The value-storage element is optional. If you don't include it,
+ the values will be stored as BLOBs inside the database.</para>
+ </note>
+
+ <para><emphasis role="bold">value-storage</emphasis> - Optional value
+ Storage plugin definition:</para>
+
+ <para><emphasis role="bold">class</emphasis>- a value storage plugin class
+ name (attribute)</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for a concrete Value Storage plugin</para>
+
+ <para><emphasis role="bold">filters</emphasis> - the list of filters
+ defining conditions when this plugin is applicable</para>
+ </section>
+
+ <section>
+ <title>Initializer configuration (optional):</title>
+
+ <para><emphasis role="bold">class</emphasis> - initializer implementation
+ class.</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs). Properties are supported:</para>
+
+ <para><emphasis role="bold">root-nodetype</emphasis> - The node type for
+ root node initialization</para>
+
+ <para><emphasis role="bold">root-permissions</emphasis> - Default
+ permissions of the root node. It is defined as a set of
+ semicolon-delimited permissions containing a group of space-delimited
+ identities (user, group etc, see Organization service documentation for
+ details) and the type of permission. For example any read; <emphasis
+ role="bold">:/admin read;</emphasis>:/admin add_node; <emphasis
+ role="bold">:/admin set_property;</emphasis>:/admin remove means that
+ users from group <emphasis role="bold">admin</emphasis> have all
+ permissions and other users have only a 'read' permission.</para>
+
+ <para>Configurable initializer adds a capability to override workspace
+ initial startup procedure (used for Clustering). Also it replaces
+ workspace element parameters auto-init-root-nodetype and
+ auto-init-permissions with root-nodetype and root-permissions.</para>
+ </section>
+
+ <section>
+ <title>Cache configuration:</title>
+
+ <para><emphasis role="bold">enabled</emphasis> - if workspace cache is
+ enabled</para>
+
+ <para><emphasis role="bold">class</emphasis> - cache implementation class,
+ optional from 1.9. Default value is
+ org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl.</para>
+
+ <para>Cache can be configured to use concrete implementation of
+ WorkspaceStorageCache interface. JCR core has two implementation to
+ use:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>LinkedWorkspaceStorageCacheImpl - default, with configurable
+ read behavior and statistic.</para>
+ </listitem>
+
+ <listitem>
+ <para>WorkspaceStorageCacheImpl - pre 1.9, still can be used.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for Workspace cache:</para>
+
+ <para><emphasis role="bold">max-size</emphasis> - cache maximum size
+ (maxSize prior to v.1.9).</para>
+
+ <para><emphasis role="bold">live-time</emphasis> - cached item live time
+ (liveTime prior to v.1.9).</para>
+
+ <para>From 1.9 LinkedWorkspaceStorageCacheImpl supports additional
+ optional parameters.</para>
+
+ <para><emphasis role="bold">statistic-period</emphasis> - period (time
+ format) of cache statistic thread execution, 5 minutes by default.</para>
+
+ <para><emphasis role="bold">statistic-log</emphasis> - if true cache
+ statistic will be printed to default logger (log.info), false by
+ default.</para>
+
+ <para><emphasis role="bold">statistic-clean</emphasis> - if true cache
+ statistic will be cleaned after was gathered, false by default.</para>
+
+ <para><emphasis role="bold">cleaner-period</emphasis> - period of eldest
+ items remover execution, 20 minutes by default.</para>
+
+ <para><emphasis role="bold">blocking-users-count</emphasis> - number of
+ concurrent users allowed to read cache storage, 0 - unlimited by
+ default.</para>
+ </section>
+
+ <section>
+ <title>Query Handler configuration:</title>
+
+ <para><emphasis role="bold">class</emphasis> - A Query Handler class
+ name</para>
+
+ <para><emphasis role="bold">properties</emphasis> - the list of properties
+ (name-value pairs) for a Query Handler (indexDir)</para>
+
+ <para>Properties and advanced features described in <link
+ linkend="JCR.SearchConfiguration">Search Configuration</link>.</para>
+ </section>
+
+ <section>
+ <title>Lock Manager configuration:</title>
+
+ <para><emphasis role="bold">time-out</emphasis> - time after which the
+ unused global lock will be removed.</para>
+
+ <para><emphasis role="bold">persister</emphasis> - a class for storing
+ lock information for future use. For example, remove lock after jcr
+ restart.</para>
+
+ <para><emphasis role="bold">path</emphasis> - a lock folder, each
+ workspace has its own.</para>
+
+ <para>Additional information about the configuration of the lock you can
+ see in <link linkend="TODO.JCR.Locking">JCR Locks Implementation
+ Specification</link>.</para>
+
+ <programlisting><!ELEMENT repository-service (repositories)>
+<!ATTLIST repository-service default-repository NMTOKEN #REQUIRED>
+<!ELEMENT repositories (repository)>
+<!ELEMENT repository (security-domain,access-control,session-max-age,authentication-policy,workspaces)>
+<!ATTLIST repository
+ default-workspace NMTOKEN #REQUIRED
+ name NMTOKEN #REQUIRED
+ system-workspace NMTOKEN #REQUIRED
+>
+<!ELEMENT security-domain (#PCDATA)>
+<!ELEMENT access-control (#PCDATA)>
+<!ELEMENT session-max-age (#PCDATA)>
+<!ELEMENT authentication-policy (#PCDATA)>
+<!ELEMENT workspaces (workspace+)>
+<!ELEMENT workspace (container,initializer,cache,query-handler)>
+<!ATTLIST workspace name NMTOKEN #REQUIRED>
+<!ELEMENT container (properties,value-storages)>
+<!ATTLIST container class NMTOKEN #REQUIRED>
+<!ELEMENT value-storages (value-storage+)>
+<!ELEMENT value-storage (properties,filters)>
+<!ATTLIST value-storage class NMTOKEN #REQUIRED>
+<!ELEMENT filters (filter+)>
+<!ELEMENT filter EMPTY>
+<!ATTLIST filter property-type NMTOKEN #REQUIRED>
+<!ELEMENT initializer (properties)>
+<!ATTLIST initializer class NMTOKEN #REQUIRED>
+<!ELEMENT cache (properties)>
+<!ATTLIST cache
+ enabled NMTOKEN #REQUIRED
+ class NMTOKEN #REQUIRED
+>
+<!ELEMENT query-handler (properties)>
+<!ATTLIST query-handler class NMTOKEN #REQUIRED>
+<!ELEMENT access-manager (properties)>
+<!ATTLIST access-manager class NMTOKEN #REQUIRED>
+<!ELEMENT lock-manager (time-out,persister)>
+<!ELEMENT time-out (#PCDATA)>
+<!ELEMENT persister (properties)>
+<!ELEMENT properties (property+)>
+<!ELEMENT property EMPTY></programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/external-value-storages.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.ExternalValueStorages">
+ <?dbhtml filename="ch-jcr-external-value-storages.html"?>
+
+ <title>External Value Storages</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>By default JCR Values are stored in the Workspace Data container
+ along with the JCR structure (i.e. Nodes and Properties). eXo JCR offers
+ an additional option of storing JCR Values separately from Workspace Data
+ container, which can be extremely helpful to keep Binary Large Objects
+ (BLOBs) for example (see [TODO<link linkend="TODO"> Binary values
+ processing</link>]).</para>
+
+ <para>Value storage configuration is a part of Repository configuration,
+ find more details <link
+ linkend="JCR.ConfigurationPersister.ValueStoragePlugin">there</link>.</para>
+
+ <para>Tree-based storage is recommended for most of cases. If you run an
+ application on Amazon EC2 - the S3 option may be interesting for
+ architecture. Simple 'flat' storage is good in speed of creation/deletion
+ of values, it might be a compromise for a small storages.</para>
+ </section>
+
+ <section>
+ <title>Tree File Value Storage</title>
+
+ <para>Holds Values in tree-like FileSystem files.
+ <property>path</property> property points to the root directory to store
+ the files.</para>
+
+ <para>This is a recommended type of external storage, it can contain large
+ amount of files limited only by disk/volume free space.</para>
+
+ <para>A disadvantage it's a higher time on Value deletion due to unused
+ tree-nodes remove.</para>
+
+ <programlisting><value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="data/values"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="1M"/>
+ </filters></programlisting>
+
+ <para>Where :<simplelist>
+ <member><parameter>id</parameter> - the value storage unique
+ identifier, used for linking with properties stored in workspace
+ container</member>
+
+ <member><parameter>path</parameter> - a location where value files
+ will be stored</member>
+ </simplelist></para>
+
+ <para>Each file value storage can have the <function>filter(s)</function>
+ for incoming values. A filter can match values by property type
+ (<property>property-type</property>), property name
+ (<property>property-name</property>), ancestor path
+ (<property>ancestor-path</property>) and/or size of values stored
+ (<property>min-value-size</property>, in bytes). In code sample we use a
+ filter with property-type and min-value-size only. I.e. storage for binary
+ values with size greater of 1MB. It's recommended to store properties with
+ large values in file value storage only.</para>
+
+ <para>Another example shows a value storage with different locations for
+ large files (<property>min-value-size</property> a 20Mb-sized filter). A
+ value storage uses ORed logic in the process of filter selection. That
+ means the first filter in the list will be asked first and if not matched
+ the next will be called etc. Here a value matches the 20 MB-sized filter
+ <property>min-value-size</property> and will be stored in the path
+ "data/20Mvalues", all other in "data/values".</para>
+
+ <programlisting><value-storages>
+ <value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="data/20Mvalues"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="20M"/>
+ </filters>
+ <value-storage>
+ <value-storage id="Storage #2" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="data/values"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="1M"/>
+ </filters>
+ <value-storage>
+<value-storages></programlisting>
+ </section>
+
+ <section>
+ <title>Simple File Value Storage</title>
+
+ <note>
+ <para>Not recommended to use in production due to low capacity
+ capabilities on most file systems.</para>
+
+ <para>But if you're sure in your file-system or data amount is small it
+ may be useful for you as haves a faster speed of Value removal.</para>
+ </note>
+
+ <para>Holds Values in flat FileSystem files. <property>path</property>
+ property points to root directory in order to store files</para>
+
+ <programlisting><value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.SimpleFileValueStorage">
+ <properties>
+ <property name="path" value="data/values"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="1M"/>
+ </filters></programlisting>
+ </section>
+
+ <section>
+ <title>Content Addressable Value storage (CAS) support</title>
+
+ <para>eXo JCR supports <phrase>Content-addressable storage</phrase>
+ feature for <phrase>Values</phrase> storing.</para>
+
+ <note>
+ <para>Content-addressable storage, also referred to as associative
+ storage and abbreviated CAS, is a mechanism for storing information that
+ can be retrieved based on its content, not its storage location. It is
+ typically used for high-speed storage and retrieval of fixed content,
+ such as documents stored for compliance with government
+ regulations.</para>
+ </note>
+
+ <para>Content Addressable Value storage stores unique content once.
+ Different properties (values) with same content will be stored as one data
+ file shared between those values. We can tell the Value content will be
+ shared across some Values in storage and will be stored on one physical
+ file.</para>
+
+ <para>Storage size will be decreased for application which governs
+ potentially same data in the content.</para>
+
+ <note>
+ <para>For example: if you have 100 different properties containing the
+ same data (e.g. mail attachment) the storage stores only one single
+ file. The file will be shared with all referencing properties.</para>
+ </note>
+
+ <para>If property Value changes it is stored in an additional file.
+ Alternatively the file is shared with other values, pointing to the same
+ content.</para>
+
+ <para>The storage calculates Value content address each time the property
+ was changed. CAS write operations are much more expensive compared to the
+ non-CAS storages.</para>
+
+ <para>Content address calculation based on java.security.MessageDigest
+ hash computation and tested with <abbrev>MD5</abbrev> and
+ <abbrev>SHA1</abbrev> algorithms.</para>
+
+ <note>
+ <para>CAS storage works most efficiently on data that does not change
+ often. For data that changes frequently, CAS is not as efficient as
+ location-based addressing.</para>
+ </note>
+
+ <para>CAS support can be enabled for <phrase>Tree</phrase> and
+ <phrase>Simple File Value Storage</phrase> types.</para>
+
+ <para>To enable CAS support just configure it in JCR Repositories
+ configuration like we do for other Value Storages.</para>
+
+ <programlisting><workspaces>
+ <workspace name="ws">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr"/>
+ <property name="dialect" value="oracle"/>
+ <property name="multi-db" value="false"/>
+ <property name="update-storage" value="false"/>
+ <property name="max-buffer-size" value="200k"/>
+ <property name="swap-directory" value="target/temp/swap/ws"/>
+ </properties>
+ <value-storages>
+<!------------------- here ----------------------->
+ <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.CASableTreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/ws"/>
+ <property name="digest-algo" value="MD5"/>
+ <property name="vcas-type" value="org.exoplatform.services.jcr.impl.storage.value.cas.JDBCValueContentAddressStorageImpl"/>
+ <property name="jdbc-source-name" value="jdbcjcr"/>
+ <property name="jdbc-dialect" value="oracle"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary"/>
+ </filters>
+ </value-storage>
+ </value-storages></programlisting>
+
+ <para>Properties:<simplelist>
+ <member><parameter>digest-algo</parameter> - digest hash algorithm
+ (MD5 and SHA1 were tested);</member>
+
+ <member><parameter>vcas-type</parameter> - Value CAS internal data
+ type, JDBC backed is currently implemented
+ org.exoplatform.services.jcr.impl.storage.value.cas.JDBCValueContentAddressStorageImp;l</member>
+
+ <member><parameter>jdbc-source-name</parameter> -
+ JDBCValueContentAddressStorageImpl specific parameter, database will
+ be used to save CAS metadata. It's simple to use same as in workspace
+ container;</member>
+
+ <member><parameter>jdbc-dialect</parameter> -
+ JDBCValueContentAddressStorageImpl specific parameter, database
+ dialect. It's simple to use same as in workspace container;</member>
+ </simplelist></para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/jdbc-data-container-config.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,592 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="ch_jdbc_data_container">
+ <?dbhtml filename="ch-jdbc-data-container-config.html"?>
+
+ <title>JDBC Data Container Config</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>eXo JCR persistent data container can work in two configuration
+ modes:<itemizedlist>
+ <listitem>
+ <para><phrase>Multi-database</phrase>: one database for each
+ workspace (used in standalone eXo JCR service mode)</para>
+ </listitem>
+
+ <listitem>
+ <para><phrase>Single-database</phrase>: all workspaces persisted in
+ one database (used in embedded eXo JCR service mode, e.g. in eXo
+ portal)</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The data container uses the JDBC driver to communicate with the
+ actual database software, i.e. any JDBC-enabled data storage can be used
+ with eXo JCR implementation.</para>
+
+ <para>Currently the data container is tested with the following
+ RDBMS:<itemizedlist>
+ <listitem>
+ <para>MySQL (5.x including UTF8 support)</para>
+ </listitem>
+
+ <listitem>
+ <para>PostgreSQL (8.x)</para>
+ </listitem>
+
+ <listitem>
+ <para>Oracle Database (9i, 10g)</para>
+ </listitem>
+
+ <listitem>
+ <para>Microsoft SQL Server (2005)</para>
+ </listitem>
+
+ <listitem>
+ <para>Sybase ASE (15.0)</para>
+ </listitem>
+
+ <listitem>
+ <para>Apache Derby/Java DB (10.1.x, 10.2.x)</para>
+ </listitem>
+
+ <listitem>
+ <para>IBM DB2 (8.x, 9.x)</para>
+ </listitem>
+
+ <listitem>
+ <para>HSQLDB (1.8.0.7)</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Each database software supports ANSI SQL standards but has its own
+ specifics too. So, each database has its own configuration in eXo JCR as a
+ database dialect parameter. If you need a more detailed configuration of
+ the database it's possible to do that by editing the metadata SQL-script
+ files.</para>
+
+ <para>In case the non-ANSI node name is used it's necessary to use a
+ database with MultiLanguage support[TODO link to MultiLanguage]. Some JDBC
+ drivers need additional parameters for establishing a Unicode friendly
+ connection. E.g. under mysql it's necessary to add an additional parameter
+ for the JDBC driver at the end of JDBC URL. For instance:
+ <code>jdbc:mysql://exoua.dnsalias.net/portal?characterEncoding=utf8</code></para>
+
+ <para>There are preconfigured configuration files for HSQLDB. Look for
+ these files in /conf/portal and /conf/standalone folders of the jar-file
+ <package>exo.jcr.component.core-XXX.XXX.jar</package> or
+ source-distribution of eXo JCR implementation.</para>
+
+ <para>By default the configuration files are located in service jars
+ <filename>/conf/portal/configuration.xml</filename> (eXo services
+ including JCR Repository Service) and
+ <filename>exo-jcr-config.xml</filename> (repositories configuration). In
+ eXo portal product JCR is configured in portal web application
+ <filename>portal/WEB-INF/conf/jcr/jcr-configuration.xml</filename> (JCR
+ Repository Service and related serivces) and repository-configuration.xml
+ (repositories configuration).</para>
+
+ <para>Read more about <link linkend="ch_configuration">Repository
+ configuration</link>.</para>
+ </section>
+
+ <section>
+ <title>Multi-database Configuration</title>
+
+ <para>You need to configure each workspace in a repository. You may have
+ each one on different remote servers as far as you need.</para>
+
+ <para>First of all configure the data containers in the
+ <classname>org.exoplatform.services.naming.InitialContextInitializer</classname>
+ service. It's the JNDI context initializer which registers (binds) naming
+ resources (DataSources) for data containers.</para>
+
+ <para>Example (standalone mode, two data containers
+ <parameter>jdbcjcr</parameter> - local HSQLDB,
+ <parameter>jdbcjcr1</parameter> - remote MySQL):<programlisting><component>
+ <key>org.exoplatform.services.naming.InitialContextInitializer</key>
+ <type>org.exoplatform.services.naming.InitialContextInitializer</type>
+ <component-plugins>
+ <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:target/temp/data/portal"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>jdbcjcr1</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="com.mysql.jdbc.Driver"/>
+ <property name="url" value="jdbc:mysql://exoua.dnsalias.net/jcr"/>
+ <property name="username" value="exoadmin"/>
+ <property name="password" value="exo12321"/>
+ <property name="maxActive" value="50"/>
+ <property name="maxIdle" value="5"/>
+ <property name="initialSize" value="5"/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugins>
+ <init-params>
+ <value-param>
+ <name>default-context-factory</name>
+ <value>org.exoplatform.services.naming.SimpleContextFactory</value>
+ </value-param>
+ </init-params>
+ </component></programlisting></para>
+
+ <para>We configure the database connection parameters:<itemizedlist>
+ <listitem>
+ <para><parameter>driverClassName</parameter>, e.g.
+ "org.hsqldb.jdbcDriver", "com.mysql.jdbc.Driver",
+ "org.postgresql.Driver"</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>url</parameter>, e.g.
+ "jdbc:hsqldb:file:target/temp/data/portal",
+ "jdbc:mysql://exoua.dnsalias.net/jcr"</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>username</parameter>, e.g. "sa", "exoadmin"</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>password</parameter>, e.g. "", "exo12321"</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>There can be connection pool configuration parameters
+ (org.apache.commons.dbcp.BasicDataSourceFactory):<itemizedlist>
+ <listitem>
+ <para><parameter>maxActive</parameter>, e.g. 50</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>maxIdle</parameter>, e.g. 5</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>initialSize</parameter>, e.g. 5</para>
+ </listitem>
+
+ <listitem>
+ <para>and other according to <ulink
+ url="http://jakarta.apache.org/commons/dbcp/configuration.html">Apache
+ DBCP configuration</ulink></para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>When the data container configuration is done we can configure the
+ repository service. Each workspace will be configured for its own data
+ container.</para>
+
+ <para>Example (two workspaces <parameter>ws</parameter> - jdbcjcr,
+ <parameter>ws1</parameter> - jdbcjcr1):<programlisting><workspaces>
+ <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr"/>
+ <property name="dialect" value="hsqldb"/>
+ <property name="multi-db" value="true"/>
+ <property name="max-buffer-size" value="200K"/>
+ <property name="swap-directory" value="target/temp/swap/ws"/>
+ </properties>
+ </container>
+ <cache enabled="true">
+ <properties>
+ <property name="max-size" value="10K"/><!-- 10Kbytes -->
+ <property name="live-time" value="30m"/><!-- 30 min -->
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index"/>
+ </properties>
+ </query-handler>
+ <lock-manager>
+ <time-out>15m</time-out><!-- 15 min -->
+ <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+ <properties>
+ <property name="path" value="target/temp/lock/ws"/>
+ </properties>
+ </persister>
+ </lock-manager>
+ </workspace>
+ <workspace name="ws1" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr1"/>
+ <property name="dialect" value="mysql"/>
+ <property name="multi-db" value="true"/>
+ <property name="max-buffer-size" value="200K"/>
+ <property name="swap-directory" value="target/temp/swap/ws1"/>
+ </properties>
+ </container>
+ <cache enabled="true">
+ <properties>
+ <property name="max-size" value="10K"/>
+ <property name="live-time" value="5m"/>
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index"/>
+ </properties>
+ </query-handler>
+ <lock-manager>
+ <time-out>15m</time-out><!-- 15 min -->
+ <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+ <properties>
+ <property name="path" value="target/temp/lock/ws1"/>
+ </properties>
+ </persister>
+ </lock-manager>
+ </workspace>
+</workspaces></programlisting><itemizedlist>
+ <listitem>
+ <para><parameter>source-name</parameter> - a javax.sql.DataSource
+ name configured in InitialContextInitializer component (was
+ <parameter>sourceName</parameter> prior JCR 1.9);</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>dialect</parameter> - a database dialect, one of
+ "hsqldb", "mysql", "mysql-utf8", "pgsql", "oracle", "oracle-oci",
+ "mssql", "sybase", "derby", "db2", "db2v8" or "auto" for dialect
+ autodetection;</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>multi-db</parameter> - enable multi-database
+ container with this parameter (set value "true");</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>max-buffer-size</parameter> - a threshold (in
+ bytes) after which a javax.jcr.Value content will be swapped to a
+ file in a temporary storage. I.e. swap for pending changes.</para>
+ </listitem>
+
+ <listitem>
+ <para><parameter>swap-directory</parameter> - a path in the file
+ system used to swap the pending changes.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>In this way we have configured two workspace which will be persisted
+ in two different databases (ws in HSQLDB, ws1 in MySQL).</para>
+
+ <note>
+ <para>Starting from v.1.9 <link linkend="ch_configuration">repository
+ configuration</link> parameters supports human-readable formats of
+ values (e.g. 200K - 200 Kbytes, 30m - 30 minutes etc)</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Single-database configuration</title>
+
+ <para>It's more simple to configure a single-database data container. We
+ have to configure one naming resource.</para>
+
+ <para>Example (embedded mode for <parameter>jdbcjcr</parameter> data
+ container):<programlisting><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.postgresql.Driver"/>
+ <property name="url" value="jdbc:postgresql://exoua.dnsalias.net/portal"/>
+ <property name="username" value="exoadmin"/>
+ <property name="password" value="exo12321"/>
+ <property name="maxActive" value="50"/>
+ <property name="maxIdle" value="5"/>
+ <property name="initialSize" value="5"/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ </external-component-plugins></programlisting></para>
+
+ <para>And configure repository workspaces in repositories configuration
+ with this one database. Parameter "multi-db" must be switched off (set
+ value "false").</para>
+
+ <para>Example (two workspaces <parameter>ws</parameter> - jdbcjcr,
+ <parameter>ws1</parameter> - jdbcjcr):<programlisting><workspaces>
+ <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr"/>
+ <property name="dialect" value="pgsql"/>
+ <property name="multi-db" value="false"/>
+ <property name="max-buffer-size" value="200K"/>
+ <property name="swap-directory" value="target/temp/swap/ws"/>
+ </properties>
+ </container>
+ <cache enabled="true">
+ <properties>
+ <property name="max-size" value="10K"/>
+ <property name="live-time" value="30m"/>
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="../temp/index"/>
+ </properties>
+ </query-handler>
+ <lock-manager>
+ <time-out>15m</time-out>
+ <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+ <properties>
+ <property name="path" value="target/temp/lock/ws"/>
+ </properties>
+ </persister>
+ </lock-manager>
+ </workspace>
+ <workspace name="ws1" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr"/>
+ <property name="dialect" value="pgsql"/>
+ <property name="multi-db" value="false"/>
+ <property name="max-buffer-size" value="200K"/>
+ <property name="swap-directory" value="target/temp/swap/ws1"/>
+ </properties>
+ </container>
+ <cache enabled="true">
+ <properties>
+ <property name="max-size" value="10K"/>
+ <property name="live-time" value="5m"/>
+ </properties>
+ </cache>
+ <lock-manager>
+ <time-out>15m</time-out>
+ <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+ <properties>
+ <property name="path" value="target/temp/lock/ws1"/>
+ </properties>
+ </persister>
+ </lock-manager>
+ </workspace>
+</workspaces></programlisting></para>
+
+ <para>In this way we have configured two workspaces which will be
+ persisted in one database (PostgreSQL).</para>
+
+ <section>
+ <title>Configuration without DataSource</title>
+
+ <para>Repository configuration without using of the
+ <classname>javax.sql.DataSource</classname> bounded in JNDI.</para>
+
+ <para>This case may be usable if you have a dedicated JDBC driver
+ implementation with special features like XA transactions,
+ statements/connections pooling etc:<itemizedlist>
+ <listitem>
+ <para>You have to remove the configuration in
+ <classname>InitialContextInitializer</classname> for your database
+ and configure a new one directly in the workspace
+ container.</para>
+ </listitem>
+
+ <listitem>
+ <para>Remove parameter "source-name" and add next lines instead.
+ Describe your values for a JDBC driver, database url and
+ username.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <note>
+ <para>But be careful in this case JDBC driver should implement and
+ provide connection pooling. Connection pooling is very recommended for
+ use with JCR to prevent a database overload.</para>
+ </note>
+
+ <programlisting><workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="dialect" value="hsqldb"/>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/portal"/>
+ <property name="username" value="su"/>
+ <property name="password" value=""/>
+ ......</programlisting>
+ </section>
+
+ <section>
+ <title>Dynamic Workspace Creation</title>
+
+ <para>Workspaces can be added dynamically during runtime.</para>
+
+ <para>This can be performed in two steps:<itemizedlist>
+ <listitem>
+ <para>Firstly,
+ <classname>ManageableRepository.configWorkspace(WorkspaceEntry
+ wsConfig)</classname> - register a new configuration in
+ RepositoryContainer and create a WorkspaceContainer.</para>
+ </listitem>
+
+ <listitem>
+ <para>Secondly, the main step,
+ <classname>ManageableRepository.createWorkspace(String
+ workspaceName)</classname> - creation of a new workspace.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Simple and Complex queries</title>
+
+ <para>eXo JCR provides two ways for interact with Database -
+ <classname>JDBCStorageConnection</classname> that uses simple queries and
+ <classname>CQJDBCStorageConection</classname> that uses complex queries
+ for reducing amount of database callings.</para>
+
+ <para>Simple queries will be used if you chose
+ <classname>org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer</classname>:<programlisting><workspaces>
+ <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </workspace>
+</worksapces></programlisting></para>
+
+ <para>Complex queries will be used if you chose
+ <classname>org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer</classname>:<programlisting><workspaces>
+ <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ ...
+ </workspace>
+</worksapces></programlisting></para>
+
+ <para>Why we should use a Complex Queries?<simplelist>
+ <member>They are optimised to reduce amount of requests to
+ database.</member>
+ </simplelist>Why we should use a Simple Queries?<simplelist>
+ <member>Simple queries implemented in way to support as many database
+ dialects as possible.</member>
+
+ <member>Simple queries do not use sub queries, left or right
+ joins.</member>
+ </simplelist></para>
+ </section>
+
+ <section>
+ <title>Forse Query Hints</title>
+
+ <para>Some databases supports hints to increase query performance (like
+ Oracle, MySQL, etc). eXo JCR have separate Complex Query implementation
+ for Orcale dialect, that uses query hints to increase performance for few
+ important queries.</para>
+
+ <para>To enable this option put next configuration
+ property:<programlisting><workspace name="ws" auto-init-root-nodetype="nt:unstructured">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="dialect" value="oracle"/>
+ <property name="force.query.hints" value="true" />
+ ......</programlisting></para>
+
+ <para>Query hints enabled by default.</para>
+
+ <para>eXo JCR uses query hints only for Complex Query Oracle dialect. For
+ all other dialects this parameter is ignored.</para>
+ </section>
+
+ <section>
+ <title>Notes for Microsoft Windows users</title>
+
+ <para>The current configuration of eXo JCR uses <ulink
+ url="http://commons.apache.org/dbcp/">Apache DBCP</ulink> connection pool
+ (<classname>org.apache.commons.dbcp.BasicDataSourceFactory</classname>).
+ It's possible to set a big value for maxActive parameter in
+ <filename>configuration.xml</filename>. That means usage of lots of TCP/IP
+ ports from a client machine inside the pool (i.e. JDBC driver). As a
+ result the data container can throw exceptions like "Address already in
+ use". To solve this problem you have to configure the client's machine
+ networking software for the usage of shorter timeouts for opened TCP/IP
+ ports.</para>
+
+ <para>Microsoft Windows has <parameter>MaxUserPort</parameter>,
+ <parameter>TcpTimedWaitDelay</parameter> registry keys in the node
+ <parameter>HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters</parameter>,
+ by default these keys are unset, set each one with values like
+ these:<itemizedlist>
+ <listitem>
+ <para>"TcpTimedWaitDelay"=dword:0000001e, sets TIME_WAIT parameter
+ to 30 seconds, default is 240.</para>
+ </listitem>
+
+ <listitem>
+ <para>"MaxUserPort"=dword:00001b58, sets the maximum of open ports
+ to 7000 or higher, default is 5000.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>A sample registry file is below:<programlisting>Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
+"MaxUserPort"=dword:00001b58
+"TcpTimedWaitDelay"=dword:0000001e</programlisting></para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/multilanguage-support.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="ch_multilanguage_support">
+ <?dbhtml filename="ch-multilanguage-support.html"?>
+
+ <title>Multilanguage support in eXo JCR RDB backend</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>Whenever relational database is used to store multilingual text data
+ of eXo Java Content Repository we need to adapt configuration in order to
+ support UTF-8 encoding. Here is a short HOWTO instruction for several
+ supported RDBMS with examples.</para>
+
+ <para>The configuration file you have to modify:
+ .../webapps/portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
+
+ <note>
+ <para>Datasource <parameter>jdbcjcr</parameter> used in examples can be
+ configured via <classname>InitialContextInitializer</classname>
+ component.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Oracle</title>
+
+ <para>In order to run multilanguage JCR on an Oracle backend Unicode
+ encoding for characters set should be applied to the database. Other
+ Oracle globalization parameters don't make any impact. The only property
+ to modify is <constant>NLS_CHARACTERSET</constant>.</para>
+
+ <para>We have tested <constant>NLS_CHARACTERSET</constant> =
+ <constant>AL32UTF8</constant> and it's works well for many European and
+ Asian languages.</para>
+
+ <para>Example of database configuration (used for JCR
+ testing):<programlisting>NLS_LANGUAGE AMERICAN
+NLS_TERRITORY AMERICA
+NLS_CURRENCY $
+NLS_ISO_CURRENCY AMERICA
+NLS_NUMERIC_CHARACTERS .,
+NLS_CHARACTERSET AL32UTF8
+NLS_CALENDAR GREGORIAN
+NLS_DATE_FORMAT DD-MON-RR
+NLS_DATE_LANGUAGE AMERICAN
+NLS_SORT BINARY
+NLS_TIME_FORMAT HH.MI.SSXFF AM
+NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
+NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
+NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
+NLS_DUAL_CURRENCY $
+NLS_COMP BINARY
+NLS_LENGTH_SEMANTICS BYTE
+NLS_NCHAR_CONV_EXCP FALSE
+NLS_NCHAR_CHARACTERSET AL16UTF16</programlisting></para>
+
+ <warning>
+ <para>JCR 1.12.x doesn't use NVARCHAR columns, so that the value of the
+ parameter NLS_NCHAR_CHARACTERSET does not matter for JCR.</para>
+ </warning>
+
+ <para>Create database with Unicode encoding and use Oracle dialect for the
+ Workspace Container:</para>
+
+ <programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="oracle" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting>
+ </section>
+
+ <section>
+ <title>DB2</title>
+
+ <para>DB2 Universal Database (DB2 UDB) supports <ulink
+ url="http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.i...">UTF-8
+ and UTF-16/UCS-2</ulink>. When a Unicode database is created, CHAR,
+ VARCHAR, LONG VARCHAR data are stored in UTF-8 form. It's enough for JCR
+ multi-lingual support.</para>
+
+ <para>Example of UTF-8 database creation:<programlisting>DB2 CREATE DATABASE dbname USING CODESET UTF-8 TERRITORY US</programlisting></para>
+
+ <para>Create database with UTF-8 encoding and use db2 dialect for
+ Workspace Container on DB2 v.9 and higher:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="db2" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+
+ <note>
+ <para>For DB2 v.8.x support change the property "dialect" to
+ db2v8.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>MySQL</title>
+
+ <para>JCR MySQL-backend requires special dialect <ulink
+ url="http://jira.exoplatform.org/browse/JCR-375">MySQL-UTF8</ulink> to be
+ used for internationalization support. But the database default charset
+ should be latin1 to use limited index space effectively (1000 bytes for
+ MyISAM engine, 767 for InnoDB). If database default charset is multibyte,
+ a JCR database initialization error is thrown concerning index creation
+ failure. In other words JCR can work on any singlebyte default charset of
+ database, with UTF8 supported by MySQL server. But we have tested it only
+ on latin1 database default charset.</para>
+
+ <para>Repository configuration, workspace container entry
+ example:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="mysql-utf8" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+ </section>
+
+ <section>
+ <title>PostgreSQL</title>
+
+ <para>On PostgreSQL-backend multilingual support can be enabled in <ulink
+ url="http://www.postgresql.org/docs/8.3/interactive/charset.html">different
+ ways</ulink>:<itemizedlist>
+ <listitem>
+ <para>Using the locale features of the operating system to provide
+ locale-specific collation order, number formatting, translated
+ messages, and other aspects. UTF-8 is widely used on Linux
+ distributions by default, so it can be useful in such case.</para>
+ </listitem>
+
+ <listitem>
+ <para>Providing a number of different character sets defined in the
+ PostgreSQL server, including multiple-byte character sets, to
+ support storing text any language, and providing character set
+ translation between client and server. We recommend to use UTF-8
+ database charset, it will allow any-to-any conversations and make
+ this issue transparent for the JCR.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Create database with UTF-8 encoding and use PgSQL dialect for
+ Workspace Container:<programlisting><workspace name="collaboration">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr" />
+ <property name="dialect" value="pgsql" />
+ <property name="multi-db" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws" />
+ </properties>
+ .....</programlisting></para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/rest-services-on-groovy.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/rest-services-on-groovy.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/rest-services-on-groovy.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.RESTServicesOnGroovy">
+ <?dbhtml filename="ch-jcr-rest-services-on-groovy.html"?>
+
+ <title>REST Services on Groovy</title>
+
+ <section>
+ <title>Concept</title>
+
+ <para>Starting from version 1.9 JCR Service supports REST services
+ creation on <ulink url="http://groovy.codehaus.org">Groovy
+ script</ulink>.</para>
+
+ <para>The feature based on <link linkend="WS.RestFramework">RESTful
+ framework</link> and uses ResourceContainer concept.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>Scripts should extend ResourceContainer and should be stored in JCR
+ as a node of type exo:groovyResourceContainer.</para>
+
+ <para>Detailed REST services step-by-step implementation check there <link
+ linkend="WS.RestServiceTutorial">Create REST service step by
+ step</link>.</para>
+
+ <para>Component configuration enables Groovy services loader:</para>
+
+ <programlisting><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.GroovyScript2RestLoader$ObservationListenerConfiguration">
+ <field name="repository">
+ <string>repository</string>
+ </field>
+ <field name="workspaces">
+ <collection type="java.util.ArrayList">
+ <value>
+ <string>collaboration</string>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+</component></programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/search-configuration.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,818 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.SearchConfiguration">
+ <?dbhtml filename="ch-jcr-search-configuration.html"?>
+
+ <title>Search Configuration</title>
+
+ <section>
+ <title>XML Configuration</title>
+
+ <para>JCR index configuration. You can find this file here:
+ <filename>.../portal/WEB-INF/conf/jcr/repository-configuration.xml</filename></para>
+
+ <programlisting><repository-service default-repository="db1">
+ <repositories>
+ <repository name="db1" system-workspace="ws" default-workspace="ws">
+ ....
+ <workspaces>
+ <workspace name="ws">
+ ....
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="${java.io.tmpdir}/temp/index/db1/ws" />
+ <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+ <property name="synonymprovider-config-path" value="/synonyms.properties" />
+ <property name="indexing-config-path" value="/indexing-configuration.xml" />
+ <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+ </properties>
+ </query-handler>
+ ...
+ </workspace>
+ </workspaces>
+ </repository>
+ </repositories>
+</repository-service></programlisting>
+ </section>
+
+ <section>
+ <title>Configuration parameters</title>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Parameter</entry>
+
+ <entry>Default</entry>
+
+ <entry>Description</entry>
+
+ <entry>Since</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>index-dir</entry>
+
+ <entry>none</entry>
+
+ <entry>The location of the index directory. This parameter is
+ mandatory. Up to 1.9 this parameter called "indexDir"</entry>
+
+ <entry>1.0</entry>
+ </row>
+
+ <row>
+ <entry>use-compoundfile</entry>
+
+ <entry>true</entry>
+
+ <entry>Advises lucene to use compound files for the index
+ files.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>min-merge-docs</entry>
+
+ <entry>100</entry>
+
+ <entry>Minimum number of nodes in an index until segments are
+ merged.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>volatile-idle-time</entry>
+
+ <entry>3</entry>
+
+ <entry>Idle time in seconds until the volatile index part is moved
+ to a persistent index even though minMergeDocs is not
+ reached.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>max-merge-docs</entry>
+
+ <entry>Integer.MAX_VALUE</entry>
+
+ <entry>Maximum number of nodes in segments that will be merged.
+ The default value changed in JCR 1.9 to Integer.MAX_VALUE.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>merge-factor</entry>
+
+ <entry>10</entry>
+
+ <entry>Determines how often segment indices are merged.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>max-field-length</entry>
+
+ <entry>10000</entry>
+
+ <entry>The number of words that are fulltext indexed at most per
+ property.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>cache-size</entry>
+
+ <entry>1000</entry>
+
+ <entry>Size of the document number cache. This cache maps uuids to
+ lucene document numbers</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>force-consistencycheck</entry>
+
+ <entry>false</entry>
+
+ <entry>Runs a consistency check on every startup. If false, a
+ consistency check is only performed when the search index detects
+ a prior forced shutdown.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>auto-repair</entry>
+
+ <entry>true</entry>
+
+ <entry>Errors detected by a consistency check are automatically
+ repaired. If false, errors are only written to the log.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>query-class</entry>
+
+ <entry>QueryImpl</entry>
+
+ <entry>Class name that implements the javax.jcr.query.Query
+ interface.This class must also extend from the class:
+ org.exoplatform.services.jcr.impl.core.query.AbstractQueryImpl.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>document-order</entry>
+
+ <entry>true</entry>
+
+ <entry>If true and the query does not contain an 'order by'
+ clause, result nodes will be in document order. For better
+ performance when queries return a lot of nodes set to
+ 'false'.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>result-fetch-size</entry>
+
+ <entry>Integer.MAX_VALUE</entry>
+
+ <entry>The number of results when a query is executed. Default
+ value: Integer.MAX_VALUE (-> all).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>excerptprovider-class</entry>
+
+ <entry>DefaultXMLExcerpt</entry>
+
+ <entry>The name of the class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.ExcerptProvider
+ and should be used for the rep:excerpt() function in a
+ query.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>support-highlighting</entry>
+
+ <entry>false</entry>
+
+ <entry>If set to true additional information is stored in the
+ index to support highlighting using the rep:excerpt()
+ function.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>synonymprovider-class</entry>
+
+ <entry>none</entry>
+
+ <entry>The name of a class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.SynonymProvider.
+ The default value is null (-> not set).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>synonymprovider-config-path</entry>
+
+ <entry>none</entry>
+
+ <entry>The path to the synonym provider configuration file. This
+ path interpreted relative to the path parameter. If there is a
+ path element inside the SearchIndex element, then this path is
+ interpreted relative to the root path of the path. Whether this
+ parameter is mandatory depends on the synonym provider
+ implementation. The default value is null (-> not set).</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>indexing-configuration-path</entry>
+
+ <entry>none</entry>
+
+ <entry>The path to the indexing configuration file.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>indexing-configuration-class</entry>
+
+ <entry>IndexingConfigurationImpl</entry>
+
+ <entry>The name of the class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfiguration.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>force-consistencycheck</entry>
+
+ <entry>false</entry>
+
+ <entry>If set to true a consistency check is performed depending
+ on the parameter forceConsistencyCheck. If set to false no
+ consistency check is performed on startup, even if a redo log had
+ been applied.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-class</entry>
+
+ <entry>none</entry>
+
+ <entry>The name of a class that implements
+ org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-more-popular</entry>
+
+ <entry>true</entry>
+
+ <entry>If set true - spellchecker return only the suggest words
+ that are as frequent or more frequent than the checked word. If
+ set false, spellchecker return null (if checked word exit in
+ dictionary), or spellchecker will return most close suggest
+ word.</entry>
+
+ <entry>1.10</entry>
+ </row>
+
+ <row>
+ <entry>spellchecker-min-distance</entry>
+
+ <entry>0.55f</entry>
+
+ <entry>Minimal distance between checked word and proposed suggest
+ word.</entry>
+
+ <entry>1.10</entry>
+ </row>
+
+ <row>
+ <entry>errorlog-size</entry>
+
+ <entry>50(Kb)</entry>
+
+ <entry>The default size of error log file in Kb.</entry>
+
+ <entry>1.9</entry>
+ </row>
+
+ <row>
+ <entry>upgrade-index</entry>
+
+ <entry>false</entry>
+
+ <entry>Allows JCR to convert an existing index into the new
+ format. Also it is possible to set this property via system
+ property, for example: -Dupgrade-index=true Indexes before JCR
+ 1.12 will not run with JCR 1.12. Hence you have to run an
+ automatic migration: Start JCR with -Dupgrade-index=true. The old
+ index format is then converted in the new index format. After the
+ conversion the new format is used. On the next start you don't
+ need this option anymore. The old index is replaced and a back
+ conversion is not possible - therefore better take a backup of the
+ index before. (Only for migrations from JCR 1.9 and
+ later.)</entry>
+
+ <entry>1.12</entry>
+ </row>
+
+ <row>
+ <entry>analyzer</entry>
+
+ <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
+
+ <entry>Class name of a lucene analyzer to use for fulltext
+ indexing of text.</entry>
+
+ <entry>1.12</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Global Search Index</title>
+
+ <section>
+ <title>Global Search Index Configuration</title>
+
+ <para>The global search index is configured in the above-mentioned
+ configuration file
+ (<filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>)
+ in the tag "query-handler".</para>
+
+ <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>
+
+ <para>In fact when using Lucene you always should use the same analyzer
+ for indexing and for querying - otherwise the results are unpredictable.
+ You don't have to worry about this, eXo JCR does this for you
+ automatically. If you don't like the StandardAnalyzer configured by
+ default just replace it by your own.</para>
+
+ <para>If you don't have a handy QueryHandler you will learn how create a
+ customized Handler in 5 minutes.</para>
+ </section>
+
+ <section>
+ <title>Customized Search Indexes and Analyzers</title>
+
+ <para>By default Exo JCR uses the Lucene standard Analyzer to index
+ contents. This analyzer uses some standard filters in the method that
+ analyzes the content:<programlisting>public TokenStream tokenStream(String fieldName, Reader reader) {
+ StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);
+ tokenStream.setMaxTokenLength(maxTokenLength);
+ TokenStream result = new StandardFilter(tokenStream);
+ result = new LowerCaseFilter(result);
+ result = new StopFilter(result, stopSet);
+ return result;
+ }</programlisting><itemizedlist>
+ <listitem>
+ <para>The first one (StandardFilter) removes 's (as 's in
+ "Peter's") from the end of words and removes dots from
+ acronyms.</para>
+ </listitem>
+
+ <listitem>
+ <para>The second one (LowerCaseFilter) normalizes token text to
+ lower case.</para>
+ </listitem>
+
+ <listitem>
+ <para>The last one (StopFilter) removes stop words from a token
+ stream. The stop set is defined in the analyzer.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>For specific cases, you may wish to use additional filters like
+ <phrase>ISOLatin1AccentFilter</phrase>, which replaces accented
+ characters in the ISO Latin 1 character set (ISO-8859-1) by their
+ unaccented equivalents.</para>
+
+ <para>In order to use a different filter, you have to create a new
+ analyzer, and a new search index to use the analyzer. You put it in a
+ jar, which is deployed with your application.</para>
+
+ <section>
+ <title>Create the filter</title>
+
+ <para>The ISOLatin1AccentFilter is not present in the current Lucene
+ version used by Exo. You can use the attached file. You can also
+ create your own filter, the relevant method is<programlisting>public final Token next(final Token reusableToken) throws java.io.IOException</programlisting>which
+ defines how chars are read and used by the filter.</para>
+ </section>
+
+ <section>
+ <title>Create the analyzer</title>
+
+ <para>The analyzer have to extends
+ org.apache.lucene.analysis.standard.StandardAnalyzer, and overload the
+ method<programlisting>public TokenStream tokenStream(String fieldName, Reader reader)</programlisting>to
+ put your own filters. You can have a glance at the example analyzer
+ attached to this article.</para>
+ </section>
+
+ <section>
+ <title>Create the search index</title>
+
+ <para>Now, we have the analyzer, we have to write the SearchIndex,
+ which will use the analyzer. Your have to extends
+ org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex. You
+ have to write the constructor, to set the right analyzer, and the
+ method<programlisting>public Analyzer getAnalyzer() {
+ return MyAnalyzer;
+ }</programlisting>to return your analyzer. You can see the attached
+ SearchIndex.</para>
+
+ <note>
+ <para>Since 1.12 version we can set Analyzer directly in
+ configuration. So, creation new SearchIndex only for new Analyzer is
+ redundant.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Configure your application to use your SearchIndex</title>
+
+ <para>In
+ <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
+ you have to replace each<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>by
+ your own class<programlisting><query-handler class="mypackage.indexation.MySearchIndex"></programlisting></para>
+ </section>
+
+ <section>
+ <title>Configure your application to use your Analyzer</title>
+
+ <para>In
+ <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
+ you have to add parameter "analyzer" to each query-handler
+ config:<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ ...
+ <property name="analyzer" value="org.exoplatform.services.jcr.impl.core.MyAnalyzer"/>
+ ...
+ </properties>
+</query-handler></programlisting></para>
+
+ <para>When you start exo, your SearchIndex will start to index
+ contents with the specified filters.</para>
+ </section>
+ </section>
+ </section>
+
+ <section>
+ <title>Index Adjustments</title>
+
+ <section>
+ <title>IndexingConfiguration</title>
+
+ <para>Starting with version 1.9, the default search index implementation
+ in JCR allows you to control which properties of a node are indexed. You
+ also can define different analyzers for different nodes.</para>
+
+ <para>The configuration parameter is called indexingConfiguration and
+ per default is not set. This means all properties of a node are
+ indexed.</para>
+
+ <para>If you wish to configure the indexing behavior you need to add a
+ parameter to the query-handler element in your configuration
+ file.</para>
+
+ <programlisting><param name="indexing-configuration-path" value="/indexing_configuration.xml"/></programlisting>
+ </section>
+
+ <section>
+ <title>Index rules</title>
+
+ <section>
+ <title>Node Scope Limit</title>
+
+ <para>To optimize the index size you can limit the node scope so that
+ <phrase>only certain properties</phrase> of a node type are
+ indexed.</para>
+
+ <para>With the below configuration only properties named Text are
+ indexed for nodes of type nt:unstructured. This configuration also
+ applies to all nodes whose type extends from nt:unstructured.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+
+ <para>Please note that you have to declare the <phrase>namespace
+ prefixes</phrase> in the configuration element that you are using
+ throughout the XML file!</para>
+ </section>
+
+ <section>
+ <title>Index Boost Value</title>
+
+ <para>It is also possible to configure a <phrase>boost value</phrase>
+ for the nodes that match the index rule. The default boost value is
+ 1.0. Higher boost values (a reasonable range is 1.0 - 5.0) will yield
+ a higher score value and appear as more relevant.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+
+ <para>If you do not wish to boost the complete node but only certain
+ properties you can also provide a boost value for the listed
+ properties:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property boost="3.0">Title</property>
+ <property boost="1.5">Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+ </section>
+
+ <section>
+ <title>Conditional Index Rules</title>
+
+ <para>You may also add a <phrase>condition</phrase> to the index rule
+ and have multiple rules with the same nodeType. The first index rule
+ that matches will apply and all remaining ones are
+ ignored:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+
+ <para>In the above example the first rule only applies if the
+ nt:unstructured node has a priority property with a value 'high'. The
+ condition syntax supports only the equals operator and a string
+ literal.</para>
+
+ <para>You may also reference properties in the condition that are not
+ on the current node:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="ancestor::*/@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured"
+ boost="0.5"
+ condition="parent::foo/@priority = 'low'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured"
+ boost="1.5"
+ condition="bar/@priority = 'medium'">
+ <property>Text</property>
+ </index-rule>
+ <index-rule nodeType="nt:unstructured">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+
+ <para>The indexing configuration also allows you to specify the type
+ of a node in the condition. Please note however that the type match
+ must be exact. It does not consider sub types of the specified node
+ type.</para>
+
+ <programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured"
+ boost="2.0"
+ condition="element(*, nt:unstructured)/@priority = 'high'">
+ <property>Text</property>
+ </index-rule>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>Exclusion from the Node Scope Index</title>
+
+ <para>Per default all configured properties are fulltext indexed if
+ they are of type STRING and included in the node scope index. A node
+ scope search finds normally all nodes of an index. That is, the select
+ jcr:contains(., 'foo') returns all nodes that have a string property
+ containing the word 'foo'. You can exclude explicitly a property from
+ the node scope index:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <index-rule nodeType="nt:unstructured">
+ <property nodeScopeIndex="false">Text</property>
+ </index-rule>
+</configuration></programlisting></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Index Aggregates</title>
+
+ <para>Sometimes it is useful to include the contents of descendant nodes
+ into a single node to easier search on content that is scattered across
+ multiple nodes.</para>
+
+ <para>JCR allows you to define index aggregates based on relative path
+ patterns and primary node types.</para>
+
+ <para>The following example creates an index aggregate on nt:file that
+ includes the content of the jcr:content node:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include>jcr:content</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>You can also restrict the included nodes to a certain
+ type:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include primaryType="nt:resource">jcr:content</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>You may also use the * to match all child nodes:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">http://wiki.exoplatform.com/xwiki/bin/edit/JCR/Search+Configuration
+ <include primaryType="nt:resource">*</include>
+ </aggregate>
+</configuration></programlisting></para>
+
+ <para>If you wish to include nodes up to a certain depth below the
+ current node you can add multiple include elements. E.g. the nt:file
+ node may contain a complete XML document under
+ jcr:content:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <aggregate primaryType="nt:file">
+ <include>*</include>
+ <include>*/*</include>
+ <include>*/*/*</include>
+ </aggregate>
+</configuration></programlisting></para>
+ </section>
+
+ <section>
+ <title>Property-Level Analyzers</title>
+
+ <section>
+ <title>Example</title>
+
+ <para>In this configuration section you define how a property has to
+ be analyzed. If there is an analyzer configuration for a property,
+ this analyzer is used for indexing and searching of this property. For
+ example:<programlisting><?xml version="1.0"?>
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+ <analyzers>
+ <analyzer class="org.apache.lucene.analysis.KeywordAnalyzer">
+ <property>mytext</property>
+ </analyzer>
+ <analyzer class="org.apache.lucene.analysis.WhitespaceAnalyzer">
+ <property>mytext2</property>
+ </analyzer>
+ </analyzers>
+</configuration></programlisting></para>
+
+ <para>The configuration above means that the property "mytext" for the
+ entire workspace is indexed (and searched) with the Lucene
+ KeywordAnalyzer, and property "mytext2" with the WhitespaceAnalyzer.
+ Using different analyzers for different languages is particularly
+ useful.</para>
+
+ <para>The WhitespaceAnalyzer tokenizes a property, the KeywordAnalyzer
+ takes the property as a whole.</para>
+ </section>
+
+ <section>
+ <title>Characteristics of Node Scope Searches</title>
+
+ <para>When using analyzers, you may encounter an unexpected behavior
+ when searching within a property compared to searching within a node
+ scope. The reason is that the node scope always uses the global
+ analyzer.</para>
+
+ <para>Let's suppose that the property "mytext" contains the text :
+ "testing my analyzers" and that you haven't configured any analyzers
+ for the property "mytext" (and not changed the default analyzer in
+ SearchIndex).</para>
+
+ <para>If your query is for example:<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting></para>
+
+ <para>This xpath does not return a hit in the node with the property
+ above and default analyzers.</para>
+
+ <para>Also a search on the node scope<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>won't
+ give a hit. Realize, that you can only set specific analyzers on a
+ node property, and that the node scope indexing/analyzing is always
+ done with the globally defined analyzer in the SearchIndex
+ element.</para>
+
+ <para>Now, if you change the analyzer used to index the "mytext"
+ property above to<programlisting><analyzer class="org.apache.lucene.analysis.Analyzer.GermanAnalyzer">
+ <property>mytext</property>
+</analyzer></programlisting>and you do the same search again, then
+ for<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting>you
+ would get a hit because of the word stemming (analyzers -
+ analyzer).</para>
+
+ <para>The other search,<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>still
+ would not give a result, since the node scope is indexed with the
+ global analyzer, which in this case does not take into account any
+ word stemming.</para>
+
+ <para>In conclusion, be aware that when using analyzers for specific
+ properties, you might find a hit in a property for some search text,
+ and you do not find a hit with the same search text in the node scope
+ of the property!</para>
+
+ <note>
+ <para>Both index rules and index aggregates influence how content is
+ indexed in JCR. If you change the configuration the existing content
+ is not automatically re-indexed according to the new rules. You
+ therefore have to manually re-index the content when you change the
+ configuration!</para>
+ </note>
+ </section>
+ </section>
+ <section>
+ <title>Advanced features</title>
+ <para>Exo JCR supports some advanced features, which are not specified in JSR 170:
+ * Get a text excerpt with
+ <emphasis role="bold">highlighted words</emphasis> that matches the query:
+ <ulink url="ExcerptProvider>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">ExcerptProvider</ulink>.
+ * Search for a term and its
+ <emphasis role="bold">synonyms</emphasis>:
+ <ulink url="SynonymSearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SynonymSearch</ulink>
+ * Search for
+ <emphasis role="bold">similar</emphasis> nodes:
+ <ulink url="SimilaritySearch>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SimilaritySearch</ulink>
+ * Check
+ <emphasis role="bold">spelling</emphasis> of a fulltext query statement:
+ <ulink url="SpellChecker>http://wiki.exoplatform.com/xwiki/bin/view/JCR/Searching+Repository+Content">SpellChecker</ulink>
+ * Define index
+ <emphasis role="bold">aggregates and rules</emphasis>: IndexingConfiguration (see this article)
+ </para>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration/workspace-persistence-storage.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.WorkspaceDataContainer">
+ <?dbhtml filename="ch-jcr-workspace-data-container.html"?>
+ <title>Workspace Data Container</title>
+
+ <para>Each Workspace of JCR has its own persistent storage to hold
+ workspace's items data. eXo Content Repository can be configured so that it
+ can use one or more workspaces that are logical units of the repository
+ content. Physical data storage mechanism is configured using mandatory
+ element <emphasis role="bold">container</emphasis>. The type of container is
+ described in the attribute <emphasis role="bold">class</emphasis> = fully
+ qualified name of
+ org.exoplatform.services.jcr.storage.WorkspaceDataContainer subclass
+ like</para>
+
+ <programlisting><container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr1"/>
+ <property name="dialect" value="hsqldb"/>
+ <property name="multi-db" value="true"/>
+ <property name="max-buffer-size" value="200K"/>
+ <property name="swap-directory" value="target/temp/swap/ws"/>
+ </properties></programlisting>
+
+ <para>Properties are Container specific parameters:</para>
+
+ <para><emphasis role="bold">source-name</emphasis> - JDBC data source name,
+ registered in JDNI by InitialContextInitializer. ( <emphasis
+ role="bold">sourceName</emphasis> prior v.1.9)</para>
+
+ <para><emphasis role="bold">dialect</emphasis> - database dialect, one of
+ "hsqldb", "mysql", "mysql-utf8", "pgsql", "oracle", "oracle-oci", "mssql",
+ "sybase", "derby", "db2", "db2v8"</para>
+
+ <para><emphasis role="bold">multi-db</emphasis> - enable multi-database
+ container with this parameter (if "true").</para>
+
+ <para><emphasis role="bold">max-buffer-size</emphasis> - a threshold in
+ bytes, if a value size is greater then it will be spooled to a temporary
+ file.</para>
+
+ <para><emphasis role="bold">swap-directory</emphasis> - a location where the
+ value will be spooled if no value storage is configured but a
+ max-buffer-size is exceeded.</para>
+
+ <para>eXo JCR has an RDB (JDBC) based, production ready <emphasis
+ role="bold">Workspace Data Container</emphasis>.</para>
+
+ <para>Workspace Data Container MAY support external storages for
+ javax.jcr.Value (which can be the case for BLOB values for example) using
+ the optional element <emphasis role="bold">value-storages</emphasis>. Data
+ Container will try to read or write Value using underlying value storage
+ plugin if the filter criteria (see below) match the current property.</para>
+
+ <programlisting><value-storages>
+ <value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="data/values"/>
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="1M"/><!-- Values large of 1Mbyte -->
+ </filters>
+.........
+</value-storages></programlisting>
+
+ <para>Where <emphasis role="bold">value-storage</emphasis> is the subclass
+ of org.exoplatform.services.jcr.storage.value.ValueStoragePlugin and
+ <emphasis role="bold">properties</emphasis> are optional plugin specific
+ parameters.</para>
+
+ <para><emphasis role="bold">filters</emphasis> : Each file value storage can
+ have the filter(s) for incoming values. If there are several filter
+ criteria, they all have to match (AND-Condition).</para>
+
+ <para>A filter can match values by property type (property-type), property
+ name (property-name), ancestor path (ancestor-path) and/or the size of
+ values stored (min-value-size, e.g. 1M, 4.2G, 100 (bytes)).</para>
+
+ <para>In a code sample we use a filter with property-type and min-value-size
+ only. That means that the storage is only for binary values whose size is
+ greater than 1Mbyte.</para>
+
+ <para>It's recommended to store properties with large values in a file value
+ storage only.</para>
+</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration-persister.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration-persister.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration-persister.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_configuration_persister">
- <?dbhtml filename="ch-configuration-persister.html"?>
- <title>JCR Configuration persister</title>
-
- <section>
- <title>Idea</title>
-
- <para>JCR Repository Service uses
- <classname>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</classname>
- component to read its configuration.</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR configuration file</description>
- <value>/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- </init-params>
- </component></programlisting>
-
- <para>In the example Repository Service will read the configuration from
- the file <filename>/conf/standalone/exo-jcr-config.xml</filename>.</para>
-
- <para>But in some cases it's required to change the configuration on the
- fly. And know that the new one will be used. Additionally we wish not to
- modify the original file.</para>
-
- <para>In this case we have to use the configuration persister feature
- which allows to store the configuration in different locations.</para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <para>On startup <classname>RepositoryServiceConfiguration</classname>
- component checks if a configuration persister was configured. In that case
- it uses the provided <classname>ConfigurationPersister</classname>
- implementation class to instantiate the persister object.</para>
-
- <para>Configuration with persister:<programlisting><component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR configuration file</description>
- <value>/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- <properties-param>
- <name>working-conf</name>
- <description>working-conf</description>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="mysql" />
- <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
- </properties-param>
- </init-params>
- </component></programlisting></para>
-
- <para>Where:<itemizedlist>
- <listitem>
- <para><parameter>source-name</parameter> - JNDI source name
- configured in <classname>InitialContextInitializer</classname>
- component. (<parameter>sourceName</parameter> prior v.1.9.) Find
- more in <link linkend="ch_configuration">database
- configuration</link>.</para>
- </listitem>
-
- <listitem>
- <para><parameter>dialect</parameter> - SQL dialect which will be
- used with database from <parameter>source-name</parameter>. Find
- more in <link linkend="ch_configuration">database
- configuration</link>.</para>
- </listitem>
-
- <listitem>
- <para><parameter>persister-class-name</parameter> - class name of
- <classname>ConfigurationPersister</classname> interface
- implementation. (<parameter>persisterClassName</parameter> prior
- v.1.9.)</para>
- </listitem>
- </itemizedlist></para>
-
- <para>ConfigurationPersister interface:<programlisting>/**
- * Init persister.
- * Used by RepositoryServiceConfiguration on init.
- * @return - config data stream
- */
- void init(PropertiesParam params) throws RepositoryConfigurationException;
-
- /**
- * Read config data.
- * @return - config data stream
- */
- InputStream read() throws RepositoryConfigurationException;
-
- /**
- * Create table, write data.
- * @param confData - config data stream
- */
- void write(InputStream confData) throws RepositoryConfigurationException;
-
- /**
- * Tell if the config exists.
- * @return - flag
- */
- boolean hasConfig() throws RepositoryConfigurationException;</programlisting></para>
-
- <para>JCR Core implementation contains a persister which stores the
- repository configuration in the relational database using JDBC calls -
- <classname>org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister</classname>.</para>
-
- <para>The implementation will crate and use table JCR_CONFIG in the
- provided database.</para>
-
- <para>But the developer can implement his own persister for his particular
- usecase.</para>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/configuration.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,436 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_configuration">
- <?dbhtml filename="ch-configuration.html"?>
-
- <title>eXo JCR configuration</title>
-
- <section>
- <title>Related documents</title>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="ch_search_configuration">Search
- Configuration</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="ch_jdbc_data_container">JDBC Data Container
- config</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="ch_external_value_storages">External Value
- Storages</link></para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Portal and Standalone configuration</title>
-
- <para>Like other eXo services eXo JCR can be configured and used in portal
- or embedded mode (as a service embedded in eXo Portal) and in standalone
- mode.</para>
-
- <para>In Embedded mode, JCR services are registered in the Portal
- container and the second option is to use a Standalone container. The main
- difference between these container types is that the first one is intended
- to be used in a Portal (Web) environment, while the second one can be used
- standalone (TODO see the comprehensive page Service Configuration for
- Beginners for more details).</para>
-
- <para>The following setup procedure is used to obtain a Standalone
- configuration (TODO find more in Container configuration):</para>
-
- <itemizedlist>
- <listitem>
- <para>Configuration that is set explicitly using
- StandaloneContainer.addConfigurationURL(String url) or
- StandaloneContainer.addConfigurationPath(String path) before
- getInstance()</para>
- </listitem>
-
- <listitem>
- <para>Configuration from $base:directory/exo-configuration.xml or
- $base:directory/conf/exo-configuration.xml file. Where $base:directory
- is either AS's home directory in case of J2EE AS environment or just
- the current directory in case of a standalone application.</para>
- </listitem>
-
- <listitem>
- <para>/conf/exo-configuration.xml in the current classloader (e.g.
- war, ear archive)</para>
- </listitem>
-
- <listitem>
- <para>Configuration from
- $service_jar_file/conf/portal/configuration.xml. WARNING: do not rely
- on some concrete jar's configuration if you have more than one jar
- containing conf/portal/configuration.xml file. In this case choosing a
- configuration is unpredictable.</para>
- </listitem>
- </itemizedlist>
-
- <para>JCR service configuration looks like:</para>
-
- <programlisting><component>
- <key>org.exoplatform.services.jcr.RepositoryService</key>
- <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
- </component>
- <component>
- <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
- <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
- <init-params>
- <value-param>
- <name>conf-path</name>
- <description>JCR repositories configuration file</description>
- <value>jar:/conf/standalone/exo-jcr-config.xml</value>
- </value-param>
- <properties-param>
- <name>working-conf</name>
- <description>working-conf</description>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="hsqldb" />
- <property name="persister-class-name" value="org.exoplatform.services.jcr.impl.config.JDBCConfigurationPersister" />
- </properties-param>
- </init-params>
- </component></programlisting>
-
- <para>conf-path : a path to a RepositoryService JCR Configuration</para>
-
- <para>working-conf : optional; JCR configuration persister configuration.
- If there isn't a working-conf the persister will be disabled</para>
-
- <section>
- <title>JCR Configuration</title>
-
- <para>The Configuration is defined in an XML file (see DTD
- below).</para>
-
- <para>JCR Service can use multiple Repositories and each repository can
- have multiple Workspaces.</para>
-
- <para>Repositories configuration parameters support human-readable
- formats of values. They are all case-insensitive:</para>
-
- <itemizedlist>
- <listitem>
- <para>Numbers formats: K,KB - kilobytes, M,MB - megabytes, G,GB -
- gigabytes, T,TB - terabytes.</para>
-
- <para>Examples: 100.5 - digit 100.5, 200k - 200 Kbytes, 4m - 4
- Mbytes, 1.4G - 1.4 Gbytes, 10T - 10 Tbytes</para>
- </listitem>
-
- <listitem>
- <para>Time format endings: ms - milliseconds, s - seconds, m -
- minutes, h - hours, d - days, w - weeks, if no ending -
- seconds.</para>
-
- <para>Examples: 500ms - 500 milliseconds, 20 or 20s - 20 seconds,
- 30m - 30 minutes, 12h - 12 hours, 5d - 5 days, 4w - 4 weeks.</para>
- </listitem>
- </itemizedlist>
-
- <para></para>
- </section>
-
- <section id="sect_repository_service_configuration">
- <title>Repository service configuration</title>
-
- <para>Default configuration of the Repository Service located in
- jar:/conf/portal/exo-jcr-config.xml, it will be available for portal and
- standalone modes.</para>
-
- <para>In portal mode it is overriden and located in the portal web
- application portal/WEB-INF/conf/jcr/repository-configuration.xml.</para>
-
- <para>Example of Repository Service configuration for standalone
- mode:</para>
-
- <programlisting><repository-service default-repository="repository">
- <repositories>
- <repository name="db1" system-workspace="ws" default-workspace="ws">
- <security-domain>exo-domain</security-domain>
- <access-control>optional</access-control>
- <session-max-age>1h</session-max-age>
- <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
- <workspaces>
- <workspace name="production">
- <!-- for system storage -->
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="multi-db" value="false" />
- <property name="update-storage" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="../temp/swap/production" />
- </properties>
- <value-storages>
- <value-storage id="system" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="../temp/values/production" />
- </properties>
- <filters>
- <filter property-type="Binary" />
- </filters>
- </value-storage>
- </value-storages>
- </container>
- <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
- <properties>
- <property name="root-nodetype" value="nt:unstructured" />
- </properties>
- </initializer>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
- <properties>
- <property name="max-size" value="10k" />
- <property name="live-time" value="1h" />
- </properties>
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="../temp/jcrlucenedb/production" />
- </properties>
- </query-handler>
- <lock-manager>
- <time-out>15m</time-out>
- <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
- <properties>
- <property name="path" value="../temp/lock/system" />
- </properties>
- </persister>
- </lock-manager>
- </workspace>
-
- <workspace name="backup">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="multi-db" value="false" />
- <property name="update-storage" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="../temp/swap/backup" />
- </properties>
- <value-storages>
- <value-storage id="draft" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="../temp/values/backup" />
- </properties>
- <filters>
- <filter property-type="Binary" />
- </filters>
- </value-storage>
- </value-storages>
- </container>
- <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
- <properties>
- <property name="root-nodetype" value="nt:unstructured" />
- </properties>
- </initializer>
- <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
- <properties>
- <property name="max-size" value="10k" />
- <property name="live-time" value="1h" />
- </properties>
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="../temp/jcrlucenedb/backup" />
- </properties>
- </query-handler>
- </workspace>
- </workspaces>
- </repository>
- </repositories>
-</repository-service>
-</programlisting>
-
- <para>Repository Service configuration:</para>
-
- <para>default-repository - the name of a default repository (one
- returned by RepositoryService.getRepository())</para>
-
- <para>repositories - the list of repositories</para>
-
- <para>Repository configuration:</para>
-
- <para>name - the name of a repository</para>
-
- <para>default-workspace - the name of a workspace obtained using
- Session's login() or login(Credentials) methods (ones without an
- explicit workspace name)</para>
-
- <para>system-workspace - name of workspace where /jcr:system node is
- placed</para>
-
- <para>security-domain - the name of a security domain for JAAS
- authentication</para>
-
- <para>access-control - the name of an access control policy. There can
- be 3 types: optional - ACL is created on-demand(default), disable - no
- access control, mandatory - an ACL is created for each added node(not
- supported yet)</para>
-
- <para>authentication-policy - the name of an authentication policy
- class</para>
-
- <para>workspaces - the list of workspaces</para>
-
- <para>session-max-age - the time after which an idle session will be
- removed (called logout). If not set, the idle session will never be
- removed.</para>
-
- <para>Workspace configuration:</para>
-
- <para>name - the name of a workspace</para>
-
- <para>auto-init-root-nodetype - DEPRECATED in JCR 1.9 (use initializer).
- The node type for root node initialization</para>
-
- <para>container - workspace data container (physical storage)
- configuration</para>
-
- <para>initializer - workspace initializer configuration</para>
-
- <para>cache - workspace storage cache configuration</para>
-
- <para>query-handler - query handler configuration</para>
-
- <para>Workspace data container configuration:</para>
-
- <para>class - A workspace data container class name</para>
-
- <para>properties - the list of properties (name-value pairs) for the
- concrete Workspace data container</para>
-
- <para>value-storages - the list of value storage plugins</para>
-
- <para>Value Storage plugin configuration (optional feature):</para>
-
- <note>
- <para>The value-storage element is optional. If you don't include it,
- the values will be stored as BLOBs inside the database.</para>
- </note>
-
- <para>value-storage - Optional value Storage plugin definition</para>
-
- <para>class- a value storage plugin class name (attribute)</para>
-
- <para>properties - the list of properties (name-value pairs) for a
- concrete Value Storage plugin</para>
-
- <para>filters - the list of filters defining conditions when this plugin
- is applicable</para>
-
- <para>Initializer configuration (optional):</para>
-
- <para>class - initializer implementation class.</para>
-
- <para>properties - the list of properties (name-value pairs). Properties
- are supported:</para>
-
- <para>root-nodetype - The node type for root node initialization</para>
-
- <para>root-permissions - Default permissions of the root node. It is
- defined as a set of semicolon-delimited permissions containing a group
- of space-delimited identities (user, group etc, see Organization service
- documentation for details) and the type of permission. For example any
- read;:/admin read;:/admin add_node;:/admin set_property;:/admin remove
- means that users from group admin have all permissions and other users
- have only a 'read' permission.</para>
-
- <para>Configurable initializer adds a capability to override workspace
- initial startup procedure.</para>
-
- <para>Cache configuration:</para>
-
- <para>enabled - if workspace cache is enabled</para>
-
- <para>class - cache implementation class, optional from 1.9. Default
- value is
- org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl.</para>
-
- <para>Cache can be configured to use concrete implementation of
- WorkspaceStorageCache interface. JCR core has two implementation to use:
- * LinkedWorkspaceStorageCacheImpl - default, with configurable read
- behavior and statistic. * WorkspaceStorageCacheImpl - pre 1.9, still can
- be used.</para>
-
- <para>properties - the list of properties (name-value pairs) for
- Workspace cache:</para>
-
- <para>max-size - cache maximum size.</para>
-
- <para>live-time - cached item live time.</para>
-
- <para>LinkedWorkspaceStorageCacheImpl supports additional optional
- parameters TODO</para>
-
- <para>Query Handler configuration:</para>
-
- <para>class - A Query Handler class name</para>
-
- <para>properties - the list of properties (name-value pairs) for a Query
- Handler (indexDir) properties and advanced features described in *Search
- Configuration*</para>
-
- <para>Lock Manager configuration:</para>
-
- <para>time-out - time after which the unused global lock will be
- removed.</para>
-
- <para>persister - a class for storing lock information for future use.
- For example, remove lock after jcr restart.</para>
-
- <para>path - a lock folder, each workspace has its own.</para>
-
- <para></para>
-
- <para>Configuration definition:</para>
-
- <programlisting><!ELEMENT repository-service (repositories)>
- <!ATTLIST repository-service default-repository NMTOKEN #REQUIRED>
- <!ELEMENT repositories (repository)>
- <!ELEMENT repository (security-domain,access-control,session-max-age,authentication-policy,workspaces)>
- <!ATTLIST repository
- default-workspace NMTOKEN #REQUIRED
- name NMTOKEN #REQUIRED
- system-workspace NMTOKEN #REQUIRED
- >
- <!ELEMENT security-domain (#PCDATA)>
- <!ELEMENT access-control (#PCDATA)>
- <!ELEMENT session-max-age (#PCDATA)>
- <!ELEMENT authentication-policy (#PCDATA)>
- <!ELEMENT workspaces (workspace+)>
- <!ELEMENT workspace (container,initializer,cache,query-handler)>
- <!ATTLIST workspace name NMTOKEN #REQUIRED>
- <!ELEMENT container (properties,value-storages)>
- <!ATTLIST container class NMTOKEN #REQUIRED>
- <!ELEMENT value-storages (value-storage+)>
- <!ELEMENT value-storage (properties,filters)>
- <!ATTLIST value-storage class NMTOKEN #REQUIRED>
- <!ELEMENT filters (filter+)>
- <!ELEMENT filter EMPTY>
- <!ATTLIST filter property-type NMTOKEN #REQUIRED>
- <!ELEMENT initializer (properties)>
- <!ATTLIST initializer class NMTOKEN #REQUIRED>
- <!ELEMENT cache (properties)>
- <!ATTLIST cache
- enabled NMTOKEN #REQUIRED
- class NMTOKEN #REQUIRED
- >
- <!ELEMENT query-handler (properties)>
- <!ATTLIST query-handler class NMTOKEN #REQUIRED>
- <!ELEMENT access-manager (properties)>
- <!ATTLIST access-manager class NMTOKEN #REQUIRED>
- <!ELEMENT lock-manager (time-out,persister)>
- <!ELEMENT time-out (#PCDATA)>
- <!ELEMENT persister (properties)>
- <!ELEMENT properties (property+)>
- <!ELEMENT property EMPTY></programlisting>
- </section>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/external-value-storages.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/external-value-storages.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/external-value-storages.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_external_value_storages">
- <?dbhtml filename="ch-external-value-storages.html"?>
-
- <title>External Value Storages</title>
-
- <section>
- <title>Introduction</title>
-
- <para>By default JCR Values are stored in the Workspace Data container
- along with the JCR structure (i.e. Nodes and Properties). eXo JCR offers
- an additional option of storing JCR Values separately from Workspace Data
- container, which can be extremely helpful to keep Binary Large Objects
- (BLOBs) for example (see [TODOBinary values processing link]).</para>
-
- <para>Value storage configuration is a part of Repository configuration,
- find more details <link
- linkend="sect_repository_service_configuration">there</link>.</para>
-
- <para>Tree-based storage is recommended for most of cases. If you run an
- application on Amazon EC2 - the S3 option may be interesting for
- architecture. Simple 'flat' storage is good in speed of creation/deletion
- of values, it might be a compromise for a small storages.</para>
- </section>
-
- <section>
- <title>Tree File Value Storage</title>
-
- <para>Holds Values in tree-like FileSystem files.
- <property>path</property> property points to the root directory to store
- the files.</para>
-
- <para>This is a recommended type of external storage, it can contain large
- amount of files limited only by disk/volume free space.</para>
-
- <para>A disadvantage it's a higher time on Value deletion due to unused
- tree-nodes remove.</para>
-
- <programlisting><value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="data/values"/>
- </properties>
- <filters>
- <filter property-type="Binary" min-value-size="1M"/>
- </filters></programlisting>
-
- <para>Where :<simplelist>
- <member><parameter>id</parameter> - the value storage unique
- identifier, used for linking with properties stored in workspace
- container</member>
-
- <member><parameter>path</parameter> - a location where value files
- will be stored</member>
- </simplelist></para>
-
- <para>Each file value storage can have the <function>filter(s)</function>
- for incoming values. A filter can match values by property type
- (<property>property-type</property>), property name
- (<property>property-name</property>), ancestor path
- (<property>ancestor-path</property>) and/or size of values stored
- (<property>min-value-size</property>, in bytes). In code sample we use a
- filter with property-type and min-value-size only. I.e. storage for binary
- values with size greater of 1MB. It's recommended to store properties with
- large values in file value storage only.</para>
-
- <para>Another example shows a value storage with different locations for
- large files (<property>min-value-size</property> a 20Mb-sized filter). A
- value storage uses ORed logic in the process of filter selection. That
- means the first filter in the list will be asked first and if not matched
- the next will be called etc. Here a value matches the 20 MB-sized filter
- <property>min-value-size</property> and will be stored in the path
- "data/20Mvalues", all other in "data/values".</para>
-
- <programlisting><value-storages>
- <value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="data/20Mvalues"/>
- </properties>
- <filters>
- <filter property-type="Binary" min-value-size="20M"/>
- </filters>
- <value-storage>
- <value-storage id="Storage #2" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
- <properties>
- <property name="path" value="data/values"/>
- </properties>
- <filters>
- <filter property-type="Binary" min-value-size="1M"/>
- </filters>
- <value-storage>
-<value-storages></programlisting>
- </section>
-
- <section>
- <title>Simple File Value Storage</title>
-
- <note>
- <para>Not recommended to use in production due to low capacity
- capabilities on most file systems.</para>
-
- <para>But if you're sure in your file-system or data amount is small it
- may be useful for you as haves a faster speed of Value removal.</para>
- </note>
-
- <para>Holds Values in flat FileSystem files. <property>path</property>
- property points to root directory in order to store files</para>
-
- <programlisting><value-storage id="Storage #1" class="org.exoplatform.services.jcr.impl.storage.value.fs.SimpleFileValueStorage">
- <properties>
- <property name="path" value="data/values"/>
- </properties>
- <filters>
- <filter property-type="Binary" min-value-size="1M"/>
- </filters></programlisting>
- </section>
-
- <section>
- <title>Content Addressable Value storage (CAS) support</title>
-
- <para>eXo JCR supports <phrase>Content-addressable storage</phrase>
- feature for <phrase>Values</phrase> storing.</para>
-
- <note>
- <para>Content-addressable storage, also referred to as associative
- storage and abbreviated CAS, is a mechanism for storing information that
- can be retrieved based on its content, not its storage location. It is
- typically used for high-speed storage and retrieval of fixed content,
- such as documents stored for compliance with government
- regulations.</para>
- </note>
-
- <para>Content Addressable Value storage stores unique content once.
- Different properties (values) with same content will be stored as one data
- file shared between those values. We can tell the Value content will be
- shared across some Values in storage and will be stored on one physical
- file.</para>
-
- <para>Storage size will be decreased for application which governs
- potentially same data in the content.</para>
-
- <note>
- <para>For example: if you have 100 different properties containing the
- same data (e.g. mail attachment) the storage stores only one single
- file. The file will be shared with all referencing properties.</para>
- </note>
-
- <para>If property Value changes it is stored in an additional file.
- Alternatively the file is shared with other values, pointing to the same
- content.</para>
-
- <para>The storage calculates Value content address each time the property
- was changed. CAS write operations are much more expensive compared to the
- non-CAS storages.</para>
-
- <para>Content address calculation based on java.security.MessageDigest
- hash computation and tested with <abbrev>MD5</abbrev> and
- <abbrev>SHA1</abbrev> algorithms.</para>
-
- <note>
- <para>CAS storage works most efficiently on data that does not change
- often. For data that changes frequently, CAS is not as efficient as
- location-based addressing.</para>
- </note>
-
- <para>CAS support can be enabled for <phrase>Tree</phrase> and
- <phrase>Simple File Value Storage</phrase> types.</para>
-
- <para>To enable CAS support just configure it in JCR Repositories
- configuration like we do for other Value Storages.</para>
-
- <programlisting><workspaces>
- <workspace name="ws">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr"/>
- <property name="dialect" value="oracle"/>
- <property name="multi-db" value="false"/>
- <property name="update-storage" value="false"/>
- <property name="max-buffer-size" value="200k"/>
- <property name="swap-directory" value="target/temp/swap/ws"/>
- </properties>
- <value-storages>
-<!------------------- here ----------------------->
- <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.CASableTreeFileValueStorage">
- <properties>
- <property name="path" value="target/temp/values/ws"/>
- <property name="digest-algo" value="MD5"/>
- <property name="vcas-type" value="org.exoplatform.services.jcr.impl.storage.value.cas.JDBCValueContentAddressStorageImpl"/>
- <property name="jdbc-source-name" value="jdbcjcr"/>
- <property name="jdbc-dialect" value="oracle"/>
- </properties>
- <filters>
- <filter property-type="Binary"/>
- </filters>
- </value-storage>
- </value-storages></programlisting>
-
- <para>Properties:<simplelist>
- <member><parameter>digest-algo</parameter> - digest hash algorithm
- (MD5 and SHA1 were tested);</member>
-
- <member><parameter>vcas-type</parameter> - Value CAS internal data
- type, JDBC backed is currently implemented
- org.exoplatform.services.jcr.impl.storage.value.cas.JDBCValueContentAddressStorageImp;l</member>
-
- <member><parameter>jdbc-source-name</parameter> -
- JDBCValueContentAddressStorageImpl specific parameter, database will
- be used to save CAS metadata. It's simple to use same as in workspace
- container;</member>
-
- <member><parameter>jdbc-dialect</parameter> -
- JDBCValueContentAddressStorageImpl specific parameter, database
- dialect. It's simple to use same as in workspace container;</member>
- </simplelist></para>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jdbc-data-container-config.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jdbc-data-container-config.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/jdbc-data-container-config.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,592 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_jdbc_data_container">
- <?dbhtml filename="ch-jdbc-data-container-config.html"?>
-
- <title>JDBC Data Container Config</title>
-
- <section>
- <title>Introduction</title>
-
- <para>eXo JCR persistent data container can work in two configuration
- modes:<itemizedlist>
- <listitem>
- <para><phrase>Multi-database</phrase>: one database for each
- workspace (used in standalone eXo JCR service mode)</para>
- </listitem>
-
- <listitem>
- <para><phrase>Single-database</phrase>: all workspaces persisted in
- one database (used in embedded eXo JCR service mode, e.g. in eXo
- portal)</para>
- </listitem>
- </itemizedlist></para>
-
- <para>The data container uses the JDBC driver to communicate with the
- actual database software, i.e. any JDBC-enabled data storage can be used
- with eXo JCR implementation.</para>
-
- <para>Currently the data container is tested with the following
- RDBMS:<itemizedlist>
- <listitem>
- <para>MySQL (5.x including UTF8 support)</para>
- </listitem>
-
- <listitem>
- <para>PostgreSQL (8.x)</para>
- </listitem>
-
- <listitem>
- <para>Oracle Database (9i, 10g)</para>
- </listitem>
-
- <listitem>
- <para>Microsoft SQL Server (2005)</para>
- </listitem>
-
- <listitem>
- <para>Sybase ASE (15.0)</para>
- </listitem>
-
- <listitem>
- <para>Apache Derby/Java DB (10.1.x, 10.2.x)</para>
- </listitem>
-
- <listitem>
- <para>IBM DB2 (8.x, 9.x)</para>
- </listitem>
-
- <listitem>
- <para>HSQLDB (1.8.0.7)</para>
- </listitem>
- </itemizedlist></para>
-
- <para>Each database software supports ANSI SQL standards but has its own
- specifics too. So, each database has its own configuration in eXo JCR as a
- database dialect parameter. If you need a more detailed configuration of
- the database it's possible to do that by editing the metadata SQL-script
- files.</para>
-
- <para>In case the non-ANSI node name is used it's necessary to use a
- database with MultiLanguage support[TODO link to MultiLanguage]. Some JDBC
- drivers need additional parameters for establishing a Unicode friendly
- connection. E.g. under mysql it's necessary to add an additional parameter
- for the JDBC driver at the end of JDBC URL. For instance:
- <code>jdbc:mysql://exoua.dnsalias.net/portal?characterEncoding=utf8</code></para>
-
- <para>There are preconfigured configuration files for HSQLDB. Look for
- these files in /conf/portal and /conf/standalone folders of the jar-file
- <package>exo.jcr.component.core-XXX.XXX.jar</package> or
- source-distribution of eXo JCR implementation.</para>
-
- <para>By default the configuration files are located in service jars
- <filename>/conf/portal/configuration.xml</filename> (eXo services
- including JCR Repository Service) and
- <filename>exo-jcr-config.xml</filename> (repositories configuration). In
- eXo portal product JCR is configured in portal web application
- <filename>portal/WEB-INF/conf/jcr/jcr-configuration.xml</filename> (JCR
- Repository Service and related serivces) and repository-configuration.xml
- (repositories configuration).</para>
-
- <para>Read more about <link linkend="ch_configuration">Repository
- configuration</link>.</para>
- </section>
-
- <section>
- <title>Multi-database Configuration</title>
-
- <para>You need to configure each workspace in a repository. You may have
- each one on different remote servers as far as you need.</para>
-
- <para>First of all configure the data containers in the
- <classname>org.exoplatform.services.naming.InitialContextInitializer</classname>
- service. It's the JNDI context initializer which registers (binds) naming
- resources (DataSources) for data containers.</para>
-
- <para>Example (standalone mode, two data containers
- <parameter>jdbcjcr</parameter> - local HSQLDB,
- <parameter>jdbcjcr1</parameter> - remote MySQL):<programlisting><component>
- <key>org.exoplatform.services.naming.InitialContextInitializer</key>
- <type>org.exoplatform.services.naming.InitialContextInitializer</type>
- <component-plugins>
- <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:target/temp/data/portal"/>
- <property name="username" value="sa"/>
- <property name="password" value=""/>
- </properties-param>
- </init-params>
- </component-plugin>
- <component-plugin>
- <name>bind.datasource</name>
- <set-method>addPlugin</set-method>
- <type>org.exoplatform.services.naming.BindReferencePlugin</type>
- <init-params>
- <value-param>
- <name>bind-name</name>
- <value>jdbcjcr1</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="com.mysql.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://exoua.dnsalias.net/jcr"/>
- <property name="username" value="exoadmin"/>
- <property name="password" value="exo12321"/>
- <property name="maxActive" value="50"/>
- <property name="maxIdle" value="5"/>
- <property name="initialSize" value="5"/>
- </properties-param>
- </init-params>
- </component-plugin>
- <component-plugins>
- <init-params>
- <value-param>
- <name>default-context-factory</name>
- <value>org.exoplatform.services.naming.SimpleContextFactory</value>
- </value-param>
- </init-params>
- </component></programlisting></para>
-
- <para>We configure the database connection parameters:<itemizedlist>
- <listitem>
- <para><parameter>driverClassName</parameter>, e.g.
- "org.hsqldb.jdbcDriver", "com.mysql.jdbc.Driver",
- "org.postgresql.Driver"</para>
- </listitem>
-
- <listitem>
- <para><parameter>url</parameter>, e.g.
- "jdbc:hsqldb:file:target/temp/data/portal",
- "jdbc:mysql://exoua.dnsalias.net/jcr"</para>
- </listitem>
-
- <listitem>
- <para><parameter>username</parameter>, e.g. "sa", "exoadmin"</para>
- </listitem>
-
- <listitem>
- <para><parameter>password</parameter>, e.g. "", "exo12321"</para>
- </listitem>
- </itemizedlist></para>
-
- <para>There can be connection pool configuration parameters
- (org.apache.commons.dbcp.BasicDataSourceFactory):<itemizedlist>
- <listitem>
- <para><parameter>maxActive</parameter>, e.g. 50</para>
- </listitem>
-
- <listitem>
- <para><parameter>maxIdle</parameter>, e.g. 5</para>
- </listitem>
-
- <listitem>
- <para><parameter>initialSize</parameter>, e.g. 5</para>
- </listitem>
-
- <listitem>
- <para>and other according to <ulink
- url="http://jakarta.apache.org/commons/dbcp/configuration.html">Apache
- DBCP configuration</ulink></para>
- </listitem>
- </itemizedlist></para>
-
- <para>When the data container configuration is done we can configure the
- repository service. Each workspace will be configured for its own data
- container.</para>
-
- <para>Example (two workspaces <parameter>ws</parameter> - jdbcjcr,
- <parameter>ws1</parameter> - jdbcjcr1):<programlisting><workspaces>
- <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr"/>
- <property name="dialect" value="hsqldb"/>
- <property name="multi-db" value="true"/>
- <property name="max-buffer-size" value="200K"/>
- <property name="swap-directory" value="target/temp/swap/ws"/>
- </properties>
- </container>
- <cache enabled="true">
- <properties>
- <property name="max-size" value="10K"/><!-- 10Kbytes -->
- <property name="live-time" value="30m"/><!-- 30 min -->
- </properties>
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="target/temp/index"/>
- </properties>
- </query-handler>
- <lock-manager>
- <time-out>15m</time-out><!-- 15 min -->
- <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
- <properties>
- <property name="path" value="target/temp/lock/ws"/>
- </properties>
- </persister>
- </lock-manager>
- </workspace>
- <workspace name="ws1" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr1"/>
- <property name="dialect" value="mysql"/>
- <property name="multi-db" value="true"/>
- <property name="max-buffer-size" value="200K"/>
- <property name="swap-directory" value="target/temp/swap/ws1"/>
- </properties>
- </container>
- <cache enabled="true">
- <properties>
- <property name="max-size" value="10K"/>
- <property name="live-time" value="5m"/>
- </properties>
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="target/temp/index"/>
- </properties>
- </query-handler>
- <lock-manager>
- <time-out>15m</time-out><!-- 15 min -->
- <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
- <properties>
- <property name="path" value="target/temp/lock/ws1"/>
- </properties>
- </persister>
- </lock-manager>
- </workspace>
-</workspaces></programlisting><itemizedlist>
- <listitem>
- <para><parameter>source-name</parameter> - a javax.sql.DataSource
- name configured in InitialContextInitializer component (was
- <parameter>sourceName</parameter> prior JCR 1.9);</para>
- </listitem>
-
- <listitem>
- <para><parameter>dialect</parameter> - a database dialect, one of
- "hsqldb", "mysql", "mysql-utf8", "pgsql", "oracle", "oracle-oci",
- "mssql", "sybase", "derby", "db2", "db2v8" or "auto" for dialect
- autodetection;</para>
- </listitem>
-
- <listitem>
- <para><parameter>multi-db</parameter> - enable multi-database
- container with this parameter (set value "true");</para>
- </listitem>
-
- <listitem>
- <para><parameter>max-buffer-size</parameter> - a threshold (in
- bytes) after which a javax.jcr.Value content will be swapped to a
- file in a temporary storage. I.e. swap for pending changes.</para>
- </listitem>
-
- <listitem>
- <para><parameter>swap-directory</parameter> - a path in the file
- system used to swap the pending changes.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>In this way we have configured two workspace which will be persisted
- in two different databases (ws in HSQLDB, ws1 in MySQL).</para>
-
- <note>
- <para>Starting from v.1.9 <link linkend="ch_configuration">repository
- configuration</link> parameters supports human-readable formats of
- values (e.g. 200K - 200 Kbytes, 30m - 30 minutes etc)</para>
- </note>
- </section>
-
- <section>
- <title>Single-database configuration</title>
-
- <para>It's more simple to configure a single-database data container. We
- have to configure one naming resource.</para>
-
- <para>Example (embedded mode for <parameter>jdbcjcr</parameter> data
- container):<programlisting><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.postgresql.Driver"/>
- <property name="url" value="jdbc:postgresql://exoua.dnsalias.net/portal"/>
- <property name="username" value="exoadmin"/>
- <property name="password" value="exo12321"/>
- <property name="maxActive" value="50"/>
- <property name="maxIdle" value="5"/>
- <property name="initialSize" value="5"/>
- </properties-param>
- </init-params>
- </component-plugin>
- </external-component-plugins></programlisting></para>
-
- <para>And configure repository workspaces in repositories configuration
- with this one database. Parameter "multi-db" must be switched off (set
- value "false").</para>
-
- <para>Example (two workspaces <parameter>ws</parameter> - jdbcjcr,
- <parameter>ws1</parameter> - jdbcjcr):<programlisting><workspaces>
- <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr"/>
- <property name="dialect" value="pgsql"/>
- <property name="multi-db" value="false"/>
- <property name="max-buffer-size" value="200K"/>
- <property name="swap-directory" value="target/temp/swap/ws"/>
- </properties>
- </container>
- <cache enabled="true">
- <properties>
- <property name="max-size" value="10K"/>
- <property name="live-time" value="30m"/>
- </properties>
- </cache>
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="../temp/index"/>
- </properties>
- </query-handler>
- <lock-manager>
- <time-out>15m</time-out>
- <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
- <properties>
- <property name="path" value="target/temp/lock/ws"/>
- </properties>
- </persister>
- </lock-manager>
- </workspace>
- <workspace name="ws1" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr"/>
- <property name="dialect" value="pgsql"/>
- <property name="multi-db" value="false"/>
- <property name="max-buffer-size" value="200K"/>
- <property name="swap-directory" value="target/temp/swap/ws1"/>
- </properties>
- </container>
- <cache enabled="true">
- <properties>
- <property name="max-size" value="10K"/>
- <property name="live-time" value="5m"/>
- </properties>
- </cache>
- <lock-manager>
- <time-out>15m</time-out>
- <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
- <properties>
- <property name="path" value="target/temp/lock/ws1"/>
- </properties>
- </persister>
- </lock-manager>
- </workspace>
-</workspaces></programlisting></para>
-
- <para>In this way we have configured two workspaces which will be
- persisted in one database (PostgreSQL).</para>
-
- <section>
- <title>Configuration without DataSource</title>
-
- <para>Repository configuration without using of the
- <classname>javax.sql.DataSource</classname> bounded in JNDI.</para>
-
- <para>This case may be usable if you have a dedicated JDBC driver
- implementation with special features like XA transactions,
- statements/connections pooling etc:<itemizedlist>
- <listitem>
- <para>You have to remove the configuration in
- <classname>InitialContextInitializer</classname> for your database
- and configure a new one directly in the workspace
- container.</para>
- </listitem>
-
- <listitem>
- <para>Remove parameter "source-name" and add next lines instead.
- Describe your values for a JDBC driver, database url and
- username.</para>
- </listitem>
- </itemizedlist></para>
-
- <note>
- <para>But be careful in this case JDBC driver should implement and
- provide connection pooling. Connection pooling is very recommended for
- use with JCR to prevent a database overload.</para>
- </note>
-
- <programlisting><workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="dialect" value="hsqldb"/>
- <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
- <property name="url" value="jdbc:hsqldb:file:target/temp/data/portal"/>
- <property name="username" value="su"/>
- <property name="password" value=""/>
- ......</programlisting>
- </section>
-
- <section>
- <title>Dynamic Workspace Creation</title>
-
- <para>Workspaces can be added dynamically during runtime.</para>
-
- <para>This can be performed in two steps:<itemizedlist>
- <listitem>
- <para>Firstly,
- <classname>ManageableRepository.configWorkspace(WorkspaceEntry
- wsConfig)</classname> - register a new configuration in
- RepositoryContainer and create a WorkspaceContainer.</para>
- </listitem>
-
- <listitem>
- <para>Secondly, the main step,
- <classname>ManageableRepository.createWorkspace(String
- workspaceName)</classname> - creation of a new workspace.</para>
- </listitem>
- </itemizedlist></para>
- </section>
- </section>
-
- <section>
- <title>Simple and Complex queries</title>
-
- <para>eXo JCR provides two ways for interact with Database -
- <classname>JDBCStorageConnection</classname> that uses simple queries and
- <classname>CQJDBCStorageConection</classname> that uses complex queries
- for reducing amount of database callings.</para>
-
- <para>Simple queries will be used if you chose
- <classname>org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer</classname>:<programlisting><workspaces>
- <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- ...
- </workspace>
-</worksapces></programlisting></para>
-
- <para>Complex queries will be used if you chose
- <classname>org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer</classname>:<programlisting><workspaces>
- <workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
- ...
- </workspace>
-</worksapces></programlisting></para>
-
- <para>Why we should use a Complex Queries?<simplelist>
- <member>They are optimised to reduce amount of requests to
- database.</member>
- </simplelist>Why we should use a Simple Queries?<simplelist>
- <member>Simple queries implemented in way to support as many database
- dialects as possible.</member>
-
- <member>Simple queries do not use sub queries, left or right
- joins.</member>
- </simplelist></para>
- </section>
-
- <section>
- <title>Forse Query Hints</title>
-
- <para>Some databases supports hints to increase query performance (like
- Oracle, MySQL, etc). eXo JCR have separate Complex Query implementation
- for Orcale dialect, that uses query hints to increase performance for few
- important queries. </para>
-
- <para>To enable this option put next configuration
- property:<programlisting><workspace name="ws" auto-init-root-nodetype="nt:unstructured">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="dialect" value="oracle"/>
- <property name="force.query.hints" value="true" />
- ......</programlisting></para>
-
- <para>Query hints enabled by default. </para>
-
- <para>eXo JCR uses query hints only for Complex Query Oracle dialect. For
- all other dialects this parameter is ignored.</para>
- </section>
-
- <section>
- <title>Notes for Microsoft Windows users</title>
-
- <para>The current configuration of eXo JCR uses Apache DBCP connection
- pool
- (<classname>org.apache.commons.dbcp.BasicDataSourceFactory</classname>).
- It's possible to set a big value for maxActive parameter in
- <filename>configuration.xml</filename>. That means usage of lots of TCP/IP
- ports from a client machine inside the pool (i.e. JDBC driver). As a
- result the data container can throw exceptions like "Address already in
- use". To solve this problem you have to configure the client's machine
- networking software for the usage of shorter timeouts for opened TCP/IP
- ports.</para>
-
- <para>Microsoft Windows has <parameter>MaxUserPort</parameter>,
- <parameter>TcpTimedWaitDelay</parameter> registry keys in the node
- <parameter>HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters</parameter>,
- by default these keys are unset, set each one with values like
- these:<itemizedlist>
- <listitem>
- <para>"TcpTimedWaitDelay"=dword:0000001e, sets TIME_WAIT parameter
- to 30 seconds, default is 240.</para>
- </listitem>
-
- <listitem>
- <para>"MaxUserPort"=dword:00001b58, sets the maximum of open ports
- to 7000 or higher, default is 5000.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>A sample registry file is below:<programlisting>Windows Registry Editor Version 5.00
-
-[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
-"MaxUserPort"=dword:00001b58
-"TcpTimedWaitDelay"=dword:0000001e</programlisting></para>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/multilanguage-support.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/multilanguage-support.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/multilanguage-support.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_multilanguage_support">
- <?dbhtml filename="ch-multilanguage-support.html"?>
-
- <title>Multilanguage support in eXo JCR RDB backend</title>
-
- <section>
- <title>Intro</title>
-
- <para>Whenever relational database is used to store multilingual text data
- of eXo Java Content Repository we need to adapt configuration in order to
- support UTF-8 encoding. Here is a short HOWTO instruction for several
- supported RDBMS with examples.</para>
-
- <para>The configuration file you have to modify:
- .../webapps/portal/WEB-INF/conf/jcr/repository-configuration.xml</para>
-
- <note>
- <para>Datasource <parameter>jdbcjcr</parameter> used in examples can be
- configured via <classname>InitialContextInitializer</classname>
- component.</para>
- </note>
- </section>
-
- <section>
- <title>Oracle</title>
-
- <para>In order to run multilanguage JCR on an Oracle backend Unicode
- encoding for characters set should be applied to the database. Other
- Oracle globalization parameters don't make any impact. The only property
- to modify is <constant>NLS_CHARACTERSET</constant>.</para>
-
- <para>We have tested <constant>NLS_CHARACTERSET</constant> =
- <constant>AL32UTF8</constant> and it's works well for many European and
- Asian languages.</para>
-
- <para>Example of database configuration (used for JCR
- testing):<programlisting>NLS_LANGUAGE AMERICAN
-NLS_TERRITORY AMERICA
-NLS_CURRENCY $
-NLS_ISO_CURRENCY AMERICA
-NLS_NUMERIC_CHARACTERS .,
-NLS_CHARACTERSET AL32UTF8
-NLS_CALENDAR GREGORIAN
-NLS_DATE_FORMAT DD-MON-RR
-NLS_DATE_LANGUAGE AMERICAN
-NLS_SORT BINARY
-NLS_TIME_FORMAT HH.MI.SSXFF AM
-NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
-NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
-NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
-NLS_DUAL_CURRENCY $
-NLS_COMP BINARY
-NLS_LENGTH_SEMANTICS BYTE
-NLS_NCHAR_CONV_EXCP FALSE
-NLS_NCHAR_CHARACTERSET AL16UTF16</programlisting></para>
-
- <warning>
- <para>JCR 1.12.x doesn't use NVARCHAR columns, so that the value of the
- parameter NLS_NCHAR_CHARACTERSET does not matter for JCR.</para>
- </warning>
-
- <para>Create database with Unicode encoding and use Oracle dialect for the
- Workspace Container:</para>
-
- <programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="oracle" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting>
- </section>
-
- <section>
- <title>DB2</title>
-
- <para>DB2 Universal Database (DB2 UDB) supports <ulink
- url="http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.i...">UTF-8
- and UTF-16/UCS-2</ulink>. When a Unicode database is created, CHAR,
- VARCHAR, LONG VARCHAR data are stored in UTF-8 form. It's enough for JCR
- multi-lingual support.</para>
-
- <para>Example of UTF-8 database creation:<programlisting>DB2 CREATE DATABASE dbname USING CODESET UTF-8 TERRITORY US</programlisting></para>
-
- <para>Create database with UTF-8 encoding and use db2 dialect for
- Workspace Container on DB2 v.9 and higher:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="db2" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
-
- <note>
- <para>For DB2 v.8.x support change the property "dialect" to
- db2v8.</para>
- </note>
- </section>
-
- <section>
- <title>MySQL</title>
-
- <para>JCR MySQL-backend requires special dialect <ulink
- url="http://jira.exoplatform.org/browse/JCR-375">MySQL-UTF8</ulink> to be
- used for internationalization support. But the database default charset
- should be latin1 to use limited index space effectively (1000 bytes for
- MyISAM engine, 767 for InnoDB). If database default charset is multibyte,
- a JCR database initialization error is thrown concerning index creation
- failure. In other words JCR can work on any singlebyte default charset of
- database, with UTF8 supported by MySQL server. But we have tested it only
- on latin1 database default charset.</para>
-
- <para>Repository configuration, workspace container entry
- example:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="mysql-utf8" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
- </section>
-
- <section>
- <title>PostgreSQL</title>
-
- <para>On PostgreSQL-backend multilingual support can be enabled in <ulink
- url="http://www.postgresql.org/docs/8.3/interactive/charset.html">different
- ways</ulink>:<itemizedlist>
- <listitem>
- <para>Using the locale features of the operating system to provide
- locale-specific collation order, number formatting, translated
- messages, and other aspects. UTF-8 is widely used on Linux
- distributions by default, so it can be useful in such case.</para>
- </listitem>
-
- <listitem>
- <para>Providing a number of different character sets defined in the
- PostgreSQL server, including multiple-byte character sets, to
- support storing text any language, and providing character set
- translation between client and server. We recommend to use UTF-8
- database charset, it will allow any-to-any conversations and make
- this issue transparent for the JCR.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>Create database with UTF-8 encoding and use PgSQL dialect for
- Workspace Container:<programlisting><workspace name="collaboration">
- <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
- <properties>
- <property name="source-name" value="jdbcjcr" />
- <property name="dialect" value="pgsql" />
- <property name="multi-db" value="false" />
- <property name="max-buffer-size" value="200k" />
- <property name="swap-directory" value="target/temp/swap/ws" />
- </properties>
- .....</programlisting></para>
- </section>
-</chapter>
Deleted: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/search-configuration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/search-configuration.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/search-configuration.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,799 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="ch_search_configuration">
- <?dbhtml filename="ch-search-configuration.html"?>
-
- <title>Search Configuration</title>
-
- <section>
- <title>XML Configuration</title>
-
- <para>JCR index configuration. You can find this file here:
- <filename>.../portal/WEB-INF/conf/jcr/repository-configuration.xml</filename></para>
-
- <programlisting><repository-service default-repository="db1">
- <repositories>
- <repository name="db1" system-workspace="ws" default-workspace="ws">
- ....
- <workspaces>
- <workspace name="ws">
- ....
- <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="${java.io.tmpdir}/temp/index/db1/ws" />
- <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
- <property name="synonymprovider-config-path" value="/synonyms.properties" />
- <property name="indexing-config-path" value="/indexing-configuration.xml" />
- <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
- </properties>
- </query-handler>
- ...
- </workspace>
- </workspaces>
- </repository>
- </repositories>
-</repository-service></programlisting>
- </section>
-
- <section>
- <title>Configuration parameters</title>
-
- <table>
- <title></title>
-
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Parameter</entry>
-
- <entry>Default</entry>
-
- <entry>Description</entry>
-
- <entry>Since</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>index-dir</entry>
-
- <entry>none</entry>
-
- <entry>The location of the index directory. This parameter is
- mandatory. Up to 1.9 this parameter called "indexDir"</entry>
-
- <entry>1.0</entry>
- </row>
-
- <row>
- <entry>use-compoundfile</entry>
-
- <entry>true</entry>
-
- <entry>Advises lucene to use compound files for the index
- files.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>min-merge-docs</entry>
-
- <entry>100</entry>
-
- <entry>Minimum number of nodes in an index until segments are
- merged.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>volatile-idle-time</entry>
-
- <entry>3</entry>
-
- <entry>Idle time in seconds until the volatile index part is moved
- to a persistent index even though minMergeDocs is not
- reached.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>max-merge-docs</entry>
-
- <entry>Integer.MAX_VALUE</entry>
-
- <entry>Maximum number of nodes in segments that will be merged.
- The default value changed in JCR 1.9 to Integer.MAX_VALUE.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>merge-factor</entry>
-
- <entry>10</entry>
-
- <entry>Determines how often segment indices are merged.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>max-field-length</entry>
-
- <entry>10000</entry>
-
- <entry>The number of words that are fulltext indexed at most per
- property.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>cache-size</entry>
-
- <entry>1000</entry>
-
- <entry>Size of the document number cache. This cache maps uuids to
- lucene document numbers</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>force-consistencycheck</entry>
-
- <entry>false</entry>
-
- <entry>Runs a consistency check on every startup. If false, a
- consistency check is only performed when the search index detects
- a prior forced shutdown.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>auto-repair</entry>
-
- <entry>true</entry>
-
- <entry>Errors detected by a consistency check are automatically
- repaired. If false, errors are only written to the log.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>query-class</entry>
-
- <entry>QueryImpl</entry>
-
- <entry>Class name that implements the javax.jcr.query.Query
- interface.This class must also extend from the class:
- org.exoplatform.services.jcr.impl.core.query.AbstractQueryImpl.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>document-order</entry>
-
- <entry>true</entry>
-
- <entry>If true and the query does not contain an 'order by'
- clause, result nodes will be in document order. For better
- performance when queries return a lot of nodes set to
- 'false'.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>result-fetch-size</entry>
-
- <entry>Integer.MAX_VALUE</entry>
-
- <entry>The number of results when a query is executed. Default
- value: Integer.MAX_VALUE (-> all).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>excerptprovider-class</entry>
-
- <entry>DefaultXMLExcerpt</entry>
-
- <entry>The name of the class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.ExcerptProvider
- and should be used for the rep:excerpt() function in a
- query.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>support-highlighting</entry>
-
- <entry>false</entry>
-
- <entry>If set to true additional information is stored in the
- index to support highlighting using the rep:excerpt()
- function.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>synonymprovider-class</entry>
-
- <entry>none</entry>
-
- <entry>The name of a class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.SynonymProvider.
- The default value is null (-> not set).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>synonymprovider-config-path</entry>
-
- <entry>none</entry>
-
- <entry>The path to the synonym provider configuration file. This
- path interpreted relative to the path parameter. If there is a
- path element inside the SearchIndex element, then this path is
- interpreted relative to the root path of the path. Whether this
- parameter is mandatory depends on the synonym provider
- implementation. The default value is null (-> not set).</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>indexing-configuration-path</entry>
-
- <entry>none</entry>
-
- <entry>The path to the indexing configuration file.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>indexing-configuration-class</entry>
-
- <entry>IndexingConfigurationImpl</entry>
-
- <entry>The name of the class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.IndexingConfiguration.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>force-consistencycheck</entry>
-
- <entry>false</entry>
-
- <entry>If set to true a consistency check is performed depending
- on the parameter forceConsistencyCheck. If set to false no
- consistency check is performed on startup, even if a redo log had
- been applied.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>spellchecker-class</entry>
-
- <entry>none</entry>
-
- <entry>The name of a class that implements
- org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>spellchecker-more-popular</entry>
-
- <entry>true</entry>
-
- <entry>If set true - spellchecker return only the suggest words
- that are as frequent or more frequent than the checked word. If
- set false, spellchecker return null (if checked word exit in
- dictionary), or spellchecker will return most close suggest
- word.</entry>
-
- <entry>1.10</entry>
- </row>
-
- <row>
- <entry>spellchecker-min-distance</entry>
-
- <entry>0.55f</entry>
-
- <entry>Minimal distance between checked word and proposed suggest
- word.</entry>
-
- <entry>1.10</entry>
- </row>
-
- <row>
- <entry>errorlog-size</entry>
-
- <entry>50(Kb)</entry>
-
- <entry>The default size of error log file in Kb.</entry>
-
- <entry>1.9</entry>
- </row>
-
- <row>
- <entry>upgrade-index</entry>
-
- <entry>false</entry>
-
- <entry>Allows JCR to convert an existing index into the new
- format. Also it is possible to set this property via system
- property, for example: -Dupgrade-index=true Indexes before JCR
- 1.12 will not run with JCR 1.12. Hence you have to run an
- automatic migration: Start JCR with -Dupgrade-index=true. The old
- index format is then converted in the new index format. After the
- conversion the new format is used. On the next start you don't
- need this option anymore. The old index is replaced and a back
- conversion is not possible - therefore better take a backup of the
- index before. (Only for migrations from JCR 1.9 and
- later.)</entry>
-
- <entry>1.12</entry>
- </row>
-
- <row>
- <entry>analyzer</entry>
-
- <entry>org.apache.lucene.analysis.standard.StandardAnalyzer</entry>
-
- <entry>Class name of a lucene analyzer to use for fulltext
- indexing of text.</entry>
-
- <entry>1.12</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
-
- <section>
- <title>Global Search Index</title>
-
- <section>
- <title>Global Search Index Configuration</title>
-
- <para>The global search index is configured in the above-mentioned
- configuration file
- (<filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>)
- in the tag "query-handler".</para>
-
- <programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>
-
- <para>In fact when using Lucene you always should use the same analyzer
- for indexing and for querying - otherwise the results are unpredictable.
- You don't have to worry about this, eXo JCR does this for you
- automatically. If you don't like the StandardAnalyzer configured by
- default just replace it by your own.</para>
-
- <para>If you don't have a handy QueryHandler you will learn how create a
- customized Handler in 5 minutes.</para>
- </section>
-
- <section>
- <title>Customized Search Indexes and Analyzers</title>
-
- <para>By default Exo JCR uses the Lucene standard Analyzer to index
- contents. This analyzer uses some standard filters in the method that
- analyzes the content:<programlisting>public TokenStream tokenStream(String fieldName, Reader reader) {
- StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);
- tokenStream.setMaxTokenLength(maxTokenLength);
- TokenStream result = new StandardFilter(tokenStream);
- result = new LowerCaseFilter(result);
- result = new StopFilter(result, stopSet);
- return result;
- }</programlisting><itemizedlist>
- <listitem>
- <para>The first one (StandardFilter) removes 's (as 's in
- "Peter's") from the end of words and removes dots from
- acronyms.</para>
- </listitem>
-
- <listitem>
- <para>The second one (LowerCaseFilter) normalizes token text to
- lower case.</para>
- </listitem>
-
- <listitem>
- <para>The last one (StopFilter) removes stop words from a token
- stream. The stop set is defined in the analyzer.</para>
- </listitem>
- </itemizedlist></para>
-
- <para>For specific cases, you may wish to use additional filters like
- <phrase>ISOLatin1AccentFilter</phrase>, which replaces accented
- characters in the ISO Latin 1 character set (ISO-8859-1) by their
- unaccented equivalents.</para>
-
- <para>In order to use a different filter, you have to create a new
- analyzer, and a new search index to use the analyzer. You put it in a
- jar, which is deployed with your application.</para>
-
- <section>
- <title>Create the filter</title>
-
- <para>The ISOLatin1AccentFilter is not present in the current Lucene
- version used by Exo. You can use the attached file. You can also
- create your own filter, the relevant method is<programlisting>public final Token next(final Token reusableToken) throws java.io.IOException</programlisting>which
- defines how chars are read and used by the filter.</para>
- </section>
-
- <section>
- <title>Create the analyzer</title>
-
- <para>The analyzer have to extends
- org.apache.lucene.analysis.standard.StandardAnalyzer, and overload the
- method<programlisting>public TokenStream tokenStream(String fieldName, Reader reader)</programlisting>to
- put your own filters. You can have a glance at the example analyzer
- attached to this article.</para>
- </section>
-
- <section>
- <title>Create the search index</title>
-
- <para>Now, we have the analyzer, we have to write the SearchIndex,
- which will use the analyzer. Your have to extends
- org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex. You
- have to write the constructor, to set the right analyzer, and the
- method<programlisting>public Analyzer getAnalyzer() {
- return MyAnalyzer;
- }</programlisting>to return your analyzer. You can see the attached
- SearchIndex.</para>
-
- <note>
- <para>Since 1.12 version we can set Analyzer directly in
- configuration. So, creation new SearchIndex only for new Analyzer is
- redundant.</para>
- </note>
- </section>
-
- <section>
- <title>Configure your application to use your SearchIndex</title>
-
- <para>In
- <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
- you have to replace each<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex"></programlisting>by
- your own class<programlisting><query-handler class="mypackage.indexation.MySearchIndex"></programlisting></para>
- </section>
-
- <section>
- <title>Configure your application to use your Analyzer</title>
-
- <para>In
- <filename>portal/WEB-INF/conf/jcr/repository-configuration.xml</filename>,
- you have to add parameter "analyzer" to each query-handler
- config:<programlisting><query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- ...
- <property name="analyzer" value="org.exoplatform.services.jcr.impl.core.MyAnalyzer"/>
- ...
- </properties>
-</query-handler></programlisting></para>
-
- <para>When you start exo, your SearchIndex will start to index
- contents with the specified filters.</para>
- </section>
- </section>
- </section>
-
- <section>
- <title>Index Adjustments</title>
-
- <section>
- <title>IndexingConfiguration</title>
-
- <para>Starting with version 1.9, the default search index implementation
- in JCR allows you to control which properties of a node are indexed. You
- also can define different analyzers for different nodes.</para>
-
- <para>The configuration parameter is called indexingConfiguration and
- per default is not set. This means all properties of a node are
- indexed.</para>
-
- <para>If you wish to configure the indexing behavior you need to add a
- parameter to the query-handler element in your configuration
- file.</para>
-
- <programlisting><param name="indexing-configuration-path" value="/indexing_configuration.xml"/></programlisting>
- </section>
-
- <section>
- <title>Index rules</title>
-
- <section>
- <title>Node Scope Limit</title>
-
- <para>To optimize the index size you can limit the node scope so that
- <phrase>only certain properties</phrase> of a node type are
- indexed.</para>
-
- <para>With the below configuration only properties named Text are
- indexed for nodes of type nt:unstructured. This configuration also
- applies to all nodes whose type extends from nt:unstructured.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
-
- <para>Please note that you have to declare the <phrase>namespace
- prefixes</phrase> in the configuration element that you are using
- throughout the XML file!</para>
- </section>
-
- <section>
- <title>Index Boost Value</title>
-
- <para>It is also possible to configure a <phrase>boost value</phrase>
- for the nodes that match the index rule. The default boost value is
- 1.0. Higher boost values (a reasonable range is 1.0 - 5.0) will yield
- a higher score value and appear as more relevant.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
-
- <para>If you do not wish to boost the complete node but only certain
- properties you can also provide a boost value for the listed
- properties:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property boost="3.0">Title</property>
- <property boost="1.5">Text</property>
- </index-rule>
-</configuration></programlisting></para>
- </section>
-
- <section>
- <title>Conditional Index Rules</title>
-
- <para>You may also add a <phrase>condition</phrase> to the index rule
- and have multiple rules with the same nodeType. The first index rule
- that matches will apply and all remaining ones are
- ignored:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="@priority = 'high'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting></para>
-
- <para>In the above example the first rule only applies if the
- nt:unstructured node has a priority property with a value 'high'. The
- condition syntax supports only the equals operator and a string
- literal.</para>
-
- <para>You may also reference properties in the condition that are not
- on the current node:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="ancestor::*/@priority = 'high'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured"
- boost="0.5"
- condition="parent::foo/@priority = 'low'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured"
- boost="1.5"
- condition="bar/@priority = 'medium'">
- <property>Text</property>
- </index-rule>
- <index-rule nodeType="nt:unstructured">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting></para>
-
- <para>The indexing configuration also allows you to specify the type
- of a node in the condition. Please note however that the type match
- must be exact. It does not consider sub types of the specified node
- type.</para>
-
- <programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured"
- boost="2.0"
- condition="element(*, nt:unstructured)/@priority = 'high'">
- <property>Text</property>
- </index-rule>
-</configuration></programlisting>
- </section>
-
- <section>
- <title>Exclusion from the Node Scope Index</title>
-
- <para>Per default all configured properties are fulltext indexed if
- they are of type STRING and included in the node scope index. A node
- scope search finds normally all nodes of an index. That is, the select
- jcr:contains(., 'foo') returns all nodes that have a string property
- containing the word 'foo'. You can exclude explicitly a property from
- the node scope index:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <index-rule nodeType="nt:unstructured">
- <property nodeScopeIndex="false">Text</property>
- </index-rule>
-</configuration></programlisting></para>
- </section>
- </section>
-
- <section>
- <title>Index Aggregates</title>
-
- <para>Sometimes it is useful to include the contents of descendant nodes
- into a single node to easier search on content that is scattered across
- multiple nodes.</para>
-
- <para>JCR allows you to define index aggregates based on relative path
- patterns and primary node types.</para>
-
- <para>The following example creates an index aggregate on nt:file that
- includes the content of the jcr:content node:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include>jcr:content</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>You can also restrict the included nodes to a certain
- type:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include primaryType="nt:resource">jcr:content</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>You may also use the * to match all child nodes:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">http://wiki.exoplatform.com/xwiki/bin/edit/JCR/Search+Configuration
- <include primaryType="nt:resource">*</include>
- </aggregate>
-</configuration></programlisting></para>
-
- <para>If you wish to include nodes up to a certain depth below the
- current node you can add multiple include elements. E.g. the nt:file
- node may contain a complete XML document under
- jcr:content:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
- xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <aggregate primaryType="nt:file">
- <include>*</include>
- <include>*/*</include>
- <include>*/*/*</include>
- </aggregate>
-</configuration></programlisting></para>
- </section>
-
- <section>
- <title>Property-Level Analyzers</title>
-
- <section>
- <title>Example</title>
-
- <para>In this configuration section you define how a property has to
- be analyzed. If there is an analyzer configuration for a property,
- this analyzer is used for indexing and searching of this property. For
- example:<programlisting><?xml version="1.0"?>
-<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
-<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
- <analyzers>
- <analyzer class="org.apache.lucene.analysis.KeywordAnalyzer">
- <property>mytext</property>
- </analyzer>
- <analyzer class="org.apache.lucene.analysis.WhitespaceAnalyzer">
- <property>mytext2</property>
- </analyzer>
- </analyzers>
-</configuration></programlisting></para>
-
- <para>The configuration above means that the property "mytext" for the
- entire workspace is indexed (and searched) with the Lucene
- KeywordAnalyzer, and property "mytext2" with the WhitespaceAnalyzer.
- Using different analyzers for different languages is particularly
- useful.</para>
-
- <para>The WhitespaceAnalyzer tokenizes a property, the KeywordAnalyzer
- takes the property as a whole.</para>
- </section>
-
- <section>
- <title>Characteristics of Node Scope Searches</title>
-
- <para>When using analyzers, you may encounter an unexpected behavior
- when searching within a property compared to searching within a node
- scope. The reason is that the node scope always uses the global
- analyzer.</para>
-
- <para>Let's suppose that the property "mytext" contains the text :
- "testing my analyzers" and that you haven't configured any analyzers
- for the property "mytext" (and not changed the default analyzer in
- SearchIndex).</para>
-
- <para>If your query is for example:<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting></para>
-
- <para>This xpath does not return a hit in the node with the property
- above and default analyzers.</para>
-
- <para>Also a search on the node scope<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>won't
- give a hit. Realize, that you can only set specific analyzers on a
- node property, and that the node scope indexing/analyzing is always
- done with the globally defined analyzer in the SearchIndex
- element.</para>
-
- <para>Now, if you change the analyzer used to index the "mytext"
- property above to<programlisting><analyzer class="org.apache.lucene.analysis.Analyzer.GermanAnalyzer">
- <property>mytext</property>
-</analyzer></programlisting>and you do the same search again, then
- for<programlisting>xpath = "//*[jcr:contains(mytext,'analyzer')]"</programlisting>you
- would get a hit because of the word stemming (analyzers -
- analyzer).</para>
-
- <para>The other search,<programlisting>xpath = "//*[jcr:contains(.,'analyzer')]"</programlisting>still
- would not give a result, since the node scope is indexed with the
- global analyzer, which in this case does not take into account any
- word stemming.</para>
-
- <para>In conclusion, be aware that when using analyzers for specific
- properties, you might find a hit in a property for some search text,
- and you do not find a hit with the same search text in the node scope
- of the property!</para>
-
- <note>
- <para>Both index rules and index aggregates influence how content is
- indexed in JCR. If you change the configuration the existing content
- is not automatically re-indexed according to the new rules. You
- therefore have to manually re-index the content when you change the
- configuration!</para>
- </note>
- </section>
- </section>
- </section>
-</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/jcr-query-usecases.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.QueryUsecases">
+ <title>JCR Query Usecases</title>
+
+ <section>
+ <title>Intro</title>
+
+ <para>JCR supports two query languages - JCR and XPath. A query, whether
+ XPath or SQL, specifies a subset of nodes within a workspace, called the
+ result set. The result set constitutes all the nodes in the workspace that
+ meet the constraints stated in the query.</para>
+ </section>
+
+ <section>
+ <title>Query Lifecycle</title>
+
+ <section>
+ <title>Query Creation and Execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make SQL query
+Query query = queryManager.createQuery("SELECT * FROM nt:base ", Query.SQL);
+// execute query
+QueryResult result = query.execute();</programlisting>
+
+ <para><emphasis role="bold">XPath</emphasis></para>
+
+ <programlisting>// get QueryManager
+QueryManager queryManager = workspace.getQueryManager();
+// make XPath query
+Query query = queryManager.createQuery("//element(*,nt:base)", Query.XPATH);
+// execute query
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Query Result Processing</title>
+
+ <programlisting>// fetch query result
+QueryResult result = query.execute();</programlisting>
+
+ <para>Now we can get result in an iterator of nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();</programlisting>
+
+ <para>or we get the result in a table:</para>
+
+ <programlisting>// get column names
+String[] columnNames = result.getColumnNames();
+// get column rows
+RowIterator rowIterator = result.getRows();
+while(rowIterator.hasNext()){
+ // get next row
+ Row row = rowIterator.nextRow();
+ // get all values of row
+ Value[] values = row.getValues();
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Scoring</title>
+
+ <para>The result returns a score for each row in the result set. The
+ score contains a value that indicates a rating of how well the result
+ node matches the query. A high value means a better matching than a low
+ value. This score can be used for ordering the result.</para>
+
+ <para>eXo JCR Scoring is a mapping of Lucene scoring. For a more
+ in-depth understanding, please study <ulink
+ url="http://lucene.apache.org/java/2_4_1/scoring.html">Lucene
+ documentation</ulink>.</para>
+
+ <para>jcr:score counted in next way - (lucene score)*1000f.</para>
+
+ <para>Score may be increased for specified nodes, see <ulink
+ url="Index Boost Value">Index Boost Value</ulink></para>
+
+ <para>Also, see an example <ulink url="JCR.Order by Score">JCR.Order by
+ Score</ulink></para>
+ </section>
+ </section>
+
+ <section>
+ <title>Query Examples</title>
+
+ <section>
+ <title>Query result settings</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="JCR.SetOffsetandSetLimit">Set Offset And
+ Limit</link></para>
+ </listitem>
+
+ <!--listitem>
+ <xi:include href="offset-and-limit.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </listitem-->
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Type Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="JCR.Find All Nodes">JCR.Find All
+ Nodes</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Find Nodes by Primary Type">JCR.Find Nodes by
+ Primary Type</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Find Nodes by Mixin Type">JCR.Find Nodes by
+ Mixin Type</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Property Constraints</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="JCR.Property Comparison">JCR.Property
+ Comparison</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.LIKE Constraint">JCR.LIKE
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Escaping in LIKE Statements">JCR.Escaping in
+ LIKE Statements</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.NOT Constraint">JCR.NOT
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.AND Constraint">JCR.AND
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.OR Constraint">JCR.OR
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Property Existence Constraint">JCR.Property
+ Existence Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Upper and Lower Case Constraints">JCR.Upper
+ and Lower Case Constraints</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Date Property Comparison">JCR.Date Property
+ Comparison</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Node Name Constraint">JCR.Node Name
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Multivalue Property Comparison">JCR.Multivalue
+ Property Comparison</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Path Constraint</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="JCR.Exact Path Constraint">JCR.Exact Path
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Child Node Constraint">JCR.Child Node
+ Constraint</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Find All Descendant Nodes">JCR.Find All
+ Descendant Nodes</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Ordering specifing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="JCR.Order by Property">JCR.Order by
+ Property</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Order by Descendant Node Property">JCR.Order
+ by Descendant Node Property</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Order by Score">JCR.Order by
+ Score</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Order by Path or Name">JCR.Order by Path or
+ Name</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title><ulink url="Fulltext Search">Fulltext Search</ulink></title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="JCR.Fulltext Search by Property">JCR.Fulltext
+ Search by Property</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="JCR.Fulltext Search by All Properties">JCR.Fulltext Search by
+ All Properties</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="Find nt:file document by content of child jcr:content node>Aggregation rule">Find
+ nt:file document by content of child jcr:content node>Aggregation
+ rule</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="How to set new Analyzer. Accent symblos ignoring>JCR.Ignore Accent Symbols">How
+ to set new Analyzer. Accent symblos ignoring>JCR.Ignore Accent
+ Symbols</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Indexing rules and additional features</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="Aggregation rule">Aggregation rule</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="JCR.Search Result Highlighting">JCR.Search Result
+ Highlighting</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="Index Boost Value">Index Boost
+ Value</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="Exclusion from the Node Scope Index>JCR.Node Scope Index">Exclusion
+ from the Node Scope Index>JCR.Node Scope Index</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="Regular expressions as property name in indexing rule > Regexp Indexing Rule">Regular
+ expressions as property name in indexing rule > Regexp Indexing
+ Rule</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="Synonim Provider">Synonim Provider</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="Spell Checking">Spell Checking</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="Find Similar Nodes">Find Similar
+ Nodes</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+
+ <section>
+ <title>Tips and tricks</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="Xpath and numbers in node names">Xpath and numbers
+ in node names</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/offset-and-limit.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/offset-and-limit.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/offset-and-limit.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<section id="JCR.SetOffsetandSetLimit">
+ <title>SetOffset and SetLimit</title>
+
+ <para>Select all nodes with primary type 'nt:unstructured' and returns only
+ 3 nodes starting with the second node in list.</para>
+
+ <section>
+ <title>Common info</title>
+
+ <para>QueryImpl class has two methods: one to indicate how many results
+ shall be returned at most, and another to fix the starting
+ position.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>setOffset(long offset) - Sets the start offset of the result
+ set.</para>
+ </listitem>
+
+ <listitem>
+ <para>setLimit(long position) - Sets the maximum size of the result
+ set.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Repository structure</title>
+
+ <para>Repository contains mix:title nodes, where jcr:title has different
+ values.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>root</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>node1 (nt:unstructured)</para>
+ </listitem>
+
+ <listitem>
+ <para>node2 (nt:unstructured)</para>
+ </listitem>
+
+ <listitem>
+ <para>node3 (nt:unstructured)</para>
+ </listitem>
+
+ <listitem>
+ <para>node4 (nt:unstructured)</para>
+ </listitem>
+
+ <listitem>
+ <para>node5 (nt:unstructured)</para>
+ </listitem>
+
+ <listitem>
+ <para>node6 (nt:unstructured)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Query execution</title>
+
+ <para><emphasis role="bold">SQL</emphasis></para>
+
+ <programlisting>// make SQL query
+QueryManager queryManager = workspace.getQueryManager();
+// create query
+String sqlStatement = "SELECT * FROM nt:unstructured";
+QueryImpl query = (QueryImpl)queryManager.createQuery(sqlStatement, Query.SQL);
+//return starting with second result
+query.setOffset(1);
+// return 3 results
+query.setLimit(3);
+// execute query and fetch result
+QueryResult result = query.execute();</programlisting>
+ </section>
+
+ <section>
+ <title>Fetch result</title>
+
+ <para>Lets get nodes:</para>
+
+ <programlisting>NodeIterator it = result.getNodes();
+
+if(it.hasNext())
+{
+ Node findedNode = it.nextNode();
+}</programlisting>
+
+ <para>In usual case (without using setOffset and setLimit methods) Node
+ iterator returns all nodes (node1...node6). But in our case NodeIterator
+ will return "node2","node3" and "node4".</para>
+
+ <para>\[node1 <emphasis role="bold">node2</emphasis> <emphasis
+ role="bold">node3</emphasis> <emphasis role="bold">node4</emphasis> node5
+ node6\]</para>
+ </section>
+</section>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/searching/searching-repository-content.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.SearchingRepositoryContent">
+ <?dbhtml filename="ch-jcr-searching-repository-conten.html"?>
+
+ <title>Searching Repository Content</title>
+
+ <section id="Introduction">
+ <title>Introduction</title>
+
+ <para>You can find the JCR configuration file here:
+ .../portal/WEB-INF/conf/jcr/repository-configuration.xml. Please read also
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> for
+ more information about index configuration.</para>
+ </section>
+
+ <section id="BidirectionalRangeIteratorsince1.9">
+ <title>Bi-directional RangeIterator (since 1.9)</title>
+
+ <para>QueryResult.getNodes() will return bi-directional NodeIterator
+ implementation.</para>
+
+ <note>
+ <para>Bi-directional NodeIterator is <emphasis role="bold">not
+ supported</emphasis> in two cases:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL query: select * from nt:base</para>
+ </listitem>
+
+ <listitem>
+ <para>XPath query: //* .</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>")</para>
+ </note>
+
+ <para>TwoWayRangeIterator interface:</para>
+
+ <programlisting>/**
+ * Skip a number of elements in the iterator.
+ *
+ * @param skipNum the non-negative number of elements to skip
+ * @throws java.util.NoSuchElementException if skipped past the first element
+ * in the iterator.
+ */
+public void skipBack(long skipNum);</programlisting>
+
+ <para>Usage:</para>
+
+ <programlisting>NodeIterator iter = queryResult.getNodes();
+while (iter.hasNext()) {
+ if (skipForward) {
+ iter.skip(10); // Skip 10 nodes in forward direction
+ } else if (skipBack) {
+ TwoWayRangeIterator backIter = (TwoWayRangeIterator) iter;
+ backIter.skipBack(10); // Skip 10 nodes back
+ }
+ .......
+}</programlisting>
+ </section>
+
+ <section id="FuzzySearchessince1.0">
+ <title>Fuzzy Searches (since 1.0)</title>
+
+ <para>JCR supports such features as Lucene Fuzzy Searches <ulink
+ url="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Apache
+ Lucene - Query Parser Syntax</ulink>.</para>
+
+ <para>To use it you have to form a query like described below:</para>
+
+ <programlisting>QueryManager qman = session.getWorkspace().getQueryManager();
+Query q = qman.createQuery("select * from nt:base where contains(field, 'ccccc~')", Query.SQL);
+QueryResult res = q.execute();</programlisting>
+ </section>
+
+ <section id="SynonymSearchsince1.9">
+ <title>SynonymSearch (since 1.9)</title>
+
+ <para>Searching with synonyms is integrated in the jcr:contains() function
+ and uses the same syntax as synonym searches in Google. If a search term
+ is prefixed by a tilde symbol ( ~ ) also synonyms of the search term are
+ taken into consideration. Example:</para>
+
+ <programlisting>SQL: select * from nt:resource where contains(., '~parameter')
+
+XPath: //element(*, nt:resource)[jcr:contains(., '~parameter')</programlisting>
+
+ <para>This feature is disabled per default and you need to add a
+ configuration parameter to the query-handler element in your jcr
+ configuration file to enable it.</para>
+
+ <programlisting><param name="synonymprovider-config-path" value="..you path to configuration file....."/>
+<param name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider"/></programlisting>
+
+ <programlisting>/**
+ * <code>SynonymProvider</code> defines an interface for a component that
+ * returns synonyms for a given term.
+ */
+public interface SynonymProvider {
+
+ /**
+ * Initializes the synonym provider and passes the file system resource to
+ * the synonym provider configuration defined by the configuration value of
+ * the <code>synonymProviderConfigPath</code> parameter. The resource may be
+ * <code>null</code> if the configuration parameter is not set.
+ *
+ * @param fsr the file system resource to the synonym provider
+ * configuration.
+ * @throws IOException if an error occurs while initializing the synonym
+ * provider.
+ */
+ public void initialize(InputStream fsr) throws IOException;
+
+ /**
+ * Returns an array of terms that are considered synonyms for the given
+ * <code>term</code>.
+ *
+ * @param term a search term.
+ * @return an array of synonyms for the given <code>term</code> or an empty
+ * array if no synonyms are known.
+ */
+ public String[] getSynonyms(String term);
+}</programlisting>
+ </section>
+
+ <section id="HighlightingSince1.9">
+ <title>Highlighting (Since 1.9)</title>
+
+ <para>An ExcerptProvider retrieves text excerpts for a node in the query
+ result and marks up the words in the text that match the query
+ terms.</para>
+
+ <para>Per default highlighting words that matched the query is disabled
+ because this feature requires that additional information is written to
+ the search index. To enable this feature you need to add a configuration
+ parameter to the query-handler element in your jcr configuration file to
+ enable it.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>Additionally there is a parameter that controls the format of the
+ excerpt created. In JCR 1.9 the default is set to
+ org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt.
+ The configuration parameter for this setting is:</para>
+
+ <programlisting><param name="excerptprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultXMLExcerpt"/></programlisting>
+
+ <section id="DefaultXMLExcerpt">
+ <title>DefaultXMLExcerpt</title>
+
+ <para>This excerpt provider creates an XML fragment of the following
+ form:</para>
+
+ <programlisting><excerpt>
+ <fragment>
+ <highlight>exoplatform</highlight> implements both the mandatory
+ XPath and optional SQL <highlight>query</highlight> syntax.
+ </fragment>
+ <fragment>
+ Before parsing the XPath <highlight>query</highlight> in
+ <highlight>exoplatform</highlight>, the statement is surrounded
+ </fragment>
+</excerpt></programlisting>
+ </section>
+
+ <section id="DefaultHTMLExcerpt">
+ <title>DefaultHTMLExcerpt</title>
+
+ <para>This excerpt provider creates an HTML fragment of the following
+ form:</para>
+
+ <programlisting><div>
+ <span>
+ <strong>exoplatform</strong> implements both the mandatory XPath
+ and optional SQL <strong>query</strong> syntax.
+ </span>
+ <span>
+ Before parsing the XPath <strong>query</strong> in
+ <strong>exoplatform</strong>, the statement is surrounded
+ </span>
+</div></programlisting>
+ </section>
+
+ <section id="Howtouseit">
+ <title>How to use it</title>
+
+ <para>If you are using XPath you must use the rep:excerpt() function in
+ the last location step, just like you would select properties:</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("//*[jcr:contains(., 'exoplatform')]/(@Title|rep:excerpt(.))", Query.XPATH);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value title = r.getValue("Title");
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+
+ <para>The above code searches for nodes that contain the word
+ exoplatform and then gets the value of the Title property and an excerpt
+ for each result node.</para>
+
+ <para>It is also possible to use a relative path in the call
+ Row.getValue() while the query statement still remains the same. Also
+ you may use a relative path to a string property. The returned value
+ will then be an excerpt based on string value of the property.</para>
+
+ <para>Both available excerpt provider will create fragments of about 150
+ characters and up to 3 fragments.</para>
+
+ <para>In SQL the function is called excerpt() without the rep prefix,
+ but the column in the RowIterator will nonetheless be labled
+ rep:excerpt(.)!</para>
+
+ <programlisting>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery("select excerpt(.) from nt:resource where contains(., 'exoplatform')", Query.SQL);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+ Row r = it.nextRow();
+ Value excerpt = r.getValue("rep:excerpt(.)");
+}</programlisting>
+ </section>
+ </section>
+
+ <section id="SpellChecker">
+ <title>SpellChecker</title>
+
+ <para>The lucene based query handler implementation supports a pluggable
+ spell checker mechanism. Per default spell checking is not available and
+ you have to configure it first. See parameter spellCheckerClass on page
+ <link linkend="JCR.SearchConfiguration">Search Configuration</link> JCR
+ currently provides an implementation class , which uses the <ulink
+ url="http://wiki.apache.org/jakarta-lucene/SpellChecker">lucene-spellchecker</ulink>
+ contrib . The dictionary is derived from the fulltext indexed content of
+ the workspace and updated periodically. You can configure the refresh
+ interval by picking one of the available inner classes of
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>OneMinuteRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>FiveMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>ThirtyMinutesRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneHourRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>SixHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>TwelveHoursRefreshInterval</para>
+ </listitem>
+
+ <listitem>
+ <para>OneDayRefreshInterval</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>E.g. if you want a refresh interval of six hours the class name is:
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$SixHoursRefreshInterval.
+ If you use
+ org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker
+ the refresh interval will be one hour.</para>
+
+ <para>The spell checker dictionary is stored as a lucene index under
+ <emphasis role="bold">"index-dir"/spellchecker</emphasis>. If it does not
+ exist, a background thread will create it on startup. Similarly the
+ dictionary refresh is also done in a background thread to not block
+ regular queries.</para>
+
+ <section id="HowdoIuseit">
+ <title>How do I use it?</title>
+
+ <para>You can spell check a fulltext statement either with an XPath or a
+ SQL query:</para>
+
+ <programlisting>// rep:spellcheck('explatform') will always evaluate to true
+Query query = qm.createQuery("/jcr:root[rep:spellcheck('explatform')]/(rep:spellcheck())", Query.XPATH);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+
+ <para>And the same using SQL:</para>
+
+ <programlisting>// SPELLCHECK('exoplatform') will always evaluate to true
+Query query = qm.createQuery("SELECT rep:spellcheck() FROM nt:base WHERE jcr:path = '/' AND SPELLCHECK('explatform')", Query.SQL);
+RowIterator rows = query.execute().getRows();
+// the above query will always return the root node no matter what string we check
+Row r = rows.nextRow();
+// get the result of the spell checking
+Value v = r.getValue("rep:spellcheck()");
+if (v == null) {
+ // no suggestion returned, the spelling is correct or the spell checker
+ // does not know how to correct it.
+} else {
+ String suggestion = v.getString();
+}</programlisting>
+ </section>
+ </section>
+
+ <section id="SimilaritySince1.12">
+ <title>Similarity (Since 1.12)</title>
+
+ <para>Starting with version, 1.12 JCR allows you to search for nodes that
+ are similar to an existing node.</para>
+
+ <para>Similarity is determined by looking up terms that are common to
+ nodes. There are some conditions that must be met for a term to be
+ considered. This is required to limit the number possibly relevant
+ terms.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Only terms with at least 4 characters are considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur at least 2 times in the source node are
+ considered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Only terms that occur in at least 5 nodes are considered.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note: The similarity functionality requires that the
+ supportHightlighting is enabled. Please make sure that you have the
+ following parameter set for the query handler in your
+ workspace.xml.</para>
+
+ <programlisting><param name="support-highlighting" value="true"/></programlisting>
+
+ <para>The functions are called rep:similar() (in XPath) and similar() (in
+ SQL) and have two arguments:</para>
+
+ <para>relativePath: a relative path to a descendant node or . for the
+ current node. absoluteStringPath: a string literal that contains the path
+ to the node for which to find similar nodes.</para>
+
+ <warning>
+ <para>Relative path is not supported yet.</para>
+ </warning>
+
+ <para>Examples:</para>
+
+ <programlisting>//element(*, nt:resource)[rep:similar(., '/parentnode/node.txt/jcr:content')]</programlisting>
+
+ <para>Finds nt:resource nodes, which are similar to node by path
+ /parentnode/node.txt/jcr:content.</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -12,26 +12,63 @@
<xi:include href="jcr/architecture.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <!-- concepts -->
+ <xi:include href="jcr/concepts/why-jcr.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-advantages.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-compatibility-levels.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-usage.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-extensions.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-applications.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/nodetype-registration.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-registry-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-namespace-altering.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/nodetypes-and-namespaces.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<!-- common configs -->
- <xi:include href="jcr/configuration.xml"
+ <xi:include href="jcr/configuration/exo-jcr-configuration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/jdbc-data-container-config.xml"
+ <xi:include href="jcr/configuration/multilanguage-support.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/external-value-storages.xml"
+ <xi:include href="jcr/configuration/search-configuration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/search-configuration.xml"
+ <xi:include href="jcr/configuration/configuration-persister.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/multilanguage-support.xml"
+ <xi:include href="jcr/configuration/jdbc-data-container-config.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/configuration-persister.xml"
+ <xi:include href="jcr/configuration/external-value-storages.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="jcr/configuration/workspace-persistence-storage.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/configuration/rest-services-on-groovy.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<!-- cluster configs -->
<xi:include href="jcr/cluster-config.xml"
@@ -52,48 +89,26 @@
<xi:include href="jcr/transaction-manager-lookup.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <!-- statistics configs -->
+ <!-- search -->
+
+ <xi:include href="jcr/searching/jcr-query-usecases.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/searching/searching-repository-content.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <!-- other -->
+
<xi:include href="jcr/statistics.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<!-- data container configs -->
<xi:include href="jcr/data-container.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="jcr/data-container-howto.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/why-jcr.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-advantages.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-compatibility-levels.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-usage.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-extensions.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-applications.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/nodetype-registration.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-registry-service.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/jcr-namespace-altering.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="jcr/concepts/nodetypes-and-namespaces.xml"
- xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
</part>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,472 +1,472 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
- <?dbhtml filename="ch-ws.html"?>
-
- <title>REST Framework</title>
-
- <important>
- <para>This describes REST framework before version exo-ws-2.0</para>
- </important>
-
- <section>
- <title>Requirements</title>
-
- <para>The purpose of eXo REST framework is to make eXo services (i.e. the
- components deployed inside eXo Container) simple and transparently
- accessible via HTTP in RESTful manner. In other words those services
- should be viewed as a set of REST Resources - endpoints of the HTTP
- request-response chain, we call those services ResourceContainers.</para>
-
- <para>image: Simplified working model</para>
-
- <para>Taking into account HTTP/REST constraints, it is considered that
- Resources (naturally mapped as Java methods) contained in
- ResourceContainer conform with the following conditions:</para>
-
- <itemizedlist>
- <listitem>
- <para>they are uniquely identifiable in the same way as it is
- specified for HTTP i.e. using URI</para>
- </listitem>
-
- <listitem>
- <para>they can accept data from an HTTP request using all possible
- mechanisms, i.e. as a part of an URL, as URI parameters, as HTTP
- headers and body</para>
- </listitem>
-
- <listitem>
- <para>they can return data to an HTTP response using all possible
- mechanisms, i.e. as HTTP status, headers and body</para>
- </listitem>
- </itemizedlist>
-
- <para>From the implementation point of view:</para>
-
- <itemizedlist>
- <listitem>
- <para>the framework should be as much JSR-311 compatible as possible
- for the time the Specification is in draft and fully compatible after
- the standard's release</para>
- </listitem>
-
- <listitem>
- <para>the ResourceContainer components should be deployable and
- accessible in the same way as an ordinary service</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Implementation</title>
-
- <para>In our REST architecture implementation, an HTTPServlet is the
- front-end for the REST engine. In this RESTful framework, endpoints for
- HTTP request are represented by java classes (ResourceContainers). All
- ResourceContainers are run as components of an ExoContainer, so they are
- configured within the same configuration file.</para>
-
- <para>ResourceBinder and ResourceDispatcher are two other important
- components of the REST engine. ResourceBinder deals with binding and
- unbinding ResourceContainer. ResourceDispatcher dispatches REST requests
- to ResourceContainer. ResourceBinder and ResourceDispatcher are also
- components of the ExoContainer</para>
-
- <section>
- <title>ResourceContainer</title>
-
- <para>A ResourceContainer is an annotated java class. Annotations must
- at least describe URLs and HTTP methods to be served by this container.
- But they may also describe other parameters, like produced content type
- or transformers. Transformers are special Java classes, used to
- serialize and deserialize Java objects.</para>
-
- <para>A very simple ResourceContainer may look like this:</para>
-
- <programlisting>@HTTPMethod("GET")
-@URITemplate("/test1/{param}/test2/")
-public Response method1(@URIParam("param") String param) {
-//...
-//...
- Response resp = Response.Builder.ok().build();
- return resp;
-}</programlisting>
-
- <para>The ResourceContainer described above is very simple, it can serve
- the GET HTTP method for the relative URL /test1/{param}/test2/ where
- {param} can be any string value. Additionally, {param} can be used as a
- method parameter of the container by annotating it as :
- @URIParam("param") String param. For example, in URL /test1/myID/test2
- the method parameter "param" has the value "myID".</para>
-
- <para>@URITemplate may be used for annotating classes or methods. If the
- TYPE scope annotation is for example @URITemplate("/testservices/") and
- a METHOD scope annotation is @URITemplate("/service1/") then that method
- can be called with the path /testservices/service1/. All
- ResourceContainer methods return Response objects. A Response includes
- HTTP status, an entity (the requested resource), HTTP headers and
- OutputEntityTransformer.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-scheme.png" />
- </imageobject>
- </mediaobject>
-
- <para>A client sends a request, after some operations, the HTTP request
- is parsed into three parts: the HTTP request stream, which consists of
- the body of the request, HTTP headers and query parameters. Then
- ResourceDispatcher gets this request. During the start of ExoContainers
- ResourceBinder collects all available ResourceContainers and after the
- start passes the list of ResourceContainers to the ResourceDispatcher.
- When ResourceDispatcher gets the request from a client it tries to
- search for a valid ResourceContainer. For this search ResourceDispatcher
- uses @HTTPMethod, @URITemplate and @ProducedMimeType annotations. The
- last one is not always necessary, if it is not specified this is set in
- / (all mime types). When ResourceDispatcher found the "right"
- ResourceContainer it tries to call a method with some parameters.
- ResourceDispatcher will send only parameters which ResourceContainer
- requests. In the code example above the parameter is a part of the
- requested URL between "/test1/" and "/test2/". ResourceContainer methods
- can consist only of some well-defined parameters. See the next
- rules:</para>
-
- <itemizedlist>
- <listitem>
- <para>Only one parameter of a method can be not annotated. This
- parameter represents the body of the HTTP request.</para>
- </listitem>
-
- <listitem>
- <para>All other parameters should be of java.lang.String types or
- must have a constructor with the java.lang.String parameter and must
- have annotation.</para>
- </listitem>
-
- <listitem>
- <para>If the parameter which represents the HTTP request body is
- present, then in the annotation @InputTransformer a java class must
- be defined that can build the requested parameter from
- java.io.InputStream. About transformation see below. After request
- processing ResourceContainer creates Request. Request is a special
- Java object which consists of HTTP status, a response header, an
- entity, a transformer. The entity is a representation of the
- requested resource. If Response has an entity it also must have
- OutputEntityTransformer. OutputEntityTransformer can be set in a few
- different ways.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Response</title>
-
- <para>Response is created by Builder. Builder is an inner static Java
- class within Response. Builder has some preset ways to build Response,
- for example (see code example above). The method ok() creates Builder
- with status 200 (OK HTTP status) and ok() returns again a Builder
- object. In this way a developer can again call other Builder methods.
- For example:</para>
-
- <programlisting>//...
-Document doc = ....
-Response response = Response.Builder.ok().entity(doc, "text/xml").transformer(new XMLOutputTransformer()).build();</programlisting>
-
- <para>In the code example above Response has HTTP status 200, an XML
- document like entity, a Content-Type header "text/xml" and
- OutputEntityTransformer of type XMLOutputTransformer. The method build()
- should be called at the end of process. In the same way a developer can
- build some other prepared Responses, like CREATED, NO CONTENT,
- FORBIDDEN, INTERNAL ERROR and other. In this example we set
- OutputEntityTransformer directly. Another mechanism to do this is the
- same like in the case with InputEntityTransformer.</para>
-
- <programlisting>//...
-@HTTPMethod("GET")
-@URITemplate("/test/resource1/")
-(a)InputTransformer(XMLInputTransformer.class)
-(a)OutputTransformer(XMLOutputTransformer.class)
-public Response method1(Document inputDoc) {
-//...
- Document doc = ....
- Response response = Response.Builder.ok(doc, "text/xml").build();
- return response;
-}</programlisting>
-
- <para>InputEntityTransformer is described in the annotation to the
- method "method1". OutputEntityTransformer is described in the annotation
- to the method "method1".</para>
- </section>
-
- <section>
- <title>Transformer</title>
-
- <para>All transformers can be created by EntityTransformerFactory.
- Transformers can be divided in two groups. Transformers from the first
- one extend the abstract class InputEntityTransformer.
- InputEntityTransformer implements the interface
- GenericInputEntityTransformer, and GenericInputEntityTransformer extends
- the interface GenericEntityTransformer. This architecture gives the
- possibility to use one class EntityTransformerFactory for creating both
- types of transformers (input and output). At first we will speak about
- InputEntityTransformer.</para>
-
- <para><command>InputEntityTransformer</command></para>
-
- <para>All classes which extend the abstract class InputEntitytransformer
- must override the method ObjectreadFrom(InputStream entityDataStream).
- This method must return an object with the same type as
- ResourceContainer requires in method parameters (one not annotated
- parameter). This mechanism works in the following way. For example, a
- class which extends InputEntityTransformer will be called
- SimpleInputTransformer. So, SimpleInputTransformer must have a simple
- constructor (without any parameters). SimpleInputTransformer also has
- two methods void setType(Class entityType) and Class getType(). Those
- methods are described in InputEntityTransformer. And, as we said above,
- SimpleInputTransformer must override the abstract method Object
- readFrom(InputStream entityDataStream). So, a developer needs to create
- a class which can build a Java Object from InputStream and then create
- annotation to ResourceContainer or some method in ResourceContainer.
- This annotation must define the type of InputEntityTransformer. Here is
- the code of the annotation InputTransformer.</para>
-
- <programlisting>//...
-@Retention(RUNTIME)
-@Target({TYPE, METHOD})
-public @interface InputTransformer {
- Class<? extends InputEntityTransformer> value();
-}</programlisting>
-
- <para>Then ResourceDispatcher gets InputTransformer from the factory
- during runtime then builds an Object from stream and adds it to the
- parameter array. See the code below.</para>
-
- <programlisting>//...
- InputEntityTransformer transformer = (InputEntityTransformer) factory_.newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] = transformer.readFrom(request.getEntityStream());
-//...
- Response response = (Response) resource.getServer().invoke(resource.getResourceContainer(), params);</programlisting>
-
- <para>A developer can find some prepared transformers in the package
- "org.exoplatform.services.rest.transformer".</para>
-
- <para><command>OutputEntityTransformer</command></para>
-
- <para>OutputEntityTransformer can be used to serialize the Object which
- represents the requested resource to OutputStream.
- OutputEntityTransformer, in future we will call it
- SimpleOutputTransformer, can be defined in a few ways.</para>
-
- <para>Now some more words about transformation. The RESTful framework
- has two multi-purpose input/output transformers. One of them is
- JAXB(Input/Output)Transformer, and another one is
- Serializable(Input/Output)Transformer. The first one uses JAXB API for
- serializing and deserializing an object. Serializable
- (Input/Output)Transformer uses the own methods of an entity for
- serialization and deserialization. Here is an example:</para>
-
- <programlisting>/...
-public class SimpleSerializableEntity implements SerializableEntity {
-
- String data;
-
- public SimpleSerializableEntity() {
- }
-
- public void readObject(InputStream in) throws IOException {
- StringBuffer sb = new StringBuffer();
- int rd = -1;
- while((rd = in.read()) != -1)
- sb.append((char)rd);
- data = sb.toString();
- }
-
- public void writeObject(OutputStream out) throws IOException {
- out.write(data.getBytes());
- }
-}</programlisting>
-
- <para>SerializableInputTransformer will try to use the method void
- readObject(InputStream in) and SerializableOutputTransformer will try to
- use the method void writeObject(OutputStream in).</para>
- </section>
-
- <section>
- <title>Binding and unbinding components (ResourceContainers)</title>
-
- <para>ResourceBinder takes care of binding and unbinding components
- which represent ResourceContainer. All ResourceContainers must be
- defined as ExoContainer components in configuration files, for
- example:</para>
-
- <programlisting><component>
- <type>org.exoplatform.services.rest.samples.RESTSampleService</type>
-</component></programlisting>
-
- <para>ResourceBinder is an ExoContainer component and implements the
- interface org.picocontainer.Startable (see the picocontainer
- documentation). So at the start of ExoContainer ResourceBinder collects
- all available ResourceContainers. ResourceBinder makes validation for
- all ResourceContainers. At least each ResourceContainer must have the
- @HTTPMethod annotation and @URITemplate annotation. Other annotations
- are not obligatory. It's not allowed to have few ResourceContainers or
- methods with the same @HTTPMethod and @URITemplate annotation value. For
- example, if one container/method has the following code:</para>
-
- <programlisting>public class SimpleResourceContainer implements ResourceContainer {
- @HTTPMethod("GET")
- @URITemplate("/services/{id}/service1/")
- @InputTransformer(StringInputTransformer.class)
- @OutputTransformer(StringOutputTransformer.class)
- public Response method1(String data, @URIParam("id") String param) {
- // ...
- }
-}</programlisting>
-
- <para>than another component with @HTTPMethod("GET") and
- @URITemplate("/services/service1/{id}/") can't be bound. And now we'll
- try to explain this situation. On the one hand URITemplate is defined by
- value /services/{id}/service1/, instead of {id} there can be any other
- string value, so the combination /services/service1/service1/ is
- possible and valid. On the other hand another URITemplate
- /services/service1/{id}/ can have the string service1 instead of {id},
- so for this resource the combination /services/service1/service1/ is
- possible and valid. And now we have two resources with the same
- URITemplate and the same HTTPMethod. This situation is not obligatory,
- we can't say what method we must call! In this case ResourceBinder
- generates InvalidResourceDescriptorException. Binder also checks the
- method parameters. In parameters only one parameter without annotation
- and of free type is allowed. All other parameters must have String type
- (or have a constructor with String) and be annotated. In other cases
- InvalidResourceDescriptorException* is generated. If all components have
- the "right" @HTTPMethod and @URITemplate annotations they should be
- bound without any problems. ResourceDispather gets a collection of
- ResourceContainers during the start and everything is ready to serve a
- request.</para>
-
- <para>Note: within the scope of one component (one class) validation for
- URI templates is not implemented, so a developer must take care of
- @URITemplate and @HTTPMethod. Both of them must not be the same for
- different methods. Except if @QueryTemplate or/and @ProducedMimeTypes
- annotation is used.</para>
- </section>
-
- <section>
- <title>ResourceDispatcher</title>
-
- <para>Now let's talk about the features of ResourceDispatcher.
- ResourceDispatcher is the main part of the RESTful engine. Above we said
- some words about transformation and the role of ResourceDispatcher in
- this process. Now we are ready to talk about annotated method
- parameters. In one of the code examples above you could see the next
- construction</para>
-
- <programlisting>public Response method1(String data, @URIParam("id") String param) {</programlisting>
-
- <para>The method method1 is described with two parameters. The first
- parameter String data is built from the entity body (InputStream). The
- second one - String param is annotated by a special type Annotation.
- This Annotation has the following code:</para>
-
- <programlisting>@Target(value={PARAMETER})
-@Retention(RUNTIME)
-public @interface URIParam {
- String value();
-}</programlisting>
-
- <para>How does it work? After having found the right method
- ResourceDispatcher gets the list of method parameters and starts
- handling them. Dispatcher tries to find the not annotated parameter
- (this entity body) and addresses InputEntityTransformer in order to
- build the required Object from InputStream. When dispatcher finds an
- annotated parameter it checks the type of annotation. It is possible to
- have four types of annotation: @URIParam, @HeaderParam, @QueryParam and
- @ContextParameter. If dispatcher has found the annotation
- @URIParam("id") then it takes the parameter with the key "id" from
- ResourceDescription and adds it into the parameter array. The same
- situation is with header, context and query parameters. So within the
- method a developer gets only the necessary parameters from header, query
- and uri. Some more information about @ContextParameters.
- @ContextParameters can be set in the configuration file of a
- component:</para>
-
- <programlisting><component>
-<type>org.exoplatform.services.rest.ResourceDispatcher</type>
- <init-params>
- <properties-param>
- <name>context-params</name>
- <property name="test" value="test_1"/>
- </properties-param>
- </init-params>
-</component></programlisting>
-
- <para>In this case any service can use this parameter, for
- example:</para>
-
- <programlisting>...method(@ContextParam("test") String p) {
- System.out.println(p);
-}</programlisting>
-
- <para>After its execution you should see "test_1" in console.</para>
-
- <para>And in each service the next context parameters can be used. The
- name of these parameters are described in ResourceDispatcher:</para>
-
- <programlisting>public static final String CONTEXT_PARAM_HOST = "host";
-public static final String CONTEXT_PARAM_BASE_URI = "baseURI";
-public static final String CONTEXT_PARAM_REL_URI = "relURI";
-public static final String CONTEXT_PARAM_ABSLOCATION = "absLocation";</programlisting>
-
- <para>After that dispatcher finishes collecting parameters that the
- method requires, invokes this method and passes the result to the client
- as it is described above.</para>
-
- <para>This part of code can explain how this mechanism works:</para>
-
- <programlisting>//...
- for (int i = 0; i < methodParametersAnnotations.length; i++) {
- if (methodParametersAnnotations[i] == null) {
- InputEntityTransformer transformer = (InputEntityTransformer) factory
- .newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] = transformer.readFrom(request.getEntityStream());
- } else {
- Constructor<?> constructor = methodParameters[i].getConstructor(String.class);
- String constructorParam = null;
- Annotation a = methodParametersAnnotations[i];
- if (a.annotationType().isAssignableFrom(URIParam.class)) {
- URIParam u = (URIParam) a;
- constructorParam = request.getResourceIdentifier().getParameters().get(u.value());
- } else if (a.annotationType().isAssignableFrom(HeaderParam.class)) {
- HeaderParam h = (HeaderParam) a;
- constructorParam = request.getHeaderParams().get(h.value());
- } else if (a.annotationType().isAssignableFrom(QueryParam.class)) {
- QueryParam q = (QueryParam) a;
- constructorParam = request.getQueryParams().get(q.value());
- } else if (a.annotationType().isAssignableFrom(ContextParam.class)) {
- ContextParam c = (ContextParam) a;
- constructorParam = contextHolder_.get().get(c.value());
- }
- if (methodParameters[i].isAssignableFrom(String.class)) {
- params[i] = constructorParam;
- } else {
- params[i] = (constructorParam != null) ? constructor.newInstance(constructorParam) : null;
- }
- }
- }
- Response resp = (Response) resource.getServer().invoke(resource.getResourceContainer(), params);
-//...</programlisting>
-
- <para>The more detailed schema looks like this:</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-scheme-detailed.png" />
- </imageobject>
- </mediaobject>
- </section>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="WS.RestFramework">
+ <?dbhtml filename="ch-ws-rest-framework.html"?>
+
+ <title>REST Framework</title>
+
+ <important>
+ <para>This describes REST framework before version exo-ws-2.0</para>
+ </important>
+
+ <section>
+ <title>Requirements</title>
+
+ <para>The purpose of eXo REST framework is to make eXo services (i.e. the
+ components deployed inside eXo Container) simple and transparently
+ accessible via HTTP in RESTful manner. In other words those services
+ should be viewed as a set of REST Resources - endpoints of the HTTP
+ request-response chain, we call those services ResourceContainers.</para>
+
+ <para>image: Simplified working model</para>
+
+ <para>Taking into account HTTP/REST constraints, it is considered that
+ Resources (naturally mapped as Java methods) contained in
+ ResourceContainer conform with the following conditions:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>they are uniquely identifiable in the same way as it is
+ specified for HTTP i.e. using URI</para>
+ </listitem>
+
+ <listitem>
+ <para>they can accept data from an HTTP request using all possible
+ mechanisms, i.e. as a part of an URL, as URI parameters, as HTTP
+ headers and body</para>
+ </listitem>
+
+ <listitem>
+ <para>they can return data to an HTTP response using all possible
+ mechanisms, i.e. as HTTP status, headers and body</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>From the implementation point of view:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the framework should be as much JSR-311 compatible as possible
+ for the time the Specification is in draft and fully compatible after
+ the standard's release</para>
+ </listitem>
+
+ <listitem>
+ <para>the ResourceContainer components should be deployable and
+ accessible in the same way as an ordinary service</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Implementation</title>
+
+ <para>In our REST architecture implementation, an HTTPServlet is the
+ front-end for the REST engine. In this RESTful framework, endpoints for
+ HTTP request are represented by java classes (ResourceContainers). All
+ ResourceContainers are run as components of an ExoContainer, so they are
+ configured within the same configuration file.</para>
+
+ <para>ResourceBinder and ResourceDispatcher are two other important
+ components of the REST engine. ResourceBinder deals with binding and
+ unbinding ResourceContainer. ResourceDispatcher dispatches REST requests
+ to ResourceContainer. ResourceBinder and ResourceDispatcher are also
+ components of the ExoContainer</para>
+
+ <section>
+ <title>ResourceContainer</title>
+
+ <para>A ResourceContainer is an annotated java class. Annotations must
+ at least describe URLs and HTTP methods to be served by this container.
+ But they may also describe other parameters, like produced content type
+ or transformers. Transformers are special Java classes, used to
+ serialize and deserialize Java objects.</para>
+
+ <para>A very simple ResourceContainer may look like this:</para>
+
+ <programlisting>@HTTPMethod("GET")
+@URITemplate("/test1/{param}/test2/")
+public Response method1(@URIParam("param") String param) {
+//...
+//...
+ Response resp = Response.Builder.ok().build();
+ return resp;
+}</programlisting>
+
+ <para>The ResourceContainer described above is very simple, it can serve
+ the GET HTTP method for the relative URL /test1/{param}/test2/ where
+ {param} can be any string value. Additionally, {param} can be used as a
+ method parameter of the container by annotating it as :
+ @URIParam("param") String param. For example, in URL /test1/myID/test2
+ the method parameter "param" has the value "myID".</para>
+
+ <para>@URITemplate may be used for annotating classes or methods. If the
+ TYPE scope annotation is for example @URITemplate("/testservices/") and
+ a METHOD scope annotation is @URITemplate("/service1/") then that method
+ can be called with the path /testservices/service1/. All
+ ResourceContainer methods return Response objects. A Response includes
+ HTTP status, an entity (the requested resource), HTTP headers and
+ OutputEntityTransformer.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/rest-scheme.png" />
+ </imageobject>
+ </mediaobject>
+
+ <para>A client sends a request, after some operations, the HTTP request
+ is parsed into three parts: the HTTP request stream, which consists of
+ the body of the request, HTTP headers and query parameters. Then
+ ResourceDispatcher gets this request. During the start of ExoContainers
+ ResourceBinder collects all available ResourceContainers and after the
+ start passes the list of ResourceContainers to the ResourceDispatcher.
+ When ResourceDispatcher gets the request from a client it tries to
+ search for a valid ResourceContainer. For this search ResourceDispatcher
+ uses @HTTPMethod, @URITemplate and @ProducedMimeType annotations. The
+ last one is not always necessary, if it is not specified this is set in
+ / (all mime types). When ResourceDispatcher found the "right"
+ ResourceContainer it tries to call a method with some parameters.
+ ResourceDispatcher will send only parameters which ResourceContainer
+ requests. In the code example above the parameter is a part of the
+ requested URL between "/test1/" and "/test2/". ResourceContainer methods
+ can consist only of some well-defined parameters. See the next
+ rules:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Only one parameter of a method can be not annotated. This
+ parameter represents the body of the HTTP request.</para>
+ </listitem>
+
+ <listitem>
+ <para>All other parameters should be of java.lang.String types or
+ must have a constructor with the java.lang.String parameter and must
+ have annotation.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the parameter which represents the HTTP request body is
+ present, then in the annotation @InputTransformer a java class must
+ be defined that can build the requested parameter from
+ java.io.InputStream. About transformation see below. After request
+ processing ResourceContainer creates Request. Request is a special
+ Java object which consists of HTTP status, a response header, an
+ entity, a transformer. The entity is a representation of the
+ requested resource. If Response has an entity it also must have
+ OutputEntityTransformer. OutputEntityTransformer can be set in a few
+ different ways.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Response</title>
+
+ <para>Response is created by Builder. Builder is an inner static Java
+ class within Response. Builder has some preset ways to build Response,
+ for example (see code example above). The method ok() creates Builder
+ with status 200 (OK HTTP status) and ok() returns again a Builder
+ object. In this way a developer can again call other Builder methods.
+ For example:</para>
+
+ <programlisting>//...
+Document doc = ....
+Response response = Response.Builder.ok().entity(doc, "text/xml").transformer(new XMLOutputTransformer()).build();</programlisting>
+
+ <para>In the code example above Response has HTTP status 200, an XML
+ document like entity, a Content-Type header "text/xml" and
+ OutputEntityTransformer of type XMLOutputTransformer. The method build()
+ should be called at the end of process. In the same way a developer can
+ build some other prepared Responses, like CREATED, NO CONTENT,
+ FORBIDDEN, INTERNAL ERROR and other. In this example we set
+ OutputEntityTransformer directly. Another mechanism to do this is the
+ same like in the case with InputEntityTransformer.</para>
+
+ <programlisting>//...
+@HTTPMethod("GET")
+@URITemplate("/test/resource1/")
+(a)InputTransformer(XMLInputTransformer.class)
+(a)OutputTransformer(XMLOutputTransformer.class)
+public Response method1(Document inputDoc) {
+//...
+ Document doc = ....
+ Response response = Response.Builder.ok(doc, "text/xml").build();
+ return response;
+}</programlisting>
+
+ <para>InputEntityTransformer is described in the annotation to the
+ method "method1". OutputEntityTransformer is described in the annotation
+ to the method "method1".</para>
+ </section>
+
+ <section>
+ <title>Transformer</title>
+
+ <para>All transformers can be created by EntityTransformerFactory.
+ Transformers can be divided in two groups. Transformers from the first
+ one extend the abstract class InputEntityTransformer.
+ InputEntityTransformer implements the interface
+ GenericInputEntityTransformer, and GenericInputEntityTransformer extends
+ the interface GenericEntityTransformer. This architecture gives the
+ possibility to use one class EntityTransformerFactory for creating both
+ types of transformers (input and output). At first we will speak about
+ InputEntityTransformer.</para>
+
+ <para><command>InputEntityTransformer</command></para>
+
+ <para>All classes which extend the abstract class InputEntitytransformer
+ must override the method ObjectreadFrom(InputStream entityDataStream).
+ This method must return an object with the same type as
+ ResourceContainer requires in method parameters (one not annotated
+ parameter). This mechanism works in the following way. For example, a
+ class which extends InputEntityTransformer will be called
+ SimpleInputTransformer. So, SimpleInputTransformer must have a simple
+ constructor (without any parameters). SimpleInputTransformer also has
+ two methods void setType(Class entityType) and Class getType(). Those
+ methods are described in InputEntityTransformer. And, as we said above,
+ SimpleInputTransformer must override the abstract method Object
+ readFrom(InputStream entityDataStream). So, a developer needs to create
+ a class which can build a Java Object from InputStream and then create
+ annotation to ResourceContainer or some method in ResourceContainer.
+ This annotation must define the type of InputEntityTransformer. Here is
+ the code of the annotation InputTransformer.</para>
+
+ <programlisting>//...
+@Retention(RUNTIME)
+@Target({TYPE, METHOD})
+public @interface InputTransformer {
+ Class<? extends InputEntityTransformer> value();
+}</programlisting>
+
+ <para>Then ResourceDispatcher gets InputTransformer from the factory
+ during runtime then builds an Object from stream and adds it to the
+ parameter array. See the code below.</para>
+
+ <programlisting>//...
+ InputEntityTransformer transformer = (InputEntityTransformer) factory_.newTransformer(resource.getInputTransformerType());
+ transformer.setType(methodParameters[i]);
+ params[i] = transformer.readFrom(request.getEntityStream());
+//...
+ Response response = (Response) resource.getServer().invoke(resource.getResourceContainer(), params);</programlisting>
+
+ <para>A developer can find some prepared transformers in the package
+ "org.exoplatform.services.rest.transformer".</para>
+
+ <para><command>OutputEntityTransformer</command></para>
+
+ <para>OutputEntityTransformer can be used to serialize the Object which
+ represents the requested resource to OutputStream.
+ OutputEntityTransformer, in future we will call it
+ SimpleOutputTransformer, can be defined in a few ways.</para>
+
+ <para>Now some more words about transformation. The RESTful framework
+ has two multi-purpose input/output transformers. One of them is
+ JAXB(Input/Output)Transformer, and another one is
+ Serializable(Input/Output)Transformer. The first one uses JAXB API for
+ serializing and deserializing an object. Serializable
+ (Input/Output)Transformer uses the own methods of an entity for
+ serialization and deserialization. Here is an example:</para>
+
+ <programlisting>/...
+public class SimpleSerializableEntity implements SerializableEntity {
+
+ String data;
+
+ public SimpleSerializableEntity() {
+ }
+
+ public void readObject(InputStream in) throws IOException {
+ StringBuffer sb = new StringBuffer();
+ int rd = -1;
+ while((rd = in.read()) != -1)
+ sb.append((char)rd);
+ data = sb.toString();
+ }
+
+ public void writeObject(OutputStream out) throws IOException {
+ out.write(data.getBytes());
+ }
+}</programlisting>
+
+ <para>SerializableInputTransformer will try to use the method void
+ readObject(InputStream in) and SerializableOutputTransformer will try to
+ use the method void writeObject(OutputStream in).</para>
+ </section>
+
+ <section>
+ <title>Binding and unbinding components (ResourceContainers)</title>
+
+ <para>ResourceBinder takes care of binding and unbinding components
+ which represent ResourceContainer. All ResourceContainers must be
+ defined as ExoContainer components in configuration files, for
+ example:</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.rest.samples.RESTSampleService</type>
+</component></programlisting>
+
+ <para>ResourceBinder is an ExoContainer component and implements the
+ interface org.picocontainer.Startable (see the picocontainer
+ documentation). So at the start of ExoContainer ResourceBinder collects
+ all available ResourceContainers. ResourceBinder makes validation for
+ all ResourceContainers. At least each ResourceContainer must have the
+ @HTTPMethod annotation and @URITemplate annotation. Other annotations
+ are not obligatory. It's not allowed to have few ResourceContainers or
+ methods with the same @HTTPMethod and @URITemplate annotation value. For
+ example, if one container/method has the following code:</para>
+
+ <programlisting>public class SimpleResourceContainer implements ResourceContainer {
+ @HTTPMethod("GET")
+ @URITemplate("/services/{id}/service1/")
+ @InputTransformer(StringInputTransformer.class)
+ @OutputTransformer(StringOutputTransformer.class)
+ public Response method1(String data, @URIParam("id") String param) {
+ // ...
+ }
+}</programlisting>
+
+ <para>than another component with @HTTPMethod("GET") and
+ @URITemplate("/services/service1/{id}/") can't be bound. And now we'll
+ try to explain this situation. On the one hand URITemplate is defined by
+ value /services/{id}/service1/, instead of {id} there can be any other
+ string value, so the combination /services/service1/service1/ is
+ possible and valid. On the other hand another URITemplate
+ /services/service1/{id}/ can have the string service1 instead of {id},
+ so for this resource the combination /services/service1/service1/ is
+ possible and valid. And now we have two resources with the same
+ URITemplate and the same HTTPMethod. This situation is not obligatory,
+ we can't say what method we must call! In this case ResourceBinder
+ generates InvalidResourceDescriptorException. Binder also checks the
+ method parameters. In parameters only one parameter without annotation
+ and of free type is allowed. All other parameters must have String type
+ (or have a constructor with String) and be annotated. In other cases
+ InvalidResourceDescriptorException* is generated. If all components have
+ the "right" @HTTPMethod and @URITemplate annotations they should be
+ bound without any problems. ResourceDispather gets a collection of
+ ResourceContainers during the start and everything is ready to serve a
+ request.</para>
+
+ <para>Note: within the scope of one component (one class) validation for
+ URI templates is not implemented, so a developer must take care of
+ @URITemplate and @HTTPMethod. Both of them must not be the same for
+ different methods. Except if @QueryTemplate or/and @ProducedMimeTypes
+ annotation is used.</para>
+ </section>
+
+ <section>
+ <title>ResourceDispatcher</title>
+
+ <para>Now let's talk about the features of ResourceDispatcher.
+ ResourceDispatcher is the main part of the RESTful engine. Above we said
+ some words about transformation and the role of ResourceDispatcher in
+ this process. Now we are ready to talk about annotated method
+ parameters. In one of the code examples above you could see the next
+ construction</para>
+
+ <programlisting>public Response method1(String data, @URIParam("id") String param) {</programlisting>
+
+ <para>The method method1 is described with two parameters. The first
+ parameter String data is built from the entity body (InputStream). The
+ second one - String param is annotated by a special type Annotation.
+ This Annotation has the following code:</para>
+
+ <programlisting>@Target(value={PARAMETER})
+@Retention(RUNTIME)
+public @interface URIParam {
+ String value();
+}</programlisting>
+
+ <para>How does it work? After having found the right method
+ ResourceDispatcher gets the list of method parameters and starts
+ handling them. Dispatcher tries to find the not annotated parameter
+ (this entity body) and addresses InputEntityTransformer in order to
+ build the required Object from InputStream. When dispatcher finds an
+ annotated parameter it checks the type of annotation. It is possible to
+ have four types of annotation: @URIParam, @HeaderParam, @QueryParam and
+ @ContextParameter. If dispatcher has found the annotation
+ @URIParam("id") then it takes the parameter with the key "id" from
+ ResourceDescription and adds it into the parameter array. The same
+ situation is with header, context and query parameters. So within the
+ method a developer gets only the necessary parameters from header, query
+ and uri. Some more information about @ContextParameters.
+ @ContextParameters can be set in the configuration file of a
+ component:</para>
+
+ <programlisting><component>
+<type>org.exoplatform.services.rest.ResourceDispatcher</type>
+ <init-params>
+ <properties-param>
+ <name>context-params</name>
+ <property name="test" value="test_1"/>
+ </properties-param>
+ </init-params>
+</component></programlisting>
+
+ <para>In this case any service can use this parameter, for
+ example:</para>
+
+ <programlisting>...method(@ContextParam("test") String p) {
+ System.out.println(p);
+}</programlisting>
+
+ <para>After its execution you should see "test_1" in console.</para>
+
+ <para>And in each service the next context parameters can be used. The
+ name of these parameters are described in ResourceDispatcher:</para>
+
+ <programlisting>public static final String CONTEXT_PARAM_HOST = "host";
+public static final String CONTEXT_PARAM_BASE_URI = "baseURI";
+public static final String CONTEXT_PARAM_REL_URI = "relURI";
+public static final String CONTEXT_PARAM_ABSLOCATION = "absLocation";</programlisting>
+
+ <para>After that dispatcher finishes collecting parameters that the
+ method requires, invokes this method and passes the result to the client
+ as it is described above.</para>
+
+ <para>This part of code can explain how this mechanism works:</para>
+
+ <programlisting>//...
+ for (int i = 0; i < methodParametersAnnotations.length; i++) {
+ if (methodParametersAnnotations[i] == null) {
+ InputEntityTransformer transformer = (InputEntityTransformer) factory
+ .newTransformer(resource.getInputTransformerType());
+ transformer.setType(methodParameters[i]);
+ params[i] = transformer.readFrom(request.getEntityStream());
+ } else {
+ Constructor<?> constructor = methodParameters[i].getConstructor(String.class);
+ String constructorParam = null;
+ Annotation a = methodParametersAnnotations[i];
+ if (a.annotationType().isAssignableFrom(URIParam.class)) {
+ URIParam u = (URIParam) a;
+ constructorParam = request.getResourceIdentifier().getParameters().get(u.value());
+ } else if (a.annotationType().isAssignableFrom(HeaderParam.class)) {
+ HeaderParam h = (HeaderParam) a;
+ constructorParam = request.getHeaderParams().get(h.value());
+ } else if (a.annotationType().isAssignableFrom(QueryParam.class)) {
+ QueryParam q = (QueryParam) a;
+ constructorParam = request.getQueryParams().get(q.value());
+ } else if (a.annotationType().isAssignableFrom(ContextParam.class)) {
+ ContextParam c = (ContextParam) a;
+ constructorParam = contextHolder_.get().get(c.value());
+ }
+ if (methodParameters[i].isAssignableFrom(String.class)) {
+ params[i] = constructorParam;
+ } else {
+ params[i] = (constructorParam != null) ? constructor.newInstance(constructorParam) : null;
+ }
+ }
+ }
+ Response resp = (Response) resource.getServer().invoke(resource.getResourceContainer(), params);
+//...</programlisting>
+
+ <para>The more detailed schema looks like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/rest-scheme-detailed.png" />
+ </imageobject>
+ </mediaobject>
+ </section>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml 2010-08-03 06:46:23 UTC (rev 2855)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml 2010-08-03 07:16:23 UTC (rev 2856)
@@ -1,221 +1,221 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
- <?dbhtml filename="ch-ws.html"?>
-
- <title>REST Service Tutorial</title>
-
- <important>
- <para>This article describes REST framework before version
- exo-ws-2.0.</para>
- </important>
-
- <section>
- <title>Introduction</title>
-
- <para>This HOW-TO explains how to create your own REST based services. In
- this HOW-TO we will create a simple calculator, which can do basic
- operations with integers.</para>
- </section>
-
- <section>
- <title>Source code</title>
-
- <programlisting>// ...
-@URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
-}</programlisting>
-
- <para>Writing <command>@URITemplate</command> before the class definition
- gives you the possibility not to set it for each method. Furthermore the
- class must implement the interface <command>ResourceContainer</command>.
- This interface doesn't have any methods, it is just an indication for the
- <command>ResourceBinder</command>. Add the code for adding two
- integers.</para>
-
- <programlisting>// ...
-@URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
- @QueryTemplate("operation=add")
- @OutputTransformer(StringOutputTransformer.class)
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1,
- @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" = ").append(item1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}</programlisting>
-
- <para>@QueryTemplate("operation=add") - only requests with query
- parameters "operation=add" can reach this method;
- @OutputTransformer(StringOutputTransformer.class) - the output
- transformer; @HTTPMethod("GET") - the HTTP method "GET".</para>
-
- <para>Write the code for other operations in the same way. Then the result
- should look like:</para>
-
- <programlisting>package org.exoplatform.services.rest.example;
-
-import org.exoplatform.services.rest.HTTPMethod;
-import org.exoplatform.services.rest.OutputTransformer;
-import org.exoplatform.services.rest.QueryTemplate;
-import org.exoplatform.services.rest.Response;
-import org.exoplatform.services.rest.URIParam;
-import org.exoplatform.services.rest.URITemplate;
-import org.exoplatform.services.rest.container.ResourceContainer;
-import org.exoplatform.services.rest.transformer.StringOutputTransformer;
-
-@URITemplate("/calculator/{item1}/{item2}/")
-(a)OutputTransformer(StringOutputTransformer.class)
-public class Calculator implements ResourceContainer {
-
- @QueryTemplate("operation=add")
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" = ").append(item1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=subtract")
- @HTTPMethod("GET")
- public Response subtract(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" - ").append(item2).append(" = ").append(item1 - item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=multiply")
- @HTTPMethod("GET")
- public Response multiply(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" * ").append(item2).append(" = ").append(item1 * item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=divide")
- @HTTPMethod("GET")
- public Response divide(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" / ").append(item2).append(" = ").append(item1 / item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}</programlisting>
-
- <para>So we are done with the source code.</para>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <para>Create the directory conf/portal and create the file
- configuration.xml in it. Add the following code to this file:</para>
-
- <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
-<configuration>
- <component>
- <type>org.exoplatform.services.rest.example.Calculator</type>
- </component>
-</configuration></programlisting>
- </section>
-
- <section>
- <title>Build</title>
-
- <para>Now we must create the following directory structure to get the
- possibility to build the source code using maven.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-build-process.png" />
- </imageobject>
- </mediaobject>
-
- <para>Then create the file pom.xml using the following:</para>
-
- <programlisting><project>
- <parent>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>config</artifactId>
- <version>trunk</version>
- </parent>
-
- <modelVersion&#624;.0.0</modelVersion>
- <groupId>org.exoplatform.ws.rest</groupId>
- <artifactId>simple.calculator</artifactId>
- <packaging>jar</packaging>
- <version>trunk</version>
- <description>Simple REST service</description>
-
- <dependencies>
- <dependency>
- <groupId>org.exoplatform.ws.rest</groupId>
- <artifactId>exo.rest.core</artifactId>
- <version>trunk</version>
- </dependency>
- </dependencies>
-</project></programlisting>
-
- <para>Build this by executing the command:</para>
-
- <programlisting>andrew@ubu:~/workspace/calculator$ mvn clean install</programlisting>
- </section>
-
- <section>
- <title>Deploy</title>
-
- <para>We have done all now. Then copy the jar file from the target
- directory of project exo-tomcat into the server with all prepared stuff
- for REST services. (You can download it here: <link
- linkend="???">http://forge.objectweb.org/project/download.php?group_id=151&file_id=...</link>)</para>
-
- <para>So just put the jar file into the lib directory of the tomcat and
- restart it. In the console you should see this message:</para>
-
- <programlisting>[INFO] ResourceBinder - Bind new ResourceContainer: org.exoplatform.services.rest.example.Calculator@19846fd</programlisting>
-
- <para>This message indicates that our service was found, bound and is
- ready to work</para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <para>Open your browser and type the following URL: <link
- linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=add</link>
- and you should see the next page:</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-run-process.png" />
- </imageobject>
- </mediaobject>
-
- <para>The service is working. This is a very simple example, but it should
- help developers use the REST framework.</para>
-
- <para>Try to check other URLs.</para>
-
- <itemizedlist>
- <listitem>
- <para><link
- linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=subtract</link>
- - must give "12 - 5 = 7";</para>
- </listitem>
-
- <listitem>
- <para><link
- linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=multiply</link>
- - must give "12 * 5 = 60";</para>
- </listitem>
-
- <listitem>
- <para><link
- linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=divide</link>-
- must give "12 / 5 = 2" (we are working with integers!);</para>
- </listitem>
- </itemizedlist>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="WS.RestServiceTutorial">
+ <?dbhtml filename="ch-ws-rest-service-tutorial.html"?>
+
+ <title>REST Service Tutorial</title>
+
+ <important>
+ <para>This article describes REST framework before version
+ exo-ws-2.0.</para>
+ </important>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>This HOW-TO explains how to create your own REST based services. In
+ this HOW-TO we will create a simple calculator, which can do basic
+ operations with integers.</para>
+ </section>
+
+ <section>
+ <title>Source code</title>
+
+ <programlisting>// ...
+@URITemplate("/calculator/{item1}/{item2}/")
+public class Calculator implements ResourceContainer {
+}</programlisting>
+
+ <para>Writing <command>@URITemplate</command> before the class definition
+ gives you the possibility not to set it for each method. Furthermore the
+ class must implement the interface <command>ResourceContainer</command>.
+ This interface doesn't have any methods, it is just an indication for the
+ <command>ResourceBinder</command>. Add the code for adding two
+ integers.</para>
+
+ <programlisting>// ...
+@URITemplate("/calculator/{item1}/{item2}/")
+public class Calculator implements ResourceContainer {
+ @QueryTemplate("operation=add")
+ @OutputTransformer(StringOutputTransformer.class)
+ @HTTPMethod("GET")
+ public Response add(@URIParam("item1") Integer item1,
+ @URIParam("item2") Integer item2) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(item1).append(" + ").append(item2).append(" = ").append(item1 + item2);
+ return Response.Builder.ok(sb.toString(), "text/plain").build();
+ }
+}</programlisting>
+
+ <para>@QueryTemplate("operation=add") - only requests with query
+ parameters "operation=add" can reach this method;
+ @OutputTransformer(StringOutputTransformer.class) - the output
+ transformer; @HTTPMethod("GET") - the HTTP method "GET".</para>
+
+ <para>Write the code for other operations in the same way. Then the result
+ should look like:</para>
+
+ <programlisting>package org.exoplatform.services.rest.example;
+
+import org.exoplatform.services.rest.HTTPMethod;
+import org.exoplatform.services.rest.OutputTransformer;
+import org.exoplatform.services.rest.QueryTemplate;
+import org.exoplatform.services.rest.Response;
+import org.exoplatform.services.rest.URIParam;
+import org.exoplatform.services.rest.URITemplate;
+import org.exoplatform.services.rest.container.ResourceContainer;
+import org.exoplatform.services.rest.transformer.StringOutputTransformer;
+
+@URITemplate("/calculator/{item1}/{item2}/")
+(a)OutputTransformer(StringOutputTransformer.class)
+public class Calculator implements ResourceContainer {
+
+ @QueryTemplate("operation=add")
+ @HTTPMethod("GET")
+ public Response add(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(item1).append(" + ").append(item2).append(" = ").append(item1 + item2);
+ return Response.Builder.ok(sb.toString(), "text/plain").build();
+ }
+
+ @QueryTemplate("operation=subtract")
+ @HTTPMethod("GET")
+ public Response subtract(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(item1).append(" - ").append(item2).append(" = ").append(item1 - item2);
+ return Response.Builder.ok(sb.toString(), "text/plain").build();
+ }
+
+ @QueryTemplate("operation=multiply")
+ @HTTPMethod("GET")
+ public Response multiply(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(item1).append(" * ").append(item2).append(" = ").append(item1 * item2);
+ return Response.Builder.ok(sb.toString(), "text/plain").build();
+ }
+
+ @QueryTemplate("operation=divide")
+ @HTTPMethod("GET")
+ public Response divide(@URIParam("item1") Integer item1, @URIParam("item2") Integer item2) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(item1).append(" / ").append(item2).append(" = ").append(item1 / item2);
+ return Response.Builder.ok(sb.toString(), "text/plain").build();
+ }
+}</programlisting>
+
+ <para>So we are done with the source code.</para>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>Create the directory conf/portal and create the file
+ configuration.xml in it. Add the following code to this file:</para>
+
+ <programlisting><?xml version="1.0" encoding="ISO-8859-1"?>
+<configuration>
+ <component>
+ <type>org.exoplatform.services.rest.example.Calculator</type>
+ </component>
+</configuration></programlisting>
+ </section>
+
+ <section>
+ <title>Build</title>
+
+ <para>Now we must create the following directory structure to get the
+ possibility to build the source code using maven.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/rest-build-process.png" />
+ </imageobject>
+ </mediaobject>
+
+ <para>Then create the file pom.xml using the following:</para>
+
+ <programlisting><project>
+ <parent>
+ <groupId>org.exoplatform.ws</groupId>
+ <artifactId>config</artifactId>
+ <version>trunk</version>
+ </parent>
+
+ <modelVersion&#624;.0.0</modelVersion>
+ <groupId>org.exoplatform.ws.rest</groupId>
+ <artifactId>simple.calculator</artifactId>
+ <packaging>jar</packaging>
+ <version>trunk</version>
+ <description>Simple REST service</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.exoplatform.ws.rest</groupId>
+ <artifactId>exo.rest.core</artifactId>
+ <version>trunk</version>
+ </dependency>
+ </dependencies>
+</project></programlisting>
+
+ <para>Build this by executing the command:</para>
+
+ <programlisting>andrew@ubu:~/workspace/calculator$ mvn clean install</programlisting>
+ </section>
+
+ <section>
+ <title>Deploy</title>
+
+ <para>We have done all now. Then copy the jar file from the target
+ directory of project exo-tomcat into the server with all prepared stuff
+ for REST services. (You can download it here: <link
+ linkend="???">http://forge.objectweb.org/project/download.php?group_id=151&file_id=...</link>)</para>
+
+ <para>So just put the jar file into the lib directory of the tomcat and
+ restart it. In the console you should see this message:</para>
+
+ <programlisting>[INFO] ResourceBinder - Bind new ResourceContainer: org.exoplatform.services.rest.example.Calculator@19846fd</programlisting>
+
+ <para>This message indicates that our service was found, bound and is
+ ready to work</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>Open your browser and type the following URL: <link
+ linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=add</link>
+ and you should see the next page:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/rest-run-process.png" />
+ </imageobject>
+ </mediaobject>
+
+ <para>The service is working. This is a very simple example, but it should
+ help developers use the REST framework.</para>
+
+ <para>Try to check other URLs.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link
+ linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=subtract</link>
+ - must give "12 - 5 = 7";</para>
+ </listitem>
+
+ <listitem>
+ <para><link
+ linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=multiply</link>
+ - must give "12 * 5 = 60";</para>
+ </listitem>
+
+ <listitem>
+ <para><link
+ linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=divide</link>-
+ must give "12 / 5 = 2" (we are working with integers!);</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
15 years, 11 months
exo-jcr SVN: r2855 - in jcr/branches/1.12.x/docs/reference/en/src/main/resources/images: concepts and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-03 02:46:23 -0400 (Tue, 03 Aug 2010)
New Revision: 2855
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/JCR-Application2.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/interceptor.jpg
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-490x333.gif
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-applications.gif
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_1.gif
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_2.gif
jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/optional.gif
Log:
EXOJCR-869 images added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/JCR-Application2.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/JCR-Application2.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/interceptor.jpg
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/interceptor.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-490x333.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-490x333.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-applications.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/jcr-applications.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_1.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_1.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_2.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/level_2.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/optional.gif
===================================================================
(Binary files differ)
Property changes on: jcr/branches/1.12.x/docs/reference/en/src/main/resources/images/concepts/optional.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
15 years, 11 months
exo-jcr SVN: r2854 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules: jcr/concepts and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-02 11:25:11 -0400 (Mon, 02 Aug 2010)
New Revision: 2854
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-advantages.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-namespace-altering.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/why-jcr.xml
Modified:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-869 JCR concepts documentation added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-advantages.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-advantages.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-advantages.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.AdvantagesofeXoJCR">
+ <title>Advantages of eXo JCR</title>
+
+ <section>
+ <title>Advantages for application developers:</title>
+
+ <para>* Data repository and application are isolated from each other so an
+ application developer should not learn the details of particular data
+ storage's interfaces and can concentrate on business logic of a particular
+ application built on top of JCR</para>
+
+ <para>* Repositories can be simply exchanged between different
+ applications without changing the applications themselves. This is the
+ matter of the repository configuration</para>
+
+ <para>* Data storage types/versions can be changed and moreover different
+ types of data storages can be combined in one repository data model (of
+ course the complexity and work of building interfaces between the
+ repository and its data storage don't disappear but these changes are
+ isolated in the repository and thus manageable from the point of view of
+ the customer)</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/jcr-490x333.gif" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Advantages for managers</title>
+
+ <para>* Using a standardized repository for content management reduces the
+ risk of being dependent on a particular software vendor and proprietary
+ API.</para>
+
+ <para>* Costs for maintaining and developing a content repository based
+ custom application is significantly lower than developing and supporting
+ your own interfaces and maintaining your own data repository applications
+ (staff can be trained once, it is possible to take help from community and
+ third party consulters).</para>
+
+ <para>* Thanks to flexible layered JCR API (see below) it is possible to
+ fit the legacy storage subsystem into new interfaces and again decrease
+ the costs and risk of losing data.</para>
+
+ <para>An extension to the API exists as we can see in the following layer
+ schema.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/JCR-Application2.jpg" />
+ </imageobject>
+ </mediaobject>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-applications.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.eXoJCRApplicationModel">
+ <title>eXo JCR Application Model</title>
+
+ <para>A large picture of interaction between Applications and JCR looks as
+ follows:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/jcr-applications.gif" />
+ </imageobject>
+ </mediaobject>
+
+ <para>Every Content (JCR) dependent application interacts with eXo JCR via
+ JSR-170 and eXo JCR API extension (mostly for administration) directly or
+ using some intermediate Framework (Neither Application nor Framework should
+ ever rely on Implementation directly!)</para>
+
+ <para>We call <emphasis role="bold">Content Application</emphasis> all
+ applications that may use JCR as a data storage. Some of them are generic
+ and completely decoupled from JCR API as interaction protocol hides Content
+ storage nature (like WebDav client), some partially decoupled (like Command
+ framework based) meaning that they do not use JCR API directly, and some
+ (most part) use JSR-170 directly.</para>
+
+ <para><emphasis role="bold">Frameworks</emphasis> is a special kind of JCR
+ client that acts as an intermediate level between Content Repository and End
+ Client Application. There are <emphasis role="bold">Protocol</emphasis>
+ (WebDav, RMI or FTP servers for example) and <emphasis
+ role="bold">Pattern</emphasis> (Command, Web(servlet), J2EE connector)
+ specific Frameworks. It is possible to build a multi-layered (in framework
+ sense) JCR application, for example Web application uses Web framework that
+ uses Command framework underneath.</para>
+
+ <para>To READ:</para>
+
+ <para>Deployment JCR standalone (ver 1_5)</para>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-namespace-altering.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-namespace-altering.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-namespace-altering.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.Namespacealtering">
+ <title>Namespace altering</title>
+
+ <para>eXo JCR implementation since 1.11 version have support of altering
+ namespaces.</para>
+
+ <section>
+ <title>Add new namespace</title>
+
+ <programlisting>ExtendedNamespaceRegistry namespaceRegistry = (ExtendedNamespaceRegistry) workspace.getNamespaceRegistry();
+namespaceRegistry.registerNamespace("newMapping", "http://dumb.uri/jcr");</programlisting>
+ </section>
+
+ <section>
+ <title>Changing existing namespace</title>
+
+ <programlisting>ExtendedNamespaceRegistry namespaceRegistry = (ExtendedNamespaceRegistry) workspace.getNamespaceRegistry();
+namespaceRegistry.registerNamespace("newMapping", "http://dumb.uri/jcr");
+namespaceRegistry.registerNamespace("newMapping2", "http://dumb.uri/jcr");
+try {
+ assertNull(namespaceRegistry.getURI("newMapping"));
+ fail("exception should have been thrown");
+} catch (NamespaceException e) {
+}
+assertNotNull(namespaceRegistry.getURI("newMapping2"));
+assertEquals("http://dumb.uri/jcr", namespaceRegistry.getURI("newMapping2"));</programlisting>
+ </section>
+
+ <section>
+ <title>Removing existing namespace</title>
+
+ <programlisting>ExtendedNamespaceRegistry namespaceRegistry = (ExtendedNamespaceRegistry) workspace.getNamespaceRegistry();
+namespaceRegistry.registerNamespace("newMapping", "http://dumb.uri/jcr");
+namespaceRegistry.unregisterNamespace("newMapping");</programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-registry-service.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.RegistryService">
+ <title>Registry Service</title>
+
+ <section id="Concept">
+ <title>Concept</title>
+
+ <para>The Registry Service is one of the key parts of the infrastructure
+ built around eXo JCR. Each JCR based service, applications etc may have
+ its own configuration and settings data and other data that have to be
+ stored persistently and used by the approptiate service or application
+ (let's call it <emphasis role="bold">Consumer</emphasis>).</para>
+
+ <para>The service acts as a centralized collector (Registry) for such
+ data. Naturally, a registry storage is JCR based i.e. stored in some JCR
+ workspace (one per Repository) as an Item tree under <emphasis
+ role="bold">/exo:registry</emphasis> node.</para>
+
+ <para>Despite the fact that the structure of the tree is well defined (see
+ the scheme below), it is not recommended for other services to manipulate
+ data using JCR API directly for better flexibility. So the Registry
+ Service acts as a mediator between a Consumer and its settings.</para>
+
+ <para>The proposed structure of the Registry Service storage.It is divided
+ into 3 logical groups: services, applications and users:</para>
+
+ <programlisting>/
+ exo:registry/ <-- registry "root" (exo:registry)
+ exo:services/ <-- service data storage (exo:registryGroup)
+ service1/
+ Consumer data (exo:registryEntry)
+ ...
+ exo:applications/ <-- application data storage (exo:registryGroup)
+ app1/
+ Consumer data (exo:registryEntry)
+ ...
+ exo:users/ <-- user personal data storage (exo:registryGroup)
+ user1/
+ Consumer data (exo:registryEntry)
+ ...</programlisting>
+
+ <para>Each upper level eXo Service may store its configuration in Exo
+ Registry. First time start from xml-config (in jar etc). Each next will be
+ from Registry. In configuration file you can add force-xml-configuration
+ parameter to component to ignore reading parameters initialization from
+ RegistryService and to use file instead:</para>
+
+ <programlisting><value-param>
+ <name>force-xml-configuration</name>
+ <value>true</value>
+</value-param></programlisting>
+ </section>
+
+ <section>
+ <title>The API</title>
+
+ <para>The main functionality of the Registry Service is pretty simple and
+ straightforward, it is described in the Registry abstract class as
+ following:</para>
+
+ <programlisting>public abstract class Registry {
+
+ /**
+ * Returns the Registry object which wraps the Node of the "exo:registry" type
+ */
+ public abstract RegistryNode getRegistry(SessionProvider sessionProvider)
+ throws RepositoryConfigurationException, RepositoryException;
+
+ /**
+ * Returns the existing RegistryEntry which wraps the Node of the "exo:registryEntry" type
+ */
+ public abstract RegistryEntry getEntry(SessionProvider sessionProvider, String groupName,
+ String entryName) throws RepositoryException;
+
+ /**
+ * Creates a new RegistryEntry
+ */
+ public abstract void createEntry(SessionProvider sessionProvider,
+ String groupName, RegistryEntry entry) throws RepositoryException;
+
+ /**
+ * Replaces a RegistryEntry
+ */
+ public abstract void recreateEntry(SessionProvider sessionProvider,
+ String groupName, RegistryEntry entry) throws RepositoryException;
+
+ /**
+ * Removes a RegistryEntry
+ */
+ public abstract void removeEntry(SessionProvider sessionProvider,
+ String groupName, String entryName) throws RepositoryException;</programlisting>
+
+ <para>As you can see it mainly looks like a simple CRUD interface for the
+ RegistryEntry object which wraps registry data for some Consumer as a
+ Registry Entry. The Registry Service itself knows nothing about the
+ wrapping data, it is Consumer's responsibility to manage and use its data
+ in its own way.</para>
+
+ <para>To create an Entity Consumer you should have an idea how to
+ serialize the data to some XML structure and then create a RegistryEntry
+ from these data at once or populate them in a RegistryEntry object (using
+ RegistryEntry(String entryName) constructor and then obtain and fill a DOM
+ document).</para>
+
+ <para>Example of RegistryService using:</para>
+
+ <programlisting> RegistryService regService = (RegistryService) container
+ .getComponentInstanceOfType(RegistryService.class);
+
+ RegistryEntry registryEntry = regService.getEntry(sessionProvider,
+ RegistryService.EXO_SERVICES, "my-service");
+
+ Document doc = registryEntry.getDocument();
+
+ String mySetting = getElementsByTagName("tagname").item(index).getTextContent();
+ .....</programlisting>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>RegistryService has only one optional properties parameter <emphasis
+ role="bold">locations</emphasis>. It is used to mention where exo:registry
+ is placed for each repository. The name of each property is interpreted as
+ a repository name and its value as a workspace name (a system workspace by
+ default).</para>
+
+ <programlisting><component>
+ <type>org.exoplatform.services.jcr.ext.registry.RegistryService</type>
+ <init-params>
+ <properties-param>
+ <name>locations</name>
+ <property name="db1" value="ws2"/>
+ </properties-param>
+ </init-params>
+</component></programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetype-registration.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,533 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.NodeTypeRegistration">
+ <title>NodeType Registration</title>
+
+ <para>eXo JCR implementation supports two ways of Nodetypes
+ registration:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>From a NodeTypeValue POJO and</para>
+ </listitem>
+
+ <listitem>
+ <para>from an XML document (stream).</para>
+ </listitem>
+ </itemizedlist>
+
+ <section>
+ <title>Interfaces and methods</title>
+
+ <section>
+ <title>ExtendedNodeTypeManager</title>
+
+ <para>The ExtendedNodeTypeManager (from JCR 1.11) interface provides the
+ following methods related to registering node types</para>
+
+ <programlisting>public static final int IGNORE_IF_EXISTS = 0;
+
+public static final int FAIL_IF_EXISTS = 2;
+
+public static final int REPLACE_IF_EXISTS = 4;
+
+
+/**
+ * Registers node type using value object.
+ */
+void registerNodeType(NodeTypeValue nodeTypeValue, int alreadyExistsBehaviour) throws RepositoryException;
+
+/**
+ * Registers all node types using XML binding value objects from xml stream.
+ */
+void registerNodeTypes(InputStream xml, int alreadyExistsBehaviour) throws RepositoryException;
+
+/**
+ * Return <code>NodeTypeValue</code> for a given nodetype name. Used for
+ * nodetype update. Value can be edited and registered via
+ * <code>registerNodeType(NodeTypeValue nodeTypeValue, int alreadyExistsBehaviour)</code>
+ */
+NodeTypeValue getNodeTypeValue(String ntName) throws NoSuchNodeTypeException, RepositoryException;
+
+/**
+ * Registers or updates the specified <code>Collection</code> of
+ * <code>NodeTypeValue</code> objects.
+ */
+public NodeTypeIterator registerNodeTypes(Collection<NodeTypeValue> values,
+ int alreadyExistsBehaviour) throws UnsupportedRepositoryOperationException,
+ RepositoryException;
+
+/**
+ * Unregisters the specified node type.
+ */
+public void unregisterNodeType(String name) throws UnsupportedRepositoryOperationException,
+ NoSuchNodeTypeException,
+ RepositoryException;
+
+/**
+ * Unregisters the specified set of node types.<p/> Used to unregister a set
+ * of node types with mutual dependencies.
+ */
+public void unregisterNodeTypes(String[] names) throws UnsupportedRepositoryOperationException,
+ NoSuchNodeTypeException,
+ RepositoryException;</programlisting>
+ </section>
+
+ <section>
+ <title>NodeTypeValue</title>
+
+ <para>The NodeTypeValue interface represents a simple container
+ structure used to define node types which are then registered through
+ the ExtendedNodeTypeManager.registerNodeType method. Implementation of
+ this interface doesn't contain any validation logic.</para>
+
+ <programlisting>/**
+ * @return Returns the declaredSupertypeNames.
+ */
+public List<String> getDeclaredSupertypeNames();
+
+/**
+ * @param declaredSupertypeNames
+ *The declaredSupertypeNames to set.
+ */
+public void setDeclaredSupertypeNames(List<String> declaredSupertypeNames);
+
+/**
+ * @return Returns the mixin.
+ */
+public boolean isMixin();
+
+/**
+ * @param mixin
+ *The mixin to set.
+ */
+public void setMixin(boolean mixin);
+
+/**
+ * @return Returns the name.
+ */
+public String getName();
+
+/**
+ * @param name
+ *The name to set.
+ */
+public void setName(String name);
+
+/**
+ * @return Returns the orderableChild.
+ */
+public boolean isOrderableChild();
+
+/**
+ * @param orderableChild
+ *The orderableChild to set.
+ */
+public void setOrderableChild(boolean orderableChild);
+
+/**
+ * @return Returns the primaryItemName.
+ */
+public String getPrimaryItemName();
+
+/**
+ * @param primaryItemName
+ *The primaryItemName to set.
+ */
+public void setPrimaryItemName(String primaryItemName);
+
+/**
+ * @return Returns the declaredChildNodeDefinitionNames.
+ */
+public List<NodeDefinitionValue> getDeclaredChildNodeDefinitionValues();
+
+/**
+ * @param declaredChildNodeDefinitionNames
+ *The declaredChildNodeDefinitionNames to set.
+ */
+public void setDeclaredChildNodeDefinitionValues(List<NodeDefinitionValue> declaredChildNodeDefinitionValues);
+
+/**
+ * @return Returns the declaredPropertyDefinitionNames.
+ */
+public List<PropertyDefinitionValue> getDeclaredPropertyDefinitionValues();
+
+/**
+ * @param declaredPropertyDefinitionNames
+ *The declaredPropertyDefinitionNames to set.
+ */
+public void setDeclaredPropertyDefinitionValues(List<PropertyDefinitionValue> declaredPropertyDefinitionValues);</programlisting>
+ </section>
+
+ <section>
+ <title>NodeDefinitionValue</title>
+
+ <para>The NodeDefinitionValue interface extends ItemDefinitionValue with
+ the addition of write methods, enabling the characteristics of a child
+ node definition to be set, after which the NodeDefinitionValue is added
+ to a NodeTypeValue.</para>
+
+ <programlisting>/**
+ * @return Returns the declaredSupertypeNames.
+ */
+public List<String> getDeclaredSupertypeNames();
+
+/**
+ * @param declaredSupertypeNames
+ *The declaredSupertypeNames to set.
+ */
+public void setDeclaredSupertypeNames(List<String> declaredSupertypeNames);
+
+/**
+ * @return Returns the mixin.
+ */
+public boolean isMixin();
+
+/**
+ * @param mixin
+ *The mixin to set.
+ */
+public void setMixin(boolean mixin);
+
+/**
+ * @return Returns the name.
+ */
+public String getName();
+
+/**
+ * @param name
+ *The name to set.
+ */
+public void setName(String name);
+
+/**
+ * @return Returns the orderableChild.
+ */
+public boolean isOrderableChild();
+
+/**
+ * @param orderableChild
+ *The orderableChild to set.
+ */
+public void setOrderableChild(boolean orderableChild);
+
+/**
+ * @return Returns the primaryItemName.
+ */
+public String getPrimaryItemName();
+
+/**
+ * @param primaryItemName
+ *The primaryItemName to set.
+ */
+public void setPrimaryItemName(String primaryItemName);
+
+/**
+ * @return Returns the declaredChildNodeDefinitionNames.
+ */
+public List<NodeDefinitionValue> getDeclaredChildNodeDefinitionValues();
+
+/**
+ * @param declaredChildNodeDefinitionNames
+ *The declaredChildNodeDefinitionNames to set.
+ */
+public void setDeclaredChildNodeDefinitionValues(List<NodeDefinitionValue> declaredChildNodeDefinitionValues);
+
+/**
+ * @return Returns the declaredPropertyDefinitionNames.
+ */
+public List<PropertyDefinitionValue> getDeclaredPropertyDefinitionValues();
+
+/**
+ * @param declaredPropertyDefinitionNames
+ *The declaredPropertyDefinitionNames to set.
+ */
+public void setDeclaredPropertyDefinitionValues(List<PropertyDefinitionValue> declaredPropertyDefinitionValues);
+
+</programlisting>
+ </section>
+
+ <section>
+ <title>PropertyDefinitionValue</title>
+
+ <para>The PropertyDefinitionValue interface extends ItemDefinitionValue
+ with the addition of write methods, enabling the characteristics of a
+ child property definition to be set, after which the
+ PropertyDefinitionValue is added to a NodeTypeValue.</para>
+
+ <programlisting>/**
+ * @return Returns the defaultValues.
+ */
+public List<String> getDefaultValueStrings();
+
+/**
+ * @param defaultValues The defaultValues to set.
+ */
+public void setDefaultValueStrings(List<String> defaultValues);
+
+/**
+ * @return Returns the multiple.
+ */
+public boolean isMultiple();
+
+/**
+ * @param multiple The multiple to set.
+ */
+public void setMultiple(boolean multiple);
+
+/**
+ * @return Returns the requiredType.
+ */
+public int getRequiredType();
+
+/**
+ * @param requiredType The requiredType to set.
+ */
+public void setRequiredType(int requiredType);
+
+/**
+ * @return Returns the valueConstraints.
+ */
+public List<String> getValueConstraints();
+
+/**
+ * @param valueConstraints The valueConstraints to set.
+ */
+public void setValueConstraints(List<String> valueConstraints);</programlisting>
+ </section>
+
+ <section>
+ <title>ItemDefinitionValue</title>
+
+ <programlisting> /**
+ * @return Returns the autoCreate.
+ */
+public boolean isAutoCreate();
+
+/**
+ * @param autoCreate The autoCreate to set.
+ */
+public void setAutoCreate(boolean autoCreate);
+
+/**
+ * @return Returns the mandatory.
+ */
+public boolean isMandatory();
+
+/**
+ * @param mandatory The mandatory to set.
+ */
+public void setMandatory(boolean mandatory);
+
+/**
+ * @return Returns the name.
+ */
+public String getName();
+
+/**
+ * @param name The name to set.
+ */
+public void setName(String name);
+
+/**
+ * @return Returns the onVersion.
+ */
+public int getOnVersion();
+
+/**
+ * @param onVersion The onVersion to set.
+ */
+public void setOnVersion(int onVersion);
+
+/**
+ * @return Returns the readOnly.
+ */
+public boolean isReadOnly();
+
+/**
+ * @param readOnly The readOnly to set.
+ */
+public void setReadOnly(boolean readOnly);</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Node type registration</title>
+
+ <para>eXo JCR implementation supports various methods of the node-type
+ registration. The most used is registration from xml file <ulink
+ url="on JCR startup>Node+types+and+Namespaces">on JCR
+ startup>Node+types+and+Namespaces</ulink>.</para>
+
+ <section>
+ <title>Run time registration from xml file.</title>
+
+ <programlisting>ExtendedNodeTypeManager nodeTypeManager = (ExtendedNodeTypeManager) session.getWorkspace()
+ .getNodeTypeManager();
+InputStream is = MyClass.class.getResourceAsStream("mynodetypes.xml");
+nodeTypeManager.registerNodeTypes(is,ExtendedNodeTypeManager.IGNORE_IF_EXISTS );</programlisting>
+ </section>
+
+ <section>
+ <title>Run time registration using NodeTypeValue.</title>
+
+ <programlisting>ExtendedNodeTypeManager nodeTypeManager = (ExtendedNodeTypeManager) session.getWorkspace()
+ .getNodeTypeManager();
+NodeTypeValue testNValue = new NodeTypeValue();
+
+List<String> superType = new ArrayList<String>();
+superType.add("nt:base");
+testNValue.setName("exo:myNodeType");
+testNValue.setPrimaryItemName("");
+testNValue.setDeclaredSupertypeNames(superType);
+List<PropertyDefinitionValue> props = new ArrayList<PropertyDefinitionValue>();
+props.add(new PropertyDefinitionValue("*",
+ false,
+ false,
+ 1,
+ false,
+ new ArrayList<String>(),
+ false,
+ 0,
+ new ArrayList<String>()));
+testNValue.setDeclaredPropertyDefinitionValues(props);
+
+nodeTypeManager.registerNodeType(testNValue, ExtendedNodeTypeManager.FAIL_IF_EXISTS);</programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Change existing node type</title>
+
+ <para>If you want to replace existing node type definition you should pass
+ ExtendedNodeTypeManager.REPLACE_IF_EXISTS as a second parameter for the
+ method ExtendedNodeTypeManager.registerNodeType.</para>
+
+ <programlisting>ExtendedNodeTypeManager nodeTypeManager = (ExtendedNodeTypeManager) session.getWorkspace()
+ .getNodeTypeManager();
+InputStream is = MyClass.class.getResourceAsStream("mynodetypes.xml");
+.....
+nodeTypeManager.registerNodeTypes(is,ExtendedNodeTypeManager.REPLACE_IF_EXISTS );</programlisting>
+ </section>
+
+ <section>
+ <title>Remove node type</title>
+
+ <note>
+ <para>Removing node type is only possible when repository doesn't
+ contains nodes of this type</para>
+ </note>
+
+ <programlisting>nodeTypeManager.unregisterNodeType("myNodeType");</programlisting>
+ </section>
+
+ <section>
+ <title>Practical How to</title>
+
+ <section>
+ <title>Add new PropertyDefinition</title>
+
+ <programlisting>
+NodeTypeValue myNodeTypeValue = nodeTypeManager.getNodeTypeValue(myNodeTypeName);
+List<PropertyDefinitionValue> props = new ArrayList<PropertyDefinitionValue>();
+props.add(new PropertyDefinitionValue("tt",
+ true,
+ true,
+ 1,
+ false,
+ new ArrayList<String>(),
+ false,
+ PropertyType.STRING,
+ new ArrayList<String>()));
+myNodeTypeValue.setDeclaredPropertyDefinitionValues(props);
+
+nodeTypeManager.registerNodeType(myNodeTypeValue, ExtendedNodeTypeManager.REPLACE_IF_EXISTS);</programlisting>
+ </section>
+
+ <section>
+ <title>Add new child NodeDefinition</title>
+
+ <programlisting>NodeTypeValue myNodeTypeValue = nodeTypeManager.getNodeTypeValue(myNodeTypeName);
+
+List<NodeDefinitionValue> nodes = new ArrayList<NodeDefinitionValue>();
+nodes.add(new NodeDefinitionValue("child",
+ false,
+ false,
+ 1,
+ false,
+ "nt:base",
+ new ArrayList<String>(),
+ false));
+testNValue.setDeclaredChildNodeDefinitionValues(nodes);
+
+nodeTypeManager.registerNodeType(myNodeTypeValue, ExtendedNodeTypeManager.REPLACE_IF_EXISTS);</programlisting>
+ </section>
+
+ <section>
+ <title>Change or removing existing PropertyDefinition or child
+ NodeDefinition</title>
+
+ <para>The main note what you should remember before changing or removing
+ existing definition is <emphasis role="bold">consistency of the existing
+ data</emphasis>. JCR <emphasis role="bold">do not allow</emphasis> you
+ to change the node type in that way in which the the existing data would
+ be incompatible with new node type. But if these changes are needed, you
+ can do it in several phases, consistently changing the node type and the
+ existing data.</para>
+
+ <para>Example</para>
+
+ <para>Add new residual property definition with name "downloadCount" to
+ the existing node type "myNodeType".</para>
+
+ <para>There are two limitations that do not allow us to made the task
+ with single call of registerNodeType method.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Existing nodes of the type "myNodeType", wich does not contain
+ properties "downloadCount" that conflicts with node type what we
+ need.</para>
+ </listitem>
+
+ <listitem>
+ <para>Registered node type "myNodeType" will not allow us to add
+ properties "downloadCount" because it has no such specific
+ properties.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>To complete the task we need to make 3 steps</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>We change the existing node type "myNodeType" by adding not
+ mandatory property "downloadCount".</para>
+ </listitem>
+
+ <listitem>
+ <para>We add to all existing nodes of the node type "myNodeType"
+ property "downloadCount".</para>
+ </listitem>
+
+ <listitem>
+ <para>We change definition of the property "downloadCount" of the
+ node type "myNodeType" to mandatory.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Changing list of super types</title>
+
+ <programlisting>NodeTypeValue testNValue = nodeTypeManager.getNodeTypeValue("exo:myNodeType");
+
+List<String> superType = testNValue.getDeclaredSupertypeNames();
+superType.add("mix:versionable");
+testNValue.setDeclaredSupertypeNames(superType);
+
+nodeTypeManager.registerNodeType(testNValue, ExtendedNodeTypeManager.REPLACE_IF_EXISTS);</programlisting>
+ </section>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/nodetypes-and-namespaces.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.NodeTypesandNamespaces">
+ <title>Node Types and Namespaces</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>Support of node types and namespaces is required by the JSR-170
+ specification. Beyond the methods required by the specification, eXo JCR
+ has its own API extension for the <ulink
+ url="JCR.NodeTypeRegistration">Node type
+ registration>NodeType+registration</ulink> as well as the ability to
+ declaratively define node types in the Repository at the start-up
+ time.</para>
+ </section>
+
+ <section>
+ <title>Node Types definition</title>
+
+ <para>Node type registration extension is declared in
+ org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager
+ interface</para>
+
+ <para>Your custom service can register some neccessary predefined node
+ types at the start-up time. The node definition should be placed in a
+ special XML file (see DTD below) and declared in the service's
+ configuration file thanks to eXo component plugin mechanism, described as
+ follows:</para>
+
+ <programlisting><external-component-plugins>
+ <target-component>org.exoplatform.services.jcr.RepositoryService</target-component>
+ <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/test/nodetypes-tck.xml</value>
+ <value>jar:/conf/test/nodetypes-impl.xml</value>
+ </values-param>
+ <values-param>
+ <name>repo1</name>
+ <description>Node types configuration file for repository with name repo1</description>
+ <value>jar:/conf/test/nodetypes-test.xml</value>
+ </values-param>
+ <values-param>
+ <name>repo2</name>
+ <description>Node types configuration file for repository with name repo2</description>
+ <value>jar:/conf/test/nodetypes-test2.xml</value>
+ </values-param>
+ </init-params>
+ </component-plugin></programlisting>
+
+ <para>There are two types of registration. First type of registration is
+ the registration of node types in all created repositories, it is
+ configured in values-param with the name <emphasis
+ role="bold">autoCreatedInNewRepository</emphasis>. The second type of
+ registration is registration of node types in specified repository and it
+ is configured in values-param with the name of repository.</para>
+
+ <para>Node type definition file format:</para>
+
+ <programlisting> <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE nodeTypes [
+ <!ELEMENT nodeTypes (nodeType)*>
+ <!ELEMENT nodeType (supertypes?|propertyDefinitions?|childNodeDefinitions?)>
+
+ <!ATTLIST nodeType
+ name CDATA #REQUIRED
+ isMixin (true|false) #REQUIRED
+ hasOrderableChildNodes (true|false)
+ primaryItemName CDATA
+ >
+ <!ELEMENT supertypes (supertype*)>
+ <!ELEMENT supertype (CDATA)>
+
+ <!ELEMENT propertyDefinitions (propertyDefinition*)>
+
+ <!ELEMENT propertyDefinition (valueConstraints?|defaultValues?)>
+ <!ATTLIST propertyDefinition
+ name CDATA #REQUIRED
+ requiredType (String|Date|Path|Name|Reference|Binary|Double|Long|Boolean|undefined) #REQUIRED
+ autoCreated (true|false) #REQUIRED
+ mandatory (true|false) #REQUIRED
+ onParentVersion (COPY|VERSION|INITIALIZE|COMPUTE|IGNORE|ABORT) #REQUIRED
+ protected (true|false) #REQUIRED
+ multiple (true|false) #REQUIRED
+ >
+ <!-- For example if you need to set ValueConstraints [],
+ you have to add an empty element <valueConstraints/>.
+ The same order is for other properties like defaultValues, requiredPrimaryTypes etc.
+ -->
+ <!ELEMENT valueConstraints (valueConstraint*)>
+ <!ELEMENT valueConstraint (CDATA)>
+ <!ELEMENT defaultValues (defaultValue*)>
+ <!ELEMENT defaultValue (CDATA)>
+
+ <!ELEMENT childNodeDefinitions (childNodeDefinition*)>
+
+ <!ELEMENT childNodeDefinition (requiredPrimaryTypes)>
+ <!ATTLIST childNodeDefinition
+ name CDATA #REQUIRED
+ defaultPrimaryType CDATA #REQUIRED
+ autoCreated (true|false) #REQUIRED
+ mandatory (true|false) #REQUIRED
+ onParentVersion (COPY|VERSION|INITIALIZE|COMPUTE|IGNORE|ABORT) #REQUIRED
+ protected (true|false) #REQUIRED
+ sameNameSiblings (true|false) #REQUIRED
+ >
+ <!ELEMENT requiredPrimaryTypes (requiredPrimaryType+)>
+ <!ELEMENT requiredPrimaryType (CDATA)>
+]></programlisting>
+ </section>
+
+ <section>
+ <title>Namespaces definition</title>
+
+ <para>Default namespaces are registered by repository at the start-up
+ time</para>
+
+ <para>Your custom service can extend a set of namespaces with some
+ application specific ones declaring it in service's configuration file
+ thanks to eXo component plugin mechanism, described as follows:</para>
+
+ <programlisting> <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="test" value="http://www.test.org/test"/>
+ </properties-param>
+ </init-params>
+ </component-plugin></programlisting>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/why-jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/why-jcr.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/why-jcr.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.WhyuseJCR">
+ <title>Why use JCR?</title>
+
+ <section>
+ <title>What is this JCR is for?</title>
+
+ <para>You already heard that JCR (Java Content Repository) is an interface
+ to access the file system, a relational database or an XML document. But
+ is it a better Hibernate (which is a generic interface for RDBMS), only
+ more generic? No, that is not correct.</para>
+
+ <para>JCR is a java interface to access - as the name says - content only.
+ Content? That means most of the times web content and but also other
+ hierarchically stored data. The content is stored in a repository. The
+ repository can be a file system, a relational database or an XML document.
+ The internal structure of JCR data looks similar to an XML document, that
+ means a document tree with nodes and data - with a small difference in JCR
+ the data is stored in "property items".</para>
+
+ <para>Or better to cite the specification of JCR: "A content repository is
+ a high-level information management system that is a superset of
+ traditional data repositories."</para>
+ </section>
+
+ <section>
+ <title>But why use JCR?</title>
+
+ <para>Remember how the data for your web site is stored? The images are
+ probably in a file system, the meta data is in some dedicated files -
+ maybe in XML - the text documents and pdfs are stored in different folders
+ with the meta data in an other place (a database?) and in a proprietary
+ structure. How do you manage to update these data and how do you manage
+ the access rights? Probably your boss asks you to manage different
+ versions of each document? The larger your web site is the more you need a
+ <ulink
+ url="http://en.wikipedia.org/wiki/Content_management_system">Content
+ Management Systems</ulink> (CMS) which tackles all these issues.</para>
+
+ <para>These CMS solutions are sold by different vendors and each vendor
+ provides its own API for interfacing the proprietary content repository.
+ The developers have to deal with this and need to learn the
+ vendor-specific API. If one time in future you wish to switch to a
+ different vendor everything is different, you have a new implementation, a
+ new interface etc.</para>
+
+ <para>JCR provides a unique java interface for interacting with both text
+ and binary data, for dealing with any kind and amount of meta data your
+ documents might have. JCR supplies methods for storing, updating, deleting
+ and retrieving your data, independent of the fact if this data is stored
+ in a RDBMS, in a file system or as an XML document - you just don't need
+ to care about. The JCR interface also defines classes and methods for
+ searching, versioning, access control, locking, and observation.</para>
+
+ <para>Furthermore an export and import functionality is specified so that
+ a switch to a different vendor is always possible.</para>
+ </section>
+
+ <section>
+ <title>What does eXo do?</title>
+
+ <para>eXo fully complies the JCR standard <ulink
+ url="http://jcp.org/en/jsr/detail?id=170">JSR 170</ulink> and therefore by
+ choosing eXo JCR you use a vendor-independent API. That's means you could
+ switch any time to a different vendor. Using the standard lowers your
+ lifecycle cost and reduces your long term risk.</para>
+
+ <para>Of course eXo does not only offer JCR, but also the complete
+ solution for ECM (Enterprise Content Management) and for WCM (Web Content
+ Management).</para>
+ </section>
+
+ <section>
+ <title>Further Reading</title>
+
+ <para>In order to understand the theory of JCR and the API please read
+ some external documents about this standard:</para>
+
+ <para>* Tom Wheeler, <ulink
+ url="http://www.tomwheeler.com/java_content_repository_tomwheeler_20071007.pdf">The
+ Java Content Repository</ulink> (2007)</para>
+
+ <para>* Roy T. Fielding, <ulink
+ url="http://www.day.com/content/dam/day/whitepapers/JSR_170_White_Paper.pdf">JSR
+ 170 Overview: Standardizing the Content Repository Interface</ulink>
+ (March 13, 2005)</para>
+
+ <para>* David Nuescheler and Janus Boye, <ulink
+ url="http://www.cmswatch.com/Feature/123">JSR-170 What's in it for
+ me?</ulink> (April 20, 2005)</para>
+
+ <para>* Benjamin Mestrallet, Tuan Nguyen, Gennady Azarenkov, Francois
+ Moron and Brice Revenant <ulink
+ url="http://www.theserverside.com/tt/articles/article.tss?l=eXoPlatform2">eXo
+ Platform v2, Portal, JCR, ECM, Groupware and Business
+ Intelligence.</ulink> (January 2006)</para>
+ </section>
+</chapter>
Modified: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-02 13:37:39 UTC (rev 2853)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-02 15:25:11 UTC (rev 2854)
@@ -65,10 +65,35 @@
<xi:include href="jcr/data-container-howto.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="jcr/concepts/why-jcr.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-advantages.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<xi:include href="jcr/concepts/jcr-compatibility-levels.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="jcr/concepts/jcr-usage.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-extensions.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-applications.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/nodetype-registration.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="jcr/concepts/jcr-registry-service.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/jcr-namespace-altering.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/concepts/nodetypes-and-namespaces.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+
</part>
15 years, 11 months
exo-jcr SVN: r2853 - in jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr: concepts and 1 other directory.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-08-02 09:37:39 -0400 (Mon, 02 Aug 2010)
New Revision: 2853
Added:
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-compatibility-levels.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-extensions.xml
jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-usage.xml
Log:
EXOJCR-869 concepts documentation added
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-compatibility-levels.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-compatibility-levels.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-compatibility-levels.xml 2010-08-02 13:37:39 UTC (rev 2853)
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.CompatibilityLevels">
+ <title>Compatibility Levels</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>The Java Content Repository specification JSR-170 has been split
+ into two compliance levels as well as a set of optional features. Level 1
+ defines a read-only repository, level 2 defines methods for writing
+ content and bidirectional interaction with the repository.</para>
+
+ <para>Exo JCR supports JSR-170 level 1 and level 2 and all optional
+ features. The recent JSR-283 is not yet supported.</para>
+ </section>
+
+ <section>
+ <title>Level 1</title>
+
+ <para>Includes read only functionality for very simple repositories.
+ Useful to port an existing data repository and convert it to a more
+ advanced form step by step. JCR uses a well known Session abstraction to
+ access the repository data (similar to the sessions we have in OS, web
+ etc)</para>
+
+ <para>Level 1 features:</para>
+
+ <para>* Initiating a session calling login method with the name of desired
+ workspace and client credentials. Involves some security mechanisms (JAAS)
+ to authenticate the client and in case the client is authorized to use the
+ data from a particular workspace, he retrieves the session with a
+ workspace tied to it.</para>
+
+ <para>* Using the obtained session the client can retrieve data (items)
+ using: traversing the tree, directly accessing a particular item
+ (requesting path or UUID) or traversing the query result. So an
+ application developer can choose the "best" form depending on the content
+ structure and desired operation.</para>
+
+ <para>* Reading property values. All content of a repository is ultimately
+ accessed through properties and stored in property values of predefined
+ types (Boolean, Binary Data, Double, Long, String) and special types Name,
+ Reference, and Path. It is possible to read property value without knowing
+ its real name as a primary item.</para>
+
+ <para>* Export to XML. Repository supports two XML/JCR data model
+ mappings: system and doc view. The ~~system view~~ provides complete XML
+ serialization without loss of information and is somewhat difficult for a
+ human to read. In contrast, the ~~document view~~ is well readable but
+ does not completely reflect the state of repository, it is used for Xpath
+ queries.</para>
+
+ <para>* Query facility with Xpath syntax. Xpath, originally developed for
+ XML, suits the JCR data model as well because the JCR data model is very
+ close to XML's one. It is applied to JCR as it would be applied to the
+ document view of the serialized repository content, returning a table of
+ property names and content matching the query.</para>
+
+ <para>* Discovery of available node types. Every node should have only one
+ ~~primary node~~ type that defines names, types and other characteristics
+ of child nodes and properties. It also can have one or more mixin data
+ types that defines additional characteristics. Level 1 provides methods
+ for discovering available in repository node types and node types of a
+ concrete node.</para>
+
+ <para>* Transient namespace remapping. Item name can have prefix delimited
+ by a single colon ":" character indicating the namespace of this name. It
+ is patterned after XML namespaces, prefix is mapped to URI to minimize
+ names collisions. In Level 1 a prefix can be temporary overridden by
+ another prefix in the scope of a session.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/level_1.gif" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>Level 2</title>
+
+ <para>JCR level 2 includes reading/writing content functionality,
+ importing from other sources and managing content definition and
+ structuring using extensible node types.</para>
+
+ <para>In addition to the Level 1 it must support the following major
+ features:</para>
+
+ <para>* Adding, moving, copying and removing items inside workspace and
+ moving, copying and cloning items between workspaces. The client can also
+ compare the persisted state of an item with its unsaved states and either
+ save the new state or discard it.</para>
+
+ <para>* Modifying and writing value of properties. Property types are
+ checked and can be converted to the defined format.</para>
+
+ <para>* Import from XML document into the repository as a tree of nodes
+ and properties. If the XML document is an export of JCR system view the
+ content of repository can be completely restored. If this is not the case,
+ the document is interpreted as a document view and the import procedure
+ builds a tree of JCR nodes and properties that matches the tree structure
+ of the XML document.</para>
+
+ <para>* Assigning node types to nodes. The primary node type is assigned
+ when adding a node. This can be done automatically based on the parent
+ node type definition and mixin node types.</para>
+
+ <para>* Persistent namespaces changes. Add, change and remove namespaces
+ stored in the namespace registry, excluding built-in namespaces required
+ by JCR.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/level_2.gif" />
+ </imageobject>
+ </mediaobject>
+ </section>
+
+ <section>
+ <title>1 Optional features</title>
+
+ <para>On top of Level 1 or Level 2 a number of optional features are
+ defined for a more advanced repository functionality. This includes
+ functions like: Versioning, (JTA) Transactions, Query using SQL, Explicit
+ Locking and Content Observation. Exo JCR supports all optional
+ features.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/optional.gif" />
+ </imageobject>
+ </mediaobject>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-extensions.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-extensions.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-extensions.xml 2010-08-02 13:37:39 UTC (rev 2853)
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.Extensions">
+ <title>JCR Extensions</title>
+
+ <section>
+ <title>JCR Service Extensions</title>
+
+ <section>
+ <title>Concept</title>
+
+ <para>eXo JCR supports <emphasis role="bold">observation</emphasis>
+ (JSR-170 8.3), which enables applications to register interest in events
+ that describe changes to a workspace, and then monitor and respond to
+ those events. The standard observation feature allows dispatching events
+ when <emphasis role="bold">persistent change</emphasis> to the workspace
+ is made.</para>
+
+ <para>eXo JCR also offers a proprietary <emphasis role="bold">Extension
+ Action</emphasis> which dispatches and fires an event upon each
+ <emphasis role="bold">transient session level change</emphasis>,
+ performed by a client. In other words the event is triggered when a
+ client's program invokes some updating method in a session or a
+ workspace (such as: Session.addNode(), Session.setProperty(),
+ Workspace.move() etc.</para>
+
+ <para>One important recommendation should be applied for an extension
+ action implementation. Each action will add its own execution time to
+ standard JCR methods (Session.addNode(), Session.setProperty(),
+ Workspace.move() etc.) execution time. As a consequence it's necessary
+ to minimize Action.execute(Context) body execution time.</para>
+
+ <para>To make the rule you can use the dedicated Thread in
+ Action.execute(Context) body for a custom logic. But if your application
+ logic requires the action to add items to a created/updated item and you
+ save these changes immediately after the JCR API method call is
+ returned, the suggestion with Thread is not applicable for you in this
+ case.</para>
+ </section>
+
+ <section>
+ <title>Implementation</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/concepts/interceptor.jpg" />
+ </imageobject>
+ </mediaobject>
+
+ <para>Interceptor framework class diagram</para>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>Add a <emphasis role="bold">SessionActionCatalog</emphasis>
+ service and an appropriate <emphasis
+ role="bold">AddActionsPlugin</emphasis> (see the example below)
+ configuration to your Exo Container configuration. As usual the plugin
+ can be configured as in-component-place, which is the case for a
+ Standalone Container or externally, which is a usual case for
+ Root/Portal Container configuration).</para>
+
+ <para>Each Action entry is exposed as
+ org.exoplatform.services.jcr.impl.ext.action. <emphasis
+ role="bold">ActionConfiguration</emphasis> of actions collection of
+ org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin$ActionsConfig
+ (see an example below). The mandatory field named <emphasis
+ role="bold">actionClassName</emphasis> is the fully qualified name of
+ org.exoplatform.services.command.action.Action implementation - the
+ command will be launched in case the current event matches the <emphasis
+ role="bold">criteria</emphasis>. All other fields are criteria. The
+ criteria are *AND*ed together. In other words, for a particular item to
+ be listened to it must meet ALL the criteria.</para>
+
+ <para>* <emphasis role="bold">workspace</emphasis> - the comma delimited
+ (ORed) list of workspaces</para>
+
+ <para>* <emphasis role="bold">eventTypes</emphasis> - a comma delimited
+ (ORed) <emphasis role="bold">list of event names</emphasis> (see below)
+ to be listened to. This is the only mandatory field, others are optional
+ and if they are missing they are interpreted as ANY.</para>
+
+ <para>* <emphasis role="bold">path</emphasis> - a comma delimited (ORed)
+ list of <emphasis role="bold">item absolute paths</emphasis> (or within
+ its subtree if <emphasis role="bold">isDeep</emphasis> is <emphasis
+ role="bold">true</emphasis>, which is the default value)</para>
+
+ <para>* <emphasis role="bold">nodeTypes</emphasis> - a comma delimited
+ (ORed) list of the <emphasis role="bold">current NodeType</emphasis>.
+ Since version 1.6.1 JCR supports the functionalities of nodeType and
+ parentNodeType. This parameter has different semantics dependent on the
+ type of the current item and the operation performed. If the <emphasis
+ role="bold">current item</emphasis> is a <emphasis
+ role="bold">property</emphasis> it means the <emphasis
+ role="bold">parent node type</emphasis>. If the <emphasis
+ role="bold">current item</emphasis> is a <emphasis
+ role="bold">node</emphasis> the semantic depends on the event type: **
+ <emphasis role="bold">add node event</emphasis>: the node type of the
+ newly added node. ** <emphasis role="bold">add mixin event</emphasis>:
+ the newly added mixing node type of the current node. ** <emphasis
+ role="bold">remove mixin event</emphasis> the removed mixin type of the
+ current node. ** <emphasis role="bold">other events</emphasis>: the
+ already assigned NodeType(s) of the current node (can be both primary
+ and mixin).</para>
+
+ <para><emphasis role="bold">NOTE:</emphasis> the list of fields can be
+ extended.</para>
+
+ <para><emphasis role="bold">NOTE2:</emphasis> no spaces between list
+ elements.</para>
+
+ <para><emphasis role="bold">NOTE3:</emphasis> <emphasis
+ role="bold">isDeep=false</emphasis> means <emphasis role="bold">node,
+ node properties and child nodes</emphasis>.</para>
+
+ <para>The list of supported Event names: <emphasis role="bold">addNode,
+ addProperty, changeProperty, removeProperty, removeNode, addMixin,
+ removeMixin, lock, unlock, checkin, checkout, read.</emphasis></para>
+
+ <programlisting><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>addNode,removeNode</string></field>
+ <field name="path"><string>/test,/exo:test</string></field>
+ <field name="isDeep"><boolean>true</boolean></field>
+ <field name="nodeTypes"><string>nt:file,nt:folder,mix:lockable</string></field>
+ <!-- field name="workspace"><string>backup</string></field -->
+ <field name="actionClassName"><string>org.exoplatform.services.jcr.ext.DummyAction</string></field>
+ </object>
+ </value>
+ </collection>
+ </field>
+ </object>
+ </object-param>
+ </init-params>
+ </component-plugin>
+ </component-plugins>
+</component></programlisting>
+ </section>
+ </section>
+
+ <section>
+ <title>Related Pages</title>
+
+ <para>Access Control extension</para>
+
+ <para>Auditing Backup service CIFS(SMB)</para>
+
+ <para>Clustering Groovy REST Services </para>
+
+ <para>Metadata Extensions </para>
+
+ <para>Organization Service </para>
+
+ <para>Registry Service </para>
+
+ <para>REST Groovy services</para>
+ </section>
+</chapter>
Added: jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-usage.xml
===================================================================
--- jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-usage.xml (rev 0)
+++ jcr/branches/1.12.x/docs/reference/en/src/main/docbook/en-US/modules/jcr/concepts/jcr-usage.xml 2010-08-02 13:37:39 UTC (rev 2853)
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.UsingJCR">
+ <title>Using JCR</title>
+
+ <section>
+ <title>1 Using eXo JCR in an application</title>
+
+ <section>
+ <title>Obtaining a Repository object</title>
+
+ <para>A javax.jcr.Repository object can be obtained either by ...: *
+ Using the eXo Container "native" mechanism. All Repositories are kept
+ with a single RepositoryService component. So it can be obtained from
+ eXo Container, described as following:</para>
+
+ <programlisting> RepositoryService repositoryService = (RepositoryService) container.getComponentInstanceOfType(RepositoryService.class);
+ Repository repository = repositoryService.getRepository("repositoryName"); </programlisting>
+
+ <para>* Using the eXo Container "native" mechanism with a thread local
+ saved "current" repository (especially if you plan using a single
+ repository which covers more than 90% of use cases)</para>
+
+ <programlisting> // set current repository at initial time
+ RepositoryService repositoryService = (RepositoryService) container.getComponentInstanceOfType(RepositoryService.class);
+ repositoryService.setCurrentRepositoryName("repositoryName");
+ ....
+ // retrieve and use this repository
+ Repository repository = repositoryService.getCurrentRepository();</programlisting>
+
+ <para>* Using JNDI as specified in JSR-170. This way you have to
+ configure the reference (see eXo <ulink
+ url="JNDI Naming configuration>Core.JNDI Naming">JNDI Naming
+ configuration>Core.JNDI Naming</ulink> )</para>
+
+ <programlisting> Context ctx = new InitialContext();
+ Repository repository =(Repository) ctx.lookup("repositoryName");</programlisting>
+ </section>
+
+ <section>
+ <title>JCR Session common considerations</title>
+
+ <para>* Remember javax.jcr.Session is not a thread safe object.
+ <emphasis role="bold">Never try to share it between threads</emphasis> *
+ Do not use <emphasis role="bold">System session</emphasis> from the
+ <emphasis role="bold">user</emphasis> related code because a system
+ session has <emphasis role="bold">unlimited rights</emphasis>. Call
+ ManageableRepository.getSystemSession() from <emphasis
+ role="bold">process</emphasis> related code only. * Call
+ Session.logout() explicitly to <emphasis role="bold">release
+ resources</emphasis> assigned to the session. * When designing your
+ application take care of the Session policy inside your application. Two
+ <emphasis role="bold">strategies</emphasis> are possible: <emphasis
+ role="bold">Stateless</emphasis> (Session per business request) and
+ <emphasis role="bold">Stateful</emphasis> (Session per User) or some
+ mix.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>JCR Application practices</title>
+
+ <section>
+ <title>Simplifying the management of a multi-workspace
+ application</title>
+
+ <para>(one-shot logout for all opened sessions)</para>
+
+ <para>Use org.exoplatform.services.jcr.ext.common.SessionProvider which
+ is responsible for caching/obtaining your JCR Sessions and closing all
+ opened sessions at once.</para>
+
+ <programlisting>public class SessionProvider {
+
+ /**
+ * Creates a SessionProvider for a certain identity
+ * @param cred
+ */
+ public SessionProvider(Credentials cred)
+
+ /**
+ * Gets the session from internal cache or creates and caches a new one
+ */
+ public Session getSession(String workspaceName, ManageableRepository repository)
+ throws LoginException, NoSuchWorkspaceException, RepositoryException
+
+ /**
+ * Calls a logout() method for all cached sessions
+ */
+ public void close()
+
+ /**
+ * a Helper for creating a System session provider
+ * @return System session
+ */
+ public static SessionProvider createSystemProvider()
+
+ /**
+ * a Helper for creating an Anonimous session provider
+ * @return System session
+ */
+ public static SessionProvider createAnonimProvider()
+
+}</programlisting>
+
+ <para>The SessionProvider is per-request or per-user object depending on
+ your policy. Create it with your application before performing JCR
+ operations, use it to obtain the Sessions and close at the end of an
+ application session(request). Example:</para>
+
+ <programlisting>// (1) obtain current javax.jcr.Credentials, for example get it from AuthenticationService
+Credentials cred = ....
+
+// (2) create SessionProvider for current user
+SessionProvider sessionProvider = new SessionProvider(ConversationState.getCurrent());
+
+// NOTE: for creating an Anonymous or System Session use the corresponding static SessionProvider.create...() method
+// Get appropriate Repository as described in "Obtaining Repository object" section for example
+ManageableRepository repository = (ManageableRepository) ctx.lookup("repositoryName");
+
+// get an appropriate workspace's session
+Session session = sessionProvider.getSession("workspaceName", repository);
+
+ .........
+// your JCR code
+ .........
+
+ // Close the session provider
+ sessionProvider.close(); </programlisting>
+ </section>
+
+ <section>
+ <title>Reusing SessionProvider</title>
+
+ <para>As shown above, creating the SessionProvider involves multiple
+ steps and you may not want to repeat them each time you need to get a
+ JCR session. In order to avoid all this plumbing code, we provide the
+ SessionProviderService whose goal is to help you to get a
+ SessionProvider object.</para>
+
+ <para>The org.exoplatform.services.jcr.ext.app.SessionProviderService
+ interface is defined as follows:</para>
+
+ <programlisting>public interface SessionProviderService {
+ void setSessionProvider(Object key, SessionProvider sessionProvider);
+ SessionProvider getSessionProvider(Object key);
+ void removeSessionProvider(Object key);
+}</programlisting>
+
+ <para>Using this service is pretty straightforward, the main contract of
+ an implemented component is getting a SessionProvider by key. eXo
+ provides two implementations :</para>
+
+ <table>
+ <title></title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Implementation</entry>
+
+ <entry>Description</entry>
+
+ <entry>Typical Use</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.exoplatform.services.jcr.ext.app.MapStoredSessionProviderService</entry>
+
+ <entry>per-user style : keeps objects in a Map</entry>
+
+ <entry>per-user. The usual practice uses a user's name or
+ Credentials as a key.</entry>
+ </row>
+
+ <row>
+ <entry>org.exoplatform.services.jcr.ext.app.ThreadLocalSessionProviderService</entry>
+
+ <entry>per-request style : keeps a single SessionProvider in a
+ static ThreadLocal variable</entry>
+
+ <entry>Always use null for the key.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>For any implementation, your code should follow the following
+ sequence :</para>
+
+ <para>* Call SessionProviderService.setSessionProvider(Object key,
+ SessionProvider sessionProvider) at the beginning of a business request
+ for Stateless application or application's session for Statefull policy.
+ * Call SessionProviderService.getSessionProvider(Object key) for
+ obtaining a SessionProvider object * Call
+ SessionProviderService.removeSessionProvider(Object key) at the end of a
+ business request for Stateless application or application's session for
+ Statefull policy.</para>
+ </section>
+ </section>
+</chapter>
15 years, 11 months