<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ ModeShape (http://www.modeshape.org)
  ~
  ~ See the COPYRIGHT.txt file distributed with this work for information
  ~ regarding copyright ownership.  Some portions may be licensed
  ~ to Red Hat, Inc. under one or more contributor license agreements.
  ~ See the AUTHORS.txt file in the distribution for a full listing of 
  ~ individual contributors.
  ~
  ~ ModeShape is free software. Unless otherwise indicated, all code in ModeShape
  ~ is licensed to you under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ ModeShape is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"	[
<!ENTITY % CustomDTD SYSTEM "../../custom.dtd">
%CustomDTD;
]>
<chapter id="web_access">
  <title>Accessing ModeShape Remotely</title>
  <para>
		ModeShape provides a pair of ways to connect from remote clients: a WebDAV interface and a RESTful interface.
		This chapter details the capabilities of both as well as the configuration required to use each.		
  </para>
  <note>
  	<para>
  		Although the WebDAV and REST servers are treated separately here, many of the configuration parameters are 
  		the same.  This is because both share a fair amount of common code and have been designed to be able to be
  		deployed simultaneously on the same server or even within the same web archive.
  	</para>
  </note>
  <note>
  	<para>
  		The WebDAV and REST servers described here exist for easy use, though they may need to be customized
      and WAR files reassembled to fit your particular application server and configuration.
      ModeShape's <link linkend="deploying_modeshape_to_jbossas">JBoss AS kit</link> is one such customization,
			with a number of additional components built specifically for the JBoss Application Server environment.
  	</para>
  </note>
  <sect1 id="webdav_server">
		<title>The ModeShape WebDAV Server</title>
		<para>
		ModeShape provides a WebDAV server interface to its JCR implementation to ease integration with client applications.
		The WebDAV server maps some of the content nodes (by default, nodes with a primary type of <code>nt:file</code>) to
		WebDAV resources and the other nodes to WebDAV folders.  This allows any WebDAV client to navigate through the
		content repository to store files in a given location, as well as to create or delete nodes in the repository. 
		The remainder of this section describes how to configure and deploy the WebDAV server. 
		</para>
	<sect2 id="modeshape_webdav_server_configuration">
		<title>Configuring the ModeShape WebDAV Server</title>
		<para>
			The ModeShape WebDAV server is deployed as a WAR and configured mostly through its web configuration file (web.xml).  
			Here is an example web configuration that is used for integration testing of the ModeShape WebDAV server along with
			an explanation of its parts.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                         "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
	<display-name>ModeShape JCR RESTful Interface</display-name>
]]></programlisting>			 
		<para>
		This first section is largely boilerplate and should look familiar to anyone who has deployed a servlet-based
		application before.  The display-name can be customized, of course.
		</para>
		<para>
			The next stanza configures the <link linkend="jcr_web_spi">repository provider</link>.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!--
    This parameter provides the fully-qualified name of a class that implements
    the o.m.web.jcr.spi.RepositoryProvider interface.  It is required
    by the ModeShapeJcrDeployer that controls the lifecycle for the ModeShape WebDAV server.
  -->
  <context-param>
    <param-name>org.modeshape.web.jcr.REPOSITORY_PROVIDER</param-name>
    <param-value>org.modeshape.web.jcr.spi.FactoryRepositoryProvider</param-value>
  </context-param>
]]></programlisting>			 
		<para>
		As noted above, this parameter informs the &ModeShapeJcrDeployer; of the specific repository provider in use.
		Unless you are using the ModeShape WebDAV server to connect to a different JCR implementation, this should
		never change.  The ModeShape REST server also uses the &ModeShapeJcrDeployer; to get access to the JCR
		repository, so the two servlets can be deployed in the same WAR.
		</para>
		<para>
			Next we configure the ModeShape &JcrEngine; itself.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!--
    This parameter, specific to the FactoryRepositoryProvider implementation, specifies
    the name of the configuration file to initialize the repository or repositories.
    This configuration file must be on the classpath and is given as a classpath-relative
    directory.
  -->
  <context-param>
    <param-name>org.modeshape.web.jcr.JCR_URL</param-name>
    <param-value>file:/configRepository.xml</param-value>
  </context-param>
]]></programlisting>			 
		<para>
		If you are not familiar with the file format for a &JcrEngine; configuration file, you can build one 
		programatically with the &JcrConfiguration; class and call <code>save(...)</code> instead of <code>build()</code>
		to output the configuration file that equates to the configuration.
		</para>

		<para>
			The &ContentMapper; implementation can also be configured, but this is optional.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
	<!--
		This parameter provides the fully-qualified name of a class that implements
		the o.m.w.jcr.webdav.ContentMapper interface.  If no value is provided for this
		parameter, o.m.w.jcr.webdav.DefaultContentMapper will be used.
	-->
	<context-param>
		<param-name>org.modeshape.web.jcr.webdav.CONTENT_MAPPER_CLASS_NAME</param-name>
		<param-value>org.modeshape.web.jcr.webdav.DefaultContentMapper</param-value>
	</context-param>
]]></programlisting>			 
		<para>
		This class is used to prepare WebDAV responses from content nodes.  The &DefaultContentMapper; implementation
		creates nodes with type <code>nt:folder</code> and <code>nt:file</code> for WebDAV requests to create WebDAV
		folders and files, respectively.  Users can provide their own implementation that maps WebDAV content to other
		node content or structures.
		</para>
		<para>
			This is followed by some additional WebDAV configuration that controls the mapping between
			JCR node types and WebDAV files and resources.  These parameters are all specific to the 
			&DefaultContentMapper; implementation.  You can omit this section entirely to use the
			default values or if a custom &ContentMapper; is used.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
<!--
	Nodes with any of the primary node types in this comma-delimited list will be treated by the 
	WebDAV implementation as content nodes.  The value below is the default value for this 
	parameter.  That is, if this init parameter is omitted, the value below will be used by default.
-->
<context-param>
	<param-name>org.modeshape.web.jcr.webdav.CONTENT_PRIMARY_TYPE_NAMES</param-name>
	<param-value>nt:resource, mode:resource</param-value>
</context-param>

