<?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.HowToImplementWorkspaceDataContainer">
  <title>How to implement Workspace Data Container</title>
    <para>To implement Workspace data container, you need to do the following:
    </para>

    <orderedlist>
      <listitem>
        <para>Read a bit about the <link
        linkend="JCR.WorkspaceDataContainer">contract</link>.</para>
      </listitem>

      <listitem>
        <para>Start a new implementation project pom.xml with
        <emphasis>org.exoplatform.jcr</emphasis> parent. It is not required, but will ease the development.</para>
      </listitem>

      <listitem>
        <para>Update sources of JCR Core and read JavaDoc on <emphasis
        role="bold">org.exoplatform.services.jcr.storage.WorkspaceDataContainer</emphasis>
        and <emphasis
        role="bold">org.exoplatform.services.jcr.storage.WorkspaceStorageConnection</emphasis>
        interfaces. They are the main part for the implemenation.</para>
      </listitem>

      <listitem>
        <para>Look at <emphasis
        role="bold">org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager</emphasis>
        sourcecode, check how data menager uses container and its connections
        (see in save() method)</para>
      </listitem>

      <listitem>
        <para>Create <emphasis
        role="bold">WorkspaceStorageConnection</emphasis> dummy implementation
        class. It's freeform class, but to be close to the eXo JCR, check how
        to implement JDBC ( <emphasis
        role="bold">org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection</emphasis>.
        Take in account usage of <emphasis
        role="bold">ValueStoragePluginProvider</emphasis> in both
        implementations.Value storage is an useful option for production
        versions. But leave it to the end of implementation work.</para>
      </listitem>

      <listitem>
        <para>Create the connection implementation unit tests to play TTD.
        (optional, but takes many benefits for the process)</para>
      </listitem>

      <listitem>
        <para>Implement CRUD starting from the read to write etc. Test the
        methods by using the external implementation ways of data read/write
        in your backend.</para>
      </listitem>

      <listitem>
        <para>When all methods of the connection done start <emphasis
        role="bold">WorkspaceDataContainer</emphasis>. Container class is very
        simple, it's like a factory for the connections only.</para>
      </listitem>

      <listitem>
        <para>Care about container reuseConnection(WorkspaceStorageConnection)
        method logic. For some backends, it cab be same as openConnection(),
        but for some others, it's important to reuse physical backend
        connection, e.g. to be in the same transaction - see JDBC
        container.</para>
      </listitem>

      <listitem>
        <para>It's almost ready to use in data manager. Start another test and
        go on.</para>
      </listitem>
    </orderedlist>

    <para>When the container will be ready to run as JCR persistence storage
    (e.g. for this level testing), it should be configured in Repository
    configuration.</para>

    <para>Assuming that our new implementation class name is <emphasis
    role="bold">org.project.jcr.impl.storage.MyWorkspaceDataContainer</emphasis>.</para>

    <programlisting language="xml">  &lt;repository-service default-repository="repository"&gt;
  &lt;repositories&gt;
    &lt;repository name="repository" system-workspace="production" default-workspace="production"&gt;
      .............
      &lt;workspaces&gt;
        &lt;workspace name="production"&gt;
          &lt;container class="org.project.jcr.impl.storage.MyWorkspaceDataContainer"&gt;
            &lt;properties&gt;
              &lt;property name="propertyName1" value="propertyValue1" /&gt;
              &lt;property name="propertyName2" value="propertyValue2" /&gt;
              .......
              &lt;property name="propertyNameN" value="propertyValueN" /&gt;
            &lt;/properties&gt;
            &lt;value-storages&gt;
              .......
            &lt;/value-storages&gt;
          &lt;/container&gt;

</programlisting>

    <para>Container can be configured by using set properties.</para>

  <section id="Valuestorageusagenotes">
    <title>Notes on Value storage usage:</title>

    <para>Value storages are pluggable to the container but if they are used,
    the container implementation should respect set of interfaces and external
    storage usage principles.</para>

    <para>If the container has <emphasis
    role="bold">ValueStoragePluginProvider</emphasis> (e.g. via constructor),
    it's just a few methods to manipulate external Values data.</para>

    <programlisting language="java">// get channel for ValueData write (add or update)
ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data,  i);
if (channel == null) {
  // write
  channel.write(data.getIdentifier(),  vd);
  // obtain storage id,  id can be used for linkage of external ValueData and PropertyData in main backend
  String storageId = channel.getStorageId();
}

....

// delete all Property Values in external storage
ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
channel.delete(propertyData.getIdentifier());

....

// read ValueData from external storage
ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
ValueData vdata = channel.read(propertyData.getIdentifier(),  orderNumber,  maxBufferSize);

</programlisting>

    <important>
      <title>Important</title>

      <para>After a sequence of write and/or delete operations on the storage
      channel, the channel should be committed (or rolled back on an error).
      See <emphasis role="bold">ValueIOChannel.commit()</emphasis> and
      <emphasis role="bold">ValueIOChannel.rollback()</emphasis> and how those
      methods are used in JDBC container.</para>
    </important>
  </section>
</section>
