sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r813971 [1/11] - /websites/staging/sling/trunk/content/
Date Sun, 22 Apr 2012 17:20:13 GMT
Author: buildbot
Date: Sun Apr 22 17:20:11 2012
New Revision: 813971

Staging update by buildbot for sling

    websites/staging/sling/trunk/content/   (props changed)

Propchange: websites/staging/sling/trunk/content/
--- cms:source-revision (original)
+++ cms:source-revision Sun Apr 22 17:20:11 2012
@@ -1 +1 @@

Modified: websites/staging/sling/trunk/content/46-line-blog.html
--- websites/staging/sling/trunk/content/46-line-blog.html (original)
+++ websites/staging/sling/trunk/content/46-line-blog.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,231 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">46 Line Blog</h1> -->
+<!-- -->
+<p>This tutorial is based on the first <em>Sling Gems</em> on The <a href="">Sling gems: a blog in 46 lines of code</a>
+. It has slightly been adapted to fit here.</p>
+<p>In this tutorial, the SlingPostServlet and the sling.js library are brought
+together using 46 (no kidding: <em>fourty-six</em>) lines of code to create a
+simple blog (or let's say <em>bloggish</em>) application.</p>
+<p>I used this example in my <a href="rapid-jcr-applications-development-with-sling.html"></a>
+ presentation at ApacheCon US 09 in Oakland (slides will be available
+soon), and I think it's a good testimony to the power and simplicity of
+<p><a name="46LineBlog-Audience"></a></p>
+<h2 id="audience">Audience</h2>
+<p>Although this is a simple sample, it requires some custom settings to work.
+If you're just starting with Sling, <a href="slingxsite:discover-sling-in-15-minutes.html">SLINGxSITE:Discover Sling in 15 minutes</a>
+ might be a better choice.</p>
+<p><a name="46LineBlog-Step0:Start,configureandlogintoSling"></a></p>
+<h2 id="step-0-start-configure-and-login-to-sling">Step 0: Start, configure and login to Sling</h2>
+<p>See <a href="slingxsite:getting-and-building-sling.html">SLINGxSITE:Getting and Building Sling</a>
+ for how to start Sling. Start it on port 8888 for the below links to work.</p>
+<p>For this sample we need the optional
+<em></em> bundle, if it's not present in
+the <a href="http://localhost:8888/system/console/bundles">OSGi console</a>
+, install and start it. That bundle is not released yet so you might need
+to build it yourself, from its [source|]
+. The bundle must then appear in the [OSGI console's list of bundles|http://localhost:8888/system/console/bundles]
+, with name = <em></em> and status =
+<p>Then, login using http://localhost:8888/?sling:authRequestLogin=1 which
+should prompt you for a username and password, use <em>admin</em> and <em>admin</em>.
+Once that's done, http://localhost:8888/index.html should say <em>You are
+currently logged in as user <em>admin</em> to workspace <em>default</em></em>.</p>
+<p><a name="46LineBlog-Step1:Creatingcontent"></a></p>
+<h2 id="step-1-creating-content">Step 1: Creating content</h2>
+<p>The easiest way to create content in Sling is to use an HTTP POST request,
+let's use a simple HTML form:</p>
+  <body>
+    <h1>Sling microblog</h1></p>
+<div class="codehilite"><pre><span class="nt">&lt;div&gt;</span>
+  <span class="nt">&lt;form</span> <span class="na">method=</span><span class="s">&quot;POST&quot;</span><span class="nt">&gt;</span>
+Title:<span class="nt">&lt;br/&gt;</span>
+<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span> <span class="na">name=</span><span class="s">&quot;title&quot;</span> <span class="na">style=</span><span class="s">&quot;width:100%&quot;</span><span class="nt">/&gt;</span>
+<span class="nt">&lt;br/&gt;</span>Text:<span class="nt">&lt;br/&gt;</span>
+<span class="nt">&lt;textarea</span> <span class="na">style=</span><span class="s">&quot;width:100%&quot;</span> <span class="na">name=</span><span class="s">&quot;text&quot;</span><span class="nt">&gt;&lt;/textarea&gt;</span>
+<span class="nt">&lt;br/&gt;</span>
+<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">value=</span><span class="s">&quot;save&quot;</span><span class="nt">/&gt;</span>
+<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;:redirect&quot;</span> <span class="na">value=</span><span class="s">&quot;*.html&quot;</span><span class="nt">/&gt;</span>
+  <span class="nt">&lt;/form&gt;</span>
+<span class="nt">&lt;/div&gt;</span>
+<span class="c">&lt;!-- code of step 2 comes here --&gt;</span>
+<div class="codehilite"><pre><span class="n">That</span><span class="err">&#39;</span><span class="n">s</span> <span class="n">two</span> <span class="n">input</span> <span class="n">fields</span><span class="p">,</span> <span class="n">a</span> <span class="n">submit</span> <span class="n">button</span> <span class="ow">and</span> <span class="n">a</span> <span class="n">hidden</span> <span class="n">field</span> <span class="n">that</span> <span class="n">tells</span>
+<p>Sling what to do after the POST (in this case: redirect to the html view of
+the node that was just created).</p>
+<div class="codehilite"><pre><span class="n">To</span> <span class="n">test</span> <span class="n">the</span> <span class="n">form</span><span class="p">,</span> <span class="n">start</span> <span class="n">Sling</span> <span class="ow">and</span> <span class="n">save</span> <span class="n">the</span> <span class="n">above</span> <span class="n">script</span> <span class="n">as</span>
+<p>{{/apps/blog/blog.esp}} {footnote}ESP is Sling's server-side javascript
+language{footnote} in the Sling repository - a WebDAV mount is the easiest
+way to do that. Browsing to {{http://localhost:8888/content/blog/*.html}}
+{footnote} This assumes your instance of Sling is running on port 8888. If
+that's not the case, adjust the example URLs accordingly. {footnote} should
+display the above form.</p>
+<div class="codehilite"><pre><span class="n">Input</span> <span class="n">some</span> <span class="n">data</span> <span class="p">(</span><span class="n">using</span> <span class="s">&quot;foo&quot;</span> <span class="k">for</span> <span class="n">the</span> <span class="n">title</span><span class="p">,</span> <span class="k">for</span> <span class="n">the</span> <span class="n">sake</span> <span class="n">of</span> <span class="k">our</span> <span class="n">examples</span>
+<p>below), save the form, and Sling
+    should display the form again, using the URL of the node that was just
+<div class="codehilite"><pre><span class="p">{</span><span class="n">note:title</span><span class="o">=</span><span class="n">AccessDeniedException</span><span class="p">?}</span>
+<span class="n">If</span> <span class="n">you</span> <span class="n">get</span> <span class="n">an</span> <span class="n">error</span> <span class="n">saying</span> <span class="n">_javax</span><span class="o">.</span><span class="n">jcr</span><span class="o">.</span><span class="n">AccessDeniedException:</span> <span class="o">...</span><span class="ow">not</span> <span class="n">allowed</span>
+<p>to add or modify item_ it means that you are not logged in as user <em>admin</em>.
+See instructions above for logging in.
+    {note}</p>
+<div class="codehilite"><pre><span class="n">At</span> <span class="n">this</span> <span class="n">point</span> <span class="n">you</span><span class="err">&#39;</span><span class="n">re</span> <span class="n">probably</span> <span class="n">looking</span> <span class="n">at</span> <span class="n">an</span> <span class="n">empty</span> <span class="n">form</span> <span class="n">with</span> <span class="n">an</span> <span class="n">URL</span> <span class="n">ending</span>
+<p>in <em>foo</em>, if you used that for the title. Or <em>foo_0</em> or <em>foo_1</em> if other
+_foo_s already existed. Don't worry about not seeing your content, we'll
+fix that right away.</p>
+<div class="codehilite"><pre><span class="n">h2</span><span class="o">.</span> <span class="n">Step</span> <span class="mi">2</span><span class="p">:</span> <span class="n">Where</span><span class="err">&#39;</span><span class="n">s</span> <span class="k">my</span> <span class="n">content</span><span class="p">?</span>
+<span class="n">To</span> <span class="n">verify</span> <span class="n">that</span> <span class="k">our</span> <span class="n">content</span> <span class="n">has</span> <span class="n">been</span> <span class="n">created</span><span class="p">,</span> <span class="n">we</span> <span class="n">can</span> <span class="n">have</span> <span class="n">a</span> <span class="n">look</span> <span class="n">at</span> <span class="n">the</span> <span class="n">JSON</span>
+<p>data at {{http://localhost:8888/content/blog/foo.tidy.json}}, which should
+display our new node's values:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">code:javascript</span><span class="p">}</span>
+<span class="p">{</span>
+  <span class="s">&quot;jcr:primaryType&quot;</span><span class="p">:</span> <span class="s">&quot;nt:unstructured&quot;</span><span class="p">,</span>
+  <span class="s">&quot;text&quot;</span><span class="p">:</span> <span class="s">&quot;This is the foo text&quot;</span><span class="p">,</span>
+  <span class="s">&quot;title&quot;</span><span class="p">:</span> <span class="s">&quot;foo&quot;</span>
+<span class="p">}</span>
+<p>That's reassuring, but what we really want is for these values to be
+displayed on the editing form for our post.</p>
+<p>Thanks to the <em>sling.js</em> client library, we just need to add a
+<em>Sling.wizard()</em> call to our form to display those values. Let's first
+add a <em><head></em> element to our form to load the <em>sling.js</em> library, before
+the existing <em><body></em> of course:</p>
+  <script src="/system/sling.js"></script>
+<div class="codehilite"><pre><span class="n">And</span> <span class="n">add</span> <span class="n">the</span> <span class="p">{{</span><span class="n">Sling</span><span class="o">.</span><span class="n">wizard</span><span class="p">()}}</span> <span class="n">after</span> <span class="n">the</span> <span class="n">form</span><span class="p">,</span> <span class="n">where</span> <span class="n">we</span> <span class="n">had</span> <span class="n">the</span> <span class="n">_code</span> <span class="n">of</span>
+<p>step 2 comes here_ comment:</p>
+<div class="codehilite"><pre>{code:html}
+<span class="c">&lt;!-- code of step 2 comes here --&gt;</span>
+<span class="nt">&lt;script&gt;</span>Sling.wizard();<span class="nt">&lt;/script&gt;</span>
+<p>Reloading the form at <em>http://localhost:8888/content/blog/</em>.html* and
+creating a new post should now redirect to an editable version of the post,
+with the form fields correctly initialized.</p>
+<p>We can now create and edit posts; let's add some navigation, using more of
+the <em>sling.js</em> functionality. </p>
+<p><a name="46LineBlog-Step3:Navigation"></a></p>
+<h2 id="step-3-navigation">Step 3: Navigation</h2>
+<p>The <em>sling.js</em> library provides utilities to access and manipulate content.
+For our blog, we'll use the <em>getContent(path)</em> method to list the
+siblings of the current node.</p>
+<p>Add the following code to your script, after the <em>Sling.wizard()</em> call
+that was added in step 2:</p>
+    <li><em><a href="/content/blog/*.html"><a href="create-new-post.html">Create new post</a>
+    <script>
+      var posts = Sling.getContent("/content/blog", 2);
+      for(var i in posts) {
+    document.write("<li>"
+      + "<a href='/content/blog/" + i + ".html'>"  <br />
+          + posts<a href="i.html">i</a>
+      + "</a></li>");
+      }
+    </script>
+<div class="codehilite"><pre><span class="n">The</span> <span class="n">first</span> <span class="nb">link</span> <span class="n">to</span> <span class="p">{{</span><span class="sr">/content/</span><span class="n">blog</span><span class="o">/*</span><span class="p">}}</span> <span class="n">brings</span> <span class="n">us</span> <span class="n">back</span> <span class="n">to</span> <span class="k">our</span> <span class="n">content</span>
+<p>creating form, which is nothing else than the editing form reading empty
+values and posting to the "magic star" URL. </p>
+<div class="codehilite"><pre><span class="n">The</span> <span class="n">rest</span> <span class="n">of</span> <span class="n">the</span> <span class="n">javascript</span> <span class="n">runs</span> <span class="n">client</span><span class="o">-</span><span class="n">side</span><span class="p">,</span> <span class="n">as</span> <span class="n">it</span> <span class="n">is</span> <span class="ow">not</span> <span class="n">embedded</span> <span class="n">in</span> <span class="p">{{</span><span class="o">&lt;</span><span class="nv">%</span>
+<p>%&gt;}} code markers, calls the {{sling.getContent}} method to get two levels
+of node data below {{/content/blog}}, and displays links to nodes that it
+<div class="codehilite"><pre><span class="n">That</span><span class="s">&#39;s a basic navigation, of course, in a real blog we&#39;</span><span class="n">d</span> <span class="n">need</span> <span class="n">some</span> <span class="n">paging</span>
+<p>and contextualization to cope with large numbers of posts.</p>
+<div class="codehilite"><pre><span class="n">Nevertheless</span><span class="p">,</span> <span class="n">with</span> <span class="n">this</span> <span class="n">addition</span> <span class="k">our</span> <span class="n">ESP</span> <span class="n">script</span> <span class="n">allows</span> <span class="n">us</span> <span class="n">to</span> <span class="n">create</span><span class="p">,</span> <span class="n">edit</span>
+<p>and navigate blog posts - not bad for 46 lines of code, including comments,
+whitespace and output formatting.</p>
+<div class="codehilite"><pre><span class="n">h2</span><span class="o">.</span> <span class="n">Step</span> <span class="mi">4</span><span class="p">:</span> <span class="n">Data</span> <span class="n">first</span><span class="p">,</span> <span class="n">structure</span> <span class="n">later</span>
+<span class="n">You</span> <span class="n">might</span> <span class="n">have</span> <span class="n">heard</span> <span class="n">this</span> <span class="n">mantra</span><span class="p">,</span> <span class="n">which</span> <span class="n">we</span> <span class="n">apply</span> <span class="n">in</span> <span class="n">many</span> <span class="n">areas</span> <span class="n">of</span> <span class="n">Sling</span><span class="o">.</span>
+<span class="n">In</span> <span class="n">this</span> <span class="k">case</span><span class="p">,</span> <span class="n">adding</span> <span class="n">a</span> <span class="k">new</span> <span class="n">field</span> <span class="n">to</span> <span class="k">our</span> <span class="n">blog</span> <span class="n">posts</span> <span class="n">could</span> <span class="ow">not</span> <span class="n">be</span> <span class="n">easier:</span>
+<p>just add an input field to the form, and Sling will do the rest.</p>
+<div class="codehilite"><pre><span class="n">Adding</span> <span class="n">this</span> <span class="n">inside</span> <span class="k">our</span> <span class="n">script</span><span class="err">&#39;</span><span class="n">s</span> <span class="p">{{</span><span class="sr">&lt;form&gt;</span><span class="p">}}</span> <span class="n">element</span><span class="p">,</span> <span class="k">for</span> <span class="n">example:</span>
+<span class="p">{</span><span class="n">code:html</span><span class="p">}</span>
+<span class="sr">&lt;br/&gt;</span><span class="n">Author:</span><span class="sr">&lt;br/&gt;</span>
+<span class="o">&lt;</span><span class="n">input</span> <span class="n">type</span><span class="o">=</span><span class="s">&quot;author&quot;</span> <span class="n">name</span><span class="o">=</span><span class="s">&quot;author&quot;</span> <span class="n">style</span><span class="o">=</span><span class="s">&quot;width:100%&quot;</span><span class="o">/&gt;</span>
+<p>Allows us to add an author name to our blog posts. No need to define
+anything at the repository level, as Sling is using it in unstructured mode
+in this case, and no need to migrate existing data, the author field of
+existing posts will simply be empty.</p>
+<p><a name="46LineBlog-IwantmyESP!"></a></p>
+<h2 id="i-want-my-esp">I want my ESP!</h2>
+<p>Now wait...we said we were going to create an ESP script, but our
+"application" is just static HTML and some client javascript at this point.</p>
+<p>That's correct - as we are using only Sling client-facing features at this
+point (HTTP POST and <em>sling.js</em>), we do not necessarily need to use ESP
+<p>To keep things simple, we'll refrain from adding ESP-based features at this
+point, but you can of course use any ESP code in the <em>blog.esp</em> "script".</p>
+<p><a name="46LineBlog-That'sthepowerofSling"></a></p>
+<h2 id="thats-the-power-of-sling">That's the power of Sling</h2>
+<p>The 46-line blog is a good example of the power of Sling. It leverages the <a href="slingxsite:manipulating-content---the-slingpostservlet-(|slingpostservlet.html">SlingPostServlet</a>
+, which handles POST requests in a form-friendly way, and the
+client library, which provides high-level functionality on the client side.</p>
+<hr />
         <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.

Modified: websites/staging/sling/trunk/content/adapters.html
--- websites/staging/sling/trunk/content/adapters.html (original)
+++ websites/staging/sling/trunk/content/adapters.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,154 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">Adapters</h1> -->
+<!-- -->
+<p><a name="Adapters-Adapters"></a></p>
+<h1 id="adapters">Adapters</h1>
+<p>The <em>Resource</em> and <em>ResourceResolver</em> interfaces are defined with a
+method <em>adaptTo</em>, which adapts the object to other classes. Using this
+mechanism the JCR session of the resource resolver calling the <em>adaptTo</em>
+method with the <em>javax.jcr.Session</em> class object. Likewise the JCR node
+on which a resource is based can be retrieved by calling the
+<em>Resource.adaptTo</em> method with the <em>javax.jcr.Node</em> class object.</p>
+<p>To use resources as scripts, the <em>Resource.adaptTo</em> method must support
+being called with the <em></em> class
+object. But of course, we do not want to integrate the script manager with
+the resource resolver. To enable adapting objects to classes which are not
+foreseen by the original implementation, a factory mechanism is used. This
+way, the script manager can provide an adapter factory to adapt
+<em>Resource</em> to <em>SlingScript</em> objects.</p>
+<p><a name="Adapters-Adaptable"></a></p>
+<h2 id="adaptable">Adaptable</h2>
+<p>The <em>Adaptable</em> interface defines the API to be implemented by a class
+providing adaptability to another class. The single method defined by this
+interface is</p>
+<div class="codehilite"><pre><span class="o">/**</span>
+ <span class="o">*</span> <span class="n">Adapts</span> <span class="n">the</span> <span class="n">adaptable</span> <span class="n">to</span> <span class="n">another</span> <span class="n">type</span><span class="o">.</span>
+ <span class="o">*</span> <span class="sr">&lt;p&gt;</span>
+ <span class="o">*</span> <span class="n">Please</span> <span class="ow">not</span> <span class="n">that</span> <span class="n">it</span> <span class="n">is</span> <span class="n">explicitly</span> <span class="n">left</span> <span class="n">as</span> <span class="n">an</span> <span class="n">implementation</span> <span class="n">detail</span>
+     * each call to this method with the same <code>type</code> yields the same
+     * object or a new object on each call.
+     * <p>
+     * Implementations of this method should document their adapted types as
+     * well as their behaviour with respect to returning newly created or not
+     * instance on each call.
+     <em>
+     * @param <AdapterType> The generic type to which this resource is adapted
+     *        to
+     * @param type The Class object of the target type, such as
+     *        <code>javax.jcr.Node.class</code> or
+     *        <code></code>
+     * @return The adapter target or <code>null</code> if the resource cannot
+     *     adapt to the requested type
+     </em>/
+    <AdapterType> AdapterType adaptTo(Class<AdapterType> type);</p>
+<p>This method is called to get a view of the same object in terms of another
+class. Examples of implementations of this method is the Sling
+<em>ResourceResolver</em> implementation providing adapting to a JCR session and
+the Sling JCR based <em>Resource</em> implementation providing adapting to a JCR
+<p><a name="Adapters-ExtendingAdapters"></a></p>
+<h2 id="extending-adapters">Extending Adapters</h2>
+<p>Sometimes an <em>Adaptable</em> implementation cannot foresee future uses and
+requirements. To cope with such extensibility requirements two interfaces
+and an abstract base class are defined:</p>
+<p><a name="Adapters-AdapterFactory"></a></p>
+<h2 id="adapterfactory">AdapterFactory</h2>
+<p>The <em>AdapterFactory</em> interface defines the service interface and API for
+factories supporting extensible adapters for <em>SlingAdaptable</em> objects.
+The interface has a single method:</p>
+<div class="codehilite"><pre>/**
+ * Adapt the given object to the adaptable type. The adaptable object is
+ * guaranteed to be an instance of one of the classes listed in the
+ * {@link #ADAPTABLE_CLASSES} services registration property. The type
+ * parameter is one of the classes listed in the {@link #ADAPTER_CLASSES}
+ * service registration properties.
+ * <span class="nt">&lt;p&gt;</span>
+ * This method may return <span class="nt">&lt;code&gt;</span>null<span class="nt">&lt;/code&gt;</span> if the adaptable object cannot
+ * be adapted to the adapter (target) type for any reason. In this case,
+     * implementation should log a message to the log facility noting the cause
+     * for not being able to adapt.
+     * <p>
+     * Note that the <code>adaptable</code> object is not required to implement
+     * the <code>Adaptable</code> interface, though most of the time this
+     * is called by means of calling the {@link Adaptable#adaptTo(Class)}
+     * method.
+     <em>
+     * @param <AdapterType> The generic type of the adapter (target) type.
+     * @param adaptable The object to adapt to the adapter type.
+     * @param type The type to which the object is to be adapted.
+     * @return The adapted object or <code>null</code> if this factory instance
+     *     cannot adapt the object.
+     </em>/
+    <AdapterType> AdapterType getAdapter(Object adaptable,
+        Class<AdapterType> type);</p>
+<p>Implementations of this interface are registered as OSGi services providing
+two lists: The list of classes wich may be adapted (property named
+<em>adaptables</em>) and the list of classes to which the adapted class may be
+adapted (property named <em>adapters</em>). A good example of an Class
+implementing <em>AdapterFactory</em> is the <em>SlingScriptAdapterFactory</em>.</p>
+<p><em>AdapterFactory</em> services are gathered by a <em>AdapterManager</em>
+implementation for use by consumers. Consumers should not care for
+<em>AdapterFactory</em> services.</p>
+<p><a name="Adapters-AdapterManager"></a></p>
+<h2 id="adaptermanager">AdapterManager</h2>
+<p>The <em>AdapterManager</em> is defines the service interface for the genralized
+and extensible use of <em>AdapterFactory</em> services. Thus the adapter manager
+may be retrieved from the service registry to try to adapt whatever object
+that needs to be adapted - provided appropriate adapters exist.</p>
+<p>The <em>AdapterManager</em> interface is defined as follows:</p>
+<div class="codehilite"><pre>/**
+ * Returns an adapter object of the requested <span class="nt">&lt;code&gt;</span>AdapterType<span class="nt">&lt;/code&gt;</span> for
+ * the given <span class="nt">&lt;code&gt;</span>adaptable<span class="nt">&lt;/code&gt;</span> object.
+ * <span class="nt">&lt;p&gt;</span>
+ * The <span class="nt">&lt;code&gt;</span>adaptable<span class="nt">&lt;/code&gt;</span> object may be any non-<span class="nt">&lt;code&gt;</span>null<span class="nt">&lt;/code&gt;</span>
+     * and is not required to implement the <code>Adaptable</code> interface.
+     <em>
+     * @param <AdapterType> The generic type of the adapter (target) type.
+     * @param adaptable The object to adapt to the adapter type.
+     * @param type The type to which the object is to be adapted.
+     * @return The adapted object or <code>null</code> if no factory exists to
+     *     adapt the <code>adaptable</code> to the <code>AdapterType</code>
+     *     or if the <code>adaptable</code> cannot be adapted for any other
+     *     reason.
+     </em>/
+    <AdapterType> AdapterType getAdapter(Object adaptable,
+        Class<AdapterType> type);</p>
+<p>Any object can theoretically be adapted to any class even if it does not
+implement the <em>Adaptable</em> interface, if an <em>AdapterFactory</em> service
+delivers a <em>getAdapter()</em> method which adapts an object to another one.
+To check if there's any existing <em>AdapterFactory</em> which can adapt a given
+object to another one the <em>AdapterManager</em> service with it's
+<em>getAdapter()</em> method does the job. So the <em>Adaptable</em> interface merely
+is an indicator that the object provides built-in support for beeing
+<p><a name="Adapters-SlingAdaptable"></a></p>
+<h2 id="slingadaptable">SlingAdaptable</h2>
+<p>The <em>SlingAdaptable</em> class is an implementation of the <em>Adaptable</em>
+interface which provides built-in support to call the <em>AdapterManager</em> to
+provide an adapter from the <em>Adaptable</em> object to the requested class.</p>
+<p>An example of extending the <em>SlingAdaptable</em> class will be the Sling JCR
+based <em>Resource</em> implementation. This way, such a resource may be adapted
+to a <em>SlingScript</em> by means of an appropriatley programmed
+<em>AdapterFactory</em> (see below).</p>
         <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.

Modified: websites/staging/sling/trunk/content/apache-sling-commons-thread-pool.html
--- websites/staging/sling/trunk/content/apache-sling-commons-thread-pool.html (original)
+++ websites/staging/sling/trunk/content/apache-sling-commons-thread-pool.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,20 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">Apache Sling Commons Thread Pool</h1> -->
+<!-- -->
+<p>The Apache Sling Commons Thread Pool bundle provides a thread pool
+services. All thread pools are managed by the
+<em>{}</em>. This service can
+be used to get a thread pool.</p>
+<p>Thread pools are managed by name - there is a default thread pool and
+custom thread pools can be generated on demand using a unique name.</p>
+<p>The thread pools are actually wrappers around the thread pool support
+(executer) from the Java library. The advantage of using this thread pool
+service is, that the pools can be configured and managed through OSGi
+configurations. In addition the bundle contains a plugin for the Apache
+Felix Web Console.</p>
+<p>When using the {nl:ThreadPoolMananger} it is important to release a thread
+pool using the manager after it has been used.</p>
         <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.

Modified: websites/staging/sling/trunk/content/apache-sling-community-roles-and-processes.html
--- websites/staging/sling/trunk/content/apache-sling-community-roles-and-processes.html (original)
+++ websites/staging/sling/trunk/content/apache-sling-community-roles-and-processes.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,82 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">Apache Sling Community Roles and Processes</h1> -->
+<!-- -->
+<p><a name="ApacheSlingCommunityRolesandProcesses-CommunityRolesandProcesses"></a></p>
+<h1 id="community-roles-and-processes">Community Roles and Processes</h1>
+<p>The Community Roles and Processes are put in effect as of 13/May/2009.
+Updated 7/December/2009 to reflect Sling being a top level project.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-Roles"></a></p>
+<h2 id="roles">Roles</h2>
+<p>There are different roles with which Sling community members may be
+associated: User, Contributor, Committer, and PMC (Project Management
+Committee) Member. These roles are assigned and assumed based on merit. </p>
+<p>The User and Contributor roles are acquired by using the software and
+participating in the community, but the Committer and PMC member roles can
+only be granted by a PMC vote.</p>
+<p>The roles defined here conform to the ASF's <a href="">definition of roles</a>
+<p><a name="ApacheSlingCommunityRolesandProcesses-Users"></a></p>
+<h3 id="users">Users</h3>
+<p>Users are the people who use any of the products of the Sling project.
+People in this role are not contributing code, but they are using the
+products, reporting bugs, making feature requests, testing code, and such.
+This is by far the most important category of people, since without users
+there is no reason for Sling. When a user starts to contribute code or
+documentation patches, they become a <em>Contributor</em>.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-Contributors"></a></p>
+<h3 id="contributors">Contributors</h3>
+<p>Contributors are the people who write code or documentation patches or
+contribute positively to the project in other ways. A volunteer's
+contribution is always recognized.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-Committers"></a></p>
+<h3 id="committers">Committers</h3>
+<p>Contributors who give frequent and valuable contributions to a subproject of Sling can have their status promoted to that of a <em><a href="">Committer</a>
+</em>. A Committer has write access to Sling's source code repository.
+Contributors of documentation are eligible as committers in the same way as
+contributors of pure code.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-PMCMembers"></a></p>
+<h3 id="pmc-members">PMC Members</h3>
+<p>Committers showing continued interest in the project and taking an active part in the evolution of the project may be elected as  <em><a href="">PMC</a>
+ members</em>. The PMC (Project Management Committee) is the official managing
+body of project and is responsible for setting its overall direction.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-Processes"></a></p>
+<h2 id="processes">Processes</h2>
+<p><a name="ApacheSlingCommunityRolesandProcesses-BecomingaUserorContributor"></a></p>
+<h3 id="becoming-a-user-or-contributor">Becoming a User or Contributor</h3>
+<p>There is no requirement for becoming a User or Contributor; these roles are
+open to everyone.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-BecomingaCommitter"></a></p>
+<h3 id="becoming-a-committer">Becoming a Committer</h3>
+<p>In order for a Contributor to become a Committer, a member of the PMC can
+nominate that Contributor to the PMC. Once a Contributor is nominated, the
+PMC calls a vote on the PMC private mailing list.</p>
+<p>If there are at least three positive votes and no negative votes after
+three days (72 hours), the results are posted to the PMC private mailing
+<p>Upon a positive vote result, the Contributor will be emailed by the PMC to
+invite him/her to become a Committer. If the invitation is accepted, an
+announcement about the new Committer is made to the developer mailing list
+and he/she is given write access to the source code repository. A
+Contributor will not officially become a Committer member until the
+appropriate legal paperwork is submitted.</p>
+<p><a name="ApacheSlingCommunityRolesandProcesses-BecomingaPMCMember"></a></p>
+<h3 id="becoming-a-pmc-member">Becoming a PMC Member</h3>
+<p>In order for a Committer to become a member of the PMC, a member of the PMC
+can nominate that Committer to the PMC. Once a Committer is nominated, the
+PMC calls a vote on the PMC private mailing list.</p>
+<p>If there are at least three positive votes and no negative votes after
+three days (72 hours), the results are posted to the PMC private mailing
+<p>To have the Committer being accepted as a PMC member, the ASF Board has
+acknowledge the addition to the PMC. The Committer should not be consulted
+about his/her desire to become a PMC member before the board
+acknowledgement, or be informed that they are being considered, since this
+could create hard feelings if the vote does not pass.</p>
+<p>Upon a positive vote result, the PMC member will be emailed by the PMC to
+invite him/her to become a PMC member. If the invitation is accepted, an
+announcement about the new PMC member is made to the developer mailing
         <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.

Modified: websites/staging/sling/trunk/content/apache-sling-eventing-and-job-handling.html
--- websites/staging/sling/trunk/content/apache-sling-eventing-and-job-handling.html (original)
+++ websites/staging/sling/trunk/content/apache-sling-eventing-and-job-handling.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,464 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">Apache Sling Eventing and Job Handling</h1> -->
+<!-- -->
+<p><em>NOTE: This documentation is work in progress!</em></p>
+<p><a name="ApacheSlingEventingandJobHandling-Overview"></a></p>
+<h2 id="overview">Overview</h2>
+<p>The Apache Sling Event Support bundle provides interesting services for
+advanced event handling and job processing. While this bundle leverages the
+OSGi EventAdmin, it provides a very powerful support for so called jobs: a
+job is a task which has to be performed by a component - the Sling job
+handling ensures that exactly one component performs this task.</p>
+<p>To get some hands on code, you can refer to the following tutorials:
+<em> <a href="how-to-manage-events-in-sling.html">How to Manage Events in Sling</a>
+</em> <a href="scheduler-service-(commons-scheduler).html">Scheduler Service (commons scheduler)</a></p>
+<p>The Sling Event Supports adds the following services:
+<em> <a href="#jobs.html">Jobs</a>
+</em> <a href="#distributed.html">Distributed Events</a>
+* <a href="#timed.html">Scheduled Events</a></p>
+<a name="ApacheSlingEventingandJobHandling-Jobs(GuaranteeofProcessing)"></a></p>
+<h2 id="jobs-guarantee-of-processing">Jobs (Guarantee of Processing)</h2>
+<p>In general, the eventing mechanism (OSGi EventAdmin) has no knowledge about
+the contents of an event. Therefore, it can't decide if an event is
+important and should be processed by someone. As the event mechanism is a
+"fire event and forget about it" algorithm, there is no way for an event
+admin to tell if someone has really processed the event. Processing of an
+event could fail, the server or bundle could be stopped etc.</p>
+<p>On the other hand, there are use cases where the guarantee of processing a
+job is a must and usually this comes with the requirement of processing
+this job exactly once. Typical examples are sending notification emails (or
+sms) or post processing of content (like thumbnail generation of images or
+<p>The Sling Event Support adds the notion of a job to the OSGi EventAdmin. A
+job is a special OSGi event that someone has to process (do the job). The
+job event has a special topic <em>org/apache/sling/event/job</em> to indicate that
+the event contains a job. These job events are consumed by the Sling Job
+Handler - it ensures that someone does the job! To support different jobs
+and different processors of such jobs, the real topic of the event is
+stored in the <em>event.job.topic</em> property of the original event. When a job
+event (event with the topic <em>org/apache/sling/event/job</em>) is received, a
+new event with the topic from the property <em>event.job.topic</em> is fired
+(Firing this event comes of course with a set of rules and constraints
+explained below).</p>
+<p>In order to distinguish a job which occured twice and a job which is
+generated "at the same time" on several nodes, each job can be uniquely
+identified by its topic (property <em>event.job.topic</em>) and an optional job
+name, the <em></em> property. It is up to the client creating the
+event to ensure that the <em></em> property is unqiue <em>and</em> identical
+on all application nodes. If the job name is not provided for the job, then
+it is up to the client to ensure that the job event is only fired once.
+Usually for jobs generated based on user interaction, a unique job name is
+not required as the job is only created through the user interaction.</p>
+<p><a name="ApacheSlingEventingandJobHandling-JobProcessors"></a></p>
+<h3 id="job-processors">Job Processors</h3>
+<p>A job processor is a service consuming and processing a job. It listens for
+OSGi events with the job topic. The OSGi EventAdmin usually comes with a
+timeout for event handlers. An event handler must consume an OSGi event as
+fast as possible otherwise the handler might get a timeout and get
+blacklisted. Therefore a job processor should never directly process the
+job in the event handler method, but do this async.</p>
+<p>In addition the Sling Job Handler needs to get notified if someone is
+processing a job and when someone has finished processing this job.</p>
+<p>To make implementing such a job processor easier, there is the <em>JobUtil</em>
+utility class along with the <em>JobProcessor</em> interface. The <em>JobUtil</em> class
+has a helper method for this: <em>processJob(Event, JobProcessor)</em>. The job
+processor must implement the <em>JobProcessor</em> interface which consists of a
+single <em>process(Event)</em> method. When the event handler receives a job event
+through the OSGi EventAdmin, it calls <em>JobUtil.processJob(event, this)</em> and
+returns. This utility method takes care to notify the Sling Job Handler
+that someone is processing the job. Then the <em>process(Event)</em> method of the
+job processor is called in the background and when it returns, the Sling
+Job Handler is notified that the job is completed (or processing failed).</p>
+<p>If the job processor wants to do the background processing by itself or
+does not need background processing at all, it must signal starting and
+completition of the job by call <em>JobUtil.acknowledgeJob(Event),
+_JobUtil.finishedJob(event)</em> or _JobUtil.rescheduleJob(Event).</p>
+<p><a name="ApacheSlingEventingandJobHandling-ProcessingofJobs"></a></p>
+<h3 id="processing-of-jobs">Processing of Jobs</h3>
+<p>Incoming jobs are first persisted in the repository (for failover etc.) and
+then a job is put into a processing queue. There are different types of
+queues defining how the jobs are processed (one after the other, in
+parallel etc.).</p>
+<p>For managing queues, the Sling Job Handler uses the OSGi ConfigAdmin - it
+is possible to configure one or more queue configurations through the
+ConfigAdmin. One way of creating and configuring such configurations is the
+Apache Felix WebConsole.</p>
+<p><a name="ApacheSlingEventingandJobHandling-QueueConfigurations"></a></p>
+<h4 id="queue-configurations">Queue Configurations</h4>
+<p>A queue configuration can have the following properties:</p>
+<tr><td> *Property Name*     </td><td> *Description* </td></tr>
+<tr><td> _queue.name_        </td><td> The name of the queue. If matching is used for
+topics, the value \{0\} can be used for replacing the matched part. </td></tr>
+<tr><td> _queue.type_        </td><td> The type of the queue: ORDERED, UNORDERED,
+<tr><td> _queue.topics_       </td><td> A list of topics processed by this queue. Either
+the concrete topic is specified or the topic string ends with /* or /. If a
+star is at the end all topics and sub topics match, with a dot only direct
+sub topics match. </td></tr>
+<tr><td> _queue.maxparallel_        </td><td> How many jobs can be processed in parallel?
+-1 for number of processors.</td></tr>
+<tr><td> _queue.retries_    </td><td> How often should the job be retried. -1 for
+endless retries. </td></tr>
+<tr><td> _queue.retrydelay_    </td><td> The waiting time in milliseconds between job
+retries. </td></tr>
+<tr><td> _queue.priority_    </td><td> The thread priority: NORM, MIN, or MAX </td></tr>
+<tr><td> _queue.runlocal_    </td><td> Should the jobs only be processed on the cluster
+node they have been created? </td></tr>
+<tr><td> _queue.applicationids_       </td><td> Optional list of application (cluster
+node) ids. If configured, these jobs are only processed on this application
+<tr><td> _service.ranking_ </td><td> A ranking for this configuration.</td></tr>
+<p>The configurations are processed in order of their service ranking. The
+first matching queue configuration is used for the job.</p>
+<p><a name="ApacheSlingEventingandJobHandling-OrderedQueues"></a></p>
+<h4 id="ordered-queues">Ordered Queues</h4>
+<p>An ordered queue processes one job after the other.</p>
+<p><a name="ApacheSlingEventingandJobHandling-UnorderedQueues"></a></p>
+<h4 id="unordered-queues">Unordered Queues</h4>
+<p>Unordered queues process jobs in parallel.</p>
+<p><a name="ApacheSlingEventingandJobHandling-Topic-Round-RobinQueues"></a></p>
+<h4 id="topic-round-robin-queues">Topic-Round-Robin Queues</h4>
+<p>The jobs are processed in parallel. Scheduling of the jobs is based on the
+topic of the jobs. These are started by doing round-robin on the available
+<p><a name="ApacheSlingEventingandJobHandling-IgnoringQueues"></a></p>
+<h4 id="ignoring-queues">Ignoring Queues</h4>
+<p>A queue of type <em>ignoring</em> ignores this job. The job is persisted but not
+processed. This can be used to delay processing of some jobs. With a
+changed configuration and a restart of the Sling Job Handler the ignored
+jobs can be processed at a later time.</p>
+<p><a name="ApacheSlingEventingandJobHandling-DroppingQueues"></a></p>
+<h4 id="dropping-queues">Dropping Queues</h4>
+<p>A queue of type <em>drop</em> is dropping a job - which means it is not processed
+at all and directly discarded.</p>
+<p><a name="ApacheSlingEventingandJobHandling-Persistence"></a></p>
+<h3 id="persistence">Persistence</h3>
+<p>The job event handler listens for all job events (all events with the topic
+<em>org/apache/sling/event/job</em>) and will as a first step persist those events
+in the JCR repository. All job events are stored in a tree under the job
+root node <em>/var/eventing/jobs</em>. Persisting the job ensures proper handling
+in a clustered environment and allows failover handling after a bundle stop
+or server restart. Once a job has been processed by someone, the job will
+be removed from the repository.</p>
+<p>When the job event listener tries to write a job into the repository it
+will check if the repository already contains a job with the given topic
+<em>event.job.topic</em> and job name (property <em></em>). If the event has
+already been written by some other application node, it's not written
+<p>Each job is stored as a separate node with the following properties:
+<tr><td> <em>Property Name</em>     </td><td> <em>Description</em> </td></tr>
+<tr><td> <em>event:topic</em>       </td><td> The topic of the job </td></tr>
+<tr><td> <em>event:id</em>       </td><td> The unique identifier of this job (optional).
+<tr><td> <em>event:created</em>     </td><td> The date and time when the event has been created
+(stored in the repository)
+<tr><td> <em>event:application</em> </td><td> The identifier of the node where the job was
+created </td></tr>
+<tr><td> <em>event:properties</em>  </td><td> Serialized properties </td></tr>
+<tr><td> <em>event:finished</em>    </td><td> The date and time when the job has been finished </td></tr>
+<tr><td> <em>event:processor</em>   </td><td> The identifier of the node which processed the job
+(after successful processing) </td></tr>
+<p>The failover of an application node is accomplished by locking. If a job is
+locked in the repository a session scoped lock is used. If this application
+node dies, the lock dies as well. Each application node observes the JCR
+locking properties and therefore gets aware of unlocked event nodes with
+the active flag set to true. If an application node finds such a node, it
+locks it, updates the <em>event:application</em> information and processes it
+accordingly. In this case the event gets the additional property
+<em>org/apache/sling/job/retry</em>. </p>
+<p>Each application is periodically removing old jobs from the repository
+(using the scheduler).</p>
+<p><a name="ApacheSlingEventingandJobHandling-DistributionofJobs"></a></p>
+<h3 id="distribution-of-jobs">Distribution of Jobs</h3>
+<p>A job event is an event like any other. Therefore it is up to the client
+generating the event to decide if the event should be distributed. If the
+event is distributed, it will be distributed with a set <em>event.application</em>
+on the remote nodes. If the job event handler receives a job with the
+<em>event.application</em> property set, it will not try to write it into the
+repository. It will just broadcast this event asynchronously as a ~FYI
+<p>If a job event is created simultanously on all application nodes, the event
+will not be distributed. The application node that actually has the lock on
+the stored job in the repository will clear the <em>event.application</em> when
+sending the event locally. All other application nodes will use the
+<em>event.application</em> stored in the repository when broadcasting the event
+<p><a name="ApacheSlingEventingandJobHandling-UsagePatterns"></a></p>
+<h2 id="usage-patterns">Usage Patterns</h2>
+<p>Based on some usage patterns, we discuss the functionality of the eventing
+<p><a name="ApacheSlingEventingandJobHandling-SendingUserGeneratedEvents"></a></p>
+<h3 id="sending-user-generated-events">Sending User Generated Events</h3>
+<p>If a user action results in an event, the event is only created on one
+single node in the cluster. The event object is generated and delivered to
+the OSGi event admin. If the <em>event.distribute</em> is not explicitly set, the
+event is only distributed localled.</p>
+<p>If the <em>event.distribute</em> is the, the cluster event handler will write the
+event into the repository. All nodes in the cluster observe the repository
+area where all events are stored. If a new event is written into that area,
+each application node will get notified. It will create the event based on
+the information in the repository, clear the <em>event.distribute</em> and publish
+the event.</p>
+<p>The flow can be described as follows:
+1. Client code generates event using OSGi API, if the <em>event.distribute</em>
+should be set, it is using the ~EventUtil.
+1. Client code sends the event to the (local) event admin.
+1. Event admin delivers the event locally.
+1. Clustering event handler receives the event if <em>event.distribute</em> is
+1. # Event handler adds <em>event.application</em> and writes the event to the
+1. # Remote repository observers get notified through JCR observation about
+the new event. They distribute the event locally with the
+<em>event.application</em> (from the node where the event occured first) and
+cleared <em>event.distribute</em>.</p>
+<p><a name="ApacheSlingEventingandJobHandling-ProcessingJCREvents"></a></p>
+<h3 id="processing-jcr-events">Processing JCR Events</h3>
+<p>JCR events are environment generated events and therefore are sent by the
+repository to each node in the cluster. In general, it is advisable to not
+built the application on the low level repository events but to use
+application events. Therefore the observer of the JCR event should create
+an OSGi event based on the changes in the repository. A decision has to be
+made if the event should be a job or a plain event.</p>
+<p>The flow can be described as follows:
+1. Client registers for JCR observation
+1. JCR notifies the client for changes
+1. Client generates OSGi event based on the JCR events (the
+<em>event.distribute</em> will not be set), it decides if it sends this event as a
+1. Client code sends the event to the (local) event admin
+1. Event admin publishes the event locally
+1. The distribution event handler does not set see the event as the
+<em>event.distribute</em> is not set.
+1. The job event handler gets the event if it has the job topic
+1. # The job event handler adds the <em>event.application</em> property and tries to
+write the job to the repository
+1. ## If no job with the topic and <em>id</em> property is in the repository, the
+event will be written and locked.
+1. ## If an event with the topic and <em>id</em> property is in the repository then:
+1. ### If the <em>event.application</em> equals the current application node, the
+event is set to active (<em>event:active</em>) in the repository again and locked
+1. ### If the <em>event.application</em> does not equal the current application
+node, the event is not distributed locally.
+1. ## If the job could be locked in the repository, the job event handler
+delivers the job locally and synchronously and it unlocks the job and sets
+<em>event:active</em> to false afterwards.</p>
+<p><a name="ApacheSlingEventingandJobHandling-SendingScheduledEvents"></a></p>
+<h3 id="sending-scheduled-events">Sending Scheduled Events</h3>
+<p>Scheduled events are OSGi events that have been created by the environemnt.
+They are generated on each application node of the cluster through an own
+scheduler instance. Sending these events works the same as sending events
+based on JCR events (see above).</p>
+<p>In most use cases a scheduler will send job events to ensure that exactly
+one application node is processing the event.</p>
+<p><a name="ApacheSlingEventingandJobHandling-ReceivingOSGiEvents"></a></p>
+<h3 id="receiving-osgi-events">Receiving OSGi Events</h3>
+<p>If you want to receive OSGi events, you can just follow the specification:
+receive it via a custom event handler which is registered on bundle start -
+a filter can be specified as a configuration property of the handler. </p>
+<p>As we follow the principle of distributing each event to every registered
+handler, the handler has to decide if it will process the event. In order
+to avoid multiple processing of this event in a clustered environment, the
+event handler should check the <em>event.application</em> property. If it is not
+set, it's a local event and the handler should process the event. If the
+<em>event.application</em> is set, it's a remote event and the handler should not
+process the event. This is a general rule of thumb - however, it's up to
+the handler to make its decision either on <em>event.application</em> or any other
+<p>It is advisable to perform the local event check even in a non clustered
+environment as it makes the migration to a cluster later on much easier and
+there is nearly no performance overhead caused by the check.</p>
+<p>The ~EventUtil class provides an utility method <em>isLocalEvent(Event)</em> which
+checks the existance of the <em>event.application</em> property and returns <em>true</em>
+if it is absend.</p>
+<a name="ApacheSlingEventingandJobHandling-DistributedEvents"></a></p>
+<h2 id="distributed-events">Distributed Events</h2>
+<p>In addition to the job handling, the Sling Event support adds handling for
+distributed events. A distributed event is an OSGi event which is sent
+across JVM boundaries to a different VM. A potential use case is to
+broadcast information in a clustered environment.</p>
+<p><a name="ApacheSlingEventingandJobHandling-SourcesofEvents"></a></p>
+<h3 id="sources-of-events">Sources of Events</h3>
+<p>When it comes to application based on Sling, there is a variety of sources
+from which OSGi events can be send:
+<em> JCR observation events
+</em> Application generated events
+<em> Events from messaging systems (~JMS)
+</em> "External events"</p>
+<p>The events can eiter be generated inside a current user context, e.g. when
+the user performs an action through the UI, or they can be out of a user
+context, e.g. for schedulded events. This leads to different weights of
+<p><a name="ApacheSlingEventingandJobHandling-WeightsofEvents"></a></p>
+<h3 id="weights-of-events">Weights of Events</h3>
+<p>We can distinguish two different weights of events, depending how they are
+distributed in a clustered environment:</p>
+<li>User generated events - these events are generated directly by some user
+action and are therefore started on one single node.</li>
+<li>Environment generated events (JCR events, scheduler events etc.) - these
+events are generated "simultanously" on all nodes.</li>
+<p>External events, like incoming JMS events etc. might fall either into the
+first or the second category. The receiver of such events must have the
+knowledge about the weight of the event.</p>
+<p><a name="ApacheSlingEventingandJobHandling-BasicPrinciples"></a></p>
+<h3 id="basic-principles">Basic Principles</h3>
+<p>The foundation of the distributed event mechanism is to distribute each
+event to every node in a clustered environment. The event distribution
+mechanism has no knowledge about the intent of the event and therefore is
+not able to make delivery decisions by itself. It is up to the sender to
+decide what should happen, however the sender must explicitly declare an
+event to be distributed. There are exceptions to "distributing everything
+to everywhere" as for example framework related events (bundle stopped,
+installed etc.) should not be distributed.</p>
+<p>The event mechanism will provide additional functionality making it easier
+for event receivers to decide if they should process an event. The event
+receiver can determine if the event is a local event or comming from a
+remote application node. Therefore a general rule of thumb is to process
+events only if they're local and just regard remote events as a FYI.</p>
+<p>The event mechanism is an <em>event</em> mechanism which should not be confused
+with a <em>messaging</em> mechanism. Events are received by the event mechanism
+and distributed to registered listeners. Concepts like durable listeners,
+guarantee of processing etc. are not part of the event mechanism itself.
+However, there is additional support for such things, like job handling.</p>
+<p>The application should try to use application events instead of low level
+JCR events whereever possible. Therefore a bridging between JCR events and
+the event mechanism is required. However, a general "automatic" mapping
+will not be provided. It is up to the application to develop such a mapping
+on a per use case base. There might be some support to make the mapping
+<p>The event handling should be made as transparent to the developer as
+possible. Therefore the additional code for a developer to make the
+eventing working in a clustered environment etc. should be kept to a
+minimum (which will hopefully reduce possible user errors).</p>
+<p><a name="ApacheSlingEventingandJobHandling-DistributedEvents"></a></p>
+<h3 id="distributed-events_1">Distributed Events</h3>
+<p>For distributed events two properties are defined (check the <em>EventUtil</em>
+<em> <em>event.distribute</em> - this flag is set by the sender of an event to give a
+hint if the event should be distributed across instances. For example JCR
+observation based events are already distributed on all instances, so there
+is no further need to distribute them. If the flag is present, the event
+will be distributed. The value has currently no meaning, however the
+EventUtil method should be used to add this property. If the flag is absent
+the event is distributed locally only.</em> <em>event.application</em> - An identifier for the current application node in
+the cluster. This information will be used to detect if an event has been
+created on different nodes. If the event has been created on the same node,
+the <em>event.application</em> is missing, if it is a remote event, the
+<em>event.application</em> contains the ID of the node, the event has been
+initially created. Use the <em>EventUtil.isLocal(Event)</em> method to detect if
+the event is a local or a distributed event.</p>
+<p>While the <em>event.distribute</em> must be set by the sender of an event (if the
+event should be distributed), the <em>event.application</em> property is
+maintained by the event mechanism. Therefore a client sending an event
+should <em>never</em> set this information by itself. This will confuse the local
+event handlers and result in unexpected behaviour. On remote events the
+<em>event.application</em> is set by the event distribution mechanism.</p>
+<p><a name="ApacheSlingEventingandJobHandling-EventDistributionAcrossApplicationNodes(Cluster)"></a></p>
+<h3 id="event-distribution-across-application-nodes-cluster">Event Distribution Across Application Nodes (Cluster)</h3>
+<p>The (local) event admin is the service distributing events locally. The
+Sling Distributing Event Handler is a registered event handler that is
+listening for events to be distributed. It distributes the events to remote
+application notes, the JCR repository is used for distribution. The
+distributing event handler writes the events into the repository, the
+distributing event handlers on other application nodes get notified through
+observation and then distribute the read events locally.</p>
+<p>As mentioned above, the client sending an event has to mark an event to be
+distributed in a cluster by setting the <em>event.distribute</em> in the event
+properties (through <em>EventUtil</em>). This distribution mechanism has the
+advantage that the application nodes do not need to know each other and the
+distribution mechanism is independent from the used event admin
+<p><a name="ApacheSlingEventingandJobHandling-StoringEventsintheRepository"></a></p>
+<h3 id="storing-events-in-the-repository">Storing Events in the Repository</h3>
+<p>Distributable events are stored in the repository, the repository will have
+a specific area (path) where all events are stored. </p>
+<p>Each event is stored as a separate node with the following properties:
+<tr><td> <em>Property Name</em>     </td><td> <em>Description</em> </td></tr>
+<tr><td> <em>event:topic</em>       </td><td> The topic of the event </td></tr>
+<tr><td> <em>event:application</em> </td><td> The identifier of the application node where the
+event was created </td></tr>
+<tr><td> <em>event:created</em>     </td><td> The date and time when the event has been created
+(stored in the repository)
+<tr><td> <em>event:properties</em>  </td><td> Serialized properties (except the
+<em>event.distribute</em>, but including the <em>event.application</em>) </td></tr>
+<p>Each application is periodically removing old events from the repository
+(using the scheduler).</p>
+<a name="ApacheSlingEventingandJobHandling-SendingScheduledEvents"></a></p>
+<h3 id="sending-scheduled-events_1">Sending Scheduled Events</h3>
+<p>Scheduled events are OSGi events that have been created by the environemnt.
+They are generated on each application node of the cluster through an own
+scheduler instance. Sending these events works the same as sending events
+based on JCR events (see above).</p>
+<p>In most use cases a scheduler will send job events to ensure that exactly
+one application node is processing the event.</p>
+<p><a name="ApacheSlingEventingandJobHandling-ReceivingOSGiEvents"></a></p>
+<h3 id="receiving-osgi-events_1">Receiving OSGi Events</h3>
+<p>If you want to receive OSGi events, you can just follow the specification:
+receive it via a custom event handler which is registered on bundle start -
+a filter can be specified as a configuration property of the handler. </p>
+<p>As we follow the principle of distributing each event to every registered
+handler, the handler has to decide if it will process the event. In order
+to avoid multiple processing of this event in a clustered environment, the
+event handler should check the <em>event.application</em> property. If it is not
+set, it's a local event and the handler should process the event. If the
+<em>event.application</em> is set, it's a remote event and the handler should not
+process the event. This is a general rule of thumb - however, it's up to
+the handler to make its decision either on <em>event.application</em> or any other
+<p>It is advisable to perform the local event check even in a non clustered
+environment as it makes the migration to a cluster later on much easier and
+there is nearly no performance overhead caused by the check.</p>
+<p>The ~EventUtil class provides an utility method <em>isLocalEvent(Event)</em> which
+checks the existance of the <em>event.application</em> property and returns <em>true</em>
+if it is absend.</p>
+<p><a name="ApacheSlingEventingandJobHandling-Scheduler"></a></p>
+<h2 id="scheduler">Scheduler</h2>
+<p>Each Sling based application will contain a scheduler service (which is
+based on the Quartz open source project).</p>
+<p><a name="ApacheSlingEventingandJobHandling-UseCases"></a></p>
+<h2 id="use-cases">Use Cases</h2>
+<p><a name="ApacheSlingEventingandJobHandling-PostProcessing(BusinessProcesses)"></a></p>
+<h3 id="post-processing-business-processes">Post Processing (Business Processes)</h3>
+<p>A typical example for post processing (or running a business process) is
+sending an email or creating thumbnails and extracting meta data from the
+content (like we do in DAM), which we will discuss here.</p>
+<p>An appropriate JCR observer will be registered. This observer detects when
+new content is put into the repository or when content is changed. In these
+cases it creates appropriate <em>CONTENT_ADDED</em>, <em>CONTENT_UPDATED</em> OSGi events
+from the JCR events. In order to ensure that these actions get processed
+accordingly, the event is send as a job (with the special job topic, the
+<em>topic</em> and <em>id</em> property).</p>
+<p>The event admin now delivers these jobs to the registered handlers. The job
+event handler gets notified and (simplified version) sends the contained
+event synchronously. One of the handlers for these events is the post
+processing service in DAM. The job mechanism ensures that exactly one
+application node is post processing and that the process has to be finished
+even if the application node dies during execution.</p>
+<p><a name="ApacheSlingEventingandJobHandling-Scheduling"></a></p>
+<h2 id="scheduling">Scheduling</h2>
+<p>The scheduler is a service which uses the open source Quartz library. The
+scheduler has methods to start jobs periodically or with a cron definition.
+In addition, a service either implementing <em>java.lang.Runnable</em> or
+<em>org.quartz.job</em> is started through the whiteboard pattern <em>if</em> it either
+contains a configuration property <em>scheduler.expression</em> or
+<em>scheduler.period</em>. The job is started with the ~PID of the service - if
+the service has no PID, the configuration property <em></em> must be
         <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.

Modified: websites/staging/sling/trunk/content/apache-sling.html
--- websites/staging/sling/trunk/content/apache-sling.html (original)
+++ websites/staging/sling/trunk/content/apache-sling.html Sun Apr 22 17:20:11 2012
@@ -82,7 +82,138 @@
 <a href="/">Home</a>
    <!--   <h1 class="title">Apache Sling</h1> -->
+<!-- -->
+<p><a name="ApacheSling-ApacheSling-BringingBacktheFun"></a></p>
+<h1 id="apache-sling-bringing-back-the-fun">Apache Sling - Bringing Back the Fun</h1>
+<p>{tm}Apache Sling{tm} is an innovative web framework that is intended to
+bring back the fun to web development.</p>
+<p>Discussions about Sling happen on our mailing lists, see the <a href="project-information.html">Project Information</a>
+ page for more info.</p>
+<p><a name="ApacheSling-ApacheSlinginfivebulletspoints"></a></p>
+<h1 id="apache-sling-in-five-bullets-points">Apache Sling in five bullets points</h1>
+<li>REST based web framework</li>
+<li>Content-driven, using a JCR content repository</li>
+<li>Powered by OSGi</li>
+<li>Scripting inside, multiple languages (JSP, server-side javascript, Scala,
+<li>Apache Open Source project</li>
+<p><a name="ApacheSling-ApacheSlinginahundredwords"></a></p>
+<h1 id="apache-sling-in-a-hundred-words">Apache Sling in a hundred words</h1>
+<p>Apache Sling is a web framework that uses a <a href="">Java Content Repository</a>
+, such as [Apache Jackrabbit|]
+, to store and manage content.</p>
+<p>Sling applications use either scripts or Java servlets, selected based on
+simple name conventions, to process HTTP requests in a RESTful way.</p>
+<p>The embedded <a href="">Apache Felix</a>
+ OSGi framework and console provide a dynamic runtime environment, where
+code and content bundles can be loaded, unloaded and reconfigured at
+<p>As the first web framework dedicated to <a href="">JSR-170</a>
+ Java Content Repositories, Sling makes it very simple to implement simple
+applications, while providing an enterprise-level framework for more
+complex applications. </p>
+<p><a name="ApacheSling-News"></a></p>
+<h2 id="news">News</h2>
+* <a href="news.html">all news...</a></p>
+<p><a name="ApacheSling-History"></a></p>
+<h2 id="history">History</h2>
+<p>Sling started as an internal project at <a href="">Day Software</a>
+, and entered the Apache Incubator in September 2007. As of June, 17th,
+2009 Apache Sling is a top level project of the Apache Software Foundation.</p>
+<p>The name "Sling" has been proposed by Roy Fielding who explained it like
+[The name is](the-name-is.html)
+ Biblical in nature.  The story of David: the weapon he uses to slay the
+giant Goliath is a sling.  Hence, our David's [David Nuescheler, CTO of
+Day Software] favorite weapon.</p>
+<p>It is also the simplest device for delivering content very fast.
+<p><a name="ApacheSling-WhousesSling?"></a></p>
+<h2 id="who-uses-sling">Who uses Sling?</h2>
+<p>See <a href="">Who is using Sling</a>
+ on our public wiki.</p>
+<p><a name="ApacheSling-Gettingstarted"></a></p>
+<h2 id="getting-started">Getting started</h2>
+<p>If you prefer doing rather than reading, please proceed to <a href="discover-sling-in-15-minutes.html">Discover Sling in 15 minutes</a>
+ or read through the recommended links in the [Getting Started]
+ section, where you can quickly get started on your own instance of Sling.</p>
+<p><a name="ApacheSling-Contents"></a></p>
+<h2 id="contents">Contents</h2>
+<li><a href="documentation.html">Documentation</a>
+ - Here you will find the documentation on Sling</li>
+<li><a href="development.html">Development</a>
+ -- Documentation on how to develop web applications with Sling and what
+tools you have at your disposal</li>
+<li><a href="links.html">Links</a></li>
+<li><a href="">Wiki</a></li>
+<li><a href="">FAQ</a></li>
+<li><a href="project-information.html">Project Information</a></li>
+<p><a name="ApacheSling-UseCasesforSling"></a></p>
+<h2 id="use-cases-for-sling">Use Cases for Sling</h2>
+<p><a name="ApacheSling-Wiki"></a></p>
+<h4 id="wiki">Wiki</h4>
+<p>Day built a Wiki system on Sling. Each Wiki page is a node (with optional
+child nodes) in the repository. As a page is requested, the respective node
+is accessed and through the applying Component is rendered.</p>
+<p>Thanks to the JCR Mapping and the resolution of the Component from the
+mapped Content, the system does not care for what actual node is addressed
+as long as there is a Content mapping and a Component capable of handling
+the Content.</p>
+<p>Thus in the tradition of REST, the attachement of a Wiki page, which
+happens to be in a node nested below the wiki page node is easily accessed
+using the URL of the wiki page attaching the relative path of the
+attachement  ode. The system resolves the URL to the attachement Content
+and just calls the attachement's Component to spool the attachement.</p>
+<p><a name="ApacheSling-DigitalAssetManagement"></a></p>
+<h4 id="digital-asset-management">Digital Asset Management</h4>
+<p>Day has implemented a Digital Asset Management (DAM) Application based on
+Sling. Thanks to the flexibility of the Content/Component combo as well as
+the service registration/access functionality offered by OSGi, extending
+DAM for new content type is merely a matter of implementing one or two
+interfaces and registering the respective service(s).</p>
+<p>Again, the managed assets may be easily spooled by directly accessing them.</p>
+<p><a name="ApacheSling-WebContentManagement"></a></p>
+<h4 id="web-content-management">Web Content Management</h4>
+<p>Last but not least, Sling offers itself very well to implementing a Web
+Content Management system. Thanks to the flexibility of rendering the
+output - remember: the system does not care what to render, as long as the
+URL resolves to a Content object for which a Component exists, which is
+called to render the Content - providing support for Web Content authors
+(not PHP programmers but users out in the field) to build pages to their
+likings can easily be done.</p>
+<p><a name="ApacheSling-References"></a></p>
+<h2 id="references">References</h2>
+<p><a name="ApacheSling-ApacheJackrabbit"></a></p>
+<h4 id="apache-jackrabbit">Apache Jackrabbit</h4>
+<p>The main purpose of Sling is to develop a content-centric Web Application
+framework for Java Content Repository (JCR) based data stores. Sling is
+implemented - with the notable exception of JCR Node Type management -
+purely in terms of the JCR API and as such may use any JCR compliant
+repository. The default implementation for <a href="">Apache Jackrabbit</a>
+ is provided out of the box.</p>
+<p><a name="ApacheSling-OSGi"></a></p>
+<h4 id="osgi">OSGi</h4>
+<p>Sling is implemented as a series of <a href="">OSGi</a>
+ Bundles and makes extensive use of the OSGi functionality, such as
+lifecycle management and the service layer. In addition, Sling requires
+several OSGi compendium services to be available, such as the Log Service,
+Http Service, Configuration Admin Service, Metatype Service, and
+Declarative Services.</p>
+<p><a name="ApacheSling-ApacheFelix"></a></p>
+<h4 id="apache-felix">Apache Felix</h4>
+<p>While Sling does not require a specific OSGi framework implementation to
+run in, Sling is being developed using <a href="">Apache Felix</a>
+ as the OSGi framework implementation. It has not been tested yet, but it
+is expected that Sling also operates perfectly inside other OSGi frameworks
+such as [Equinox|]
+ and [Knopflerfish|]
         <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.

View raw message