<!--
	Nodes with any of the primary node types in this comma-delimited list will be treated by the 
	WebDAV implementation as resource (file) nodes.  The value below is the default value for this 
	parameter.  That is, if this init parameter is omitted, the value below will be used by default.
-->
<context-param>
	<param-name>org.modeshape.web.jcr.webdav.RESOURCE_PRIMARY_TYPE_NAMES</param-name>
	<param-value>nt:file</param-value>
</context-param>

<!--
	Each folder created through the WebDAV servlet will be created as a node with the primary node 
	type below.  The value below is the default value for this parameter.  That is, if this init 
	parameter is omitted, the value below will be used by default.
-->
<context-param>
	<param-name>org.modeshape.web.jcr.webdav.NEW_FOLDER_PRIMARY_TYPE_NAME</param-name>
	<param-value>nt:folder</param-value>
</context-param>

<!--
	Each resource (file created through the WebDAV servlet will be created as a node with the primary 
	node type below.  The value below is the default value for this parameter.  That is, if this init 
	parameter is omitted, the value below will be used by default.
-->
<context-param>
	<param-name>
		org.modeshape.web.jcr.webdav.NEW_RESOURCE_PRIMARY_TYPE_NAME
	</param-name>
	<param-value>nt:file</param-value>
</context-param>

<!--
	Content created through the WebDAV servlet will be created as a node with the primary node 
	type below.  The value below is the default value for this parameter.  That is, if this init 
	parameter is omitted, the value below will be used by default.
-->
<context-param>
	<param-name>
		org.modeshape.web.jcr.webdav.NEW_CONTENT_PRIMARY_TYPE_NAME
	</param-name>
	<param-value>nt:resource</param-value>
</context-param>

]]></programlisting>			 
		<para>
		In general, this part of the web configuration file should not be modified.
		</para>
		<para>
			Next, the &RequestResolver; must be configured.  The &RequestResolver; converts the incoming 
			URI into a repository name, workspace name, and path within the repository. ModeShape provides several
			implementations:
      <itemizedlist>
        <listitem>
            <para>
							<code>&MultiRepositoryRequestResolver;</code> - supports multiple repositories
							and workspaces, by using a URI format with repository name and workspace name
							as the first two levels of the URI. This was added in ModeShape 2.3.0.Final,
							and is now the resolver that is configured by default.
						</para>
        </listitem>
        <listitem>
            <para>
							<code>&SingleRepositoryRequestResolver;</code> - maps URIs onto a single repository
  						and workspace that are configured in the web.xml. This is useful if you want to limit
							which repository and workspace is exposed via WebDAV.
						</para>
        </listitem>
        <listitem>
            <para>
							<code>&DefaultRequestResolver;</code> - maps URIs onto a single repository
  						and workspace that are configured in the web.xml. This used to be the default resolver,
							and is identical to <code>SingleRepositoryRequestResolver</code>. However, it is now
							deprecated and will be removed in a future version.
						</para>
        </listitem>
      </itemizedlist>
			If none of these fit your needs, it is easy to develop a custom implementation of this interface.
		</para>
		<para>
			To specify the resolver, set the <code>org.modeshape.web.jcr.webdav.REQUEST_RESOLVER_CLASS_NAME</code> property
			to the name of the &RepositoryResolver; implementation class. For example, here is how the
			&MultiRepositoryRequestResolver; class is specified:
		</para>
<programlisting language="XML" role="XML"><![CDATA[
<!--
	This optional parameter provides the name of the o.m.w.j.webdav.RequestResolver
	implementation class.  The provided value must be the name of a class that 
	implements the RequestResolver interface and has a public, no-arg constructor.
	If no value is provided, o.m.w.j.webdav.MultiRepositoryRequestResolver will be used.
-->
<context-param>
	<param-name>org.modeshape.web.jcr.webdav.REQUEST_RESOLVER_CLASS_NAME</param-name>
	<param-value>org.modeshape.web.jcr.webdav.MultiRepositoryRequestResolver</param-value>
</context-param>
]]></programlisting>
			<para>
				Alternatively, if the &SingleRepositoryRequestResolver; class is to be used, then two additional properties must define
				the repository name and workspace name:
			</para>
<programlisting language="XML" role="XML"><![CDATA[
<!--
	This optional parameter provides the name of the o.m.w.j.webdav.RequestResolver
	implementation class.  The provided value must be the name of a class that 
	implements the RequestResolver interface and has a public, no-arg constructor.
-->
<context-param>
	<param-name>org.modeshape.web.jcr.webdav.REQUEST_RESOLVER_CLASS_NAME</param-name>
	<param-value>org.modeshape.web.jcr.webdav.SingleRepositoryRequestResolver</param-value>
</context-param>

<!--
	This parameter is required if (and only if) the SingleRequestResolver is used.
	It provides the name of the JCR repository that will be accessed.  An exception
	will be thrown if no value is provided for this parameter.
-->
<context-param>
	<param-name>
		org.modeshape.web.jcr.webdav.SINGLE_REPOSITORY_RESOLVER_REPOSITORY_NAME
	</param-name>
	<param-value>repository</param-value>
</context-param>

<!--
	This parameter is required if (and only if) the SingleRequestResolver is used.
	It provides the name of the JCR workspace that will be accessed.  An exception
	will be thrown if no value is provided for this parameter.
-->
<context-param>
	<param-name>
		org.modeshape.web.jcr.webdav.SINGLE_REPOSITORY_RESOLVER_WORKSPACE_NAME
	</param-name>
	<param-value>default</param-value>
</context-param>

]]></programlisting>			 
		<para>
			ModeShape also provides the older &DefaultRequestResolver; class is to be used, which is now
			deprecated. Please switch use the &SingleRepositoryRequestResolver; or &MultiRepositoryRequestResolver; classes.
			This class is provided for backward compatibility.
		</para>
		<para>
			Once the &RequestResolver; has been specified, then more brief boilerplate ensues defines additional configuration information:
		</para>
