Using Jakarta Slide

Dec 5, 2004
Yoon Kyung Koo (yoonforh at gmail dot com)

Configuration files


Services / Stores

Slide can store the data it manages in a broad array of repositories. Each repository is accessed through a module called a Service or a Store. Each of these services have widely different dependencies, and can need a lot of extra setup steps. It is expected that services will be developed by Slide adopters to address their specific content management needs. For example, one company would want to access its website and NFS file server through Slide, so a NFS Service will be needed, along with a HTTP service.

The scope of the Slide project is not to integrate every existing repository in the universe (although there will be out-of-the-box support for the most widely used ones), but to enable users to easily write services which would enable access to them.

Default services included with Slide are:


The Domain configuration file

Sample configuration file : click here.

Slide needs a configuration file to initialize the Domain. This configuration file defines the namespaces which are part of this domain, the services associated with them, and the namespaces data configuration. This file uses the XML language for its syntax.

A domain is an aggregation of one or more namespaces. If we use the UNIX filesystem analogy, a domain represents the root ("/") anchor where filesystems (in this case, namespaces) are mounted.

The domain controls access to its registered namespaces and performs initialization and connection management on behalf of the namespaces.

When Slide is first initialized, the Domain configuration is loaded. Once again, if you are familiar with UNIX, the domain configuration file is the equivalent of the fstab file. The path to the domain configuration file is given through the org.apache.slide.domain property in your slide.properties file (which must be located somewhere in your CLASSPATH).

The domain configuration is written by an administrator and tells how to initialize each Namespace. The namespace initialization includes information like:


Jakarta Slide core API

Architecture

The Slide architecture is a matrix of modules, ranging from high-level to low-level services, clearly separating functionality around different aspects (content, structure, security, locking and versioning).

Content in Slide is organized in Namespaces, which contain a hierarchical tree of information (analogous to directories and files in a filesystem). Multiple namespaces are aggregated in a Domain. The default implementation of a Slide domain is as a static entity, so only one domain can exist per JVM.

The high-level interfaces (Helpers) are meant to provide a simple, standardized way of manipulating a namespace from a client application. Underneath these interfaces lie pluggable, low-level services (Stores), which take care of actual storing the information.

Overview of the Slide architecture

Stores

Stores are low level services that handle the actual storage of content and related data. Stores are totally pluggable, enabling the use of the most appropriate storage method for the type of data to store.

Two different kinds of services exist:

This distinction has been made because it's easy to see that while some repositories are very efficient at managing and indexing small amounts of data (relational databases are a good example of this), others are best for storing big chunks of data (for example filesystems).

Within Slide, every object can possibly have a different kind of backing low-level service. For example, some objects might be stored in a remote LDAP directory, while others could be stored in an local SQL database. Thus, the content of a namespace can be distributed across several different descriptors and content stores.

It is up to the administrator to choose how objects will be stored using the Slide configuration file, which maps low-level services to individual nodes in the namespace.

Services are attributed to nodes in the namespace. This mapping is automatically inherited by sub-nodes. Here is an example of how one namespace might be mapped into different low-level services:

Namespace mapped to multiple stores

It is obvious that decent transaction capabilities are required in each individual store as well as across all the stores. Slide provides it's own transaction manager based on the Java Transaction API (JTA) to comply with this requirement. Operations that include multiple objects and span various stores can be grouped in transactions and rolled back if one of the operations fails.

Transactions in Slide

Helpers

Slide also provides a higher level abstraction of the content management system through a set of Java classes, called helpers. These encompass all the functionality a client application will need, clearly separated by aspect. These high-level services allow an application to access content in a uniform fashion, no matter where it might be located, or how it is physically stored.

Tight dependencies exist between the high-level services because of the need to enforce security, locking and other constraints throughout the client API.

The following helpers are provided:

Instances of these helpers for a specific namespace can be obtained through the NamespaceAccessToken that you receive when accessing the namespace.


Content Interface

