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>