<programlisting language="XML" role="XML"><![CDATA[
<!-- Required parameter for ModeShape WebDAV - should not be modified -->
<listener>
	<listener-class>org.modeshape.web.jcr.ModeShapeJcrDeployer</listener-class>
</listener>

<!-- Required WebDAV servlet - should not be modified -->
<servlet>
	<servlet-name>WebDAV</servlet-name>
	<servlet-class>org.modeshape.web.jcr.webdav.ModeShapeWebdavServlet</servlet-class>
	
	<!--
		The webdav library requires this parameter to be present, but does not use it.
	-->
	<init-param>
		<param-name>rootpath</param-name>
		<param-value>.</param-value>
	</init-param>
</servlet>

<!-- Required parameter for ModeShape WebDAV - should not be modified -->
<servlet-mapping>
	<servlet-name>WebDAV</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>

]]></programlisting>			 
		
		<para>
			Finally, security must be configured for the WebDAV server.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
	<!-- 
		The ModeShape WebDAV implementation leverages the HTTP credentials to for authentication 
		and authorization within the JCR repository.  Unless the repository provides for anonymous 
		access, it makes no sense to try to log into the JCR repository without credentials, so 
		this constraint helps lock down the repository.
		
		This should generally not be modified. 
	-->
	<security-constraint>
		<display-name>ModeShape WebDAV</display-name>
		<web-resource-collection>
			<web-resource-name>WebDAV</web-resource-name>
			<url-pattern>/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<!--  
				A user must be assigned this role to connect to any JCR repository, in addition to 
				needing the READONLY or READWRITE roles to actually read or modify the data.  This 
				is not used internally, so another role could be substituted here.
			-->
			<role-name>connect</role-name>
		</auth-constraint>
	</security-constraint>

	<!--  
		Any auth-method will work for ModeShape.  BASIC is used this example for simplicity.
	 -->
	<login-config>
		<auth-method>BASIC</auth-method>
	</login-config>

	<!-- 
		This must match the role-name in the auth-constraint above. 
	 -->
	<security-role>
		<role-name>connect</role-name>
	</security-role>
</web-app>

]]></programlisting>			 
		<para>
		As noted above, the WebDAV server will not function properly unless security is configured.  All authorization
		methods supported by the Servlet specification are supported by ModeShape and can be used interchangeable, as
		long as authenticated users have the connect role listed above. 
		</para>	
		
	</sect2>
	<sect2 id="modeshape_webdav_server_deployment">
		<title>Deploying the ModeShape WebDAV Server</title>
		<para>
			Deploying the ModeShape WebDAV server only requires three steps: <link linkend="modeshape_webdav_server_configuration">
			preparing the web configuration</link>, configuring the users and their roles in your web container 
			(outside the scope of this document), and assembling the WAR.  This section describes the requirements 
			for assembling the WAR.
	  </para>
	  <para>
	  		If you are using Maven to build your projects, the WAR can be built from a POM.  Here is a portion of the 
	  		POM used to build the ModeShape WebDAV Server integration subproject.
		</para>
