You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bu...@apache.org on 2012/12/12 10:17:17 UTC

svn commit: r841833 [17/28] - in /websites/staging/sling/trunk/content: ./ site/ site/46-line-blog.data/ site/authentication.data/ site/documentation.data/ site/first-steps.data/ site/getting-and-building-sling.data/ site/how-to-manage-events-in-sling....

Added: websites/staging/sling/trunk/content/site/manipulating-content-the-slingpostservlet.html
==============================================================================
--- websites/staging/sling/trunk/content/site/manipulating-content-the-slingpostservlet.html (added)
+++ websites/staging/sling/trunk/content/site/manipulating-content-the-slingpostservlet.html Wed Dec 12 09:16:44 2012
@@ -0,0 +1,917 @@
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<HTML>
+  <HEAD>
+    <TITLE>Apache Sling - Manipulating Content - The SlingPostServlet</TITLE>
+    <LINK rel="stylesheet" href="http://incubator.apache.org/sling/site/media.data/site.css" type="text/css" media="all">
+    <LINK rel="icon" href="http://incubator.apache.org/sling/site/media.data/favicon.ico">
+    <META http-equiv="Content-Type" content="text/html;charset=UTF-8">
+  </HEAD>
+  <BODY>
+    <DIV class="title">
+      <DIV class="logo">
+        <A href="http://incubator.apache.org/sling/site/index.html">
+          <IMG border="0" alt="Apache Sling" src="http://incubator.apache.org/sling/site/media.data/logo.png">
+        </A>
+      </DIV>
+      <DIV class="header">
+        <A href="http://incubator.apache.org/">
+          <IMG border="0" alt="Apache Incubator" src="http://incubator.apache.org/images/apache-incubator-logo.png">
+        </A>
+      </DIV>
+    </DIV>
+    <DIV class="menu">
+                                    <P style="display: none"></P>
+
+<UL>
+	<LI><A href="documentation.html" title="Documentation">Documentation</A></LI>
+	<LI><A href="advanced-topics.html" title="Advanced Topics">Advanced Topics</A></LI>
+	<LI><A href="development.html" title="Development">Development</A></LI>
+	<LI><SPAN class="nobr"><A href="http://incubator.apache.org/sling/site/downloads.cgi" title="Visit page outside Confluence" rel="nofollow">Downloads<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN></LI>
+	<LI><A href="contributing.html" title="Contributing">Contributing</A></LI>
+	<LI><A href="links.html" title="Links">Links</A></LI>
+	<LI><SPAN class="nobr"><A href="http://cwiki.apache.org/SLING/faq.html" title="Visit page outside Confluence" rel="nofollow">FAQ<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN></LI>
+	<LI><SPAN class="nobr"><A href="http://cwiki.apache.org/SLING/" title="Visit page outside Confluence" rel="nofollow">Wiki<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN></LI>
+	<LI><A href="project-information.html" title="Project Information">Project Information</A></LI>
+	<LI><SPAN class="nobr"><A href="http://incubator.apache.org/sling/apidocs/sling5/index.html" title="Visit page outside Confluence" rel="nofollow">Sling 5 API<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN></LI>
+	<LI><SPAN class="nobr"><A href="http://www.apache.org/foundation/thanks.html" title="Visit page outside Confluence" rel="nofollow">Sponsors<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN></LI>
+	<LI><SPAN class="nobr"><A href="http://www.apache.org/foundation/sponsorship.html" title="Visit page outside Confluence" rel="nofollow">Sponsorship<SUP><IMG class="rendericon" src="http://cwiki.apache.org/confluence/images/icons/linkext7.gif" height="7" width="7" align="absmiddle" alt="" border="0"></SUP></A></SPAN>
+
+<IFRAME src="http://www.apache.org/ads/button.html" style="border-width:0; float: left" frameborder="0" scrolling="no" width="135" height="135"></IFRAME>
+<P style="height: 100px"></P>
+</LI>
+</UL>
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        </DIV>
+    <DIV class="main">
+        <DIV class="breadcrump" style="font-size: 80%;">
+<A href="apache-sling.html" title="Apache Sling Website">Apache Sling Website</A>&nbsp;&gt;&nbsp;<A href="apache-sling.html" title="Apache Sling">Apache Sling</A>&nbsp;&gt;&nbsp;<A href="advanced-topics.html" title="Advanced Topics">Advanced Topics</A>&nbsp;&gt;&nbsp;<A href="" title="Manipulating Content - The SlingPostServlet">Manipulating Content - The SlingPostServlet</A>
+        </DIV>
+<H1><A name="ManipulatingContent-TheSlingPostServlet-ManipulatingContent%3ATheSlingPostServlet"></A>Manipulating Content: The SlingPostServlet</H1>
+
+
+<DIV>
+<UL>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-MultipleWaystoModifyContent">Multiple Ways to Modify Content</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-Quickstart%253ACreatingContent">Quickstart: Creating Content</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-SlingPostServletOperations">SlingPostServlet Operations</A>
+<UL>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-ContentCreationorModification">Content Creation or Modification</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-ContentRemoval">Content Removal</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-CopyingContent">Copying Content</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-MovingContent">Moving Content</A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-NullOperation">Null Operation</A></LI>
+</UL></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-SpecialParameters">Special Parameters</A>
+<UL>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Aorder%257D%257D"><TT>:order</TT></A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Aredirect%257D%257D"><TT>:redirect</TT></A></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Astatus%257D%257D"><TT>:status</TT></A></LI>
+</UL></LI>
+  <LI><A href="#ManipulatingContent-TheSlingPostServlet-AdvancedTopic%253AExtendingtheSlingPostServlet">Advanced Topic: Extending the SlingPostServlet</A></LI>
+</UL></DIV>
+
+
+
+<H2><A name="ManipulatingContent-TheSlingPostServlet-MultipleWaystoModifyContent"></A>Multiple Ways to Modify Content</H2>
+
+<P>As always in life there is more than one way to do it. So to modify content in a JCR repository underlying Sling, you have multiple options, two of which are WebDAV and the Sling default POST Servlet also called the <EM>SlingPostServlet</EM>. This page is about how you can modify - create, modify, copy, move, delete - content through the <EM>SlingPostServlet</EM>. In addition it also explains how to extend the SlingPostServlet with new operations.</P>
+
+
+<P>What is Content anyway ? In the following discussion, I use the terms <EM>Content</EM> and <EM>Item</EM> interchangeably. With <EM>Content</EM> I just mean some data to be stored in the JCR repository to be later used as the basis for some presentation. In this sense <EM>Content</EM> is a rather conceptual term. <EM>Item</EM> is the name of the parent interface of the JCR <EM>Node</EM> and <EM>Property</EM> interfaces. When speaking of <EM>Items</EM> we mean some actual data stored in the repository ignoring whether the data is actually stored as a <EM>Node</EM> with child nodes and properties or just a single <EM>Property</EM>.</P>
+
+
+<H2><A name="ManipulatingContent-TheSlingPostServlet-Quickstart%3ACreatingContent"></A>Quickstart: Creating Content</H2>
+
+<P>To create content you simply send an HTTP POST request using the path of the node to store the content in and include the actual content as request parameters. So one possibility to do just that is by having an HTML Form like the following:</P>
+
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-java">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;http:<SPAN class="code-comment">//host/some/<SPAN class="code-keyword">new</SPAN>/content&quot;</SPAN> &gt;
+</SPAN>   &lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;title&quot;</SPAN> value=&quot;&quot; /&gt;
+   &lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;text&quot;</SPAN> value=&quot;&quot; /&gt;
+&lt;/form&gt;</PRE>
+</DIV></DIV>
+
+
+<P>This simple form will set the <TT>title</TT> and <TT>text</TT> properties on a node at <TT>/some/new/content</TT>. If this node does not exist it is just created otherwise the existing content would be modified.</P>
+
+<P>Similarly you can do this using the <TT>curl</TT> command line tool:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -Ftitle=&quot;some title text&quot; -Ftext=&quot;some body text content&quot; http://host/some/new/content
+</PRE>
+</DIV></DIV>
+
+
+<P>You might want to use a specific JCR node type for a newly created node. This is possibly by simply setting a <TT>jcr:primaryType</TT> property on the request, e.g.</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;jcr:primaryType=nt:unstructured&quot; -Ftitle=&quot;some title text&quot; -Ftext=&quot;some body text content&quot; http://host/some/new/content
+</PRE>
+</DIV></DIV>
+
+<P>Similary you may assing JCR mixin node types using the <TT>jcr:mixinTypes</TT> property and a Sling resource type using the <TT>sling:resourceType</TT> property. For example:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;sling:resourceType=sling:sample&quot; -Ftitle=&quot;some title text&quot; -Ftext=&quot;some body text content&quot; http://host/some/new/content
+</PRE>
+</DIV></DIV>
+
+
+
+
+<H2><A name="ManipulatingContent-TheSlingPostServlet-SlingPostServletOperations"></A>SlingPostServlet Operations</H2>
+
+
+<P>The SlingPostServlet is actually just a frontend to the actual operations. To select the actual operation to execute, the <TT>:operation</TT> request parameter is used. Out of the box, the SlingPostServlet supports the following operations:</P>
+
+<UL>
+	<LI>property not set or empty &ndash; Create new content or modify existing content</LI>
+	<LI><TT>delete</TT> &ndash; Remove existing content</LI>
+	<LI><TT>move</TT> &ndash; Move existing content to a new location</LI>
+	<LI><TT>copy</TT> &ndash; Copy existing content to a new location</LI>
+	<LI><TT>nop</TT> &ndash; Explicitly requests to do nothing and just sets the response status</LI>
+</UL>
+
+
+<P>All these operations always operate on the resource of the request as returned by <TT>SlingHttpServletRequest.getResource()</TT>. Some operations require additional parameters to be set to operate completely.</P>
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-ContentCreationorModification"></A>Content Creation or Modification</H3>
+
+
+<P>The simplest and most common use case, probably, is content creation and modification. We already saw an example above in the quickstart section. In this section we elaborate more on the concrete stuff.</P>
+
+<P>First, the request URL indicates the actual repository node to be handled. If the URL addresses an existing node, the request parameters just provide values for the properties to be set on the existing node.</P>
+
+<P>If the resource of the request is a synthetic resource, e.g. <TT>NonExistingResource</TT> or <TT>StarResource</TT>, a new item is created. The path (including name) of the item to be created is derived from the resource path:</P>
+
+<UL>
+	<LI>If the resource path ends with a <TT>/*</TT> or <TT>/</TT> the name of the item is automatically created using a name creation algorithm taking into account various request parameters.</LI>
+	<LI>Otherwise the resource path is used as the path and name of the new item.</LI>
+</UL>
+
+
+<P>In both cases the path may still include selectors and extensions, which are cut off the path before finding out, what to do.</P>
+
+<P>To illustrate this algorithm, lets look at some examples:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Resource Path </TH>
+<TH class="confluenceTh"> Item path </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/new</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/new</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/new.html</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/new</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/new.print.a4.html</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/new</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/xxx</TT> where <TT>xxx</TT> is a generated name </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/*</TT></TD>
+<TD class="confluenceTd"> <TT>/content/xxx</TT> where <TT>xxx</TT> is a generated name </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/*.html</TT></TD>
+<TD class="confluenceTd"> <TT>/content/xxx</TT> where <TT>xxx</TT> is a generated name </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/*.print.a4.html</TT></TD>
+<TD class="confluenceTd"> <TT>/content/xxx</TT> where <TT>xxx</TT> is a generated name </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-SettingPropertyValues"></A>Setting Property Values</H5>
+
+<P>Setting property values is as simple as just adding a request parameter whose name is the name of the property to be set and whose value is the value to be assigned to the property. We already saw how to do this in the quick start examples above.</P>
+
+<P>Here is another example show a simple HTML form to create a new node with an automatically created name:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;title&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>If this form is submitted with <EM>title</EM> and <EM>This is some Text</EM> as values for the <TT>title</TT> and <TT>text</TT> fields, resp., a new node is created at the path <TT>/content/page/first</TT> and the <TT>title</TT> and <TT>text</TT> properties set to the respective field values. If a node at <TT>/content/page/first</TT> already existed before submitting the form, the <TT>title</TT> and <TT>text</TT> properties are just updated to the new values from the form fields.</P>
+
+<P>If a parameter has multiple values, the respective property will be created as a multi-value property. So for example the command line:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -Fmulti=one -Fmulti=two http://host/content/page
+</PRE>
+</DIV></DIV>
+
+<P>Would assign the <TT>/content/page/multi</TT> property the value <EM>[ &quot;one&quot;, &quot;two&quot; ]</EM>.</P>
+
+<P>This is pretty much all there is to know about creating and modifying content. The following sections will now introduce more functionality which help you with more fine-grained control in your content management application.</P>
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-FileUploads"></A>File Uploads</H5>
+
+<P>File uploads are typically done using the <TT>&lt;input type=&quot;file&quot;&quot;/&gt;</TT> element of an HTML form and ensuring the correct form encoding. The SlingPostServlet handles uploaded files specially, in that the file data is not simply written into a property, but a node is actually created with three properties:</P>
+
+<UL>
+	<LI><TT>jcr:data</TT> &ndash; The actual file contents</LI>
+	<LI><TT>jcr:lastModified</TT> &ndash; The time stamp of processing the uploaded file</LI>
+	<LI><TT>jcr:mimeType</TT> &ndash; The MIME type from the original file submission (if contained in the file body part) or derived from the original file name</LI>
+</UL>
+
+
+<P>The name of the node is either taken from the parameter name or if the name is <TT>*</TT> from the name of the uploaded file.</P>
+
+<P>The primary node type of the uploaded file is selected using the following algorithm:</P>
+
+<OL>
+	<LI>If a <TT>@TypeHint</TT> suffixed parameter (see below for a description) is present check whether the value is a known non-mixin node type. If so, the node is created with this primary node type.</LI>
+	<LI>If a <TT>@TypeHint</TT> suffixed parameter is not present or the value does not denote an existing non-mixin node type, the node will be created as an <TT>nt:file</TT> node if the parent node is of type <TT>nt:folder</TT>. Otherwise the node will be created with primary node type <TT>nt:resource</TT>.</LI>
+</OL>
+
+
+<P>If the node to be created is <TT>nt:file</TT>, the actual file data will really be stored in the <TT>jcr:content</TT> child node of the new <TT>nt:file</TT> node whose primary node type is then set as <TT>nt:resource</TT>.</P>
+
+<P>Example 1: Upload an image to a node named <TT>image</TT> below <TT>/content/page</TT>:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page&quot;</SPAN> enctype=<SPAN class="code-quote">&quot;multipart/form-data&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;file&quot;</SPAN> name=<SPAN class="code-quote">&quot;image&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+
+<P>Example 2: Upload a file as a node of type <TT>nt:file</TT> below <TT>/content/folder</TT>:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page&quot;</SPAN> enctype=<SPAN class="code-quote">&quot;multipart/form-data&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;file&quot;</SPAN> name=<SPAN class="code-quote">&quot;*&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;*@TypeHint&quot;</SPAN> value=<SPAN class="code-quote">&quot;nt:file&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>Assuming the user selected a file named <TT>myImage.jpg</TT> the uploaded file would be stored in an <TT>nt:file</TT> node at <TT>/content/folder/myImage.jpg</TT>.</P>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-OmittingSomeParameters"></A>Omitting Some Parameters</H5>
+
+<P>There may be times, that you have forms which contain a lot of fields, which you do not want to actually store in content. Such forms usually are created using some client-side GUI library which uses the fields for its own purposes. To be able to easily differentiate between real content to be actually stored and such control parameters, you may prefix the names of the fields destined for content with a dot-slash (<TT>./</TT>).</P>
+
+<P>As soon as the SlingPostServlet encounters parameters prefixed with dot-slash, only those parameters are considered for content updates while all other parameters not prefixed are just ignored. In addition to dot-slash prefixed parameters, also parameters prefixed with dot-dot-slash (<TT>../</TT>) and slash (<TT>/</TT>) are considered in this situation.</P>
+
+<P>For example, the following form only uses the first two fields for content update and ignores the rest:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;./title&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;../first/text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;control0&quot;</SPAN> /&gt;</SPAN><SPAN class="code-tag"><SPAN class="code-comment">&lt;!-- ignored --&gt;</SPAN></SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;control1&quot;</SPAN> /&gt;</SPAN><SPAN class="code-tag"><SPAN class="code-comment">&lt;!-- ignored --&gt;</SPAN></SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>Because the SlingPostServlet encounters the <TT>./title</TT> parameter, only parameters prefixed with dot-slash, dot-dot-slash and slash are considered for content update. In this case this would <TT>./title</TT> and <TT>../first/text</TT> while <TT>control0</TT> and <TT>control1</TT> are not prefixed and thus ignored.</P>
+
+<P>Background: The name of the parameters used for content update are actually intended to be relative path names of the properties to modify. So in effect using the field name <TT>text</TT> is equivalent to <TT>./text</TT> &ndash; dot-slash meaning relative to the current node identified by the <TT>action</TT> attribute value for <TT>form</TT> tag &ndash; or <TT>../first/text</TT> if <TT>first</TT> is the name of the node to modify &ndash; dot-dot-slash meaning relative to the parent node of the node identified by the <TT>action</TT> attribute value of the <TT>form</TT> tag.</P>
+
+<P>Parameters whose name start with a colon (<TT>:</TT>) are always ignored by the SlingPostServlet with respect to content update. The reason is that the prefixing colon is intended as a marker for SlingPostServlet control parameters.</P>
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-ControllingContentUpdateswith%7B%7B@%7D%7DSuffixes"></A>Controlling Content Updates with <TT>@</TT> Suffixes</H5>
+
+<P>Generally just creating forms with parameters and their values suffices it completely. Sometimes, though, you want to have more control on how the parameter values are actually stored in the properties. For example, you want to set a property to a default value if the user did provide an actual value. Or you might want to store a parameter explicitly with a given data type, such as numeric, boolean etc.</P>
+
+<P>The SlingPostServlet provides such property control in the form of <TT>@</TT> suffixed parameters, which are now presented.</P>
+
+<P>The <TT>@</TT> suffixed parameters are not used on their own but always in conjunction with a plain parameter. The part of the parameter name before the <TT>@</TT> suffix is used in this case for correlation and must match exactly the name of the parameter to which the <TT>@</TT> suffixed parameter belongs.</P>
+
+<P>For example, the parameter <TT>width@TypeHint</TT> applies to the <TT>width</TT> parameter and the <TT>./height@TypeHint</TT> parameter applies to the <TT>./height</TT> parameter. As can be seen, the correlation between the parameters is a simple case-sensitive string comparison. That is the <TT>widht@TypeHint</TT> parameter would not apply to the <TT>./width</TT> even though both parameters address the same property but they do not have a string match.</P>
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@TypeHint%7D%7D"></A><TT>@TypeHint</TT></H6>
+
+<P>Parameters with the <TT>@TypeHint</TT> suffix may be used to force storing the named parameter in a property with the given type. The value of the <TT>@TypeHint</TT> parameter, if applied to a parameter for a property, is the JCR property type name. If the <TT>@TypeHint</TT> parameter is applied to a field upload parameter, the value is used to indicate the JCR primary node type for the node into which the uploaded file is stored.</P>
+
+<P>If the <TT>@TypeHint</TT> ends with &quot;[]&quot;, it indicates a multi-value property. A multi-value property is usually auto-detected if there are mutliple values for the property (ie. request parameter). But if only a single value is present in the request, the desired property type needs to be explicitly defined as multi-value by stating <TT>@TypeHint=&lt;type&gt;[]</TT>.</P>
+
+<P>Example: The following form sets the numeric <TT>width</TT>, the boolean <TT>checked</TT>, and the multi-valued <TT>hobbys</TT> (with 3 values to enter) properties:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;width&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;width@TypeHint&quot;</SPAN> value=<SPAN class="code-quote">&quot;Long&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;checkbox&quot;</SPAN> name=<SPAN class="code-quote">&quot;checked&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;checked@TypeHint&quot;</SPAN> value=<SPAN class="code-quote">&quot;Boolean&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;hobbys&quot;</SPAN>/&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;hobbys&quot;</SPAN>/&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;hobbys&quot;</SPAN>/&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;hobbys@TypeHint&quot;</SPAN> value=<SPAN class="code-quote">&quot;String[]&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>In real applications you would need some javascript that allows to add/remove values, ie. add/remove inputs with the name &quot;hobbys&quot;. Or a pure javascript based form post would be used, that gathers the properties to update programmatically, but the additional parameter <TT>hobbys@TypeHint=String[]</TT> would be the same.</P>
+
+<P>The <TT>@TypeHint</TT> suffixed parameter is assumed to be single-valued. If the parameter has multiple values, only the first is actually used.</P>
+
+<P>For more information on applying <TT>@TypeHint</TT> to a file upload parameter see the section on File Uploads above.</P>
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@DefaultValue%7D%7D"></A><TT>@DefaultValue</TT></H6>
+
+
+<P>The <TT>@DefaultValue</TT> suffixed parameter may be provided to set a property to a default value should no value be provided in the actual parameters. Same as for normal paramaters, the <TT>@DefaultValue</TT> parameter may have multiple values to create multi-valued properties.</P>
+
+<P>Example: Set the <TT>text</TT> property to a default value if the user does not provide one:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;text@DefaultValue&quot;</SPAN> value=<SPAN class="code-quote">&quot;--- Default Value ---&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@ValueFrom%7D%7D"></A><TT>@ValueFrom</TT></H6>
+
+<P>In some situations, an HTML form with parameters may be reused to update content. But one or more form parameters may not comply with the names expected to be used for properties. In this case a parameter suffixed with <TT>@ValueFrom</TT> may be set containing the name of the parameter providing the actual data to be used.</P>
+
+<P>Example: To set the property <TT>text</TT> from a form element <TT>supplied_text</TT>, you might use the following form:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;supplied_text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;./text@ValueFrom&quot;</SPAN> value=<SPAN class="code-quote">&quot;supplied_text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>To prevent storing the additional paramaters in the repository you might want to use the prefixing mechanism as shown in the example above, where the <TT>@ValueFrom</TT> parameter is prefixed and thus the <TT>supplied_text</TT> parameter is not used for property setting.</P>
+
+<P>The <TT>@ValueFrom</TT> suffixed parameter is assumed to be single-valued. If the parameter has multiple values it is ignored completely.</P>
+
+<P>The <TT>@ValueFrom</TT> suffixed parameter is also special in that there must not be a correlated parameter without a suffix. Thus have parameters <TT>text</TT> and <TT>text@ValueFrom</TT> may have unexpected results.</P>
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@Delete%7D%7D"></A><TT>@Delete</TT></H6>
+
+<P>Sometimes it may be required to not set a property to a specific value but to just remove it while processing the content update request. One such situation is a property filled from one or more checkboxes in an HTML form. If none of the checkboxes are checked, no parameter is actually submitted for these checkboxes. Hence the SlingPostServlet will not touch this property and effectively leave it untouched, while the natural reaction would have been to remove the property.</P>
+
+<P>Here comes the <TT>@Delete</TT> suffixed parameter. This simply causes the indicated property be removed if it exists. If the property does not exist, nothing more happens. The actual value of the <TT>@Delete</TT> suffixed parameter does not care as long as the parameter is submitted.</P>
+
+<P>Example: To ensure the <TT>color</TT> property is actually removed if no color has been selected, you might use the following form:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/first&quot;</SPAN>&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;checkbox&quot;</SPAN> name=<SPAN class="code-quote">&quot;color&quot;</SPAN> value=<SPAN class="code-quote">&quot;red&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;checkbox&quot;</SPAN> name=<SPAN class="code-quote">&quot;color&quot;</SPAN> value=<SPAN class="code-quote">&quot;green&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;checkbox&quot;</SPAN> name=<SPAN class="code-quote">&quot;color&quot;</SPAN> value=<SPAN class="code-quote">&quot;blue&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;color@Delete&quot;</SPAN> value=<SPAN class="code-quote">&quot;delete text&quot;</SPAN> /&gt;</SPAN><SPAN class="code-tag"><SPAN class="code-comment">&lt;!-- actual value is ignored --&gt;</SPAN></SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+
+<P>The <TT>@Delete</TT> suffixed parameter is also special in that there need not be a correlated parameter without a suffix. If both &ndash; a parameters <TT>text</TT> and <TT>text@Delete</TT> are set, the <TT>text</TT> property is first deleted and then filled with the new content.</P>
+
+<P>The <TT>@Delete</TT> suffixed parameter in fact calls for a sub-operation, which is executed after the node addressed by the request URL is created (if needed) but before any other tasks of content creattion and modification are done. Any item &ndash; this may be a property or a node, actually &ndash; addressed by the <TT>@Delete</TT> suffixed parameter is just removed if it exists. If the item does not exist, nothing happens.</P>
+
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@MoveFrom%7D%7D"></A><TT>@MoveFrom</TT></H6>
+
+<P>Now, that your bright and shiny content management application has great Flash-based file upload feature you will want to be able to use the pre-uploaded files for your content with the same request as when you upload other content. For example you might have a node storing some text and an illustration you uploaded as an image file.</P>
+
+<P>To support this kind of functionality, the <TT>@MoveFrom</TT> suffixed parameter may be set to the repository path of the node to where you uploaded the image file.</P>
+
+<P>Example: Your Flash-based file upload stored the file on the server at <TT>/tmp/upload/123</TT>. You now want to store this file along with a title and a text in a newly created node. The following form will be your friend:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/&quot;</SPAN>&gt;</SPAN><SPAN class="code-tag"><SPAN class="code-comment">&lt;!-- trailing slash generates a name for the new node --&gt;</SPAN></SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;image@MoveFrom&quot;</SPAN> value=<SPAN class="code-quote">&quot;/tmp/upload/123&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;title&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>If there exists no repository item at the indicated path, nothing is done. If the item indicated by the <TT>@MoveFrom</TT> suffixed parameter already exists, it is replaced by the item addressed by the parameter value &ndash; unless of course there is no item at the named location.</P>
+
+<P>The <TT>@MoveFrom</TT> suffixed parameter is assumed to be single-valued. If the parameter has multiple values it is ignored completely.</P>
+
+<P>The <TT>@MoveFrom</TT> suffixed parameter is also special in that there must not be a correlated parameter without a suffix. Thus have parameters <TT>text</TT> and <TT>text@MoveFrom</TT> may have unexpected results.</P>
+
+<P>The <TT>@MoveFrom</TT> suffixed parameter in fact calls for a sub-operation, which is executed after the <TT>@Delete</TT> sub operation but before any other tasks of content creattion and modification are done.</P>
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B@CopyFrom%7D%7D"></A><TT>@CopyFrom</TT></H6>
+
+<P>Similar to the <TT>@MoveFrom</TT> suffix exists a <TT>@CopyFrom</TT> suffix. The latter works exactly the same as the former except that the item addressed by the parameter value is not moved but just copied.</P>
+
+<P>Example: Your Flash-based file upload stored the file on the server at <TT>/tmp/upload/123</TT>. You now want to store this file along with a title and a text in a newly created node. The following form may be your friend:</P>
+
+<DIV class="code"><DIV class="codeContent">
+<PRE class="code-html"><SPAN class="code-tag">&lt;form method=<SPAN class="code-quote">&quot;POST&quot;</SPAN> action=<SPAN class="code-quote">&quot;/content/page/&quot;</SPAN>&gt;</SPAN><SPAN class="code-tag"><SPAN class="code-comment">&lt;!-- trailing slash generates a name for the new node --&gt;</SPAN></SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;hidden&quot;</SPAN> name=<SPAN class="code-quote">&quot;image@CopyFrom&quot;</SPAN> value=<SPAN class="code-quote">&quot;/tmp/upload/123&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;title&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;text&quot;</SPAN> name=<SPAN class="code-quote">&quot;text&quot;</SPAN> /&gt;</SPAN>
+    <SPAN class="code-tag">&lt;input type=<SPAN class="code-quote">&quot;Submit&quot;</SPAN> /&gt;</SPAN>
+<SPAN class="code-tag">&lt;/form&gt;</SPAN></PRE>
+</DIV></DIV>
+
+<P>If there exists no repository item at the indicated path, nothing is done. If the item indicated by the <TT>@CopyFrom</TT> suffixed parameter already exists, it is replaced by the item addressed by the parameter value &ndash; unless of course there is no item at the named location.</P>
+
+<P>The <TT>@CopyFrom</TT> suffixed parameter is assumed to be single-valued. If the parameter has multiple values it is ignored completely.</P>
+
+<P>The <TT>@CopyFrom</TT> suffixed parameter is also special in that there must not be a correlated parameter without a suffix. Thus have parameters <TT>text</TT> and <TT>text@CopyFrom</TT> may have unexpected results.</P>
+
+<P>The <TT>@CopyFrom</TT> suffixed parameter in fact calls for a sub-operation, which is executed after the <TT>@MoveFrom</TT> sub operation but before any other tasks of content creattion and modification are done.</P>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-AlgorithmforNodeNameCreation"></A>Algorithm for Node Name Creation</H5>
+
+<P>If request is posted with an URL ending in slash <TT>/</TT> or slash-star <TT>/*</TT>, the SlingPostServlet derives a name for the node to be created upon the request applying the following algorithm:</P>
+
+
+<OL>
+	<LI>If a <TT>:name</TT> parameter is supplied, the (first) value of this parameter is used unmodified as the name for the new node. If the name is illegally formed with respect to JCR name requirements, an exception will be thrown when trying to create the node. The assumption with the <TT>:name</TT> parameter is, that the caller knows what he (or she) is supplying and should get the exact result if possible.</LI>
+	<LI>Otherwise if a <TT>:nameHint</TT> parameter is supplied, the (first) value of this parameter is used to generate the node name. A name filtering is applied to this hint to ensure a valid JCR node name.</LI>
+	<LI>Otherwise a series of request paramaters supplied to set content is inspected for a possible name. The list of the names of these parameter is configurable with the SlingPostServlet and defaults ot <TT>[ title, jcr:title, name, description, jcr:description, abstract ]</TT>. The first request parameter with a non-empty value is used and filtered to get the valid JCR name.</LI>
+	<LI>Otherwise an ever increasing auto generated number is used. Filtering is also applied to this numeric name.</LI>
+</OL>
+
+
+
+<P>The filtering algorithm to create a valid name of the hints from above steps (except the first) works as follows:</P>
+
+<UL>
+	<LI>Convert the proposed name to all lower case.</LI>
+	<LI>Replace all characters not in the range [0..9a..z_] by a single underscore <TT>&#95;</TT>.</LI>
+	<LI>If the name starts with a digit prepend an underscore. Technically names with leading digits are valid, but they present major issues when using such names in JCR XPath expressions. The algorithm takes care to not create names with two or more consecutive underscore characters.</LI>
+	<LI>Finally the name is cut to a configurable maximum length (default is 20 characters).</LI>
+</UL>
+
+
+
+<P>For example the <TT>:nameHint</TT> value <EM>A quick brown Fox ...</EM> is filtered to become <EM>a&#95;quick&#95;brown&#95;fox&#95;</EM></P>
+
+<P>After generating and filtering the name it is further guaranteed that the name is unique: If a node of the same name as just generated from the algorithm already exists below the same parent node a numeric index is appended to the new node name to make it unique.</P>
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H5>
+
+<P>The modification operation has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> An existing node has been updated with content </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 201/CREATED </TD>
+<TD class="confluenceTd"> A new node has been created and filled with content </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request </TD>
+</TR>
+</TBODY></TABLE>
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-ContentRemoval"></A>Content Removal</H3>
+
+<P>To remove existing content just address the item to be removed and set the <TT>:operation</TT> parameter to <TT>delete</TT>. For example the following command line removes the <TT>/content/sample</TT> page:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:operation=delete&quot; http://host/content/sample
+</PRE>
+</DIV></DIV>
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H5>
+
+<P>The delete operation has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> The resource (and all its descendents) has been removed </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 404/NOT FOUND </TD>
+<TD class="confluenceTd"> The request URL does not address an existing repository item </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-DeletingMultipleItems"></A>Deleting Multiple Items</H5>
+
+<P>By using the <TT>:applyTo</TT> request parameter it is possible to remove multiple items in one single request. Deleting items in this way leaves you with less control, though. In addition, if a single item removal fails, no item at all is removed.</P>
+
+<P>When specifying the item(s) to be removed with the <TT>:applyTo</TT> parameter, the request resource is left untouched (unless of course if listed in the <TT>:applyTo</TT> parameter) and only used to resolve any relative paths in the <TT>:applyTo</TT> parameter.</P>
+
+<P>To for example remove the <TT>/content/page1</TT> and <TT>/content/page2</TT> nodes, you might use the following command line:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:operation=delete&quot; -F&quot;:applyTo=/content/page1&quot; -F&quot;:applyTo=/content/page2&quot; http://host/content/sample
+</PRE>
+</DIV></DIV>
+
+<P>If any resource listed in the <TT>:applyTo</TT> parameter does not exist, it is silently ignored.</P>
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H6>
+
+<P>The delete operation applied to multiple resources has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> All requested and existing resources have been removed </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-CopyingContent"></A>Copying Content</H3>
+
+
+<P>To copy existing content to a new location, the <TT>copy</TT> operation is specified. This operation copies the item addressed by the request URL to a new location indicated by the <TT>:dest</TT> parameter. The <TT>:dest</TT> parameter is the absolute or relative path to which the resource is copied. If the path is relative it is assumed to be below the same parent as the request resource. If it is terminated with a <TT>/</TT> character the request resource is copied to an item of the same name under the destination path.</P>
+
+<P>To illustrate the <TT>:dest</TT> parameter handling, lets look at a few examples. All examples are based on addressing the <TT>/content/sample</TT> item:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> <TT>:dest</TT> Parameter </TH>
+<TH class="confluenceTh"> Destination Absolute Path </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/newSample</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/newSample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>different/newSample</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/newSample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/different/</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/sample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>different/</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/sample</TT> </TD>
+</TR>
+</TBODY></TABLE>
+
+
+<P>If an item already exists at the location derived from the <TT>:dest</TT> parameter, the copy operation fails unless the <TT>:replace</TT> parameter is set to <TT>true</TT> (case is ignored when checking the parameter value).</P>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H5>
+
+<P>The copy operation has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> The node has been copied to the new location replacing an existing item at the destination </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 201/CREATED </TD>
+<TD class="confluenceTd"> The node has been copied to the new location creating a new item at the destination </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 412/PRECONDITION FAILED </TD>
+<TD class="confluenceTd"> An item already exists at the destination and the <TT>:replace</TT> parameter is not set to <TT>true</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-CopyingMultipleItems"></A>Copying Multiple Items</H5>
+
+<P>By using the <TT>:applyTo</TT> request parameter it is possible to copy multiple items in one single request. Copying items in this way leaves you with less control, though. In addition, if a single item copy fails, no item at all is copied.</P>
+
+<P>When specifying the item(s) to be copied with the <TT>:applyTo</TT> parameter, the request resource is left untouched (unless of course if listed in the <TT>:applyTo</TT> parameter) and only used to resolve any relative paths in the <TT>:applyTo</TT> parameter.</P>
+
+<P>To for example copy the <TT>/content/page1</TT> and <TT>/content/page2</TT> nodes to <TT>/content/target</TT>, you might use the following command line:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:operation=copy&quot; -F&quot;:applyTo=/content/page1&quot; -F&quot;:applyTo=/content/page2&quot; -F&quot;:dest=/content/target/&quot; http://host/content/sample
+</PRE>
+</DIV></DIV>
+
+<P>Please note the trailing slash character (<TT>/</TT>) in the value of the <TT>:dest</TT> parameter. This is required for mult-item copy operations using the <TT>:applyTo</TT> parameter. The copied items are created below the node indicated by the <TT>:dest</TT>.</P>
+
+<P>If any resource listed in the <TT>:applyTo</TT> parameter does not exist, it is silently ignored. Any item already existing at the copy destination whose name is the same as the name of an item to be copied is silently overwritten with the source item.</P>
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H6>
+
+<P>The copy operation applied to multiple resources has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> All requested and existing resources have been copied </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 412/PRECONDITION FAILED </TD>
+<TD class="confluenceTd"> The node indicated by the <TT>:dest</TT> parameter does not exist </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request. This status is also set if the <TT>:dest</TT> parameter value does not have a trailing slash character. </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-MovingContent"></A>Moving Content</H3>
+
+
+<P>To move existing content to a new location, the <TT>move</TT> operation is specified. This operation moves the item addressed by the request URL to a new location indicated by the <TT>:dest</TT> parameter. The <TT>:dest</TT> parameter is the absolute or relative path to which the resource is moved. If the path is relative it is assumed to be below the same parent as the request resource. If it is terminated with a <TT>/</TT> character the request resource is moved to an item of the same name under the destination path.</P>
+
+<P>To illustrate the <TT>:dest</TT> parameter handling, lets look at a few examples. All examples are based on addressing the <TT>/content/sample</TT> item:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> <TT>:dest</TT> Parameter </TH>
+<TH class="confluenceTh"> Destination Absolute Path </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/newSample</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/newSample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>different/newSample</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/newSample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>/content/different/</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/sample</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>different/</TT> </TD>
+<TD class="confluenceTd"> <TT>/content/different/sample</TT> </TD>
+</TR>
+</TBODY></TABLE>
+
+
+<P>If an item already exists at the location derived from the <TT>:dest</TT> parameter, the move operation fails unless the <TT>:replace</TT> parameter is set to <TT>true</TT> (case is ignored when checking the parameter value).</P>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H5>
+
+<P>The move operation has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> The node has been moved to the new location replacing an existing item at the destination </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 201/CREATED </TD>
+<TD class="confluenceTd"> The node has been moved to the new location creating a new item at the destination </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 412/PRECONDITION FAILED </TD>
+<TD class="confluenceTd"> An item already exists at the destination and the <TT>:replace</TT> parameter is not set to <TT>true</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H5><A name="ManipulatingContent-TheSlingPostServlet-MovingMultipleItems"></A>Moving Multiple Items</H5>
+
+<P>By using the <TT>:applyTo</TT> request parameter it is possible to move multiple items in one single request. Moving items in this way leaves you with less control, though. In addition, if a single item move fails, no item at all is moved.</P>
+
+<P>When specifying the item(s) to be moved with the <TT>:applyTo</TT> parameter, the request resource is left untouched (unless of course if listed in the <TT>:applyTo</TT> parameter) and only used to resolve any relative paths in the <TT>:applyTo</TT> parameter.</P>
+
+<P>To for example move the <TT>/content/page1</TT> and <TT>/content/page2</TT> nodes to <TT>/content/target</TT>, you might use the following command line:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:operation=move&quot; -F&quot;:applyTo=/content/page1&quot; -F&quot;:applyTo=/content/page2&quot; -F&quot;:dest=/content/target/&quot; http://host/content/sample
+</PRE>
+</DIV></DIV>
+
+<P>Please note the trailing slash character (<TT>/</TT>) in the value of the <TT>:dest</TT> parameter. This is required for mult-item move operations using the <TT>:applyTo</TT> parameter. The moved items are created below the node indicated by the <TT>:dest</TT>.</P>
+
+<P>If any resource listed in the <TT>:applyTo</TT> parameter does not exist, it is silently ignored. Any item already existing at the move destination whose name is the same as the name of an item to be moved is silently overwritten with the source item.</P>
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H6>
+
+<P>The move operation applied to multiple resources has the following status responses:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> All requested and existing resources have been moved </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 412/PRECONDITION FAILED </TD>
+<TD class="confluenceTd"> The node indicated by the <TT>:dest</TT> parameter does not exist </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> 500/INTERNAL SERVER ERROR </TD>
+<TD class="confluenceTd"> Some exception, for example a <TT>RepositoryException</TT>, occurred while processing the request. This status is also set if the <TT>:dest</TT> parameter value does not have a trailing slash character. </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-NullOperation"></A>Null Operation</H3>
+
+<P>Sometimes it is useful to explicitly request that nothing is to be done. The SlingPostServlet now provides such an operation under the name <TT>nop</TT>. Apart from doing nothing, the <TT>nop</TT> operations sets the response status to either the default <TT>200/OK</TT> or to any status requested by the <TT>:nopstatus</TT> request parameter.</P>
+
+<P>The <TT>:nopstatus</TT> request parameter must be an integral number in the range [ 100 .. 999 ]. If the parameter value cannot be parsed to an integer or the value is outside of this range, the default status <TT>200/OK</TT> is still set.</P>
+
+
+<H6><A name="ManipulatingContent-TheSlingPostServlet-ResponseStatus"></A>Response Status</H6>
+
+<P>The null operation sets a default status or the status requested by the <TT>:nopstatus</TT> request parameter.</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Status </TH>
+<TH class="confluenceTh"> Explanation </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> 200/OK </TD>
+<TD class="confluenceTd"> Default status set if <TT>:nopstatus</TT> parameter is not set or does not have a valid value </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> {:nopstatus} </TD>
+<TD class="confluenceTd"> The status as requested by the <TT>:nopstatus</TT> parameter </TD>
+</TR>
+</TBODY></TABLE>
+
+
+
+<H2><A name="ManipulatingContent-TheSlingPostServlet-SpecialParameters"></A>Special Parameters</H2>
+
+
+<P>Some parameters have special significance for the complete processing of the SlingPostServlet or are used by multiple operations. This section summarizes these parameters:</P>
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B%3Aorder%7D%7D"></A><TT>:order</TT></H3>
+
+<P>Child nodes may be ordered if the primary node type of their common parent node is defined as having orderable child nodes. To employ such ordering, the content creation/modification, move and copy operations support the <TT>:order</TT> parameter which apply child node ordering amongst its sibblings of the target node.</P>
+
+<P>The <TT>:order</TT> parameter may have the following values:</P>
+
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Value </TH>
+<TH class="confluenceTh"> Description </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>first</TT> </TD>
+<TD class="confluenceTd"> Place the target node as the first amongst its sibblings </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>last</TT> </TD>
+<TD class="confluenceTd"> Place the target node as the last amongst its sibblings </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>before <EM>xyz</EM></TT> </TD>
+<TD class="confluenceTd"> Place the target node immediately before the sibbling whose name is <EM>xyz</EM> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> <TT>after <EM>xyz</EM></TT> </TD>
+<TD class="confluenceTd"> Place the target node immediately after the sibbling whose name is <EM>xyz</EM> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> numeric </TD>
+<TD class="confluenceTd"> Place the target node at the indicated numeric place amongst its sibblings where <EM>0</EM> is equivalent to <TT>first</TT> and <EM>1</EM> means the second place </TD>
+</TR>
+</TBODY></TABLE>
+
+
+<P>Note that simple content reordering can be requested without applying any other operations. This is easiest done by placing a request to the resource to be reordered and just setting the <TT>:order</TT> parameter. For example to order the <TT>/content/sample/page5</TT> resource above its sibbling resource <TT>/content/sample/other</TT> a simple request</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:order=before other&quot; http://host/content/sample/page5
+</PRE>
+</DIV></DIV>
+
+<P>does the trick. To be redirected after the reodering, the <TT>:redirect</TT> parameter may optionally also be specified.</P>
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B%3Aredirect%7D%7D"></A><TT>:redirect</TT></H3>
+
+<P>Instructs the SlingPostServlet to redirect the client to the indicated location if the operation succeeds. That is the reponse status is set to <EM>302/FOUND</EM> and the <TT>Location</TT> header is set to the value of the <TT>:redirect</TT> parameter.</P>
+
+
+<H3><A name="ManipulatingContent-TheSlingPostServlet-%7B%7B%3Astatus%7D%7D"></A><TT>:status</TT></H3>
+
+<P>By default the SlingPostServlet sets response status according to the status of the operation executed. In some cases, it may be desirable to not have the real status codes (e.g. 404 or 505) but a normal <EM>200/OK</EM> to trick the client browser into displaying the response content generated by the SlingPostServlet.</P>
+
+<P>To not send the actual response status back to the client, the <TT>:status</TT> request parameter should be set to <TT>browser</TT>. If this parameter is not set, is empty, is set to <TT>standard</TT> or to any other value, the actual status code is sent back to the client.</P>
+
+
+
+<H2><A name="ManipulatingContent-TheSlingPostServlet-AdvancedTopic%3AExtendingtheSlingPostServlet"></A>Advanced Topic: Extending the SlingPostServlet</H2>
+
+
+<P>The supported operations of the SlingPostServlet may be extended by registering an OSGi service of type <TT>org.apache.sling.servlets.post.SlingPostOperation</TT> with the <TT>sling.post.operation</TT> service registration property set to the name of the operation. This name may then be used as the value of the <TT>:operation</TT> parameter to select the extended operation.</P>
+
+<P>As a simple example, let us register an operation named <EM>ping</EM>. This operation actually does nothing actually. First let's create the operation. We are using the Apache Felix Maven SCR Plugin to create an Declarative Services descriptor for this operation, so apart from packaging this class and the descriptor in a bundle, there is nothing more to be done.</P>
+
+<DIV class="code"><DIV class="codeHeader"><B>PingOperation.java</B></DIV><DIV class="codeContent">
+<PRE class="code-java">/**
+ * @scr.component metatype=<SPAN class="code-quote">&quot;no&quot;</SPAN> immediate=<SPAN class="code-quote">&quot;<SPAN class="code-keyword">true</SPAN>&quot;</SPAN>
+ * @scr.service
+ * @scr.property name=<SPAN class="code-quote">&quot;sling.post.operation&quot;</SPAN> value=<SPAN class="code-quote">&quot;ping&quot;</SPAN>
+ */
+<SPAN class="code-keyword">public</SPAN> class PingOperation <SPAN class="code-keyword">implements</SPAN> SlingPostOperation {
+
+    <SPAN class="code-keyword">public</SPAN> void run(SlingHttpServletRequest request, HtmlResponse response) {
+
+    }
+
+}</PRE>
+</DIV></DIV>
+
+<P>That's all. Package this in a bundle and deploy to a running Sling instance. Then you POST to this using <TT>ping</TT> as the operation name:</P>
+
+<DIV class="preformatted"><DIV class="preformattedContent">
+<PRE>$ curl -F&quot;:operation=ping&quot; http://host/content
+</PRE>
+</DIV></DIV>
+
+
+<P>For your convenience an abstract implementation of this interface exists as the <TT>org.apache.sling.servlets.post.AbstractSlingPostOperation</TT> abstract class, from which you may extend and implement the <TT>doRun(SlingHttpServletRequest, HtmlResponse)</TT> method.</P>
+        <DIV class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+Last modified by fmeschbe on 2009-01-03 13:52:22.0
+        </DIV>
+    </DIV>
+  </BODY>
+</HTML>
+