Method Summary
 void create(SlideToken token, java.lang.String strUri, boolean isVersioned)
          Create new revision descriptors. Set the isVersioned as true to manage the resource in versioned way.
 void create(SlideToken token, java.lang.String strUri, NodeRevisionDescriptor revisionDescriptor, NodeRevisionContent revisionContent)
          Create new revision in main branch.
 void create(SlideToken token, java.lang.String strUri, java.lang.String branch, NodeRevisionDescriptor newRevisionDescriptor, NodeRevisionContent revisionContent)
          Create new revision based on a previous revision.
 NodeRevisionNumber fork(SlideToken token, java.lang.String strUri, java.lang.String branchName, NodeRevisionDescriptor basedOnRevisionDescriptor)
          Create a branch based on specified revision.
 NodeRevisionNumber fork(SlideToken token, java.lang.String strUri, java.lang.String branchName, NodeRevisionNumber basedOnRevisionNumber)
          Create a branch based on specified revision.
 void merge(SlideToken token, java.lang.String strUri, NodeRevisionDescriptor mainBranch, NodeRevisionDescriptor branch, NodeRevisionDescriptor newRevisionDescriptor, NodeRevisionContent revisionContent)
          Merge specified branches into a single branch.
 void merge(SlideToken token, java.lang.String strUri, java.lang.String mainBranch, java.lang.String branch, NodeRevisionDescriptor newRevisionDescriptor, NodeRevisionContent revisionContent)
          Merge specified branches into a single branch.
 void remove(SlideToken token, NodeRevisionDescriptors revisionDescriptors)
          Remove all revisions at this Uri.
 void remove(SlideToken token, java.lang.String strUri, NodeRevisionDescriptor revisionDescriptor)
          Remove specified revision.
 void remove(SlideToken token, java.lang.String strUri, NodeRevisionNumber revisionNumber)
          Remove specified revision.
 NodeRevisionDescriptor retrieve(SlideToken token, NodeRevisionDescriptors revisionDescriptors)
          Retrieve revision descriptor from the latest revision in the main branch.
 NodeRevisionContent retrieve(SlideToken token, NodeRevisionDescriptors revisionDescriptors, NodeRevisionDescriptor revisionDescriptor)
          Retrieve revision content.
 NodeRevisionDescriptor retrieve(SlideToken token, NodeRevisionDescriptors revisionDescriptors, NodeRevisionNumber revisionNumber)
          Retrieve revision descriptor.
 NodeRevisionDescriptor retrieve(SlideToken token, NodeRevisionDescriptors revisionDescriptors, java.lang.String branch)
          Retrieve revision descriptor from the latest revision of a branch.
 NodeRevisionDescriptors retrieve(SlideToken token, java.lang.String strUri)
          Retrieve revision descriptors.
 NodeRevisionContent retrieve(SlideToken token, java.lang.String strUri, NodeRevisionDescriptor revisionDescriptor)
          Retrieve revision content.
 void store(SlideToken token, java.lang.String strUri, NodeRevisionDescriptor revisionDescriptor, NodeRevisionContent revisionContent)
          Update contents of an existing revision.


Structure Interface

Structure helper. Provides methods to manage and navigate the hierarchy of nodes in a namespace.
Method Summary
 void addBinding(SlideToken token, ObjectNode collectionNode, java.lang.String segment, ObjectNode sourceNode)
          Modifies the collection identified by collectionNode, by adding a new binding from the specified segment to the resource identified by sourceNode.
 void create(SlideToken token, ObjectNode object, java.lang.String strUri)
          Creates a new node in the namespace.
 void createLink(SlideToken token, LinkNode link, java.lang.String linkUri, ObjectNode linkedObject)
          Creates a link to another node in the namespace.
 java.lang.String generateUniqueUri(SlideToken token, java.lang.String parentUri)
          Generates an URI that is guranteed to be unqiue globally.
 java.util.Enumeration getChildren(SlideToken token, ObjectNode object)
          Returns the children of a node.
 ObjectNode getParent(SlideToken token, ObjectNode object)
          Returns the parent of a node.
 java.util.List getParents(SlideToken token, ObjectNode object, boolean pathOnly, boolean storeOnly, boolean includeSelf)
          Return all parents of this object node.
 void remove(SlideToken token, ObjectNode object)
          Removes a node from the namespace.
 void removeBinding(SlideToken token, ObjectNode collectionNode, java.lang.String segment)
          Modifies the collection identified by collectionNode, by removing the binding for the specified segment.
 ObjectNode retrieve(SlideToken token, java.lang.String strUri)
          Retrieves a node by URI, following any links.
 ObjectNode retrieve(SlideToken token, java.lang.String strUri, boolean translateLastUriElement)
          Retrieves a node by URI.
 void store(SlideToken token, ObjectNode object)
          Stores/updates an object.
 