<programlisting role='XML'><![CDATA[
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<artifactId>modeshape</artifactId>
		<groupId>org.modeshape</groupId>
		<version>2.0</version>
		<relativePath>../..</relativePath>
	</parent>
	<artifactId>modeshape-web-jcr-webdav-war</artifactId>
	<packaging>war</packaging>
	<name>ModeShape JCR WebDAV Servlet</name>
	<description>ModeShape servlet that provides WebDAV access to JCR items</description>
	<url>http://www.modeshape.org</url>
	<dependencies>
		<dependency>
			<groupId>org.modeshape</groupId>
			<artifactId>modeshape-web-jcr-webdav</artifactId>
			<version>${project.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>
</project>

]]></programlisting> 
	  <para>
		If you use this approach, make sure that web configuration file is in the <code>/src/main/webapp/WEB-INF</code>
		directory.
	  </para>
	  <para>
	  	Of course, the JBoss WebDAV Server WAR can still be built if you are not using Maven.  Simply construct a WAR with
	  	the following contents:
<programlisting>
+ /WEB-INF
	+ /classes
	|	+ configRepository.xml
	|	+ log4j.properties (Optional)
	+ /lib
	|	+ aperture-1.1.0.Beta1.jar
	|	+ hamcrest-core-1.1.jar
	|	+ jakarta-regexp-1.4.jar
	|	+ jcr-2.0.jar
	|	+ joda-time-1.6.jar
	|	+ junit-dep-4.4.jar
	|	+ lucene-analyzers-3.0.2.jar
	|	+ lucene-core-3.0.2.jar
	|	+ lucene-regex-3.0.2.jar
	|	+ lucene-snowball-3.0.2.jar
	|	+ lucene-misc-3.0.2.jar
	|	+ modeshape-cnd-&versionNumber;.jar
	|	+ modeshape-common-&versionNumber;.jar
	|	+ modeshape-graph-&versionNumber;.jar
	|	+ modeshape-jcr-&versionNumber;.jar
	|	+ modeshape-jcr-api-&versionNumber;.jar
	|	+ modeshape-mimetype-detector-aperture-&versionNumber;.jar
	|	+ modeshape-repository-&versionNumber;.jar
	|	+ modeshape-search-lucene-&versionNumber;.jar
	|	+ modeshape-web-jcr-&versionNumber;.jar
	|	+ modeshape-web-jcr-webdav-&versionNumber;.jar
	|	+ rdf2go.api-4.6.2.jar
	|	+ slf4j-api-1.6.1.jar
	|	+ slf4j-log4j12-1.6.1.jar
	|	+ stax-api-1.0-2.jar
	|	+ webdav-servlet-2.0.1.jar
	+ web.xml
			
</programlisting>	  	
	  	If you are using sequencers or any connectors other than the in-memory or federated connector, you will also have
	  	to add the JARs for those dependencies into the <code>WEB-INF/lib</code> directory as well.  You will also have to 
	  	change the version numbers on the JARs to reflect the current version of ModeShape. 
	  </para>
	  <note>
		  <para>
			  Your servlet container may already provide a logging system, and you may need to remove the "slf4j-log4j12-1.5.8.jar"
			  and replace with the appropriate <ulink url="&SLF4JManual;">SLF4J binding</ulink> jar. Or, if your servlet container
			  already uses SLF4J globally, you may want to remove all of the "slf4j*.jar" files.
		  </para>
	  </note>
	  <para>
	  	This WAR can be deployed into your servlet container.
	  </para>
	</sect2>
  </sect1>
  <sect1 id="rest_server">
		<title>The ModeShape REST Server</title>
		<para>
		ModeShape provides a RESTful interface to its JCR implementation that allows HTTP-based 
		access and updating of content.  Although the initial version of this REST server only supports the ModeShape
		JCR implementation, it has been designed to make integration with other JCR implementors easy.  This
		section describes how to configure and deploy the REST server. 
		</para>
	<sect2 id="supported_rest_resources">
		<title>Supported Resources and Methods</title>
		<para>
			The REST Server currently supports the URIs and HTTP methods described below.  The URI patterns assume
			that the REST server is deployed at its conventional location of "/resources".  These URI patterns would
			change if the REST server were deployed under a different web context and URI patterns below would
			change accordingly.
		</para>
		<note>
			<para>
				The <link linkend="deloying_modeshape_to_jbossas">JBoss AS kit</link> by default will deploy the RESTful service 
				at the "/modeshape-rest" location, which is more descriptive and better	fits with the other deployed applications 
				and services. To use these examples against this RESTful service, simply replace "/resources" with "/modeshape-rest"
				in each of the URLs.
			</para>
		</note>
		<para>
		  Currently, only JSON-encoded responses are provided.
		</para>
				<table frame='all'>
			<title>Supported URIs for the ModeShape REST Server</title>
			<tgroup cols='3' align='left' colsep='1' rowsep='1'>
	      <colspec colname='URI' colwidth="3*"/>
	      <colspec colname='methods' colwidth="1*"/>
	      <colspec colname='description' colwidth="1*"/>
				<thead>
					<row>
			  		<entry>URI Pattern</entry>
			  		<entry>HTTP Method(s)</entry>
			  		<entry>HTTP Description</entry>
					</row>
				</thead>
				<tbody>
					<row>
						<entry>/resources</entry>
						<entry>Returns a list of accessible repositories</entry>
						<entry>GET</entry>
					</row>
					<row>
						<entry>/resources/{repositoryName}</entry>
						<entry>Returns a list of accessible workspaces within that repository</entry>
						<entry>GET</entry>
					</row>
					<row>
						<entry>/resources/{repositoryName}/{workspaceName}</entry>
						<entry>Returns a list of available operations within the workspace</entry>
						<entry>GET</entry>
					</row>
					<row>
						<entry>/resources/{repositoryName}/{workspaceName}/item/{path}</entry>
						<entry>Accesses the item (node or property) at the path</entry>
						<entry>GET, POST, PUT, DELETE</entry>
					</row>
					<row>
						<entry>/resources/{repositoryName}/{workspaceName}/query</entry>
						<entry>Executes the query in the request body</entry>
						<entry>POST</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		<para>
		Note that this approach supports dynamic discovery of the available repositories on the server.  A typical
		conversation might start with a request to the server to check the available repositories.
<programlisting>
GET http://www.example.com/resources
</programlisting>		 
		This request would generate a response that mapped the names of the available repositories to metadata information
		about the repositories like so:
<programlisting><![CDATA[
{
	"modeshape%3arepository" : { 
		"repository" : {
			"name" : "modeshape%3arepository",
			"resources" : { "workspaces":"/resources/modeshape%3arepository" }
			"metadata" : {
			   "jcr.specification.name" : "Content Repository for Java Technology API",
         "jcr.specification.version" : "2.0",
         "jcr.repository.name" : "ModeShape JCR Repository",
         "jcr.repository.vendor.url" : "http://www.modeshape.org",
         "jcr.repository.version" : "2.6.0.FINAL",
         "option.versioning.supported" : "true",
         
         ... etc. ...

         }
			}
		}
	}
}
]]></programlisting>		 
		The actual response wouldn't be pretty-printed like the example, but the format would be the same.  The name
		of the repository ("repository" URL-encoded) is mapped to a repository object that contains a name
		(the redundant "repository") and a list of available resources within the repository and their respective
		URIs.  Note that ModeShape supports deploying multiple JCR repositories side-by-side on the same server,
		so this response could easily contain multiple repositories in a real deployment.  
	</para>
	<para>
	  Also, the "metadata" section is included only in responses from RESTful services starting with the version 2.5.0.Final release,
	  and contains the <ulink url='&JcrApi;javax/jcr/Repository.html#getDescriptor(java.lang.String)'>JCR descriptors</ulink> 
	  keys and values, where each value will either be a string or, if there are multiple values for the descriptor, an array of strings.
	  Note not all the descriptors are shown in the above example.
	</para>
	<para>		
		The only thing that you can do with a repository through the REST interface at this time is to
		get a list of its workspaces.  A request to do so can be built up from the previous response like this:
<programlisting>
GET http://www.example.com/resources/modeshape%3arepository
</programlisting>		 
		This request (and all of the following requests) actually create a JCR &Session; to service the request and
		require that security be configured.  This process is described in more detail in 
		<link linkend="modeshape_rest_server_configuration">a later section</link>.  Assuming that security has been properly
		configured, the response would look something like this:
<programlisting><![CDATA[
{
	"default" : {
		"workspace" : {
			"name" : "default",
			"resources" : { 
				"items":"/resources/modeshape%3arepository/default/items", 
				"query":"/resources/modeshape%3arepository/default/query"
			},
		}
	}
}
]]></programlisting>	
		Like the first response, this response consists of a list of workspace names mapped to metadata about the
		workspaces.  The example above only lists one workspace for simplicity, but there could be many different
		workspaces returned in a real deployment.  Note that the "items" resource builds the full URI to the root
		of the items hierarchy, including the encoding of the repository name and the workspace name and the "query"
		resource builds the full URI needed to execute queries.
		</para>
		<para>
		Now a request can be built to retrieve the root item of the repository.
<programlisting>
GET http://www.example.com/resources/modeshape%3arepository/default/items
</programlisting>		 
		Any other item in the repository could be accessed by appending its path to the URI above.  In a default
		repository with no content, this would return the following response:  
