incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r818658 [22/23] - in /websites/staging/sling/trunk/content: ./ tutorials-how-tos/
Date Tue, 22 May 2012 08:25:36 GMT
Added: websites/staging/sling/trunk/content/tutorials-how-tos/how-to-manage-events-in-sling.html
==============================================================================
--- websites/staging/sling/trunk/content/tutorials-how-tos/how-to-manage-events-in-sling.html (added)
+++ websites/staging/sling/trunk/content/tutorials-how-tos/how-to-manage-events-in-sling.html Tue May 22 08:25:32 2012
@@ -0,0 +1,275 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Sling - How to Manage Events in Sling</title>
+    <link rel="stylesheet" href="/css/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><strong>Documentation</strong> <br />
+<a href="/getting-started.html">Getting Started</a> <br />
+<a href="/the-sling-engine.html">The Sling Engine</a> <br />
+<a href="/development.html">Development</a> <br />
+<a href="/bundles.html">Bundles</a> <br />
+<a href="/tutorials-how-tos.html">Tutorials &amp; How-Tos</a> <br />
+<a href="/configuration.html">Configuration</a> <br />
+<a href="http://s.apache.org/sling.wiki">Wiki</a> <br />
+<a href="http://s.apache.org/sling.faq">FAQ</a> <br />
+<a href="/sitemap.html">Site Map</a></p>
+<p><strong>API Docs</strong>  <br />
+<a href="http://sling.apache.org/apidocs/sling6/index.html">Sling 6</a> <br />
+<a href="http://sling.apache.org/apidocs/sling5/index.html">Sling 5</a> <br />
+</p>
+<p><strong>Project info</strong> <br />
+<a href="http://sling.apache.org/site/downloads.cgi">Downloads</a> <br />
+<a href="http://www.apache.org/licenses/">License</a> <br />
+<a href="/contributing.html">Contributing</a> <br />
+<a href="/news.html">News</a> <br />
+<a href="/links.html">Links</a> <br />
+<a href="/project-information.html">Project Information</a> <br />
+<a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a> <br />
+<a href="http://svn.apache.org/viewvc/sling/trunk">Browse Source Repository</a> <br />
+<a href="/security.html">Security</a> <br />
+</p>
+<p><strong>Sponsorship</strong> <br />
+<a href="http://www.apache.org/foundation/thanks.html">Thanks</a> <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a> <br />
+<a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a> <br />
+</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>
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/tutorials-how-tos.html">Tutorials & How-Tos</a>
+      </div>
+      <h1>How to Manage Events in Sling</h1>
+      <h1 id="how-to-manage-events-in-sling">How to Manage Events in Sling</h1>
+<p>Apache Sling provides some mechanisms and support for managing events.</p>
+<p>The event mechanism is leveraging the OSGi Event Admin Specification (OSGi Compendium 113). The OSGi API is very simple and lightweight. Sending an event is just generating the event object and calling the event admin. Receiving the event is implementing a single interface and declaring through properties which topics one is interested in. 
+Sling makes a distinction between events and job events. Unlike events, job events are garanteed to be processed. In other words: someone has to do something with the job event (do the job). </p>
+<p>For more details please refer to the following resources:
+<em> <a href="">Eventing, Jobs and Scheduling section</a> to get detailed information on the eventing mechanisms in Sling.
+</em> package <a href="">org.osgi.service.event</a> of the OSGI API.
+* package <a href="">org.apache.sling.event</a> of the Sling API.</p>
+<p>This page drives you through the implementation of two services that rely on the Sling eventing mechanisms. The services implement the following use case: whenever a file is uploaded to a temporary location in your web application, the file is moved to a specific location according to its MIME type.</p>
+<h2 id="introduction">Introduction</h2>
+<p>You will now implement the logic to listen to files posted to <em>/tmp/dropbox</em> and to move them to the appropriate locations depending on the MIME type:
+<em> images (.png) are moved to </em>/dropbox/images/<em>
+</em> music (.mp3) are moved to <em>/dropbox/music/</em>
+<em> movies (.avi) are moved to </em>/dropbox/movies/<em>
+</em> otherwise the files are moved to <em>/dropbox/other/</em></p>
+<p>To do that, you will implement two services. The first one, called <em>DropBoxService</em>:
+<em> Listens to OSGI events.
+</em> Sends a job event if a resource has been added to <em>/tmp/dropbox</em>.</p>
+<p>The second one, called <em>DropBoxEventHandler</em>:
+<em> Listens to the former job event.
+</em> Moves the file according to its extension.</p>
+<h2 id="listening-to-osgi-events">Listening to OSGI Events</h2>
+<p>To listen to the specific OSGI event <em>"resource added"</em>:
+<em> The property </em>event.topics<em> needs to be set to </em>org.apache.sling.api.SlingConstants.TOPIC<em>RESOURCE</em>ADDED* in the class annotations.</p>
+<div class="codehilite"><pre> <span class="o">*</span> <span class="nv">@scr</span><span class="o">.</span><span class="n">property</span> <span class="n">name</span><span class="o">=</span><span class="s">&quot;event.topics&quot;</span> <span class="n">valueRef</span><span class="o">=</span><span class="s">&quot;org.apache.sling.api.SlingConstants.TOPIC_RESOURCE_ADDED&quot;</span>
+</pre></div>
+
+
+<p>You can refer to the <a href="">org.apache.sling.api.SlingConstants</a> class in the Javadocs to know about other events available in Sling.</p>
+<h2 id="sending-job-events">Sending Job Events</h2>
+<p>To send a job event the service needs to implement:
+<em> the </em>org.osgi.service.event.EventHandler<em> interface.
+</em> the <em>org.apache.sling.event.JobProcessor</em> interface.</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">DropBoxService</span> <span class="n">implements</span> <span class="n">JobProcessor</span><span class="p">,</span> <span class="n">EventHandler</span> <span class="p">{</span>
+</pre></div>
+
+
+<p>To send the job event the Event Admin service needs to be referenced:</p>
+<div class="codehilite"><pre>    <span class="o">/**</span> 
+     <span class="o">*</span> <span class="n">The</span> <span class="n">OSGI</span> <span class="n">event</span> <span class="n">admin</span> <span class="n">used</span> <span class="k">for</span> <span class="n">sending</span> <span class="n">events</span> 
+     <span class="o">*</span> <span class="nv">@scr</span><span class="o">.</span><span class="n">reference</span>
+     <span class="o">*/</span>
+    <span class="n">private</span> <span class="n">EventAdmin</span> <span class="n">eventAdmin</span><span class="p">;</span>
+</pre></div>
+
+
+<p>The job topic for dropbox job events needs to be defined:</p>
+<div class="codehilite"><pre>    <span class="sr">/** The job topic for dropbox job events. */</span>
+    <span class="n">public</span> <span class="n">static</span> <span class="n">final</span> <span class="n">String</span> <span class="n">JOB_TOPIC</span> <span class="o">=</span> <span class="s">&quot;com/sling/eventing/dropbox/job&quot;</span><span class="p">;</span>
+</pre></div>
+
+
+<p>The <em>org.osgi.service.event.EventHandler#handleEvent(Event event)</em> method needs to be implemented:</p>
+<div class="codehilite"><pre>    <span class="n">public</span> <span class="n">void</span> <span class="n">handleEvent</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">EventUtil</span><span class="o">.</span><span class="n">isLocal</span><span class="p">(</span><span class="n">event</span><span class="p">))</span> <span class="p">{</span>
+            <span class="n">EventUtil</span><span class="o">.</span><span class="n">processJob</span><span class="p">(</span><span class="n">event</span><span class="p">,</span> <span class="n">this</span><span class="p">);</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p>The <em>org.apache.sling.event.JobProcessor#process(Event event)</em> method needs to be implemented.</p>
+<p>Its logic is as follows:
+<em> The OSGI event is analyzed.
+</em> If the event is a file that has been added to <em>/tmp/dropbox</em>:
+<strong> An event is created with 2 properties:
+<strong><em> A property to set the event as a job event.
+</em></strong> A property for the file path.
+</strong> The job event is sent to all the listeners that subscribe to the topic of the event.</p>
+<div class="codehilite"><pre>    <span class="n">public</span> <span class="n">boolean</span> <span class="n">process</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">String</span> <span class="n">propPath</span> <span class="o">=</span> <span class="p">(</span><span class="n">String</span><span class="p">)</span> <span class="n">event</span><span class="o">.</span><span class="n">getProperty</span><span class="p">(</span><span class="n">SlingConstants</span><span class="o">.</span><span class="n">PROPERTY_PATH</span><span class="p">);</span>
+        <span class="n">String</span> <span class="n">propResType</span> <span class="o">=</span> <span class="p">(</span><span class="n">String</span><span class="p">)</span> <span class="n">event</span><span class="o">.</span><span class="n">getProperty</span><span class="p">(</span><span class="n">SlingConstants</span><span class="o">.</span><span class="n">PROPERTY_RESOURCE_TYPE</span><span class="p">);</span>
+        <span class="sr">//</span> <span class="n">an</span> <span class="n">event</span> <span class="n">is</span> <span class="n">sent</span> <span class="k">if</span> <span class="n">a</span> <span class="n">file</span> <span class="n">is</span> <span class="n">added</span> <span class="n">to</span> <span class="sr">/tmp/</span><span class="n">dropbox</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">propPath</span><span class="o">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">&quot;/tmp/dropbox&quot;</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">propResType</span><span class="o">.</span><span class="n">equals</span><span class="p">(</span><span class="s">&quot;nt:file&quot;</span><span class="p">))</span> <span class="p">{</span>
+            <span class="n">final</span> <span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span><span class="p">();</span>
+            <span class="n">props</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">EventUtil</span><span class="o">.</span><span class="n">PROPERTY_JOB_TOPIC</span><span class="p">,</span> <span class="n">JOB_TOPIC</span><span class="p">);</span>
+            <span class="n">props</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="s">&quot;resourcePath&quot;</span><span class="p">,</span> <span class="n">propPath</span><span class="p">);</span>
+            <span class="n">Event</span> <span class="n">dropboxJobEvent</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Event</span><span class="p">(</span><span class="n">EventUtil</span><span class="o">.</span><span class="n">TOPIC_JOB</span><span class="p">,</span> <span class="n">props</span><span class="p">);</span>
+            <span class="n">eventAdmin</span><span class="o">.</span><span class="n">sendEvent</span><span class="p">(</span><span class="n">dropboxJobEvent</span><span class="p">);</span>
+            <span class="nb">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;the dropbox job has been sent: {}&quot;</span><span class="p">,</span> <span class="n">propPath</span><span class="p">);</span>
+        <span class="p">}</span>
+        <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p>The complete code for the <em>DropBoxService</em> service is available <a href="">here</a>.</p>
+<h2 id="listening-to-job-events">Listening to Job Events</h2>
+<p>Now that you have implemented a service that sends a job event when a file is uploaded to <em>/tmp/dropbox</em>, you will implement the service <em>DropBoxEventHandler</em> that listens to those job events and moves the files to a location according to their MIME types.</p>
+<p>To listen to the job events that have been defined before:
+<em> The property </em>event.topics<em> needs to be set to </em>mypackage.DropBoxService.JOB_TOPIC* in the class annotations.</p>
+<div class="codehilite"><pre> <span class="o">*</span> <span class="nv">@scr</span><span class="o">.</span><span class="n">property</span> <span class="n">name</span><span class="o">=</span><span class="s">&quot;event.topics&quot;</span> <span class="n">valueRef</span><span class="o">=</span><span class="s">&quot;mypackage.DropBoxService.JOB_TOPIC&quot;</span>
+</pre></div>
+
+
+<h2 id="handling-job-events">Handling Job Events</h2>
+<p>To move the files the service needs to implement:
+<em> the </em>org.osgi.service.event.EventHandler<em> interface.
+</em> the <em>org.apache.sling.event.JobProcessor</em> interface.</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="n">class</span> <span class="n">DropBoxEventHandler</span> <span class="n">implements</span> <span class="n">JobProcessor</span><span class="p">,</span> <span class="n">EventHandler</span> <span class="p">{</span>
+</pre></div>
+
+
+<p>Some class fields need to be defined for:
+<em> The default log.
+</em> The references to the SlingRepository and the JcrResourceResolverFactory services, which are used in the implementation.
+* The destination paths of the files.</p>
+<p>{code}
+   /*<em> Default log. </em>/
+    protected final Logger log = LoggerFactory.getLogger(this.getClass());</p>
+<div class="codehilite"><pre><span class="sr">/** @scr.reference */</span>
+<span class="n">private</span> <span class="n">SlingRepository</span> <span class="n">repository</span><span class="p">;</span>
+
+<span class="o">/**</span>
+ <span class="o">*</span> <span class="nv">@scr</span><span class="o">.</span><span class="n">reference</span>
+ <span class="o">*/</span>
+<span class="n">private</span> <span class="n">JcrResourceResolverFactory</span> <span class="n">resolverFactory</span><span class="p">;</span>
+
+<span class="n">private</span> <span class="n">final</span> <span class="n">static</span> <span class="n">String</span> <span class="n">IMAGES_PATH</span> <span class="o">=</span> <span class="s">&quot;/dropbox/images/&quot;</span><span class="p">;</span>
+<span class="n">private</span> <span class="n">final</span> <span class="n">static</span> <span class="n">String</span> <span class="n">MUSIC_PATH</span> <span class="o">=</span> <span class="s">&quot;/dropbox/music/&quot;</span><span class="p">;</span>
+<span class="n">private</span> <span class="n">final</span> <span class="n">static</span> <span class="n">String</span> <span class="n">MOVIES_PATH</span> <span class="o">=</span> <span class="s">&quot;/dropbox/movies/&quot;</span><span class="p">;</span>
+<span class="n">private</span> <span class="n">final</span> <span class="n">static</span> <span class="n">String</span> <span class="n">OTHER_PATH</span> <span class="o">=</span> <span class="s">&quot;/dropbox/other/&quot;</span><span class="p">;</span>
+
+<span class="n">The</span> <span class="o">*</span><span class="n">org</span><span class="o">.</span><span class="n">osgi</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">EventHandler</span><span class="c1">#handleEvent(Event event)* method needs to be implemented:</span>
+
+<span class="n">public</span> <span class="n">void</span> <span class="n">handleEvent</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">EventUtil</span><span class="o">.</span><span class="n">isLocal</span><span class="p">(</span><span class="n">event</span><span class="p">))</span> <span class="p">{</span>
+        <span class="n">EventUtil</span><span class="o">.</span><span class="n">processJob</span><span class="p">(</span><span class="n">event</span><span class="p">,</span> <span class="n">this</span><span class="p">);</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">The</span> <span class="o">*</span><span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">sling</span><span class="o">.</span><span class="n">event</span><span class="o">.</span><span class="n">JobProcessor</span><span class="c1">#process(Event event)* method needs to be implemented.</span>
+
+<span class="n">Its</span> <span class="n">logic</span> <span class="n">is</span> <span class="n">as</span> <span class="n">follows:</span>
+<span class="o">*</span> <span class="n">The</span> <span class="n">resource</span> <span class="n">path</span> <span class="n">is</span> <span class="n">extracted</span> <span class="n">from</span> <span class="n">the</span> <span class="n">job</span> <span class="n">event</span> <span class="n">property</span><span class="o">.</span>
+<span class="o">*</span> <span class="n">The</span> <span class="n">resource</span> <span class="n">is</span> <span class="n">obtained</span> <span class="n">from</span> <span class="n">the</span> <span class="n">resource</span> <span class="n">path</span><span class="o">.</span>
+<span class="o">*</span> <span class="n">If</span> <span class="n">the</span> <span class="n">resource</span> <span class="n">is</span> <span class="n">a</span> <span class="n">file</span><span class="p">,</span> <span class="n">the</span> <span class="n">destination</span> <span class="n">path</span> <span class="n">is</span> <span class="nb">defined</span> <span class="n">based</span> <span class="n">on</span> <span class="n">the</span> <span class="n">file</span> <span class="n">MIME</span> <span class="n">type</span><span class="o">.</span>
+<span class="o">*</span> <span class="n">The</span> <span class="n">file</span> <span class="n">is</span> <span class="n">moved</span> <span class="n">to</span> <span class="n">the</span> <span class="k">new</span> <span class="n">location</span><span class="o">.</span>
+
+<span class="n">public</span> <span class="n">boolean</span> <span class="n">process</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">Session</span> <span class="n">adminSession</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="n">try</span> <span class="p">{</span>
+        <span class="n">String</span> <span class="n">resourcePath</span> <span class="o">=</span> <span class="p">(</span><span class="n">String</span><span class="p">)</span> <span class="n">event</span><span class="o">.</span><span class="n">getProperty</span><span class="p">(</span><span class="s">&quot;resourcePath&quot;</span><span class="p">);</span>
+        <span class="n">String</span> <span class="n">resourceName</span> <span class="o">=</span> <span class="n">resourcePath</span><span class="o">.</span><span class="n">substring</span><span class="p">(</span><span class="n">resourcePath</span><span class="o">.</span><span class="n">lastIndexOf</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+        <span class="n">adminSession</span> <span class="o">=</span> <span class="n">repository</span><span class="o">.</span><span class="n">loginAdministrative</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">ResourceResolver</span> <span class="n">resourceResolver</span> <span class="o">=</span> <span class="n">resolverFactory</span><span class="o">.</span><span class="n">getResourceResolver</span><span class="p">(</span><span class="n">adminSession</span><span class="p">);</span>
+        <span class="n">Resource</span> <span class="n">res</span> <span class="o">=</span> <span class="n">resourceResolver</span><span class="o">.</span><span class="n">getResource</span><span class="p">(</span><span class="n">resourcePath</span><span class="p">);</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">ResourceUtil</span><span class="o">.</span><span class="n">isA</span><span class="p">(</span><span class="n">res</span><span class="p">,</span> <span class="s">&quot;nt:file&quot;</span><span class="p">))</span> <span class="p">{</span>
+            <span class="n">String</span> <span class="n">mimeType</span> <span class="o">=</span> <span class="n">res</span><span class="o">.</span><span class="n">getResourceMetadata</span><span class="p">()</span><span class="o">.</span><span class="n">getContentType</span><span class="p">();</span>
+            <span class="n">String</span> <span class="n">destDir</span><span class="p">;</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">mimeType</span><span class="o">.</span><span class="n">equals</span><span class="p">(</span><span class="s">&quot;image/png&quot;</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">destDir</span> <span class="o">=</span> <span class="n">IMAGES_PATH</span><span class="p">;</span>
+            <span class="p">}</span>
+            <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">mimeType</span><span class="o">.</span><span class="n">equals</span><span class="p">(</span><span class="s">&quot;audio/mpeg&quot;</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">destDir</span> <span class="o">=</span> <span class="n">MUSIC_PATH</span><span class="p">;</span>
+            <span class="p">}</span>
+            <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">mimeType</span><span class="o">.</span><span class="n">equals</span><span class="p">(</span><span class="s">&quot;video/x-msvideo&quot;</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">destDir</span> <span class="o">=</span> <span class="n">MOVIES_PATH</span><span class="p">;</span>
+            <span class="p">}</span>
+            <span class="k">else</span> <span class="p">{</span>
+                <span class="n">destDir</span> <span class="o">=</span> <span class="n">OTHER_PATH</span><span class="p">;</span>
+            <span class="p">}</span>
+            <span class="n">adminSession</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">resourcePath</span><span class="p">,</span> <span class="n">destDir</span> <span class="o">+</span> <span class="n">resourceName</span><span class="p">);</span>
+            <span class="n">adminSession</span><span class="o">.</span><span class="n">save</span><span class="p">();</span>
+            <span class="nb">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;The file {} has been moved to {}&quot;</span><span class="p">,</span> <span class="n">resourceName</span><span class="p">,</span> <span class="n">destDir</span><span class="p">);</span>
+        <span class="p">}</span>
+        <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+    <span class="p">}</span> <span class="n">catch</span> <span class="p">(</span><span class="n">RepositoryException</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
+        <span class="nb">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;RepositoryException: &quot;</span> <span class="o">+</span> <span class="n">e</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span> <span class="n">finally</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">adminSession</span> <span class="o">!=</span> <span class="n">null</span> <span class="o">&amp;&amp;</span> <span class="n">adminSession</span><span class="o">.</span><span class="n">isLive</span><span class="p">())</span> <span class="p">{</span>
+            <span class="n">adminSession</span><span class="o">.</span><span class="n">logout</span><span class="p">();</span>
+            <span class="n">adminSession</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">The</span> <span class="n">complete</span> <span class="n">code</span> <span class="k">for</span> <span class="n">the</span> <span class="o">*</span><span class="n">DropBoxEventHandler</span><span class="o">*</span> <span class="n">service</span> <span class="n">is</span> <span class="n">available</span> <span class="p">[</span><span class="n">here</span><span class="o">|^</span><span class="n">DropBoxEventHandler</span><span class="o">.</span><span class="n">java</span><span class="p">]</span><span class="o">.</span>
+</pre></div>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1341347 by fmeschbe on Tue, 22 May 2012 08:25:18 +0000
+      </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>

Added: websites/staging/sling/trunk/content/tutorials-how-tos/installing-and-upgrading-bundles.html
==============================================================================
--- websites/staging/sling/trunk/content/tutorials-how-tos/installing-and-upgrading-bundles.html (added)
+++ websites/staging/sling/trunk/content/tutorials-how-tos/installing-and-upgrading-bundles.html Tue May 22 08:25:32 2012
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Sling - Installing and Upgrading Bundles</title>
+    <link rel="stylesheet" href="/css/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><strong>Documentation</strong> <br />
+<a href="/getting-started.html">Getting Started</a> <br />
+<a href="/the-sling-engine.html">The Sling Engine</a> <br />
+<a href="/development.html">Development</a> <br />
+<a href="/bundles.html">Bundles</a> <br />
+<a href="/tutorials-how-tos.html">Tutorials &amp; How-Tos</a> <br />
+<a href="/configuration.html">Configuration</a> <br />
+<a href="http://s.apache.org/sling.wiki">Wiki</a> <br />
+<a href="http://s.apache.org/sling.faq">FAQ</a> <br />
+<a href="/sitemap.html">Site Map</a></p>
+<p><strong>API Docs</strong>  <br />
+<a href="http://sling.apache.org/apidocs/sling6/index.html">Sling 6</a> <br />
+<a href="http://sling.apache.org/apidocs/sling5/index.html">Sling 5</a> <br />
+</p>
+<p><strong>Project info</strong> <br />
+<a href="http://sling.apache.org/site/downloads.cgi">Downloads</a> <br />
+<a href="http://www.apache.org/licenses/">License</a> <br />
+<a href="/contributing.html">Contributing</a> <br />
+<a href="/news.html">News</a> <br />
+<a href="/links.html">Links</a> <br />
+<a href="/project-information.html">Project Information</a> <br />
+<a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a> <br />
+<a href="http://svn.apache.org/viewvc/sling/trunk">Browse Source Repository</a> <br />
+<a href="/security.html">Security</a> <br />
+</p>
+<p><strong>Sponsorship</strong> <br />
+<a href="http://www.apache.org/foundation/thanks.html">Thanks</a> <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a> <br />
+<a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a> <br />
+</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>
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/tutorials-how-tos.html">Tutorials & How-Tos</a>
+      </div>
+      <h1>Installing and Upgrading Bundles</h1>
+      <h1 id="installing-and-upgrading-bundles">Installing and Upgrading Bundles</h1>
+<p>{note}
+We recommend to use the Apache Felix Web Console. The documentation below describes the old Sling Management Console, which isn't in use any more. Please refer to the documentation of the <a href="">Apache Felix Web Console</a>.
+{note}</p>
+<p>OSGi bundles installed in the OSGi framework, which is provided by Sling, may be upgraded or removed and new bundles may be installed by using the Sling Management Console. This page is about using the Sling Management Console for those tasks.</p>
+<p>Basically, you have two choices to install and upgrade bundles: Upload the bundle files or install them from a Bundle Repository.</p>
+<h2 id="sling-management-console">Sling Management Console</h2>
+<p>The Sling Management Console is installed by default when Sling is running and may be reached at on the page <code>/system/console</code> in the Sling Context by default. For example if you installed the Sling Web Application in the <code>/sample</code> context of the Servlet Container running at <code>http``://somehost:4402</code>, you would access the Sling Management Console at <code>http``://somehost:4402/sample/system/console</code>.</p>
+<p>You will be prompted for a user name and password to access the Sling Management Console. This password is preset to be <em>admin</em> for the user name and <em>admin</em> for the password.</p>
+<p>NB: Both the username and password and the location of the Sling Management Console inside the Web Application Context is configurable in the <em>Sling Management Console</em> configuration on the <em>Configuration</em> page.</p>
+<h2 id="installing-and-upgrading-bundles-by-upload">Installing and upgrading bundles by Upload</h2>
+<p>To install a new bundle or upgrade an already installed bundle, go to the <em>Bundles</em> page in the Sling Management Console. At the top and the bottom of the page you have a form to specify and upload a bundle as a file :</p>
+<ul>
+<li>Select the bundle file to upload</li>
+<li>Click the <em>Start</em> checkbox, if you want to start the bundle after installation. If the bundle is upgraded, this checkbox is ignored.</li>
+<li>Specify the start level of the bundle in the <em>Start Level</em> field. This must be a number higher than 0 and is ignored for bundles, which are already installed. Most of the time, you will use the default value.</li>
+<li>Click the <em>Install or Update</em> button</li>
+</ul>
+<p>After clicking the button, the bundle file will be uploaded. If a bundle with the same bundle symbolic name is already installed, the respective bundle will be updated with the new bundle file. Otherwise the bundle file will be installed as a new bundle and its start level is set as defined. Additionally the bundle will optionally be started.</p>
+<p>After having updated a bundle, you should also refresh the packages by clicking on the <em>Refresh Packages</em> button. The reson for this is, that the old version of the bundle is still used by other bundles even after upgrading to a new version. Only when the packages are refreshed any users of the bundle will be relinked to use the new bundle version. As this might be a somewhat lengthy operation, which also stops and restarts using bundles, this operation has to be executed explicitly.</p>
+<p>Also, if you plan to upgrade multiple bundles, you may wish to upgrade all bundles before repackaging the using bundles.</p>
+<h2 id="installing-and-upgrading-bundles-from-the-bundle-repository">Installing and upgrading bundles from the Bundle Repository</h2>
+<p>The OSGi Bundle Repository is a repository of bundles, from which Sling may download and install or upgrade bundles very easily. Unlike the installation of bundles by file upload, the OSGi Bundle Repository has the functionality to resolve and dependencies of bundles to be installed.</p>
+<p>Say you wish to install bundle <em>X</em> which depends on packages provided by bundle <em>Y</em>. When uploading bundle <em>X</em> as a file it will not resolve, that is Sling (the OSGi framework actually) is not able to ensure proper operation of bundle <em>X</em> and thus prevents the bundle from being started and used. You will have to manually upload bundle <em>Y</em> yourself. When using the OSGi Bundle Repository, you just select bundle <em>X</em> for installation and the bundle repository will find out, that bundle <em>Y</em> is also required and will automatically download and install it along with bundle <em>X</em>.</p>
+<h3 id="the-bundle-repository-page">The Bundle Repository page</h3>
+<p>Installation or update of bundles may be done on the <em>Bundle Repository</em> page of the Sling Management Console. In the upper part of the page, you will see a list (usually just a single entry) of OSGi Bundle Repositories known to Sling. In the lower part of the list you see the bundles available from these repositories. To install or update bundles, just check the respective button and click on the <em>Deploy Selected</em> or <em>Deploy and Start Selected</em> button at the bottom of the page depending on whether you want to start the bundle(s) after installation or not.</p>
+<p>See below for more information on OSGi Bundle Repository management.</p>
+<h3 id="the-bundles-page">The Bundles page</h3>
+<p>You may also want to upgrade already installed bundles from the <em>Bundles</em> page of the Sling Management Console. For each bundle listed in this page, there is an <em>Upgrade</em> button. If there is an upgrade to the installed bundle available in the OSGi Bundle Repository, the button is enabled and clicking on the button will upgrade the respective bundle. If no upgrade is available from the OSGi Bundle Repository, this button is disabled.</p>
+<h3 id="managing-osgi-bundle-repositories">Managing OSGi Bundle Repositories</h3>
+<p>Currently management of known OSGi Bundle Repositories is very simple. If a configured bundle repository is not available on startup, it will be marked as being inactive. If you know the repository is now available, you may click on the <em>Refresh</em> button, to activate it. Similarly, the contents of the repository may be modified by for example adding new bundles or updating bundles in the repository, these changes will be made known to Sling by clicking the <em>Refresh</em> button.</p>
+<p>There exists no GUI functionality yet to add a new repository to the list of known repositories. Instead you may submit a request with parameters <code>action</code> whose value must be <code>refreshOBR</code> and <code>repository</code> whose value must be the URL to the repository descriptor file generally called <code>repository.xml</code>.</p>
+<p>For example, if you run Sling on <code>http``://localhost:7402/sample</code> with default location of the Sling Management Console, the following request would add a repository at <code>/tmp/repo/repository.xml</code> in the filesystem:</p>
+<div class="codehilite"><pre><span class="n">http:</span><span class="sr">//</span><span class="n">localhost:7402</span><span class="sr">/sample/s</span><span class="n">ystem</span><span class="sr">/console/</span><span class="n">bundlerepo</span><span class="p">?</span><span class="n">action</span><span class="o">=</span><span class="n">refreshOBR</span><span class="o">&amp;</span><span class="n">repository</span><span class="o">=</span><span class="n">file:</span><span class="sr">///tmp/</span><span class="n">repo</span><span class="o">/</span><span class="n">repository</span><span class="o">.</span><span class="n">xml</span>
+</pre></div>
+
+
+<p>Note: Only use <code>file:</code> URLs if you know Sling has access to the named file !</p>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1341347 by fmeschbe on Tue, 22 May 2012 08:25:18 +0000
+      </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>

Added: websites/staging/sling/trunk/content/tutorials-how-tos/jackrabbit-persistence.html
==============================================================================
--- websites/staging/sling/trunk/content/tutorials-how-tos/jackrabbit-persistence.html (added)
+++ websites/staging/sling/trunk/content/tutorials-how-tos/jackrabbit-persistence.html Tue May 22 08:25:32 2012
@@ -0,0 +1,177 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Sling - Jackrabbit Persistence</title>
+    <link rel="stylesheet" href="/css/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><strong>Documentation</strong> <br />
+<a href="/getting-started.html">Getting Started</a> <br />
+<a href="/the-sling-engine.html">The Sling Engine</a> <br />
+<a href="/development.html">Development</a> <br />
+<a href="/bundles.html">Bundles</a> <br />
+<a href="/tutorials-how-tos.html">Tutorials &amp; How-Tos</a> <br />
+<a href="/configuration.html">Configuration</a> <br />
+<a href="http://s.apache.org/sling.wiki">Wiki</a> <br />
+<a href="http://s.apache.org/sling.faq">FAQ</a> <br />
+<a href="/sitemap.html">Site Map</a></p>
+<p><strong>API Docs</strong>  <br />
+<a href="http://sling.apache.org/apidocs/sling6/index.html">Sling 6</a> <br />
+<a href="http://sling.apache.org/apidocs/sling5/index.html">Sling 5</a> <br />
+</p>
+<p><strong>Project info</strong> <br />
+<a href="http://sling.apache.org/site/downloads.cgi">Downloads</a> <br />
+<a href="http://www.apache.org/licenses/">License</a> <br />
+<a href="/contributing.html">Contributing</a> <br />
+<a href="/news.html">News</a> <br />
+<a href="/links.html">Links</a> <br />
+<a href="/project-information.html">Project Information</a> <br />
+<a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a> <br />
+<a href="http://svn.apache.org/viewvc/sling/trunk">Browse Source Repository</a> <br />
+<a href="/security.html">Security</a> <br />
+</p>
+<p><strong>Sponsorship</strong> <br />
+<a href="http://www.apache.org/foundation/thanks.html">Thanks</a> <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a> <br />
+<a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a> <br />
+</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>
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/tutorials-how-tos.html">Tutorials & How-Tos</a>
+      </div>
+      <h1>Jackrabbit Persistence</h1>
+      <h1 id="jackrabbit-persistence">Jackrabbit Persistence</h1>
+<p>Out-of-the-box the embedded Jackrabbit repository used by Sling (the Embedded Jackrabbit Repository bundle) uses Derby to persist the JCR nodes and properties. For some applications or environments it may be required or required to replace Derby with another backing store such as PostgreSQL or Oracle.</p>
+<p>This page is based on the journey of Tony Giaccone to get Sling running with a PostgreSQL based Jackrabbit instance.</p>
+<h2 id="management-summary">Management Summary</h2>
+<p>To replace Derby as the persistence manager for Jackrabbit the following steps are required:</p>
+<ol>
+<li>Provide a JDBC driver for your database as an OSGi bundle</li>
+<li>Reconfigure Jackrabbit to use your database</li>
+<li>(Re-) Start the Embedded Jackrabbit bundle</li>
+</ol>
+<p>When you are not using the Derby persistence manager, you may safely remove the Derby bundle from your Sling instance.</p>
+<h2 id="jdbc-driver">JDBC Driver</h2>
+<p>The hardest thing to do is probably getting the JDBC driver for your database. One option is to look at the bundles provided by Spring Source in their repository at http://www.springsource.com/repository/.</p>
+<p>Another option is to create the bundle on your own using Peter Kriens' <a href="">BND Tool</a>:</p>
+<ol>
+<li>Get the JDBC driver for your database from the driver provider</li>
+<li>
+<p>Wrap the JDBC driver library into an OSGi bundle:</p>
+<h1 id="example-for-postgresql-jdbc-3-driver-84-701">Example for PostgreSQL JDBC 3 driver 8.4-701</h1>
+<p>$ java -jar bnd.jar wrap postgresql-8.4-701.jdbc3.jar
+$ mv postgresql-8.4-701.jdbc3.bar postgresql-8.4-701.jdbc3-bnd.jar</p>
+</li>
+<li>
+<p>Deploy the driver to your local Maven 2 Repository (Required if adding the JDBC driver to a Maven build, e.g. using the Sling Launchpad Plugin)</p>
+<p>$ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql -Dversion=8.4.701.jdbc3 \
+        -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jar </p>
+</li>
+</ol>
+<p>Tony reports no success with the Spring Source bundle, whily the BND approach worked for the PostgreSQL JDBC driver.</p>
+<h2 id="replace-derby-in-a-running-sling-instance">Replace Derby in a running Sling Instance</h2>
+<p>To replace Derby in a running Sling instance follow these steps (e.g. through the Web Console at <code>/system/console</code>):</p>
+<ol>
+<li>Uninstall the Apache Derby bundle</li>
+<li>Install the JDBC bundle prepared in the first step</li>
+<li>Stop the Jackrabbit Embedded Repository bundle\
+This needs to be reconfigured and restarted anyway. So lets just stop it to prevent failures in the next step.</li>
+<li>Refresh the packages (click the <em>Refresh Packages</em> button)</li>
+</ol>
+<p>Alternatively, you may wish to stop Sling after uninstalling Derby and installing the JDBC bundle. Technically, this is not required, though.</p>
+<h2 id="reconfiguring-jackrabbit">Reconfiguring Jackrabbit</h2>
+<p>To actually use a persistence manager other than the default (Derby) persistence manager, you have to configure Jackrabbit to use it. Create a <code>repository.xml</code> file in the <code>sling/jackrabbit</code> folder before starting Sling for the first time. If the repository was already started, you can also modify the existing file.</p>
+<p>To prepare a repository.xml file before first startup, use the <code>[repository.xml]()</code> as a template and modify it by replacing the <code>&lt;PersistenceManager&gt;</code> elements to refer to the selected persistence manager.</p>
+<p>If the file already exists, you can modifiy this existing file and there is no need to get the original from the SVN repository.</p>
+<p>For example to use PostgreSQL instead of Derby modify the <code>&lt;PersistenceManager&gt;</code> elements as follows:</p>
+<div class="codehilite"><pre><span class="nt">&lt;Repository&gt;</span>
+    ...
+    <span class="nt">&lt;Workspace</span> <span class="na">name=</span><span class="s">&quot;</span><span class="cp">${</span><span class="n">wsp</span><span class="o">.</span><span class="n">name</span><span class="cp">}</span><span class="s">&quot;</span><span class="nt">&gt;</span>
+        ...
+        <span class="nt">&lt;PersistenceManager</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager&quot;</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;org.postgresql.Driver&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schema&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;user&quot;</span> <span class="na">value=</span><span class="s">&quot;YOUR_USER_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;password&quot;</span> <span class="na">value=</span><span class="s">&quot;YOUR_PASSWORD_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;jcr_</span><span class="cp">${</span><span class="n">wsp</span><span class="o">.</span><span class="n">name</span><span class="cp">}</span><span class="s">_&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;externalBLOBs&quot;</span> <span class="na">value=</span><span class="s">&quot;false&quot;/</span><span class="nt">&gt;</span>
+        <span class="nt">&lt;/PersistenceManager&gt;</span>
+        ...
+    <span class="nt">&lt;/Workspace&gt;</span>
+
+    <span class="nt">&lt;Versioning</span> <span class="na">rootPath=</span><span class="s">&quot;</span><span class="cp">${</span><span class="n">rep</span><span class="o">.</span><span class="n">home</span><span class="cp">}</span><span class="s">/version&quot;</span><span class="nt">&gt;</span>
+        ...
+        <span class="nt">&lt;PersistenceManager</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager&quot;</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;org.postgresql.Driver&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schema&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;user&quot;</span> <span class="na">value=</span><span class="s">&quot;YOUR_USER_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;password&quot;</span> <span class="na">value=</span><span class="s">&quot;YOUR_PASSWORD_HERE&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;version_&quot;/</span><span class="nt">&gt;</span>
+            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;externalBLOBs&quot;</span> <span class="na">value=</span><span class="s">&quot;false&quot;/</span><span class="nt">&gt;</span>
+        <span class="nt">&lt;/PersistenceManager&gt;</span>
+    <span class="nt">&lt;/Versioning&gt;</span>
+    ...
+<span class="nt">&lt;/Repository&gt;</span>
+</pre></div>
+
+
+<p>Modify the <code>url</code>, <code>user</code>, and <code>password</code> parameters to match your database setup.</p>
+<p>If you reconfigure Jackrabbit to use the new persistence manager, the existing repository data in the <code>sling/jackrabbit</code> directory, except the <code>repository.xml</code> file, of course, should now be removed.</p>
+<p>Finally either start Sling or start the Jackrabbit Embedded Repository bundle.</p>
+<h2 id="credits">Credits</h2>
+<p>This description is based on Tony Giaccone's description <a href="">Swapping Postgres for Derby</a> sent to the Sling Users mailing list.</p>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1341347 by fmeschbe on Tue, 22 May 2012 08:25:18 +0000
+      </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>

Added: websites/staging/sling/trunk/content/tutorials-how-tos/testing-sling-based-applications.html
==============================================================================
--- websites/staging/sling/trunk/content/tutorials-how-tos/testing-sling-based-applications.html (added)
+++ websites/staging/sling/trunk/content/tutorials-how-tos/testing-sling-based-applications.html Tue May 22 08:25:32 2012
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Sling - Testing Sling-based applications</title>
+    <link rel="stylesheet" href="/css/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><strong>Documentation</strong> <br />
+<a href="/getting-started.html">Getting Started</a> <br />
+<a href="/the-sling-engine.html">The Sling Engine</a> <br />
+<a href="/development.html">Development</a> <br />
+<a href="/bundles.html">Bundles</a> <br />
+<a href="/tutorials-how-tos.html">Tutorials &amp; How-Tos</a> <br />
+<a href="/configuration.html">Configuration</a> <br />
+<a href="http://s.apache.org/sling.wiki">Wiki</a> <br />
+<a href="http://s.apache.org/sling.faq">FAQ</a> <br />
+<a href="/sitemap.html">Site Map</a></p>
+<p><strong>API Docs</strong>  <br />
+<a href="http://sling.apache.org/apidocs/sling6/index.html">Sling 6</a> <br />
+<a href="http://sling.apache.org/apidocs/sling5/index.html">Sling 5</a> <br />
+</p>
+<p><strong>Project info</strong> <br />
+<a href="http://sling.apache.org/site/downloads.cgi">Downloads</a> <br />
+<a href="http://www.apache.org/licenses/">License</a> <br />
+<a href="/contributing.html">Contributing</a> <br />
+<a href="/news.html">News</a> <br />
+<a href="/links.html">Links</a> <br />
+<a href="/project-information.html">Project Information</a> <br />
+<a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a> <br />
+<a href="http://svn.apache.org/viewvc/sling/trunk">Browse Source Repository</a> <br />
+<a href="/security.html">Security</a> <br />
+</p>
+<p><strong>Sponsorship</strong> <br />
+<a href="http://www.apache.org/foundation/thanks.html">Thanks</a> <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a> <br />
+<a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a> <br />
+</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>
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/tutorials-how-tos.html">Tutorials & How-Tos</a>
+      </div>
+      <h1>Testing Sling-based applications</h1>
+      <h1 id="testing-sling-based-applications">Testing Sling-based applications</h1>
+<p>Automated testing of OSGi components and services can be challenging, as many of them depend on other services that must be present or simulated for testing.</p>
+<p>This page describes the various approaches that we use to test Sling itself, and introduces a number of tools that can help testing OSGi and HTTP-based applications.</p>
+<div class="toc">
+<ul>
+<li><a href="#testing-sling-based-applications">Testing Sling-based applications</a><ul>
+<li><a href="#unit-tests">Unit tests</a></li>
+<li><a href="#tests-that-use-a-jcr-repository">Tests that use a JCR repository</a></li>
+<li><a href="#mock-classes-and-services">Mock classes and services</a><ul>
+<li><a href="#side-note-injecting-services-in-private-fields">Side note: injecting services in private fields</a></li>
+</ul>
+</li>
+<li><a href="#pax-exam">Pax Exam</a></li>
+<li><a href="#sling-testing-tools-server-side-junit-tests">Sling testing tools: server-side JUnit tests</a></li>
+<li><a href="#http-based-integration-tests">HTTP-based integration tests</a></li>
+<li><a href="#summary">Summary</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<h2 id="unit-tests">Unit tests</h2>
+<p>When possible, unit tests are obviously the fastest executing ones, and it's easy to keep them close to the code that they're testing. </p>
+<p>We have quite a lot of those in Sling, the older use the JUnit3 TestCase base class, and later ones use JUnit4 annotations. Mixing both approaches is possible, there's no need to rewrite existing tests.</p>
+<h2 id="tests-that-use-a-jcr-repository">Tests that use a JCR repository</h2>
+<p>Utility classes from our <a href="">commons/testing</a> module make it easy to get a real JCR repository for testing. That's a bit slower than pure unit tests, of course, but this only adds 1-2 seconds to the execution of a test suite.</p>
+<p>The <code>RepositoryProviderTest</code> in that module uses this technique to get a JCR repository.</p>
+<p>Note that our utilities do not cleanup the repository between tests, so you must be careful about test isolation, for example by using unique paths for each test.</p>
+<h2 id="mock-classes-and-services">Mock classes and services</h2>
+<p>The next step is to use mock classes and services to simulate components that are needed for testing. This makes it possible to test OSGi service classes without an OSGi framework.</p>
+<p>We have a number of custom-written mock services in Sling, like <a href="">MockNodeType</a> for example. These handwritten mocks implement just what's needed for their tests, so they might not be reusable as is.</p>
+<p>In other cases we use <a href="">jmock</a> to help create mock objects without having to write much code - such mocking libraries take care of the plumbing and allow you to write just the bits of code that matter (often with funny syntaxes). The tests of the [org.apache.sling.event|https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/event/] bundle, for example, make extensive use of such mock services.</p>
+<p>The problem with mocks is that it can become hard to make sure you're actually testing something, and not just "mocking mocks". At a certain level of complexity, it becomes quicker and clearer to actually start an OSGi framework for automated tests.</p>
+<h3 id="side-note-injecting-services-in-private-fields">Side note: injecting services in private fields</h3>
+<p>To inject (real or fake) services in others for testing, without having to create getters and setters just for this, we use a reflection-based trick, as in this example:</p>
+<p><DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>setting a private field via reflection</B></DIV><DIV class="codeContent panelContent">
+    // set resource resolver factory
+    // in a ServletResolver object which has a private resourceResolverFactory field</p>
+<div class="codehilite"><pre><span class="x">ServletResolver servletResolver = ....</span>
+<span class="x">Class</span><span class="cp">&lt;?</span><span class="o">&gt;</span> <span class="nx">resolverClass</span> <span class="o">=</span> <span class="nx">servletResolver</span><span class="o">.</span><span class="nx">getClass</span><span class="p">()</span><span class="o">.</span><span class="nx">getSuperclass</span><span class="p">();</span>
+<span class="k">final</span> <span class="nx">java</span><span class="o">.</span><span class="nx">lang</span><span class="o">.</span><span class="nx">reflect</span><span class="o">.</span><span class="nx">Field</span> <span class="nx">resolverField</span> <span class="o">=</span> <span class="nx">resolverClass</span><span class="o">.</span><span class="nx">getDeclaredField</span><span class="p">(</span><span class="s2">&quot;resourceResolverFactory&quot;</span><span class="p">);</span>
+<span class="nx">resolverField</span><span class="o">.</span><span class="nx">setAccessible</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
+<span class="nx">resolverField</span><span class="o">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">servletResolver</span><span class="p">,</span> <span class="nx">factory</span><span class="p">);</span>
+</pre></div>
+
+
+<h2 id="pax-exam">Pax Exam</h2>
+<p><a href="">Pax Exam</a> allows you to easily start an OSGi framework during execution of a JUnit test suite.</p>
+<p>We currently use it for our <a href="">Sling installer integration tests</a> for example. As parts of the installer interact directly with the OSGi framework, it felt safer to test it in a realistic situation rather than mock everything.</p>
+<p>Such tests are obviously slower than plain unit tests and tests that use mocks. Our installer integration tests, using Pax Exam, take about a minute to execute on a 2010 macbook pro.</p>
+<h2 id="sling-testing-tools-server-side-junit-tests">Sling testing tools: server-side JUnit tests</h2>
+<p>The <a href="">Sling testing tools</a> include a module that executes JUnit tests server-side, in a Sling instance. This allows integration tests to run in a realistic environment, and could also be used for self-testing production systems.</p>
+<p>As I write this, we are not using those tools to test Sling itself, but we have a <a href="">complete example</a> of integration tests that use them to run server-side JUnit tests, including automatic setup of the test Sling instance.</p>
+<h2 id="http-based-integration-tests">HTTP-based integration tests</h2>
+<p>The highest level of integration is testing a complete Sling instance via its HTTP interface.</p>
+<p>We use this technique to test Sling itself: the <a href="">launchpad/integration-tests</a> module defines the tests (462 of them as I write this), and the [launchpad/testing|https://svn.apache.org/repos/asf/sling/trunk/launchpad/testing] module executes them, after setting up a Sling instance from scratch (which is quite easy as Sling is just a runnable jar). </p>
+<p>A simple mechanism (described in README files in these modules) allows individual tests to be executed quickly against a previously started Sling instance, to be able to write and debug tests efficiently.</p>
+<p>The test code could be made simpler using the fluent HTTP interfaces defined in the Sling testing tools described above, but the launchpad tests were written before that module was created, and as they're stable there's no reason to rewrite them. If you're planning on using this technique for your own applications, we recommend looking at the Sling testing tools instead of these "legacy" tests - but the basic technique is the same.</p>
+<p>One problem with these launchpad tests is that the tests of all Sling modules are defined in a single testing module, they are not co-located with the code that they test. This could be improved by providing the tests in bundles that can be created from the same Maven modules that the code that they test.</p>
+<h2 id="summary">Summary</h2>
+<p>Combining the above testing techniques has worked well for us in creating and testing Sling. Being able to test things at different levels of integration has proved an efficient way to get good test coverage without having to write too much boring test code.</p>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1341347 by fmeschbe on Tue, 22 May 2012 08:25:18 +0000
+      </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>

Modified: websites/staging/sling/trunk/content/url-decomposition.html
==============================================================================
--- websites/staging/sling/trunk/content/url-decomposition.html (original)
+++ websites/staging/sling/trunk/content/url-decomposition.html Tue May 22 08:25:32 2012
@@ -82,57 +82,139 @@
         <a href="/">Home</a>
       </div>
       <h1>URL decomposition</h1>
-      <p><a name="URLdecomposition-URLdecomposition"></a></p>
-<h1 id="url-decomposition">URL decomposition</h1>
-<p>During the <em>Resource Resolution</em> step, the client request URL is decomposed
-into the following parts:</p>
+      <h1 id="url-decomposition">URL decomposition</h1>
+<p>During the <em>Resource Resolution</em> step, the client request URL is decomposed into the following parts:</p>
 <ol>
-<li><em>Resource Path</em> -  The longest substring of the request URL such that the
-resource path is either the complete request URL or the next character in
-the request URL after the resource path is a dot (<em>.</em>).</li>
-<li><em>Selectors</em> -  If the first character in the request URL after the
-resource path is a dot, the string after the dot up to but not including
-the last dot before the next slash character or the end of the request URL.
-If the resource path spans the complete request URL no seletors exist. If
-only one dot follows the resource path before the end of the request URL or
-the next slash, also no selectors exist.</li>
-<li><em>Extension</em> -  The string after the last dot after the resource path in
-the request URL but before the end of the request URL or the next slash
-after the resource path in the request URL. </li>
-<li><em>Suffix Path</em> -  If the request URL contains a slash character after the
-resource path and optional selectors and extension, the path starting with
-the slash up to the end of the request URL is the suffix path. Otherwise,
-the suffix path is empty. Note, that after the resource path at least a dot
-must be in the URL to let Sling detect the resource path.</li>
+<li><em>Resource Path</em> -  The longest substring of the request URL such that the resource path is either the complete request URL or the next character in the request URL after the resource path is a dot (<code>.</code>).</li>
+<li><em>Selectors</em> -  If the first character in the request URL after the resource path is a dot, the string after the dot up to but not including the last dot before the next slash character or the end of the request URL. If the resource path spans the complete request URL no seletors exist. If only one dot follows the resource path before the end of the request URL or the next slash, also no selectors exist.</li>
+<li><em>Extension</em> -  The string after the last dot after the resource path in the request URL but before the end of the request URL or the next slash after the resource path in the request URL. </li>
+<li><em>Suffix Path</em> -  If the request URL contains a slash character after the resource path and optional selectors and extension, the path starting with the slash up to the end of the request URL is the suffix path. Otherwise, the suffix path is empty. Note, that after the resource path at least a dot must be in the URL to let Sling detect the resource path.</li>
 </ol>
-<p>There's a cheat sheet on Day's dev page under <a href="http://dev.day.com/content/docs/en/cq/current/developing/sling_cheatsheet.html">http://dev.day.com/content/docs/en/cq/current/developing/sling_cheatsheet.html</a>
- available to get you familiar with the URL decomposition of Sling.</p>
-<p><em>Examples</em>: Assume there is a Resource at <em>/a/b</em>, which has no children.</p>
+<p>There's a cheat sheet on Day's dev page under <a href="">http://dev.day.com/content/docs/en/cq/current/developing/sling_cheatsheet.html</a> available to get you familiar with the URL decomposition of Sling.</p>
+<p><em>Examples</em>: Assume there is a Resource at <code>/a/b</code>, which has no children.</p>
 <table>
-<tr><th> URI </th><th> Resource Path </th><th> Selectors </th><th> Extension </th><th> Suffix </th><th> Resource
-Found </th></tr>
-<tr><td> /a/b               </td><td> /a/b </td><td> null  </td><td> null </td><td> null       </td><td> yes </td></tr>
-<tr><td> /a/b.html          </td><td> /a/b </td><td> null  </td><td> html </td><td> null       </td><td> yes </td></tr>
-<tr><td> /a/b.s1.html           </td><td> /a/b </td><td> s1    </td><td> html </td><td> null       </td><td> yes </td></tr>
-<tr><td> /a/b.s1.s2.html        </td><td> /a/b </td><td> s1.s2 </td><td> html </td><td> null       </td><td> yes </td></tr>
-<tr><td> /a/b/c/d           </td><td> /a/b/c/d </td><td> null  </td><td> null </td><td> null       </td><td> no! </td></tr>
-<tr><td> /a/b./c/d           </td><td> /a/b </td><td> null  </td><td> null </td><td> /c/d   </td><td> yes </td></tr>
-<tr><td> /a/b.html/c/d      </td><td> /a/b </td><td> null  </td><td> html </td><td> /c/d       </td><td> yes </td></tr>
-<tr><td> /a/b.s1.html/c/d       </td><td> /a/b </td><td> s1    </td><td> html </td><td> /c/d       </td><td> yes </td></tr>
-<tr><td> /a/b.s1.s2.html/c/d        </td><td> /a/b </td><td> s1.s2 </td><td> html </td><td> /c/d       </td><td> yes </td></tr>
-<tr><td> /a/b/c/d.s.txt     </td><td> /a/b/c/d </td><td> s  </td><td> txt </td><td> null </td><td> no! </td></tr>
-<tr><td> /a/b.html/c/d.s.txt        </td><td> /a/b </td><td> null  </td><td> html </td><td> /c/d.s.txt </td><td> yes </td></tr>
-<tr><td> /a/b.s1.html/c/d.s.txt    </td><td> /a/b </td><td> s1    </td><td> html </td><td> /c/d.s.txt </td><td> yes </td></tr>
-<tr><td> /a/b.s1.s2.html/c/d.s.txt </td><td> /a/b </td><td> s1.s2 </td><td> html </td><td> /c/d.s.txt </td><td> yes </td></tr>
+<thead>
+<tr>
+<th>URI</th>
+<th>Resource Path</th>
+<th>Selectors</th>
+<th>Extension</th>
+<th>Suffix</th>
+<th>Resource Found</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>/a/b</td>
+<td>/a/b</td>
+<td>null</td>
+<td>null</td>
+<td>null</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.html</td>
+<td>/a/b</td>
+<td>null</td>
+<td>html</td>
+<td>null</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.html</td>
+<td>/a/b</td>
+<td>s1</td>
+<td>html</td>
+<td>null</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.s2.html</td>
+<td>/a/b</td>
+<td>s1.s2</td>
+<td>html</td>
+<td>null</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b/c/d</td>
+<td>/a/b/c/d</td>
+<td>null</td>
+<td>null</td>
+<td>null</td>
+<td>no!</td>
+</tr>
+<tr>
+<td>/a/b./c/d</td>
+<td>/a/b</td>
+<td>null</td>
+<td>null</td>
+<td>/c/d</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.html/c/d</td>
+<td>/a/b</td>
+<td>null</td>
+<td>html</td>
+<td>/c/d</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.html/c/d</td>
+<td>/a/b</td>
+<td>s1</td>
+<td>html</td>
+<td>/c/d</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.s2.html/c/d</td>
+<td>/a/b</td>
+<td>s1.s2</td>
+<td>html</td>
+<td>/c/d</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b/c/d.s.txt</td>
+<td>/a/b/c/d</td>
+<td>s</td>
+<td>txt</td>
+<td>null</td>
+<td>no!</td>
+</tr>
+<tr>
+<td>/a/b.html/c/d.s.txt</td>
+<td>/a/b</td>
+<td>null</td>
+<td>html</td>
+<td>/c/d.s.txt</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.html/c/d.s.txt</td>
+<td>/a/b</td>
+<td>s1</td>
+<td>html</td>
+<td>/c/d.s.txt</td>
+<td>yes</td>
+</tr>
+<tr>
+<td>/a/b.s1.s2.html/c/d.s.txt</td>
+<td>/a/b</td>
+<td>s1.s2</td>
+<td>html</td>
+<td>/c/d.s.txt</td>
+<td>yes</td>
+</tr>
+</tbody>
 </table>
-
 <p>{info:title=Automated tests and examples}
-The <a href="http://svn.apache.org/repos/asf/sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/request/SlingRequestPathInfoTest.java">SlingRequestPathInfoTest</a>
- demonstrates and tests this decomposition. Feel free to suggest additional
-tests that help clarify how this works!
+The <a href="">SlingRequestPathInfoTest</a> demonstrates and tests this decomposition. Feel free to suggest additional tests that help clarify how this works!
 {info}</p>
       <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
-        Rev. 1328899 by fmeschbe on Sun, 22 Apr 2012 16:52:13 +0000
+        Rev. 1341347 by fmeschbe on Tue, 22 May 2012 08:25:18 +0000
       </div>
       <div class="trademarkFooter"> 
         Apache Sling, Sling, Apache, the Apache feather logo, and the Apache Sling project



Mime
View raw message