NodeRevisionDescriptors class

Method Summary
(package private)  void addSuccessor(NodeRevisionNumber number, NodeRevisionNumber successor)
          Add relation.
 NodeRevisionDescriptors cloneObject()
          Clone.
 java.util.Enumeration enumerateBranchNames()
          Enumerate all branch names.
 java.util.Enumeration enumerateRevisionNumbers()
          Enumerate all revision numbers in all branches.
 boolean equals(java.lang.Object obj)
          Equals.
 NodeRevisionNumber getInitialRevision()
          Get initial revision.
 NodeRevisionNumber getLatestRevision()
          Get latest revision from main branch.
 NodeRevisionNumber getLatestRevision(java.lang.String branchName)
          Get latest revision from a branch.
 java.lang.String getOriginalUri()
          OriginalUri accessor.
 java.util.Enumeration getSuccessors(NodeRevisionNumber number)
          Get relations.
 java.lang.String getUri()
          Uri accessor.
 boolean hasRevisions()
          Has revision ?
 boolean isAncestorDescendant(NodeRevisionNumber ancNrn, NodeRevisionNumber descNrn)
          Return true, if ancNrn and descNrn are in an ancestor-descendant relationship in this history.
 boolean isRedirected()
          Returns true, if and only if uri != originalUri
 boolean isVersioned()
          Use versioning accessor.
(package private)  void removeSuccessor(NodeRevisionNumber number, NodeRevisionNumber successor)
          Remove relation.
(package private)  void setLatestRevision(NodeRevisionNumber number)
          Latest revision mutator.
(package private)  void setLatestRevision(java.lang.String branch, NodeRevisionNumber number)
          Latest revision mutator.
(package private)  void setOriginalUri(java.lang.String originalUri)
          OriginalUri mutator.
(package private)  void setSuccessors(NodeRevisionNumber number, NodeRevisionNumber successor)
          Add relation.
(package private)  void setSuccessors(NodeRevisionNumber number, java.util.Vector successors)
          Add relation.
 void setUri(java.lang.String uri)
          Uri mutator.
(package private)  void setVersioned(boolean useVersioning)
          Use versioning mutator.
 void validate(java.lang.String expectedUri)
          Validate.

NodeRevisionDescriptor class

Method Summary
 void addLabel(java.lang.String label)
          Add new label.
 NodeRevisionDescriptor cloneObject()
          Clone.
 java.util.Enumeration enumerateLabels()
          Enumerate labels.
 java.util.Enumeration enumerateProperties()
          Properties values enumerator.
 java.util.Enumeration enumeratePropertiesName()
          Properties names enumerator.
 java.util.Enumeration enumerateRemovedProperties()
           
 java.util.Enumeration enumerateUpdatedProperties()
           
 boolean equals(java.lang.Object obj)
          Equals.
 boolean exists(java.lang.String name)
          Tests if a property has been set.
 boolean exists(java.lang.String name, java.lang.String namespace)
          Tests if a property has been set.
 java.lang.String getBranchName()
          Branch name accessor.
 java.lang.String getContentLanguage()
          Content language accessor.
 long getContentLength()
          Content length accessor.
 java.lang.String getContentType()
          Get the MIME content type of the data (if any).
 java.lang.String getCreationDate()
          Creation date accessor.
 java.util.Date getCreationDateAsDate()
          Creation date accessor.
 java.lang.String getCreationUser()
          Get the creation user
 java.lang.String getETag()
          Get the ETAG property (if any).
 java.lang.String getLastModified()
          Last modification date accessor.
 java.util.Date getLastModifiedAsDate()
          Creation date accessor.
 java.lang.String getModificationDate()
          Modification date accessor.
 java.lang.String getModificationUser()
          Get the mofications user
 java.lang.String getName()
          Name accessor.
 java.lang.String getNamespacedPropertyName(java.lang.String namespace, java.lang.String propertyName)
          Calculate the property name concatenated with the namespace, if available
 java.lang.String getOwner()
          Get the owner property (if any).