<programlisting><![CDATA[
{
	"properties": {
		"jcr:primaryType": "mode:root",
		"jcr:uuid": "97d7e2ef-996e-4d99-8ec2-dc623e6c2239"
	},
	"children": ["jcr:system"]
]]></programlisting>		 
	    The response contains a mapping of property names to their values and an array of child names.  Had one of
	    the properties been multi-valued, the values for that property would have been provided as an array as well, 
	    as will shortly be shown.
	    </para>
	    <para>
	    The items resource also contains an option query parameter: <code>mode:depth</code>.  This parameter, which defaults
	    to 1, controls how deep the hierarchy of returned nodes should be.  Had the request had the parameter:
<programlisting>
GET http://www.example.com/resources/modeshape%3arepository/default/items?mode:depth=2
</programlisting>		 
	    Then the response would have contained details for the children of the root node as well.
<programlisting><![CDATA[
{
	"properties": {
		"jcr:primaryType": "mode:root",
		"jcr:uuid": "163bc5e5-3b57-4e63-b2ae-ededf43d3445"
	},
	"children": {
		"jcr:system": {
			"properties": {"jcr:primaryType": "mode:system"},
    		"children": ["mode:namespaces"]
		}
	}
}
]]></programlisting>		 
		</para>
		<para>
		It is also possible to use the RESTful API to add, modify and remove repository content.  Removes are simple -
		a DELETE request with no body returns a response with no body.
<programlisting>
DELETE http://www.example.com/resources/modeshape%3arepository/default/items/path/to/deletedNode
</programlisting>		 
		</para>
		<para>
		Adding content simply requires a POST to the name of the <emphasis>relative</emphasis> root node of the
		content that you wish to add and a request body in the same format as the response from a GET.  Adding multiple
		nodes at once is supported, as shown below.
<programlisting><![CDATA[
POST http://www.example.com/resources/modeshape%3arepository/default/items/newNode

{
	"properties": {
		"jcr:primaryType": "nt:unstructured",
		"jcr:mixinTypes": "mix:referenceable",
		"someProperty": "foo"
	},
	"children": {
		"newChildNode": {
			"properties": {"jcr:primaryType": "nt:unstructured"}
		}
	}
}
]]></programlisting>		 
		Note that protected properties like jcr:uuid are not provided but that the primary type and mixin types are
		provided as properties.  The REST server will translate these into the appropriate calls behind the
		scenes.  The JSON-encoded response from the request will contain the node that you just posted, including 
		any autocreated properties and child nodes.  
		</para>
		<para>		
		If you do not need this information, add <code>mode:includeNode=false</code>
		as a query parameter to your URL. 
<programlisting><![CDATA[
POST http://www.example.com/resources/modeshape%3arepository/default/items/newNode?mode:includeNode=false

{
	"properties": {
		"jcr:primaryType": "nt:unstructured",
		"jcr:mixinTypes": "mix:referenceable",
		"someProperty": "foo"
	},
	"children": {
		"newChildNode": {
			"properties": {"jcr:primaryType": "nt:unstructured"}
		}
	}
}
]]></programlisting>		
		This will instruct the REST server to only return the path of the newly-created node in the response.
		</para>
		<para>
		The PUT method allows for updates of nodes and properties.  If the URI points to a property, the body of the
		request should be the new JSON-encoded value for the property, which includes the property name (allowing
		proper determination of whether the values are binary; see the 
		<link linkend="binary_properties_in_rest_representations">next section"</link>").
<programlisting><![CDATA[
PUT http://www.example.com/resources/modeshape%3arepository/default/items/some/existing/node/someProperty

{
	"someProperty" : "bar"
}
]]></programlisting>
		Setting multiple properties at once can be performed by providing a URI to a node instead of a property. The
		body of the request should then be a JSON object that maps property names to their new values.
<programlisting><![CDATA[
PUT http://www.example.com/resources/modeshape%3arepository/default/items/some/existing/node

{
	"someProperty": "foobar",
	"someOtherProperty": "newValue"
}
]]></programlisting>
		The JSON request can even contain a properties container:
<programlisting><![CDATA[
PUT http://www.example.com/resources/modeshape%3arepository/default/items/some/existing/node

{
	"properties": {
		"someProperty": "foobar",
		"someOtherProperty": "newValue"
	}
}
]]></programlisting>
		</para>
		<para>		
		A subgraph can be updated all at once using a PUT against a URI of the top node in the subgraph. Note that
		in this case, very node in the subgraph must be provided in the JSON request (any node not in the request will be removed).
		This method will attempt to set all of the properties to the new value(s) as specified in the JSON request,
		plus any descendant node in the JSON request that doesn't reflect an existing node will be created while any
		existing node not reflected in the JSON request will be removed. (Any specifications of "jcr:primaryType" are ignored
		if the node already exists.) In other words, the request only needs to contain the properties that are changed. 
		Of course, if a node is being added, all of its properties need to be included in the request. 
	</para>
	<para>
		Here is an example:
<programlisting><![CDATA[
PUT http://www.example.com/resources/modeshape%3arepository/default/items/some/existing/node

{
	"properties": {
		"jcr:primaryType": "nt:unstructured",
		"jcr:mixinTypes": "mix:referenceable",
		"someProperty": "foo"
	},
	"children": {
		"childNode": {
			"properties": {"jcr:primaryType": "nt:unstructured"}
		}
	}
}
]]></programlisting>		
		This will update the existing node at "/some/existing/node" with the specified properties, and ensure
		that it contains one child node named "childNode". Note that the body of this request is identical in structure
		to that of the POST requests.
		</para>


		<para>
		Queries can be executed through the REST interface by POSTing to the query URI with the query statement in the 
		body of the request.  The query language <emphasis>must</emphasis> be specified by setting the appropriate MIME 
		type.
				<table frame='all'>
			<title>Query Content Types for the ModeShape REST Server</title>
			<tgroup cols='2' align='left' colsep='1' rowsep='1'>
	      <colspec colname='language' colwidth="3*"/>
	      <colspec colname='content type' colwidth="1*"/>
				<thead>
					<row>
			  		<entry>Query Language</entry>
			  		<entry>Content Type</entry>
					</row>
				</thead>
				<tbody>
					<row>
						<entry>XPath</entry>
						<entry>application/jcr+xpath</entry>
					</row>
					<row>
						<entry>JCR-SQL</entry>
						<entry>application/jcr+sql</entry>
					</row>
					<row>
						<entry>JCR-SQL2</entry>
						<entry>application/jcr+sql2</entry>
					</row>
					<row>
						<entry>Full Text Search</entry>
						<entry>application/jcr+search</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		If no content type is specified or the content type for the request is not one of the content types listed
		above, the request will generate a response code of 400 (BAD REQUEST).
		</para><para>
		All queries for a given workspace are posted to the same URI and the request body is not JSON-encoded.
<programlisting><![CDATA[
POST http://www.example.com/resources/modeshape%3arepository/default/query

/a/b/c/d[@foo='bar']
]]></programlisting>		 
		Assuming that the request above was POSTed with a content type of <code>application/jcr+xpath</code>, a
		response would be generated that consisted of a JSON object that contained a property named "rows".  The "rows"
		property would contain an array of rows with each element being a JSON object that represented one row
		in the query result set.
		</para>
<programlisting><![CDATA[
{
	"types": {
		"someProperty": "STRING",
		"someOtherProperty": "BOOLEAN",
		"jcr:path": "STRING",
		"jcr:score": "DECIMAL"
	},
	"rows": {
		{
			"someProperty": "foobar",
			"someOtherProperty": "true",
			"jcr:path" : "/a/b/c/d",
			"jcr:score" : 0.9327
		},
		{
			"someProperty": "localValue",
			"someOtherProperty": "false",
			"jcr:path" : "/a/b/c/d[2]",
			"jcr:score" : 0.8143
		}
	}
}
]]></programlisting>		 
		<para>
		If ModeShape is used as the underlying JCR implementation, the JSON object in the response will
		also contain a "types" property.  The value of the "types" property is a JSON object that maps
		column names to their JCR type.		
		</para>

		<sect3 id="binary_properties_in_rest_representations">
			<title>Binary properties</title>
			<para>
		    Binary property values are included in any of the the responses or requests, but are represented 
		    string values containing the <ulink url="&Wikipedia;Base64">Base 64 encoding</ulink> of the binary content.  
		    Any such property is explicitly annotated such that "/base64/" is appended to the property name.  
		    First of all, this makes it very clear to the client and service which properties are encoded, allowing them 
		    to properly decode the values before use.  Secondly, the "/base64/" suffix was carefully chosen because it 
		    cannot be used in a real property name (without escaping).  Here's an example of a node containing a "jcr:primaryType" 
		    property with a single string value, a "jcr:uuid" property with another single UUID value, another 
		    "options" property that has two integer values, and a fourth "content" property that has a single
		    binary value:
<programlisting><![CDATA[
{
	"properties": {
		"jcr:primaryType": "nt:unstructured",
		"jcr:uuid": "163bc5e5-3b57-4e63-b2ae-ededf43d3445"
		"options": [ "1", "2" ]
		"content/base64/": 
	"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
	},
}
]]></programlisting>
	      All values of a property will always be Base 64 encoded if at least one of the values is binary.
	      If there are multiple values, then they will be separated by commas and will appear within '[' and ']' 
	      characters (just like other properties).
			</para>
		</sect3>
	</sect2>
	<sect2 id="modeshape_rest_server_configuration">
		<title>Configuring the ModeShape REST Server</title>
		<para>
			The ModeShape REST server is deployed as a WAR and configured mostly through its web configuration file (web.xml).  
			Here is an example web configuration that is used for integration testing of the ModeShape REST server along with
			an explanation of its parts.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                         "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <display-name>ModeShape JCR RESTful Interface</display-name>
]]></programlisting>			 
		<para>
		This first section is largely boilerplate and should look familiar to anyone who has deployed a servlet-based
		application before.  The display-name can be customized, of course.
		</para>
		<para>
			The next stanza configures the <link linkend="jcr_web_spi">repository provider</link>.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!--
    This parameter provides the fully-qualified name of a class that implements
    the o.m.web.jcr.spi.RepositoryProvider interface.  It is required
    by the ModeShapeJcrDeployer that controls the lifecycle for the ModeShape REST server.
  -->
  <context-param>
    <param-name>org.modeshape.web.jcr.REPOSITORY_PROVIDER</param-name>
    <param-value>org.modeshape.web.jcr.spi.FactoryRepositoryProvider</param-value>
  </context-param>
]]></programlisting>			 
		<para>
		As noted above, this parameter informs the &ModeShapeJcrDeployer; of the specific repository provider in use.
		Unless you are using the ModeShape REST server to connect to a different JCR implementation, this should
		never change.
		</para>

		<para>
			Next we configure the ModeShape &JcrEngine; itself.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!--
    This parameter, specific to the FactoryRepositoryProvider implementation, specifies
    the name of the configuration file to initialize the repository or repositories.
    This configuration file must be on the classpath and is given as a classpath-relative
    directory.
  -->
  <context-param>
    <param-name>org.modeshape.web.jcr.JCR_URL</param-name>
    <param-value>file:/configRepository.xml</param-value>
  </context-param>
]]></programlisting>			 
		<para>
		If you are not familiar with the file format for a &JcrEngine; configuration file, you can build one 
		programatically with the &JcrConfiguration; class and call <code>save(...)</code> instead of <code>build()</code>
		to output the configuration file that equates to the configuration.
		</para>

		<para>
			This is followed by a bit of RESTEasy and JAX-RS boilerplate.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!--
    This parameter defines the JAX-RS application class, which is really just a metadata class
    that lets the JAX-RS engine (RESTEasy in this case) know which classes implement pieces
    of the JAX-RS specification like exception handling and resource serving.
		
    This should not be modified. 
  -->
  <context-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>org.modeshape.web.jcr.rest.JcrApplication</param-value>
  </context-param>

  <!-- Required parameter for RESTEasy - should not be modified -->
  <listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
  </listener>

  <!-- Required parameter for ModeShape REST - should not be modified -->
  <listener>
    <listener-class>org.modeshape.web.jcr.ModeShapeJcrDeployer</listener-class>
  </listener>

  <!-- Required parameter for RESTEasy - should not be modified -->
  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
  </servlet>

  <!-- Required parameter for ModeShape REST - should not be modified -->
  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

]]></programlisting>			 
		<para>
		In general, this part of the web configuration file should not be modified.
		</para>
		
		<para>
			Finally, security must be configured for the REST server.
		</para>