Added: websites/staging/sling/trunk/content/site/mappings-for-resource-resolution.html
==============================================================================
--- websites/staging/sling/trunk/content/site/mappings-for-resource-resolution.html (added)
+++ websites/staging/sling/trunk/content/site/mappings-for-resource-resolution.html Wed Dec 12 09:16:44 2012
@@ -0,0 +1,286 @@
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<HTML>
+  <HEAD>
+    <TITLE>Apache Sling - Mappings for Resource Resolution</TITLE>
+    <LINK rel="stylesheet" href="http://sling.apache.org/site/media.data/site.css" type="text/css" media="all">
+    <LINK rel="icon" href="http://sling.apache.org/site/media.data/favicon.ico">
+    <META http-equiv="Content-Type" content="text/html;charset=UTF-8">
+  </HEAD>
+  <BODY>
+    <DIV class="title">
+      <DIV class="logo">
+        <A href="http://sling.apache.org/site/index.html">
+          <IMG border="0" alt="Apache Sling" src="http://sling.apache.org/site/media.data/logo.png">
+        </A>
+      </DIV>
+      <DIV class="header">
+        <A href="http://www.apache.org/">
+          <IMG border="0" alt="Apache" src="http://sling.apache.org/site/media.data/apache.png">
+        </A>
+      </DIV>
+    </DIV>
+    <DIV class="menu">
+<P><B>Documentation</B><BR class="atl-forced-newline">
+<A href="getting-started.html" title="Getting Started">Getting Started</A><BR class="atl-forced-newline">
+<A href="the-sling-engine.html" title="The Sling Engine">The Sling Engine</A><BR class="atl-forced-newline">
+<A href="development.html" title="Development">Development</A><BR class="atl-forced-newline">
+<A href="bundles.html" title="Bundles">Bundles</A><BR class="atl-forced-newline">
+<A href="tutorials-how-tos.html" title="Tutorials & How-Tos">Tutorials &amp; How&#45;Tos</A><BR class="atl-forced-newline">
+<A href="configuration.html" title="Configuration">Configuration</A><BR class="atl-forced-newline">
+<A href="http://sling.apache.org/apidocs/sling6/index.html" class="external-link" rel="nofollow">API docs</A><BR class="atl-forced-newline">
+<A href="http://s.apache.org/sling.wiki" class="external-link" rel="nofollow">Wiki</A><BR class="atl-forced-newline">
+<A href="http://s.apache.org/sling.faq" class="external-link" rel="nofollow">FAQ</A><BR class="atl-forced-newline"></P>
+
+<P><B>Project info</B><BR class="atl-forced-newline">
+<A href="http://sling.apache.org/site/downloads.cgi" class="external-link" rel="nofollow">Downloads</A><BR class="atl-forced-newline">
+<A href="http://www.apache.org/licenses/" class="external-link" rel="nofollow">License</A><BR class="atl-forced-newline">
+<A href="contributing.html" title="Contributing">Contributing</A><BR class="atl-forced-newline">
+<A href="news.html" title="News">News</A><BR class="atl-forced-newline">
+<A href="links.html" title="Links">Links</A><BR class="atl-forced-newline">
+<A href="project-information.html" title="Project Information">Project Information</A><BR class="atl-forced-newline">
+<A href="https://issues.apache.org/jira/browse/SLING" class="external-link" rel="nofollow">Issue Tracker</A><BR class="atl-forced-newline">
+<A href="http://svn.apache.org/viewvc/sling/trunk" class="external-link" rel="nofollow">Browse Source Repository</A><BR class="atl-forced-newline">
+<A href="security.html" title="Security">Security</A><BR class="atl-forced-newline"></P>
+
+<P><B>Sponsorship</B><BR class="atl-forced-newline">
+<A href="http://www.apache.org/foundation/thanks.html" class="external-link" rel="nofollow">Thanks</A><BR class="atl-forced-newline">
+<A href="http://www.apache.org/foundation/sponsorship.html" class="external-link" rel="nofollow">Become a Sponsor</A><BR>
+<A href="http://www.apache.org/foundation/buy_stuff.html" class="external-link" rel="nofollow">Buy Stuff</A></P>
+
+
+  <IFRAME src="http://www.apache.org/ads/button.html" style="border-width:0; float: left" frameborder="0" scrolling="no" width="135" height="135"></IFRAME>
+  <P style="height: 135px"></P>
+    </DIV>
+    <DIV class="main">
+        <DIV class="breadcrump" style="font-size: 80%;">
+<A href="apache-sling.html" title="Apache Sling Website">Apache Sling Website</A>&nbsp;&gt;&nbsp;<A href="apache-sling.html" title="Apache Sling">Apache Sling</A>&nbsp;&gt;&nbsp;<A href="documentation.html" title="Documentation">Documentation</A>&nbsp;&gt;&nbsp;<A href="the-sling-engine.html" title="The Sling Engine">The Sling Engine</A>&nbsp;&gt;&nbsp;<A href="" title="Mappings for Resource Resolution">Mappings for Resource Resolution</A>
+        </DIV>
+<H1><A name="MappingsforResourceResolution-MappingsforResourceResolution"></A>Mappings for Resource Resolution</H1>
+
+
+<H2><A name="MappingsforResourceResolution-Configuration"></A>Configuration</H2>
+
+
+<H3><A name="MappingsforResourceResolution-Properties"></A>Properties</H3>
+
+<P>The mapping of request URLs to resources is mainly configured in a configuration tree which is (by default) located below <TT>/etc/map</TT>. The actual location can be configured with the <TT>resource.resolver.map.location</TT> property of the <TT>org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl</TT> configuration.</P>
+
+
+<P>When dealing with the new resource resolution we have a number of properties influencing the process:</P>
+<UL>
+	<LI><TT>sling:match</TT> &ndash; This property when set on a node in the <TT>/etc/map</TT> tree (see below) defines a partial regular expression which is used instead of the node's name to match the incoming request. This property is only needed if the regular expression includes characters which are not valid JCR name characters. The list of invalid characters for JCR names is: /, :, [, ], &#42;, ', &quot;, &#124; and any whitespace except blank space. In addition a name without a name space may not be <TT>.</TT> or <TT>..</TT> and a blank space is only allowed inside the name.</LI>
+	<LI><TT>sling:redirect</TT> &ndash; This property when set on a node in the <TT>/etc/map</TT> tree (see below) causes a redirect response to be sent to the client, which causes the client to send in a new request with the modified location. The value of this property is applied to the actual request and sent back as the value of <TT>Location</TT> response header.</LI>
+	<LI><TT>sling:status</TT> &ndash; This property defines the HTTP status code sent to the client with the <TT>sling:redirect</TT> response. If this property is not set, it defaults to 302 (Found). Other status codes supported are 300 (Multiple Choices), 301 (Moved Permanently), 303 (See Other), and 307 (Temporary Redirect).</LI>
+	<LI><TT>sling:internalRedirect</TT> &ndash; This property when set on a node in the <TT>/etc/map</TT> tree (see below) causes the current path to be modified internally to continue with resource resolution.</LI>
+	<LI><TT>sling:alias</TT> &ndash; The property may be set on any resource to indicate an alias name for the resource. For example the resource <TT>/content/visitors</TT> may have the <TT>sling:alias</TT> property set to <TT>besucher</TT> allowing the resource to be addressed in an URL as <TT>/content/besucher</TT>.</LI>
+</UL>
+
+
+<H3><A name="MappingsforResourceResolution-NodeTypes"></A>Node Types</H3>
+
+<P>To ease with the definition of redirects and aliases, the following node types are defined:</P>
+<UL>
+	<LI><TT>sling:ResourceAlias</TT> &ndash; This mixin node type defines the <TT>sling:alias</TT> property and may be attached to any node, which does not otherwise allow setting a property named <TT>sling:alias</TT></LI>
+	<LI><TT>sling:MappingSpec</TT> &ndash; This mixin node type defines the <TT>sling:match</TT>, <TT>sling:redirect</TT>, <TT>sling:status</TT>, and <TT>sling:internaleRedirect</TT> properties to define a matching and redirection inside the <TT>/etc/map</TT> hierarchy.</LI>
+	<LI><TT>sling:Mapping</TT> &ndash; Primary node type which may be used to easily construct entries in the <TT>/etc/map</TT> tree. The node type extends the <TT>sling:MappingSpec</TT> mixin node type to allow setting the required matching and redirection. In addition the <TT>sling:Resource</TT> mixin node type is extended to allow setting a resource type and the <TT>nt:hierarchyNode</TT> node type is extended to allow locating nodes of this node type below <TT>nt:folder</TT> nodes.</LI>
+</UL>
+
+
+<P>Note, that these node types only help setting the properties. The implementation itself only cares for the properties and their values and not for any of these node types.</P>
+
+<H2><A name="MappingsforResourceResolution-NamespaceMangling"></A>Namespace Mangling</H2>
+
+<P>There are systems accessing Sling, which have a hard time handling URLs containing colons &ndash; <TT>:</TT> &ndash; in the path part correctly. Since URLs produced and supported by Sling may colons because JCR Item based resources may be namespaced (e.g. <TT>jcr:content</TT>), a special namespace mangling feature is built into the <TT>ResourceResolver.resolve</TT> and <TT>ResourceResolver(map)</TT> methods.</P>
+
+<P>Namespace mangling operates such, that any namespace prefix identified in resource path to be mapped as an URL in the <TT>map</TT> methods is modified such that the prefix is enclosed in underscores and the colon removed.</P>
+
+<P><EM>Example</EM>: The path <TT>/content/_a_sample/jcr:content/jcr:data.png</TT> is modified by namespace mangling in the <TT>map</TT> method to get at <TT>/content/_a_sample/_jcr_content/_jcr_data.png</TT>.</P>
+
+<P>Conversely the <TT>resolve</TT> methods must undo such namespace mangling to get back at the resource path. This is simple done by modifying any path such that segments starting with an underscore enclosed prefix are changed by removing the underscores and adding a colon after the prefix. There is one catch, tough: Due to the way the SlingPostServlets automatically generates names, there may be cases where the actual name would be matching this mechanism. Therefore only prefixes are modified which are actually namespace prefixes.</P>
+
+<P><EM>Example</EM>: The path <TT>/content/_a_sample/<EM>jcr_content/_jcr_data.png</EM></TT> <EM>is modified by namespace mangling in the</EM> <TT><EM>resolve</EM></TT> <EM>method to get</EM> <TT><EM>/content/_a_sample/jcr:content/jcr:data.png</EM></TT><EM>. The prefix</EM> <TT><EM>&#95;a</EM></TT><TT>}} is not modified because there is no registered namespace with prefix {{a</TT>. On the other hand the prefix <TT><EM>jcr</EM></TT> is modified because there is of course a registered namespace with prefix <TT>jcr</TT>.</P>
+
+<H2><A name="MappingsforResourceResolution-RootLevelMappings"></A>Root Level Mappings</H2>
+
+<P>Root Level Mappings apply to the request at large including the scheme, host.port and uri path. To accomplish this a path is constructed from the request as {<TT>scheme}/{host.port}/{uri_path</TT>}. This string is then matched against mapping entries below <TT>/etc/map</TT> which are structured in the content analogously. The longest matching entry string is used and the replacement, that is the redirection property, is applied.</P>
+
+<H3><A name="MappingsforResourceResolution-MappingEntrySpecification"></A>Mapping Entry Specification</H3>
+
+<P>Each entry in the mapping table is a regular expression, which is constructed from the resource path below <TT>/etc/map</TT>. If any resource along the path has a <TT>sling:match</TT> property, the respective value is used in the corresponding segment instead of the resource name. Only resources either having a <TT>sling:redirect</TT> or <TT>sling:internalRedirect</TT> property are used as table entries. Other resources in the tree are just used to build the mapping structure.</P>
+
+<P><B>Example</B></P>
+
+<P>Consider the following content</P>
+<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
+<PRE>/etc/map
+      +-- http
+           +-- example.com.80
+                +-- sling:redirect = &quot;http://www.example.com/&quot;
+           +-- www.example.com.80
+                +-- sling:internalRedirect = &quot;/example&quot;
+           +-- any_example.com.80
+                +-- sling:match = &quot;.+\.example\.com\.80&quot;
+                +-- sling:redirect = &quot;http://www.example.com/&quot;
+           +-- localhost_any
+                +-- sling:match = &quot;localhost\.\d*&quot;
+                +-- sling:internalRedirect = &quot;/content&quot;
+                +-- cgi-bin
+                     +-- sling:internalRedirect = &quot;/scripts&quot;
+                +-- gateway
+                     +-- sling:internalRedirect = &quot;http://gbiv.com&quot;
+                +-- (stories)
+                     +-- sling:internalRedirect = &quot;/anecdotes/$1&quot;
+</PRE>
+</DIV></DIV>
+<P>This would define the following mapping entries:</P>
+<DIV class="table-wrap">
+<TABLE class="confluenceTable"><TBODY>
+<TR>
+<TH class="confluenceTh"> Regular Expression </TH>
+<TH class="confluenceTh"> Redirect </TH>
+<TH class="confluenceTh"> Internal </TH>
+<TH class="confluenceTh"> Description </TH>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/example.com.80 </TD>
+<TD class="confluenceTd"> <A href="http://www.example.com/" class="external-link" rel="nofollow">http://www.example.com</A> </TD>
+<TD class="confluenceTd"> no </TD>
+<TD class="confluenceTd"> Redirect all requests to the Second Level Domain to www </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/www.example.com.80 </TD>
+<TD class="confluenceTd"> /example </TD>
+<TD class="confluenceTd"> yes </TD>
+<TD class="confluenceTd"> Prefix the URI paths of the requests sent to this domain with the string <TT>/example</TT> </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/.+\.example\.com\.80 </TD>
+<TD class="confluenceTd"> <A href="http://www.example.com/" class="external-link" rel="nofollow">http://www.example.com</A> </TD>
+<TD class="confluenceTd"> no </TD>
+<TD class="confluenceTd"> Redirect all requests to sub domains to www. The actual regular expression for the host.port segment is taken from the <TT>sling:match</TT> property. </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/localhost\.\d&#42; </TD>
+<TD class="confluenceTd"> /content </TD>
+<TD class="confluenceTd"> yes </TD>
+<TD class="confluenceTd"> Prefix the URI paths with <TT>/content</TT> for requests to localhost, regardless of actual port the request was received on. This entry only applies if the URI path does not start with <TT>/cgi-bin</TT>, <TT>gateway</TT> or <TT>stories</TT> because there are longer match entries. The actual regular expression for the host.port segment is taken from the <TT>sling:match</TT> property. </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/localhost\.\d*/cgi-bin </TD>
+<TD class="confluenceTd"> /scripts </TD>
+<TD class="confluenceTd"> yes </TD>
+<TD class="confluenceTd"> Replace the <TT>/cgi-bin</TT> prefix in the URI path with <TT>/scripts</TT> for requests to localhost, regardless of actual port the request was received on. </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/localhost\.\d*/gateway </TD>
+<TD class="confluenceTd"> <A href="http://gbiv.com/" class="external-link" rel="nofollow">http://gbiv.com</A> </TD>
+<TD class="confluenceTd"> yes </TD>
+<TD class="confluenceTd"> Replace the <TT>/gateway</TT> prefix in the URI path with <TT><A href="http://gbiv.com/" class="external-link" rel="nofollow">http://gbiv.com</A></TT> for requests to localhost, regardless of actual port the request was received on. </TD>
+</TR>
+<TR>
+<TD class="confluenceTd"> http/localhost\.\d*/(stories) </TD>
+<TD class="confluenceTd"> /anecdotes/stories </TD>
+<TD class="confluenceTd"> yes </TD>
+<TD class="confluenceTd"> Prepend the URI paths starting with <TT>/stories</TT> with <TT>/anecdotes</TT> for requests to localhost, regardless of actual port the request was received on. </TD>
+</TR>
+</TBODY></TABLE>
+</DIV>
+
+
+<H3><A name="MappingsforResourceResolution-RegularExpressionmatching"></A>Regular Expression matching</H3>
+
+<P>As said above the mapping entries are regular expressions which are matched against path. As such these regular expressions may also contain capturing groups as shown in the example above: <TT>http/localhost\.\d*/(stories)</TT>. After matching the path against the regular expression, the replacement pattern is applied which allows references back to the capturing groups.</P>
+
+<P>To illustrate the matching and replacement is applied according to the following pseudo code:</P>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
+<PRE class="code-java">
+<SPAN class="code-object">String</SPAN> path = request.getScheme + <SPAN class="code-quote">&quot;/&quot;</SPAN> + request.getServerName() + <SPAN class="code-quote">&quot;.&quot;</SPAN> + request.getServerPort() + <SPAN class="code-quote">&quot;/&quot;</SPAN> + request.getPathInfo();
+<SPAN class="code-object">String</SPAN> result = <SPAN class="code-keyword">null</SPAN>;
+<SPAN class="code-keyword">for</SPAN> (MapEntry entry: mapEntries) {
+    Matcher matcher = entry.pattern.matcher(path);
+    <SPAN class="code-keyword">if</SPAN> (matcher.find()) {
+        <SPAN class="code-object">StringBuffer</SPAN> buf = <SPAN class="code-keyword">new</SPAN> <SPAN class="code-object">StringBuffer</SPAN>();
+        matcher.appendReplacement(buf, entry.getRedirect());
+        matcher.appendTail(buf);
+        result = buf.toString();
+        <SPAN class="code-keyword">break</SPAN>;
+    }
+}
+</PRE>
+</DIV></DIV>
+<P>At the end of the loop, <TT>result</TT> contains the mapped path or <TT>null</TT> if no entry matches the request <TT>path</TT>.</P>
+
+<P><B>NOTE:</B> Since the entries in the <TT>/etc/map</TT> are also used to reverse map any resource paths to URLs, using regular expressions in the Root Level Mappings prevent the respective entries from being used for reverse mappings. Therefor, it is strongly recommended to not use regular expression matching, unless you have a strong need.</P>
+
+<H3><A name="MappingsforResourceResolution-RedirectionValues"></A>Redirection Values</H3>
+
+<P>The result of matching the request path and getting the redirection is either a path into the resource tree or another URL. If the result is an URL, it is converted into a path again and matched against the mapping entries. This may be taking place repeatedly until an absolute or relative path into the resource tree results.</P>
+
+<P>The following pseudo code summarizes this behaviour:</P>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
+<PRE class="code-java">
+<SPAN class="code-object">String</SPAN> path = ....;
+<SPAN class="code-object">String</SPAN> result = path;
+<SPAN class="code-keyword">do</SPAN> {
+    result = applyMapEntries(result);
+} <SPAN class="code-keyword">while</SPAN> (isURL(result));
+</PRE>
+</DIV></DIV>
+<P>As soon as the result of applying the map entries is an absolute or relative path (or no more map entries match), Root Level Mapping terminates and the next step in resource resolution, resource tree access, takes place.</P>
+
+<H2><A name="MappingsforResourceResolution-ResourceTreeAccess"></A>Resource Tree Access</H2>
+
+<P>The result of Root Level Mapping is an absolute or relative path to a resource. If the path is relative &ndash; e.g. <TT>myproject/docroot/sample.gif</TT> &ndash; the resource resolver search path (<TT>ResourceResolver.getSearchPath()</TT> is used to build absolute paths and resolve the resource. In this case the first resource found is used. If the result of Root Level Mapping is an absolute path, the path is used as is.</P>
+
+<P>Accessing the resource tree after applying the Root Level Mappings has four options:</P>
+<UL>
+	<LI>Check whether the path addresses a so called Star Resource. A Star Resource is a resource whose path ends with or contains <TT>/&#42;</TT>. Such resources are used by the <TT>SlingPostServlet</TT> to create new content below an existing resource. If the path after Root Level Mapping is absolute, it is made absolute by prepending the first search path entry.</LI>
+	<LI>Check whether the path exists in the repository. if the path is absolute, it is tried directly. Otherwise the search path entries are prepended  to the path until a resource is found or the search path is exhausted without finding a resource.</LI>
+	<LI>Drill down the resource tree starting from the root, optionally using the search path until a resource is found.</LI>
+	<LI>If no resource can be resolved, a Missing Resource is returned.</LI>
+</UL>
+
+
+<H3><A name="MappingsforResourceResolution-DrillingDowntheResourceTree"></A>Drilling Down the Resource Tree</H3>
+
+<P>Drilling down the resource tree starts at the root and for each segment in the path checks whether a child resource of the given name exists or not. If not, a child resource is looked up, which has a <TT>sling:alias</TT> property whose value matches the given name. If neither exists, the search is terminated and the resource cannot be resolved.</P>
+
+<P>The following pseudo code shows this algorithm assuming the path is absolute:</P>
+<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
+<PRE class="code-java">
+<SPAN class="code-object">String</SPAN> path = ...; <SPAN class="code-comment">// the absolute path
+</SPAN>Resource current = getResource(<SPAN class="code-quote">&quot;/&quot;</SPAN>);
+<SPAN class="code-object">String</SPAN>[] segments = path.split(<SPAN class="code-quote">&quot;/&quot;</SPAN>);
+<SPAN class="code-keyword">for</SPAN> (<SPAN class="code-object">String</SPAN> segment: segments) {
+    Resource child = getResource(current, segment);
+    <SPAN class="code-keyword">if</SPAN> (child == <SPAN class="code-keyword">null</SPAN>) {
+        Iterator&lt;Resource&gt; children = listChildren(current);
+        current = <SPAN class="code-keyword">null</SPAN>;
+        <SPAN class="code-keyword">while</SPAN> (children.hasNext()) {
+            child = children.next();
+            <SPAN class="code-keyword">if</SPAN> (segment.equals(getSlingAlias(child))) {
+                current = child;
+                <SPAN class="code-keyword">break</SPAN>;
+            }
+        }
+        <SPAN class="code-keyword">if</SPAN> (current == <SPAN class="code-keyword">null</SPAN>) {
+            <SPAN class="code-comment">// fail
+</SPAN>            <SPAN class="code-keyword">break</SPAN>;
+        }
+    } <SPAN class="code-keyword">else</SPAN> {
+        current = child;
+    }
+}
+</PRE>
+</DIV></DIV>
+        <DIV class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+Last modified by jck on 2010-08-24 07:36:00.0
+        </DIV>
+        <DIV class="trademarkFooter">
+Apache Sling, Sling, Apache, the Apache feather logo, and the Apache Sling project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
+        </DIV>
+    </DIV>
+  </BODY>
+</HTML>
+