(package private)  java.util.Hashtable getProperties()
          Properties accessor.
 java.util.Enumeration getPropertiesNames()
          Deprecated. Replaced by enumeratePropertiesName
 java.util.Enumeration getPropertiesValues()
          Deprecated. Replaced by enumerate properties
 NodeProperty getProperty(java.lang.String name)
          Property accessor.
 NodeProperty getProperty(java.lang.String name, java.lang.String namespace)
          Property accessor.
 java.lang.String getResourceType()
          Get the ResourceType property (if any).
 NodeRevisionNumber getRevisionNumber()
          Revision number accessor.
 java.lang.String getSource()
          Get the source property (if any).
 boolean propertyValueContains(java.lang.String name, java.lang.String substr)
          Checks whether the value of the given property contains the specified substring.
 boolean propertyValueContains(java.lang.String name, java.lang.String namespace, java.lang.String substr)
          Checks whether the value of the given property contains the specified substring.
 void removeLabel(java.lang.String label)
          Remove a label.
 void removeLabels()
          Remove all labels.
 void removeProperty(NodeProperty property)
          Remove a property.
 void removeProperty(java.lang.String property)
          Remove a property.
 void removeProperty(java.lang.String property, java.lang.String nameSpace)
          Remove a property.
 void resetRemovedProperties()
           
 void resetUpdatedProperties()
           
(package private)  void setBranchName(java.lang.String branchName)
          Branch name mutator.
 void setContentLanguage(java.lang.String contentLanguage)
          Content language mutator.
 void setContentLength(long contentLength)
          Creation length mutator.
 void setContentLength(java.lang.String contentLength)
          Creation length mutator.
 void setContentType(java.lang.String contentType)
          Content type mutator.
 void setCreationDate(java.util.Date creationDate)
          Creation date mutator.
 void setCreationDate(java.lang.String creationDate)
          Creation date mutator.
 void setCreationUser(java.lang.String creationUser)
          Creation user mutator.
(package private)  void setDefaultProperties(java.util.Enumeration defaultProperties)
          Set default properties.
 void setETag(java.lang.String eTag)
          Set ETAG property.
 void setLastModified(java.util.Date lastModified)
          Last modified mutator.
 void setLastModified(java.lang.String lastModified)
          Last modified mutator.
 void setModificationDate(java.util.Date modificationDate)
          Modification date mutator.
 void setModificationDate(java.lang.String modificationDate)
          Modification date mutator.
 void setModificationUser(java.lang.String modificationUser)
          Modification user mutator.
 void setName(java.lang.String name)
          Name mutator.
 void setOwner(java.lang.String owner)
          Set owner property.
 void setOwner(java.lang.String owner, java.lang.String userpath)
          Set owner property.
(package private)  void setProperties(java.util.Hashtable properties)
          Properties mutator.
 void setProperty(NodeProperty property)
          Property mutatory.
 void setProperty(java.lang.String name, java.lang.Object value)
          Property mutator.
 void setProperty(java.lang.String name, java.lang.String namespace, java.lang.Object value)
          Property mutator.
 void setResourceType(java.lang.String resourceType)
          Set ResourceType property.
(package private)  void setRevisionNumber(NodeRevisionNumber number)
          Revision number mutator.
 void setSource(java.lang.String source)
          Set source property.
 void validate()
          Validate.

NodeRevisionNumber class

Method Summary
(package private)  NodeRevisionNumber cloneObject()
          Clone.
 boolean equals(java.lang.Object obj)
          Equals.
 int getMajor()
          Get the first number in the revision number.
 int getMinor()
          Get the second number in the revision number.
 int getNbDigits()
          Return number of digits if the revision number.
 int getNumber(int pos)
          Get a number by specifying its order.
 int hashCode()
          HashCode.
 java.lang.String toString()
          Get a String representation of the revision number.
 void validate()
          Validate.

Definition Node

1. Domain.xml Definition Node