<programlisting language="XML" role="XML"><![CDATA[
  <!-- 
    The ModeShape REST implementation leverages the HTTP credentials to for authentication and 
    authorization within the JCR repository.  It makes no sense to try to log into the JCR 
    repository without credentials, so this constraint helps lock down the repository.
		
    This should generally not be modified. 
  -->
  <security-constraint>
    <display-name>ModeShape REST</display-name>
    <web-resource-collection>
      <web-resource-name>RestEasy</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
			<!--  
        A user must be assigned this role to connect to any JCR repository, in addition to needing the 
        READONLY or READWRITE roles to actually read or modify the data.  This is not used internally, 
        so another role could be substituted here.
      -->
      <role-name>connect</role-name>
    </auth-constraint>
  </security-constraint>

  <!--  
    Any auth-method will work for ModeShape.  BASIC is used this example for simplicity.
  -->
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>

  <!-- 
    This must match the role-name in the auth-constraint above. 
  -->
  <security-role>
    <role-name>connect</role-name>
  </security-role>
</web-app>

]]></programlisting>			 
		<para>
		As noted above, the REST server will not function properly unless security is configured.  All authorization
		methods supported by the Servlet specification are supported by ModeShape and can be used interchangeable, as
		long as authenticated users have the connect role listed above. 
		</para>	
		
	</sect2>
	<sect2 id="modeshape_rest_server_deployment">
		<title>Deploying the ModeShape REST Server</title>
		<para>
			Just as with the ModeShape WebDAV server, deploying the ModeShape REST server only requires three steps: <link linkend="modeshape_rest_server_configuration">
			preparing the web configuration</link>, configuring the users and their roles in your web container 
			(outside the scope of this document), and assembling the WAR.  This section describes the requirements 
			for assembling the WAR.
	  </para>
	  <para>
	  		If you are using Maven to build your projects, the WAR can be built from a POM.  Here is a portion of the 
	  		POM used to build the ModeShape REST Server integration subproject.
		</para>
<programlisting role='XML'><![CDATA[
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<artifactId>modeshape</artifactId>
		<groupId>org.modeshape</groupId>
		<version>2.0</version>
		<relativePath>../..</relativePath>
	</parent>
	<artifactId>modeshape-web-jcr-rest-war</artifactId>
	<packaging>war</packaging>
	<name>ModeShape JCR REST Servlet</name>
	<description>ModeShape servlet that provides RESTful access to JCR items</description>
	<url>http://www.modeshape.org</url>
	<dependencies>
		<dependency>
			<groupId>org.modeshape</groupId>
			<artifactId>modeshape-web-jcr-rest</artifactId>
			<version>2.0</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-client</artifactId>
			<version>1.2.1.GA</version>
		</dependency>		
	</dependencies>
</project>

]]></programlisting> 
	  <para>
		If you use this approach, make sure that web configuration file is in the <code>/src/main/webapp/WEB-INF</code>
		directory.
	  </para>
	  <para>
	  	The JBoss REST Server WAR is still easy enough to build if you are not using Maven.  Simply construct a WAR with
	  	the following contents:
<programlisting>
+ /WEB-INF
	+ /classes
	|	+ configRepository.xml
	|	+ log4j.properties (Optional)
	+ /lib
	|	+ activation-1.1.jar
	|	+ commons-codec-1.2.jar
	|	+ commons-httpclient-3.1.jar
	|	+ hamcrest-core-1.1.jar
	|	+ httpclient-4.0.jar
	|	+ httpcore-4.0.1.jar
	|	+ jakarta-regexp-1.4.jar
	|	+ javassist-3.6.0.GA.jar
	|	+ jaxb-api-2.1.jar
	|	+ jaxb-impl-2.1.12.jar
	|	+ jaxrs-api-1.2.1.GA.jar
	|	+ jcl-over-slf4j-1.5.8.jar
	|	+ jcr-2.0.jar
	|	+ jettison-1.1.jar
	|	+ joda-time-1.6.jar
	|	+ jsr250-api-1.0.jar
	|	+ junit-dep-4.4.jar
	|	+ lucene-analyzers-3.0.0.jar
	|	+ lucene-core-3.0.0.jar
	|	+ lucene-regex-3.0.0.jar
	|	+ lucene-snowball-3.0.0.jar
	|	+ modeshape-cnd-&versionNumber;.jar
	|	+ modeshape-common-&versionNumber;.jar
	|	+ modeshape-graph-&versionNumber;.jar
	|	+ modeshape-jcr-&versionNumber;.jar
	|	+ modeshape-jcr-api-&versionNumber;.jar
	|	+ modeshape-repository-&versionNumber;.jar
	|	+ modeshape-search-lucene-&versionNumber;.jar
	|	+ modeshape-web-jcr-&versionNumber;.jar
	|	+ modeshape-web-jcr-rest-&versionNumber;.jar
	|	+ resteasy-jaxb-provider-1.2.1.GA.jar
	|	+ resteasy-jaxrs-1.2.1.GA.jar
	|	+ resteasy-jettison-provider-1.2.1.GA.jar
	|	+ scannotation-1.0.2.jar
	|	+ sjsxp-1.0.1.jar
	|	+ slf4j-api-1.6.1.jar
	|	+ slf4j-log4j12-1.6.1.jar
	|	+ slf4j-simple-1.5.8.jar
	|	+ stax-api-1.0-2.jar
	+ web.xml
			