From my understanding, the definition section sets where all the data concerning different parts of Slide will be stored. In the example all sub-stores (lock, content, etc...) are stored using "org.apache.slide.store.txfile.[WWW]TxXMLFileDescriptorsStore", which essentially stores data in an XML formatted file.

<definition>
<store name="tx">
<parameter name="tlock-timeout">120</parameter>
<nodestore classname="org.apache.slide.store.txfile.TxXMLFileDescriptorsStore">
<parameter name="rootpath">store/metadata</parameter>
<parameter name="workpath">work/metadata</parameter>
<parameter name="defer-saving">true</parameter>
<parameter name="timeout">120</parameter>
</nodestore>
<sequencestore classname="org.apache.slide.store.txfile.FileSequenceStore">
<parameter name="rootpath">store/sequence</parameter>
</sequencestore>
<securitystore>
<reference store="nodestore"/>
</securitystore>
<lockstore>
<reference store="nodestore"/>
</lockstore>
<revisiondescriptorsstore>
<reference store="nodestore"/>
</revisiondescriptorsstore>
<revisiondescriptorstore>
<reference store="nodestore"/>
</revisiondescriptorstore>
<contentstore classname="org.apache.slide.store.txfile.TxFileContentStore">
<parameter name="rootpath">store/content</parameter>
<parameter name="workpath">work/content</parameter>
<parameter name="defer-saving">true</parameter>
<parameter name="timeout">120</parameter>
</contentstore>
<!-- uncomment if you want to use the sample Indexer -->
<!-- be sure to have Lucene in your classpath -->
<!--
<contentindexer classname="org.apache.slide.index.SampleTxtContainsIndexer">
<parameter name="indexpath">./index</parameter>
</contentindexer>
-->
</store>
<scope match="/" store="tx"/>
</definition>

To setup Slide with multiple Store Definitions see MultiStoreConfig

1.1. General Store Information

Stores are low level services that handle the actual storage of content and related data. Stores are totally pluggable, enabling the use of the most appropriate storage method for the type of data to store.

Two different kinds of services exist:

This distinction has been made because it's easy to see that while some repositories are very efficient at managing and indexing small amounts of data (relational databases are a good example of this), others are best for storing big chunks of data (for example filesystems). Within Slide, every object can possibly have a different kind of backing low-level service. For example, some objects might be stored in a remote LDAP directory, while others could be stored in an local SQL database. Thus, the content of a namespace can be distributed across several different descriptors and content stores. It is up to the administrator to choose how objects will be stored using the Slide configuration file, which maps low-level services to individual nodes in the namespace. Services are attributed to nodes in the namespace. This mapping is automatically inherited by sub-nodes. Here is an example of how one namespace might be mapped into different low-level services:

1.2. Parameters

1.2.1. Cache Parameters
<parameter name="cache-mode">cluster</parameter>

Caching mode should be set to "cluster" when you want every change in the file system to be immediately displayed in Slide. Other options for this parameter are not yet known - if you know it please add / elaborate here

For more information see CacheConfiguration.

1.2.2. Locking
<parameter name="tlock-timeout">120</parameter>

This determines how many seconds pass before your Slide session times out?

1.2.3. Rootpath
<parameter name="rootpath">store/metadata</parameter>

1.2.4. Cache Timeout

For Slide 2.2 and above you can add this parameter for more caching with a timeout (100 sec in this case)

<parameter name="cache-timeout">100</parameter>
<parameter name="cache-mode">full</parameter>

1.3. Scope

"You need to add the scope to have the store (tx) visible."

<scope match="/" store="tx"/>

"So far, you can choose to configure the <scope> tags either directly underneath each store, or put all the <scope> tags at the bottom of configuring all your stores at this time. Soon there will be a standard and expectation, but for now lasse faire."

Basically this determines how you access your Slide applicatio. In the above example accessing the Slide application would be: http://localhost:8080/tx

1.4. General Store Definition Information (Low Level Services)

This describes low-level services configuration for the store. (For some reason, it was decided that these low level services also be called "stores" - this makes it a bit confusing.)

<contentstore classname="org.apache.slide.store.txfile.TxFileContentStore">

"classname" specifies the class that implements the sub-store in question. This hints at developers being able to create their own custom store, which is was Slide was designed for from the beginning. For more information see the CreateNewSlideStore entry.

The following are sub-store class implementions that are built into Slide -

TxFileContentStore

[WWW]TxXMLFileDescriptorsStore

[WWW]JDBCStore

FileSequenceStore

From my understanding (please correct me if I'm wrong), you have the following choices in regard to low level services related to stores.

  1. Define the low level service by associating it with the appropriate concrete class
<securitystore classname="org.apache.slide.store.mem.TransientSecurityStore"/>
  1. Define a low level service that can be referenced by other low level services as seen in nodestore
<nodestore classname="org.apache.slide.store.txfile.TxXMLFileDescriptorsStore">
<parameter name="rootpath">store/metadata</parameter>
<parameter name="workpath">work/metadata</parameter>
<parameter name="defer-saving">true</parameter>
<parameter name="timeout">120</parameter>
</nodestore>
<securitystore>
<reference store="nodestore"/>
</securitystore>

"The reference means that for the security store the same object is used as is, is configured at the node store." To get a better understanding compare the default nodestore definition (above) and the nodestore definition using JDBC. The default nodestore stores all of its data in XML format text files while the nodestore below stores the data in predefined tables.

1.4.1. callback-store Parameter
<parameter name="callback-store">org.apache.slide.store.simple.WebdavFileStore</parameter>

1.4.2. rootpath Parameter

This is where all the resources in the "files, content, etc..." collection go to

<parameter name="rootpath">c:/tmp</parameter>

1.5. Content Store Low Level Service

<contentstore classname="org.apache.slide.store.txfile.TxFileContentStore">
<parameter name="rootpath">store/content</parameter>
<parameter name="workpath">work/content</parameter>
<parameter name="defer-saving">true</parameter>
<parameter name="timeout">120</parameter>
</contentstore>

1.6. Node Store Low Level Service

1.6.1. Default File Based Node Store Low Level Service

Using the default node store, will have the namespace's data be stored in XML formatted text files.

<nodestore classname="org.apache.slide.store.txfile.TxXMLFileDescriptorsStore">
<parameter name="rootpath">store/metadata</parameter>
<parameter name="workpath">work/metadata</parameter>
<parameter name="defer-saving">true</parameter>
<parameter name="timeout">120</parameter>
</nodestore>

1.6.2. JDBC Node Store Low Level Service

Of course, for ease of maintenance most people will probably want to use a database to store most of the data related to a Slide namespace. In the example below, most sub-stores (except content) are using the JDBC configured nodestore.

Note

If you want to try a JDBC nodestore you also have to create all the necessary tables and views that Slide expects. You can use the scripts (configured for most major database servers) found in jakarta-slide-2.1-tomcat-5.0.28/webapps/slide/db-schema/ (for 2.1).

<nodestore classname="org.apache.slide.store.impl.rdbms.JDBCStore">
<parameter name="adapter">org.apache.slide.store.impl.rdbms.PostgresRDBMSAdapter</parameter>
<parameter name="driver">org.postgresql.Driver</parameter>
<parameter name="url">jdbc:postgresql://19.26.54.86:5432/db_name</parameter>
<parameter name="user">test</parameter>
<parameter name="password">12345</parameter>
<parameter name="dbcpPooling">true</parameter>
<parameter name="maxPooledConnections">10</parameter>
<parameter name="isolation">SERIALIZABLE</parameter>
<parameter name="compress">false</parameter>
</nodestore>
<parameter name="driver">org.postgresql.Driver</parameter>

Put the name of the jdbc driver you want to use here.

<parameter name="url">jdbc:postgresql://19.26.54.86:5432/db_name</parameter>

The database url varies by database and jdbc driver. Consult the accompanying jdbc documentation.

<parameter name="user">test</parameter>
<parameter name="password">12345</parameter>

A username / password combination that can access the database.

<parameter name="dbcpPooling">true</parameter>
<parameter name="maxPooledConnections">10</parameter>

This enables DBCPPooling and specifies the number of connections it can have.

<parameter name="compress">false</parameter>

I believe if you set this true, Slide will compress (using zip) incomming data and uncompress outbound data. This is quite useful.

1.7. Sequence Store

1.8. Security Store

1.9. Lock Store

J2EEStore

In order to use the J2EE stores, the Domain.xml file needs to contain the following configuration for the store:
<definition>
<store name="j2ee">
<nodestore classname="org.apache.slide.store.impl.rdbms.J2EEStore">
<parameter name="datasource">jdbc/mtx</parameter>
<parameter name="adapter">org.apache.slide.store.impl.rdbms.MySqlRDBMSAdapter</parameter>
<parameter name="compress">false</parameter>
</nodestore>
<securitystore>
<reference store="nodestore"/>
</securitystore>
<lockstore>
<reference store="nodestore"/>
</lockstore>
<revisiondescriptorsstore>
<reference store="nodestore"/>
</revisiondescriptorsstore>
<revisiondescriptorstore>
<reference store="nodestore"/>
</revisiondescriptorstore>
<contentstore>
<reference store="nodestore"/>
</contentstore>
</store>
<scope match="/" store="j2ee"/>
</definition>
where the adapter determines which database adapter you want to use. In this case you configured the MySQL adapter. Most adapters have a parameter to decide whether the content shall be compressed (zipped) before storing to the database. This might be fast in some enviroments. This option is switched off here.

You have to create the tables of the database schema manually. Schemata are available in src/conf/schema if you have the source distribution or in slide/db-schema if you have the Tomcat bundled or binary distribution.

If your store is not configured using a datasource looked up using JNDI you will have to provide more information to Slide like this for example:

	
<definition>
<store name="MySqlStore">
<nodestore classname="org.apache.slide.store.impl.rdbms.JDBCStore">
<parameter name="adapter">org.apache.slide.store.impl.rdbms.MySqlRDBMSAdapter</parameter>
<parameter name="driver">com.mysql.jdbc.Driver</parameter>
<parameter name="url">jdbc:mysql://localhost/Slide</parameter>
<parameter name="user">root</parameter>
<parameter name="dbcpPooling">true</parameter>
<parameter name="maxPooledConnections">10</parameter>
<parameter name="isolation">SERIALIZABLE</parameter>
<parameter name="compress">false</parameter>
</nodestore>
<contentstore>
<reference store="nodestore" />
</contentstore>
<securitystore>
<reference store="nodestore" />
</securitystore>
<lockstore>
<reference store="nodestore" />
</lockstore>
<revisiondescriptorsstore>
<reference store="nodestore" />
</revisiondescriptorsstore>
<revisiondescriptorstore>
<reference store="nodestore" />
</revisiondescriptorstore>
</store>
<scope match="/" store="MySqlStore"/>
</definition>
You can see you will have to configure you driver, the connection url and the user for the database. You can optionally configure if connection pooling using DBCP is enabled or not and if enabled how many connections shall be pooled. If you want you can also choose the isolation level of your database. SERIALIZABLE is a safe choice, but - depending on you database - at least READ COMMITTED is recommended.

Locks Needed

1. Table of accesses per method

Method Read Write Implemented
COPY source uri recursive target uri recursive YES
DELETE target uri recursive target uri recursive YES
GET like head - YES
HEAD uri - YES
MKCOL like put like put without calls to history folder YES
MOVE source and target uri recursive source and target uri recursive YES
OPTIONS like head - YES
POST like head - YES
PROPPATCH uri uri and history sub folder YES
PUT uri and history folder uri and direct parent, history and sub folder when resource is put under version control, subfolder when already under version control YES
VERSION uri and history folder uri and history and sub folder YES
REPORT uri und history folder - YES
CHECKIN like checkout like checkout YES
CHECKOUT uri und history folder uri and history sub folder YES
UNCHECKOUT like checkout like checkout YES
SEARCH global - YES
PROPFIND source uri and descendants if depth > 0 - YES
LOCK like head uri YES
UNLOCK like head uri YES
ACL uri uri and history sub folder YES
SUBSCRIBE - - n/a
UNSUBSCRIBE - - n/a
POLL - - n/a
NOTIFY - - n/a
MKWORKSPACE ? ? tentative as global write lock
UPDATE ? ? tentative as global write lock
LABEL ? ? tentative as global write lock
BIND ? ? tentative as global write lock
UNBIND ? ? tentative as global write lock
REBIND ? ? tentative as global write lock