</programlisting>	  	
	  	If you are using sequencers or any connectors other than the in-memory or federated connector, you will also have
	  	to add the JARs for those dependencies into the <code>WEB-INF/lib</code> directory as well.  You will also have to 
	  	change the version numbers on the JARs to reflect the current version of ModeShape. 
	  </para>
	  <note>
		  <para>
			  Your servlet container may already provide a logging system, and you may need to remove the "slf4j-log4j12-1.5.8.jar"
			  and replace with the appropriate <ulink url="&SLF4JManual;">SLF4J binding</ulink> jar. Or, if your servlet container
			  already uses SLF4J globally, you may want to remove all of the "slf4j*.jar" files.
		  </para>
	  </note>
	  <para>
	  	This WAR can be deployed into your servlet container.
	  </para>
	</sect2>

    <sect2 id="modeshape_rest_client_api">
        <title>ModeShape REST Client API</title>
        <para>
            The ModeShape REST Client API provides a POJO way of using the ModeShape REST web service to publish (upload) and 
            unpublish (delete) files from ModeShape repositories. Java objects open the HTTP connection, create the HTTP request URLs, 
            attach the payload associated with <code>PUT</code> and <code>POST</code> requests, parse the HTTP JSON response back 
            into Java objects, and close the HTTP connection.
        </para>
        <para>
            Here are the Java business objects you will need (all found in the <code>org.modeshape.web.jcr.rest.client.domain</code> 
            package):

            <itemizedlist>
                <listitem>
                    <para><code>Server</code> - hosts one or more ModeShape JCR repositories,</para>
                </listitem>
                <listitem>
                    <para><code>Repository</code> - a ModeShape JCR repository containing one or more workspaces, and</para>
                </listitem>
                <listitem>
                    <para><code>Workspace</code> - a ModeShape JCR repository workspace.</para>
                </listitem>
            </itemizedlist>
        </para>
        <para>
            Along with the POJOs above, an <code>org.modeshape.web.jcr.rest.client.IRestClient</code> is needed. The 
            <code>IRestClient</code> is responsible for executing the publishing and unpublishing operations. You can also use the
            <code>IRestClient</code> to find out what repositories and workspaces are available on a ModeShape server.

            <note>
                <para>
                    The only implementation of <code>IRestClient</code> is <code>JsonRestClient</code> as JSON-encoded responses are 
                    all that are currently available.
                </para>
            </note>
                
            Here's a code snippet that publishes (uploads) a file:

            <programlisting><![CDATA[
// Setup POJOs
Server server = new Server("http://localhost:8080", "username", "password");
Repository repository = new Repository("repositoryName", server);
Workspace workspace = new Workspace("workspaceName", repository);

// Publish
File file = new File("/path/to/file");
IRestClient restClient = new JsonRestClient();
Status status = restClient.publish(workspace, "/workspace/path/", file);

if (status.isError() {
    // Handle error here
}
            ]]></programlisting>
        </para>
        <para>
            Successfully executing the above code results in the creation a JCR folder node (<code>nt:folder</code>) for each segment of the 
            workspace path (if the folder didn't already exist). Also, a JCR file node (a node with primary type <code>nt:file</code>) is 
            created or updated under the last folder node and the file contents are encoded and uploaded into a child node of that file node.
        </para>
        </sect2>
    </sect1>
	<sect1 id="jcr_web_spi">
		<title>Repository Providers</title>
		<para>
			Both the ModeShape REST server and the ModeShape WebDAV server can also be used as an interface to to other JCR repositories by creating
			an implementation of the &RepositoryProvider; interface that connects to the other repository.			
		</para>
		<para>
			The &RepositoryProvider; only has a few methods that must be implemented.  When the &ModeShapeJcrDeployer; starts
			up, it will dynamically load the &RepositoryProvider; implementation (as noted above) and call the <code>
			startup(ServletContext)</code> method on the provider.  The provider can use this method to load any
			required configuration parameters from the web configuration (web.xml) and initialize the repository.
		</para>
		<para> 
			As an example, here's the ModeShape JCR provider implementation of this method with exception handling omitted for brevity.
<programlisting><![CDATA[
public void startup( ServletContext context ) {
    String configFile = context.getInitParameter(CONFIG_FILE);

     InputStream configFileInputStream = getClass().getResourceAsStream(configFile);
     jcrEngine = new JcrConfiguration().loadFrom(configFileInputStream).build();
     jcrEngine.start();
}
]]></programlisting>
			As you can see, the name of configuration file for the &JcrEngine; is read from the servlet context and used
			to initialize the engine. 
			Once the repository has been started, it is now ready to accept the main methods that provide the interface
			to the repository.		
		</para>			 
		<para>
  			The first method returns the set of repository names supported by this repository.
<programlisting><![CDATA[
public Set<String> getJcrRepositoryNames() {
    return new HashSet<String>(jcrEngine.getRepositoryNames());
}
]]></programlisting> 
			The ModeShape JCR repository does support multiple repositories on the same server.  Other JCR implementations
			that don't support multiple repositories are free to return a singleton set containing any string from this method.
		</para>
		<para>
			The other required method returns an open JCR &Session; for the user from the current request in a given repository
			and workspace.  The provider can use the &HttpServletRequest; to get the authentication credentials for the 
			HTTP user.
<programlisting><![CDATA[
public Session getSession( HttpServletRequest request,
                           String repositoryName,
                           String workspaceName ) throws RepositoryException {
    Repository repository = getRepository(repositoryName);

	SecurityContext context = new ServletSecurityContext(request);
	Credentials credentials = new SecurityContextCredentials(context);
    return repository.login(credentials, workspaceName);
}
]]></programlisting>
			The <code>getSession(...)</code> method is used by most of the REST server methods to access the JCR 
			repository and return results as needed.			
		</para>
		<para>
			Finally, the <code>shutdown()</code> method signals that the web context is being undeployed and the JCR
			repository should shutdown and clean up any resources that are in use.
		</para>
	</sect1>
	<sect1>
		<title>Summary</title>
		<para>
			This chapter has described two ways to access a ModeShape JCR repository remotely through HTTP-based protocols.  In the 
			<link linkend="provided-connectors-part">next chapter</link>,
			the different repository connectors will be described so that you can start to use ModeShape to store new data, connect
			to existing data through JCR, or both.
		</para>
	</sect1>	
</chapter>

