incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r1328899 [1/8] - in /sling/site/trunk: content/ templates/
Date Sun, 22 Apr 2012 16:52:16 GMT
Author: fmeschbe
Date: Sun Apr 22 16:52:13 2012
New Revision: 1328899

First shot cwiki conversion


Added: sling/site/trunk/content/46-line-blog.mdtext
--- sling/site/trunk/content/46-line-blog.mdtext (added)
+++ sling/site/trunk/content/46-line-blog.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,231 @@
+Title: 46 Line Blog
+This tutorial is based on the first _Sling Gems_ on The [Sling gems: a blog in 46 lines of code](
+. It has slightly been adapted to fit here.
+In this tutorial, the SlingPostServlet and the sling.js library are brought
+together using 46 (no kidding: _fourty-six_) lines of code to create a
+simple blog (or let's say _bloggish_) application.
+I used this example in my [](rapid-jcr-applications-development-with-sling.html)
+ 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
+<a name="46LineBlog-Audience"></a>
+## Audience
+Although this is a simple sample, it requires some custom settings to work.
+If you're just starting with Sling, [SLINGxSITE:Discover Sling in 15 minutes](slingxsite:discover-sling-in-15-minutes.html)
+ might be a better choice.
+<a name="46LineBlog-Step0:Start,configureandlogintoSling"></a>
+## Step 0: Start, configure and login to Sling
+See [SLINGxSITE:Getting and Building Sling](slingxsite:getting-and-building-sling.html)
+ for how to start Sling. Start it on port 8888 for the below links to work.
+For this sample we need the optional bundle, if it's not present in
+the [OSGi console](http://localhost:8888/system/console/bundles)
+, 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 = and status =
+Then, login using http://localhost:8888/?sling:authRequestLogin=1 which
+should prompt you for a username and password, use _admin_ and _admin_.
+Once that's done, http://localhost:8888/index.html should say _You are
+currently logged in as user *admin* to workspace *default*_.
+<a name="46LineBlog-Step1:Creatingcontent"></a>
+## Step 1: Creating content
+The easiest way to create content in Sling is to use an HTTP POST request,
+let's use a simple HTML form:
+  <body>
+    <h1>Sling microblog</h1>
+    <div>
+      <form method="POST">
+	Title:<br/>
+	<input type="text" name="title" style="width:100%"/>
+	<br/>Text:<br/>
+	<textarea style="width:100%" name="text"></textarea>
+	<br/>
+	<input type="submit" value="save"/>
+	<input type="hidden" name=":redirect" value="*.html"/>
+      </form>
+    </div>
+    <!-- code of step 2 comes here -->
+  </body>
+    That's two input fields, a submit button and a hidden field that tells
+Sling what to do after the POST (in this case: redirect to the html view of
+the node that was just created).
+    To test the form, start Sling and save the above script as
+{{/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.
+    Input some data (using "foo" for the title, for the sake of our examples
+below), save the form, and Sling
+    should display the form again, using the URL of the node that was just
+    {note:title=AccessDeniedException?}
+    If you get an error saying _javax.jcr.AccessDeniedException: ...not allowed
+to add or modify item_ it means that you are not logged in as user _admin_.
+See instructions above for logging in.
+    {note}
+    At this point you're probably looking at an empty form with an URL ending
+in _foo_, if you used that for the title. Or _foo_0_ or _foo_1_ if other
+_foo_s already existed. Don't worry about not seeing your content, we'll
+fix that right away.
+    h2. Step 2: Where's my content?
+    To verify that our content has been created, we can have a look at the JSON
+data at {{http://localhost:8888/content/blog/foo.tidy.json}}, which should
+display our new node's values:
+    {code:javascript}
+    {
+      "jcr:primaryType": "nt:unstructured",
+      "text": "This is the foo text",
+      "title": "foo"
+    }
+That's reassuring, but what we really want is for these values to be
+displayed on the editing form for our post.
+Thanks to the _sling.js_ client library, we just need to add a
+*Sling.wizard()* call to our form to display those values. Let's first
+add a *<head>* element to our form to load the _sling.js_ library, before
+the existing *<body>* of course:
+  <script src="/system/sling.js"></script>
+    And add the {{Sling.wizard()}} after the form, where we had the _code of
+step 2 comes here_ comment:
+    {code:html}
+    <!-- code of step 2 comes here -->
+    <script>Sling.wizard();</script>
+Reloading the form at *http://localhost:8888/content/blog/*.html* and
+creating a new post should now redirect to an editable version of the post,
+with the form fields correctly initialized.
+We can now create and edit posts; let's add some navigation, using more of
+the _sling.js_ functionality. 
+<a name="46LineBlog-Step3:Navigation"></a>
+## Step 3: Navigation
+The _sling.js_ library provides utilities to access and manipulate content.
+For our blog, we'll use the *getContent(path)* method to list the
+siblings of the current node.
+Add the following code to your script, after the *Sling.wizard()* call
+that was added in step 2:
+    <li><em><a href="/content/blog/*.html">[Create new post](create-new-post.html)
+    <script>
+      var posts = Sling.getContent("/content/blog", 2);
+      for(var i in posts) {
+	document.write("<li>"
+	  + "<a href='/content/blog/" + i + ".html'>"	 
+          + posts[i](i.html)
+	  + "</a></li>");
+      }
+    </script>
+    The first link to {{/content/blog/*}} brings us back to our content
+creating form, which is nothing else than the editing form reading empty
+values and posting to the "magic star" URL. 
+    The rest of the javascript runs client-side, as it is not embedded in {{<%
+%>}} code markers, calls the {{sling.getContent}} method to get two levels
+of node data below {{/content/blog}}, and displays links to nodes that it
+    That's a basic navigation, of course, in a real blog we'd need some paging
+and contextualization to cope with large numbers of posts.
+    Nevertheless, with this addition our ESP script allows us to create, edit
+and navigate blog posts - not bad for 46 lines of code, including comments,
+whitespace and output formatting.
+    h2. Step 4: Data first, structure later
+    You might have heard this mantra, which we apply in many areas of Sling.
+    In this case, adding a new field to our blog posts could not be easier:
+just add an input field to the form, and Sling will do the rest.
+    Adding this inside our script's {{<form>}} element, for example:
+    {code:html}
+    <br/>Author:<br/>
+    <input type="author" name="author" style="width:100%"/>
+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.
+<a name="46LineBlog-IwantmyESP!"></a>
+## I want my ESP!
+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.
+That's correct - as we are using only Sling client-facing features at this
+point (HTTP POST and *sling.js*), we do not necessarily need to use ESP
+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 _blog.esp_ "script".
+<a name="46LineBlog-That'sthepowerofSling"></a>
+## That's the power of Sling
+The 46-line blog is a good example of the power of Sling. It leverages the [SlingPostServlet](slingxsite:manipulating-content---the-slingpostservlet-(|slingpostservlet.html)
+, which handles POST requests in a form-friendly way, and the
+client library, which provides high-level functionality on the client side.

Added: sling/site/trunk/content/adapters.mdtext
--- sling/site/trunk/content/adapters.mdtext (added)
+++ sling/site/trunk/content/adapters.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,170 @@
+Title: Adapters
+<a name="Adapters-Adapters"></a>
+# Adapters
+The *Resource* and *ResourceResolver* interfaces are defined with a
+method *adaptTo*, which adapts the object to other classes. Using this
+mechanism the JCR session of the resource resolver calling the *adaptTo*
+method with the *javax.jcr.Session* class object. Likewise the JCR node
+on which a resource is based can be retrieved by calling the
+*Resource.adaptTo* method with the *javax.jcr.Node* class object.
+To use resources as scripts, the *Resource.adaptTo* method must support
+being called with the ** 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
+*Resource* to *SlingScript* objects.
+<a name="Adapters-Adaptable"></a>
+## Adaptable
+The *Adaptable* interface defines the API to be implemented by a class
+providing adaptability to another class. The single method defined by this
+interface is
+    /**
+     * Adapts the adaptable to another type.
+     * <p>
+     * Please not that it is explicitly left as an implementation detail
+     * 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.
+     *
+     * @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
+     */
+    <AdapterType> AdapterType adaptTo(Class<AdapterType> type);
+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
+*ResourceResolver* implementation providing adapting to a JCR session and
+the Sling JCR based *Resource* implementation providing adapting to a JCR
+<a name="Adapters-ExtendingAdapters"></a>
+## Extending Adapters
+Sometimes an *Adaptable* implementation cannot foresee future uses and
+requirements. To cope with such extensibility requirements two interfaces
+and an abstract base class are defined:
+  * *AdapterManager*
+  * *AdapterFactory*
+  * *SlingAdaptable*
+<a name="Adapters-AdapterFactory"></a>
+## AdapterFactory
+The *AdapterFactory* interface defines the service interface and API for
+factories supporting extensible adapters for *SlingAdaptable* objects.
+The interface has a single method:
+    /**
+     * 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.
+     * <p>
+     * This method may return <code>null</code> 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.
+     *
+     * @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.
+     */
+    <AdapterType> AdapterType getAdapter(Object adaptable,
+    	Class<AdapterType> type);
+Implementations of this interface are registered as OSGi services providing
+two lists: The list of classes wich may be adapted (property named
+_adaptables_) and the list of classes to which the adapted class may be
+adapted (property named _adapters_). A good example of an Class
+implementing *AdapterFactory* is the *SlingScriptAdapterFactory*.
+*AdapterFactory* services are gathered by a *AdapterManager*
+implementation for use by consumers. Consumers should not care for
+*AdapterFactory* services.
+<a name="Adapters-AdapterManager"></a>
+## AdapterManager
+The *AdapterManager* is defines the service interface for the genralized
+and extensible use of *AdapterFactory* 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.
+The *AdapterManager* interface is defined as follows:
+    /**
+     * Returns an adapter object of the requested <code>AdapterType</code> for
+     * the given <code>adaptable</code> object.
+     * <p>
+     * The <code>adaptable</code> object may be any non-<code>null</code>
+     * and is not required to implement the <code>Adaptable</code> interface.
+     *
+     * @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.
+     */
+    <AdapterType> AdapterType getAdapter(Object adaptable,
+    	Class<AdapterType> type);
+Any object can theoretically be adapted to any class even if it does not
+implement the *Adaptable* interface, if an *AdapterFactory* service
+delivers a *getAdapter()* method which adapts an object to another one.
+To check if there's any existing *AdapterFactory* which can adapt a given
+object to another one the *AdapterManager* service with it's
+*getAdapter()* method does the job. So the *Adaptable* interface merely
+is an indicator that the object provides built-in support for beeing
+<a name="Adapters-SlingAdaptable"></a>
+## SlingAdaptable
+The *SlingAdaptable* class is an implementation of the *Adaptable*
+interface which provides built-in support to call the *AdapterManager* to
+provide an adapter from the *Adaptable* object to the requested class.
+An example of extending the *SlingAdaptable* class will be the Sling JCR
+based *Resource* implementation. This way, such a resource may be adapted
+to a *SlingScript* by means of an appropriatley programmed
+*AdapterFactory* (see below).

Added: sling/site/trunk/content/apache-sling-commons-thread-pool.mdtext
--- sling/site/trunk/content/apache-sling-commons-thread-pool.mdtext (added)
+++ sling/site/trunk/content/apache-sling-commons-thread-pool.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,17 @@
+Title: Apache Sling Commons Thread Pool
+The Apache Sling Commons Thread Pool bundle provides a thread pool
+services. All thread pools are managed by the
+_{}_. This service can
+be used to get a thread pool.
+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.
+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.
+When using the {nl:ThreadPoolMananger} it is important to release a thread
+pool using the manager after it has been used.

Added: sling/site/trunk/content/apache-sling-community-roles-and-processes.mdtext
--- sling/site/trunk/content/apache-sling-community-roles-and-processes.mdtext (added)
+++ sling/site/trunk/content/apache-sling-community-roles-and-processes.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,103 @@
+Title: Apache Sling Community Roles and Processes
+<a name="ApacheSlingCommunityRolesandProcesses-CommunityRolesandProcesses"></a>
+# Community Roles and Processes
+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.
+<a name="ApacheSlingCommunityRolesandProcesses-Roles"></a>
+## Roles
+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. 
+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.
+The roles defined here conform to the ASF's [definition of roles](
+<a name="ApacheSlingCommunityRolesandProcesses-Users"></a>
+### Users
+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 _Contributor_.
+<a name="ApacheSlingCommunityRolesandProcesses-Contributors"></a>
+### Contributors
+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.
+<a name="ApacheSlingCommunityRolesandProcesses-Committers"></a>
+### Committers
+Contributors who give frequent and valuable contributions to a subproject of Sling can have their status promoted to that of a _[Committer](
+_. 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.
+<a name="ApacheSlingCommunityRolesandProcesses-PMCMembers"></a>
+### PMC Members
+Committers showing continued interest in the project and taking an active part in the evolution of the project may be elected as  _[PMC](
+ members_. The PMC (Project Management Committee) is the official managing
+body of project and is responsible for setting its overall direction.
+<a name="ApacheSlingCommunityRolesandProcesses-Processes"></a>
+## Processes
+<a name="ApacheSlingCommunityRolesandProcesses-BecomingaUserorContributor"></a>
+### Becoming a User or Contributor
+There is no requirement for becoming a User or Contributor; these roles are
+open to everyone.
+<a name="ApacheSlingCommunityRolesandProcesses-BecomingaCommitter"></a>
+### Becoming a Committer
+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.
+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
+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.
+<a name="ApacheSlingCommunityRolesandProcesses-BecomingaPMCMember"></a>
+### Becoming a PMC Member
+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.
+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
+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.
+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

Added: sling/site/trunk/content/apache-sling-eventing-and-job-handling.mdtext
--- sling/site/trunk/content/apache-sling-eventing-and-job-handling.mdtext (added)
+++ sling/site/trunk/content/apache-sling-eventing-and-job-handling.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,559 @@
+Title: Apache Sling Eventing and Job Handling
+*NOTE: This documentation is work in progress!*
+<a name="ApacheSlingEventingandJobHandling-Overview"></a>
+## Overview
+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.
+To get some hands on code, you can refer to the following tutorials:
+* [How to Manage Events in Sling](how-to-manage-events-in-sling.html)
+* [Scheduler Service (commons scheduler)](scheduler-service-(commons-scheduler).html)
+The Sling Event Supports adds the following services:
+* [Jobs](#jobs.html)
+* [Distributed Events](#distributed.html)
+* [Scheduled Events](#timed.html)
+<a name="ApacheSlingEventingandJobHandling-Jobs(GuaranteeofProcessing)"></a>
+## Jobs (Guarantee of Processing)
+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.
+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
+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 _org/apache/sling/event/job_ 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 _event.job.topic_ property of the original event. When a job
+event (event with the topic _org/apache/sling/event/job_) is received, a
+new event with the topic from the property _event.job.topic_ is fired
+(Firing this event comes of course with a set of rules and constraints
+explained below).
+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 _event.job.topic_) and an optional job
+name, the _event.job.id_ property. It is up to the client creating the
+event to ensure that the _event.job.id_ property is unqiue *and* 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.
+<a name="ApacheSlingEventingandJobHandling-JobProcessors"></a>
+### Job Processors
+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.
+In addition the Sling Job Handler needs to get notified if someone is
+processing a job and when someone has finished processing this job.
+To make implementing such a job processor easier, there is the _JobUtil_
+utility class along with the _JobProcessor_ interface. The _JobUtil_ class
+has a helper method for this: _processJob(Event, JobProcessor)_. The job
+processor must implement the _JobProcessor_ interface which consists of a
+single _process(Event)_ method. When the event handler receives a job event
+through the OSGi EventAdmin, it calls _JobUtil.processJob(event, this)_ and
+returns. This utility method takes care to notify the Sling Job Handler
+that someone is processing the job. Then the _process(Event)_ 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).
+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 _JobUtil.acknowledgeJob(Event),
+_JobUtil.finishedJob(event)_ or _JobUtil.rescheduleJob(Event).
+<a name="ApacheSlingEventingandJobHandling-ProcessingofJobs"></a>
+### Processing of Jobs
+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.).
+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.
+<a name="ApacheSlingEventingandJobHandling-QueueConfigurations"></a>
+#### Queue Configurations
+A queue configuration can have the following properties:
+<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>
+The configurations are processed in order of their service ranking. The
+first matching queue configuration is used for the job.
+<a name="ApacheSlingEventingandJobHandling-OrderedQueues"></a>
+#### Ordered Queues
+An ordered queue processes one job after the other.
+<a name="ApacheSlingEventingandJobHandling-UnorderedQueues"></a>
+#### Unordered Queues
+Unordered queues process jobs in parallel.
+<a name="ApacheSlingEventingandJobHandling-Topic-Round-RobinQueues"></a>
+#### Topic-Round-Robin Queues
+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
+<a name="ApacheSlingEventingandJobHandling-IgnoringQueues"></a>
+#### Ignoring Queues
+A queue of type _ignoring_ 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.
+<a name="ApacheSlingEventingandJobHandling-DroppingQueues"></a>
+#### Dropping Queues
+A queue of type _drop_ is dropping a job - which means it is not processed
+at all and directly discarded.
+<a name="ApacheSlingEventingandJobHandling-Persistence"></a>
+### Persistence
+The job event handler listens for all job events (all events with the topic
+_org/apache/sling/event/job_) 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 _/var/eventing/jobs_. 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.
+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
+_event.job.topic_ and job name (property _event.job.id_). If the event has
+already been written by some other application node, it's not written
+Each job is stored as a separate node with the following properties:
+<tr><td> *Property Name*     </td><td> *Description* </td></tr>
+<tr><td> _event:topic_       </td><td> The topic of the job </td></tr>
+<tr><td> _event:id_	      </td><td> The unique identifier of this job (optional).
+<tr><td> _event:created_     </td><td> The date and time when the event has been created
+(stored in the repository)
+<tr><td> _event:application_ </td><td> The identifier of the node where the job was
+created </td></tr>
+<tr><td> _event:properties_  </td><td> Serialized properties </td></tr>
+<tr><td> _event:finished_    </td><td> The date and time when the job has been finished </td></tr>
+<tr><td> _event:processor_   </td><td> The identifier of the node which processed the job
+(after successful processing) </td></tr>
+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 _event:application_ information and processes it
+accordingly. In this case the event gets the additional property
+Each application is periodically removing old jobs from the repository
+(using the scheduler).
+<a name="ApacheSlingEventingandJobHandling-DistributionofJobs"></a>
+### Distribution of Jobs
+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 _event.application_
+on the remote nodes. If the job event handler receives a job with the
+_event.application_ property set, it will not try to write it into the
+repository. It will just broadcast this event asynchronously as a ~FYI
+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 _event.application_ when
+sending the event locally. All other application nodes will use the
+_event.application_ stored in the repository when broadcasting the event
+<a name="ApacheSlingEventingandJobHandling-UsagePatterns"></a>
+## Usage Patterns
+Based on some usage patterns, we discuss the functionality of the eventing
+<a name="ApacheSlingEventingandJobHandling-SendingUserGeneratedEvents"></a>
+### Sending User Generated Events
+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 _event.distribute_ is not explicitly set, the
+event is only distributed localled.
+If the _event.distribute_ 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 _event.distribute_ and publish
+the event.
+The flow can be described as follows:
+1. Client code generates event using OSGi API, if the _event.distribute_
+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 _event.distribute_ is
+1. # Event handler adds _event.application_ 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
+_event.application_ (from the node where the event occured first) and
+cleared _event.distribute_.
+<a name="ApacheSlingEventingandJobHandling-ProcessingJCREvents"></a>
+### Processing JCR Events
+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.
+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
+_event.distribute_ 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
+_event.distribute_ is not set.
+1. The job event handler gets the event if it has the job topic
+1. # The job event handler adds the _event.application_ property and tries to
+write the job to the repository
+1. ## If no job with the topic and _id_ property is in the repository, the
+event will be written and locked.
+1. ## If an event with the topic and _id_ property is in the repository then:
+1. ### If the _event.application_ equals the current application node, the
+event is set to active (_event:active_) in the repository again and locked
+1. ### If the _event.application_ 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
+_event:active_ to false afterwards.
+<a name="ApacheSlingEventingandJobHandling-SendingScheduledEvents"></a>
+### Sending Scheduled Events
+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).
+In most use cases a scheduler will send job events to ensure that exactly
+one application node is processing the event.
+<a name="ApacheSlingEventingandJobHandling-ReceivingOSGiEvents"></a>
+### Receiving OSGi Events
+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. 
+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 _event.application_ property. If it is not
+set, it's a local event and the handler should process the event. If the
+_event.application_ 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 _event.application_ or any other
+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.
+The ~EventUtil class provides an utility method _isLocalEvent(Event)_ which
+checks the existance of the _event.application_ property and returns _true_
+if it is absend.
+<a name="ApacheSlingEventingandJobHandling-DistributedEvents"></a>
+## Distributed Events
+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.
+<a name="ApacheSlingEventingandJobHandling-SourcesofEvents"></a>
+### Sources of Events
+When it comes to application based on Sling, there is a variety of sources
+from which OSGi events can be send:
+* JCR observation events
+* Application generated events
+* Events from messaging systems (~JMS)
+* "External events"
+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
+<a name="ApacheSlingEventingandJobHandling-WeightsofEvents"></a>
+### Weights of Events
+We can distinguish two different weights of events, depending how they are
+distributed in a clustered environment:
+ * User generated events - these events are generated directly by some user
+action and are therefore started on one single node.
+ * Environment generated events (JCR events, scheduler events etc.) - these
+events are generated "simultanously" on all nodes.
+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.
+<a name="ApacheSlingEventingandJobHandling-BasicPrinciples"></a>
+### Basic Principles
+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.
+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.
+The event mechanism is an *event* mechanism which should not be confused
+with a *messaging* 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.
+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
+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).
+<a name="ApacheSlingEventingandJobHandling-DistributedEvents"></a>
+### Distributed Events
+For distributed events two properties are defined (check the _EventUtil_
+* _event.distribute_ - 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.
+* _event.application_ - 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 _event.application_ is missing, if it is a remote event, the
+_event.application_ contains the ID of the node, the event has been
+initially created. Use the _EventUtil.isLocal(Event)_ method to detect if
+the event is a local or a distributed event.
+While the _event.distribute_ must be set by the sender of an event (if the
+event should be distributed), the _event.application_ property is
+maintained by the event mechanism. Therefore a client sending an event
+should *never* set this information by itself. This will confuse the local
+event handlers and result in unexpected behaviour. On remote events the
+_event.application_ is set by the event distribution mechanism.
+<a name="ApacheSlingEventingandJobHandling-EventDistributionAcrossApplicationNodes(Cluster)"></a>
+### Event Distribution Across Application Nodes (Cluster)
+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.
+As mentioned above, the client sending an event has to mark an event to be
+distributed in a cluster by setting the _event.distribute_ in the event
+properties (through _EventUtil_). 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
+<a name="ApacheSlingEventingandJobHandling-StoringEventsintheRepository"></a>
+### Storing Events in the Repository
+Distributable events are stored in the repository, the repository will have
+a specific area (path) where all events are stored. 
+Each event is stored as a separate node with the following properties:
+<tr><td> *Property Name*     </td><td> *Description* </td></tr>
+<tr><td> _event:topic_       </td><td> The topic of the event </td></tr>
+<tr><td> _event:application_ </td><td> The identifier of the application node where the
+event was created </td></tr>
+<tr><td> _event:created_     </td><td> The date and time when the event has been created
+(stored in the repository)
+<tr><td> _event:properties_  </td><td> Serialized properties (except the
+_event.distribute_, but including the _event.application_) </td></tr>
+Each application is periodically removing old events from the repository
+(using the scheduler).
+<a name="ApacheSlingEventingandJobHandling-SendingScheduledEvents"></a>
+### Sending Scheduled Events
+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).
+In most use cases a scheduler will send job events to ensure that exactly
+one application node is processing the event.
+<a name="ApacheSlingEventingandJobHandling-ReceivingOSGiEvents"></a>
+### Receiving OSGi Events
+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. 
+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 _event.application_ property. If it is not
+set, it's a local event and the handler should process the event. If the
+_event.application_ 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 _event.application_ or any other
+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.
+The ~EventUtil class provides an utility method _isLocalEvent(Event)_ which
+checks the existance of the _event.application_ property and returns _true_
+if it is absend.
+<a name="ApacheSlingEventingandJobHandling-Scheduler"></a>
+## Scheduler
+Each Sling based application will contain a scheduler service (which is
+based on the Quartz open source project).
+<a name="ApacheSlingEventingandJobHandling-UseCases"></a>
+## Use Cases
+<a name="ApacheSlingEventingandJobHandling-PostProcessing(BusinessProcesses)"></a>
+### Post Processing (Business Processes)
+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.
+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 _CONTENT_ADDED_, _CONTENT_UPDATED_ 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
+_topic_ and _id_ property).
+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.
+<a name="ApacheSlingEventingandJobHandling-Scheduling"></a>
+## Scheduling
+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 _java.lang.Runnable_ or
+_org.quartz.job_ is started through the whiteboard pattern *if* it either
+contains a configuration property _scheduler.expression_ or
+_scheduler.period_. The job is started with the ~PID of the service - if
+the service has no PID, the configuration property _scheduler.name_ must be

Added: sling/site/trunk/content/apache-sling.mdtext
--- sling/site/trunk/content/apache-sling.mdtext (added)
+++ sling/site/trunk/content/apache-sling.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,176 @@
+Title: Apache Sling
+<a name="ApacheSling-ApacheSling-BringingBacktheFun"></a>
+# Apache Sling - Bringing Back the Fun
+{tm}Apache Sling{tm} is an innovative web framework that is intended to
+bring back the fun to web development.
+Discussions about Sling happen on our mailing lists, see the [Project Information](project-information.html)
+ page for more info.
+<a name="ApacheSling-ApacheSlinginfivebulletspoints"></a>
+# Apache Sling in five bullets points
+* REST based web framework
+* Content-driven, using a JCR content repository
+* Powered by OSGi
+* Scripting inside, multiple languages (JSP, server-side javascript, Scala,
+* Apache Open Source project
+<a name="ApacheSling-ApacheSlinginahundredwords"></a>
+# Apache Sling in a hundred words
+Apache Sling is a web framework that uses a [Java Content Repository](
+, such as [Apache Jackrabbit|]
+, to store and manage content.
+Sling applications use either scripts or Java servlets, selected based on
+simple name conventions, to process HTTP requests in a RESTful way.
+The embedded [Apache Felix](
+ OSGi framework and console provide a dynamic runtime environment, where
+code and content bundles can be loaded, unloaded and reconfigured at
+As the first web framework dedicated to [JSR-170](
+ Java Content Repositories, Sling makes it very simple to implement simple
+applications, while providing an enterprise-level framework for more
+complex applications. 
+<a name="ApacheSling-News"></a>
+## News
+* [all news...](news.html)
+<a name="ApacheSling-History"></a>
+## History
+Sling started as an internal project at [Day Software](
+, 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.
+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.
+It is also the simplest device for delivering content very fast.
+<a name="ApacheSling-WhousesSling?"></a>
+## Who uses Sling?
+See [Who is using Sling](
+ on our public wiki.
+<a name="ApacheSling-Gettingstarted"></a>
+## Getting started
+If you prefer doing rather than reading, please proceed to [Discover Sling in 15 minutes](discover-sling-in-15-minutes.html)
+ or read through the recommended links in the [Getting Started]
+ section, where you can quickly get started on your own instance of Sling.
+<a name="ApacheSling-Contents"></a>
+## Contents
+* [Documentation](documentation.html)
+ \- Here you will find the documentation on Sling
+* [Development](development.html)
+ -- Documentation on how to develop web applications with Sling and what
+tools you have at your disposal
+* [Links](links.html)
+* [Wiki](
+* [FAQ](
+* [Project Information](project-information.html)
+<a name="ApacheSling-UseCasesforSling"></a>
+## Use Cases for Sling
+<a name="ApacheSling-Wiki"></a>
+#### Wiki
+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.
+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.
+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.
+<a name="ApacheSling-DigitalAssetManagement"></a>
+#### Digital Asset Management
+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).
+Again, the managed assets may be easily spooled by directly accessing them.
+<a name="ApacheSling-WebContentManagement"></a>
+#### Web Content Management
+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.
+<a name="ApacheSling-References"></a>
+## References
+<a name="ApacheSling-ApacheJackrabbit"></a>
+#### Apache Jackrabbit
+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 [Apache Jackrabbit](
+ is provided out of the box.
+<a name="ApacheSling-OSGi"></a>
+#### OSGi
+Sling is implemented as a series of [OSGi](
+ 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.
+<a name="ApacheSling-ApacheFelix"></a>
+#### Apache Felix
+While Sling does not require a specific OSGi framework implementation to
+run in, Sling is being developed using [Apache Felix](
+ 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|]

Added: sling/site/trunk/content/architecture.mdtext
--- sling/site/trunk/content/architecture.mdtext (added)
+++ sling/site/trunk/content/architecture.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,228 @@
+Title: Architecture
+<a name="Architecture-ArchitectureofSling"></a>
+# Architecture of Sling
+The following is a short list of high-lights of Sling:
+* *[OSGi](#osgi.html)
+* --- The Sling application is built as a series of OSGi bundles and makes
+heavy use of a number of OSGi core and compendium services.
+* *[#Sling API](#sling-api.html)
+* --- To implement content based Web applications with Sling, an API has
+been defined, this extends the Servlet API and provides more functionality
+to work on the content.
+* *[#Request Processing](#request-processing.html)
+* --- Sling takes a unique approach to handling requests in that a request
+URL is first resolved to a resource, then based on the resource (and only
+the resource) it selects the actual servlet or script to handle the
+* *[#Resources](#resources.html)
+* --- The central mantra of Sling is the *Resource*, which represents the
+resource addressed by any request URL. It is the resource that is first
+resolved when handling a request. Based on the resource, a first servlet or
+script is then accessed to actually handle the request.
+* *[#Servlets and Scripts](#servlets-and-scripts.html)
+* --- Servlets and Scripts are handled uniformly in that they are
+represented as resources themselves and are accessible by a resource path.
+* *[#Launchpad](#launchpad.html)
+* --- Sling uses a very thin launcher to integrate with an existing servlet
+container, launching Sling as a Web application or providing a main class
+to represent a standalone Java application.
+The following sections elaborate on each of these highlights.
+<a name="Architecture-OSGi"></a>
+## OSGi
+ is a consortium that has developed a specification to build modular and
+extensible applications. This offers [various benefits|]
+. We deal mainly with two parts of the specifications: The Core
+Specification, which defines the OSGi Framework and Core Services, and the
+Compendium Services Specification, which defines a host of services that
+extend the functionality of the OSGi Framework.
+<a name="Architecture-OSGiFramework"></a>
+### OSGi Framework
+The OSGi Framework is made up of three layers -- Module, Lifecycle, and
+Services -- that define how extensible applications are built and deployed.
+The responsibilities of the layers are:
+* *Module* --- Defines how a module, or a _Bundle_ in OSGi-speak, is
+defined. Basically, a bundle is just a plain old JAR file, whose manifest
+file has some defined entries. These entries identify the bundle with a
+symbolic name, a version and more. In addition there are headers which
+define what a bundle provides -- *Export-Package* -- and what a bundle
+requires to be operative -- *Import-Package* and *Require-Bundle*.
+* *Lifecycle* --- The lifecycle layer defines the states a bundle may be in
+and describes the state changes. By providing a class, which implements the
+*BundleActivator* interface and which is named in the
+*Bundle-Activator* manifest header, a bundle may hook into the lifecycle
+process when the bundle is started and stopped.
+* *Services* --- For the application to be able to interact, the OSGi Core
+Specification defines the service layer. This describes a registry for
+services, which may be shared.
+<a name="Architecture-CompendiumServices"></a>
+### Compendium Services
+Based on the OSGi Framework specification, the Compendium Services
+specification defines a (growing) number of extension services, which may
+be used by applications for various tasks. Of these Compendium Services,
+Sling is using just a small number:
+* *Log Service* --- Sling comes with its own implementation of the OSGi Log
+Service specification. The respective bundle not only provides this
+implementation, it also exports the SLF4J, Log4J and Commons Logging APIs
+needed for the Sling application to perform logging.
+* *Http Service* --- Sling leverages the OSGi Http Service to hook into a
+servlet container to provide the Web Application Framework mechanism.
+* *Configuration Admin Service* --- To simplify configuration of services
+in Sling, the OSGi Configuration Admin service is used. This provides a
+uniform API to configure services and to build configuration management
+* *Metatype Service* --- The OSGi Metatype Service defines a way to
+describe the data types. Sling uses this service to describe the
+configurations that may be created using the Configuration Admin Service.
+These meta type descriptions are used by configuration management agents to
+present to user interface to manage the configurations.
+* *Event Admin Service* --- Sling uses the OSGi EventAdmin service to
+dispatch events when scheduling tasks.
+* *Declarative Services* --- One of the most important (beside the Log
+Service) services used by Sling is the Declarative Services Specification.
+This specification defines how to declaratively create components and
+services to have the Declarative Services runtime actually manage the
+lifecycle, configuration and references of components.
+<a name="Architecture-SlingAPI"></a>
+## Sling API
+The Sling API is an extension to the Servlet API which provides more
+functionality to interact with the Sling framework and also to extend Sling
+itself and to implement Sling applications.
+See the [Sling API](sling-api.html)
+ page for more information.
+<a name="Architecture-RequestProcessing"></a>
+## Request Processing
+Traditional Web Application framework emply more or less elaborate methods
+to select a Servlet or Controller based on the request URL, which in turn
+tries to load some data (usually from a database) to act upon and finally
+to render the result somehow.
+Sling turns this processing around in that it places the data to act upon
+at the center and consequently uses the request URL to first resolve the
+data to process. This data is internally represented as an instance of the
+*Resource* interface. Based on this resource as well as the request
+method and more properties of the request URL a script or servlet is then
+selected to handle the request.
+See the [Servlets](servlets.html)
+ page for more information.
+<a name="Architecture-Resources"></a>
+## Resources
+The Resource is one of the central parts of Sling. Extending from JCR's
+_Everything is Content_, Sling assumes _Everthing is a Resource_. Thus
+Sling is maintaining a virtual tree of resources, which is a merger of the
+actual contents in the JCR Repository and resources provided by so called
+resource providers.
+Each resource has a path by which it is addressed in the resource tree, a
+resource type and some resource metadata (such as file size, last
+modification time). It is important to understand, that a *Resource*
+instance actually is only a handle to the actual data. By virtue of the
+*adaptTo(Class<Type>)* method, a resource may be coerced into another
+data type, which may then be used while processing the request. Examples of
+data types are *javax.jcr.Node* and **.
+See the [Resources](resources.html)
+ page for more information.
+<a name="Architecture-ServletsandScripts"></a>
+## Servlets and Scripts
+Scripts are usually provided as content in a JCR repository. But since
+Sling is using a resource tree, a script actually is represented as a
+Resource and may be provided from within a Bundle (by virtue of the bundle
+resource provider) or even from the platform file system (by virtue of the
+file system resource provider).
+Accessing scripts in the resource tree, allows for a very easy to
+understand mapping from resource type to some script path.
+Having found the script resource, we still need access to the appropriate
+script language implementation to evaluate the script. To this avail, Sling
+is making use of the *Resource.adaptTo(Class<Type>)* method: If a script
+language implementation is available for the extension of the script name
+an adaptor for the script resource can be found, which handles the
+evaluation of the script.
+Besides scripting languages, such as ECMAScript, Groovy, JSP, Sling also
+supports regular servlets. To be able to use servlets for request
+processing, such servlets must be registered as OSGi services for the
+*javax.servlet.Servlet* interface and provide a number of service
+registration properties, which are used to use the servlets. In fact
+servlets thus registered as OSGi services are mapped into the resource tree
+by means of a servlet resource provider. This resource provider mapps the
+servlets into the resource tree using the service registration properties
+to build one or more resource paths for the servlet.
+As a result of mapping servlets into the resource tree and the possibility
+to adapt resource to an adaptor data type, scripts and servlets may be
+handled completely transparently: The servlet resolver just looks for a
+resource matching the resource type and adapts the resource found to
+*javax.jcr.Servlet*. If the resource happens to be provided by a servlet
+resource provider, the adapter is of course the servlet itself. If the
+resource happens to be a script, the adapter is a servlet facade which
+internally calls the script language implementation to evaluate the script.
+See the [Servlet Resolution](servlet-resolution.html)
+ page for more information.
+<a name="Architecture-Launchpad"></a>
+## Launchpad
+Sling may be launched as a standalone application using the Sling
+Application or as a Web Application running inside any Servlet API 2.4 or
+newer Servlet Container.
+The Sling Application is a standalone Java Application which is really
+small: Just the main class and some glue classes. The OSGi framework as
+well as the OSGi API libraries are packaged as a JAR file, which is loaded
+through a custom classloader. This enables to update the framework and/or
+OSGi API libraries from within Sling by updating the system bundle.
+The Sling Servlet is equally small as the Sling Application. It uses the
+Felix *HttpService* bridge as the glue between the servlet container and
+the OSGi framework.
+As we have seen, Sling may be launched as a standalone Java Application or
+as a Web Application inside any compliant Servlet Container. To hide the
+differences of the launching mechanism, Sling internally registers a
+Servlet with an OSGi *HttpService*. Regardless of how Sling is launched,
+the Felix implementation of the OSGi *HttpService* specification is used.
+When Sling is launched as a standalone Java Application, Felix HttpService
+uses an embedded version of the Jetty servlet container. When Sling is
+launched as a Web Application, the Felix HttpService Bridge is used.
+Optionally, PAX Web's implementation of HttpService can be used when Sling
+is launched as a standalone Java Application. See the [Maven Launchpad Plugin](maven-launchpad-plugin.html)
+ page for information on how to do this.
+See [The Sling Launchpad](the-sling-launchpad.html)
+ for more information.

Added: sling/site/trunk/content/assembly.mdtext
--- sling/site/trunk/content/assembly.mdtext (added)
+++ sling/site/trunk/content/assembly.mdtext Sun Apr 22 16:52:13 2012
@@ -0,0 +1,288 @@
+Title: Assembly
+<a name="Assembly-Assembly:BundlingBundles"></a>
+# Assembly: Bundling Bundles
+The Assembly concept grew out of a need to bundle together a set of OSGi
+Bundles to deploy applications. The concept has been developped before the
+OSGi Deployment Package Service Specification has been published in the
+Release 4.1 Compendium Services Specification. It will have to be discussed
+whether the Assembly concept is dropped in favor of the Deplyoment Package
+<a name="Assembly-Introduction"></a>
+## Introduction
+This chapter discusses the units of deployment as well as the units of
+functionality. The following contents is based on the Module and Service
+specifications of the OSGi Service Platform Core Specification, Release 4
+but enhances functionality for ease of use and in terms of best practices.
+The term _Units of Deployment_ describes the idea of packaging up
+functionality implemented by Java Classes into modules, so called
+_Bundles_. For bigger and more complicated applications the fine grained
+modularity of _Bundles_ may be to complicated, so this chapter proposes an
+extension called _Assembly_. The goal of the _Assembly_ specification
+presented below is to provide functionality to delivery a collection of
+bundles belonging together.
+The term _Units of Functionality_ describes the idea of providing services
+implemented by Java Classes, so called _Services_. A _Service_ is an
+abstraction and does not actually prescribe the implementation of specific
+interfaces. Instead the OSGi specification states how functionality may be
+provided to clients by registering objects implementing interfaces defining
+the functionality in terms of a Java API.
+<a name="Assembly-Bundles"></a>
+## Bundles
+The core unit of deployment is the _Bundle_. The OSGi core specification
+defines a _Bundle_ to be a Java Archive (JAR) file whose manifest - the
+*META-INF/MANIFEST.MF* file - contains specific headers identifying the
+bundle. Most manifest headers are optional with defined default values -
+only the *Bundle-SymbolicName* header is actually required and the
+*Bundle-ManifestVersion* header should be set to *2* to identify the
+bundle to be a R4 bundle. Other information defined in the manifest is the
+bundle version, the list of packages exported - provided to other bundles -
+and imported - used and required to be provided by other bundles. See
+chapter _3.2.1 Bundle Manifest Header_ of the OSGi Service Platform Core
+Specification for a complete list of the defined bundle manifest headers.
+Bundles may be installed, updated , started, stopped and removed in an OSGi
+framework individually.
+<a name="Assembly-Assemblies"></a>
+## Assemblies
+For the deployment of bigger systems, the number of bundles may increase
+very quickly. To ease the management of products consisting of multiple
+bundles, this chapter introduces the _Assembly_. An Assembly is simply a
+collection of bundles deployed together. An Assembly - like a Bundle - is a
+JAR file whose manifest contains specific headers. In fact, an Assembly is
+just a standard bundle, with additional functionality.
+Assemblies are managed by the _Assembly Manager_ which itself is a bundle
+installed into the framework.
+<a name="Assembly-Assemblymanifestheaders"></a>
+### Assembly manifest headers
+As an Assembly is a standard Bundle, all the defined Bundle manifest
+headers may be specified. In addition, for the _Assembly Manager_ to
+recognize an assembly and for the OSGi Bundle Repository to support
+dependency resolution, the following manifest headers are defined. All
+headers are optional with documented default values except where noted.
+* *Assembly-Bundles* - The list of bundles contained in this assembly. See
+below for the definition of the syntax of this header. This header is
+required. The presence of this headers identifies an Assembly to the
+_Assembly Manager_.
+* *Assembly-BundleRepository* - A comma-separated list of URLs pointing to
+OSGi Bundle Repository descriptors. These bundle repositories will be used
+to install bundles listed in the *Assembly-Bundles* header. This header
+is optional with not default value.
+<a name="Assembly-AssemblyLifecycle"></a>
+### Assembly Lifecycle
+An Assembly, like all bundles, may be in any of the defined bundle states:
+* *Installed* - The Assembly bundle has been installed into the system but
+not yet resolved. The _Assembly Manager_ will try to install all bundles
+listed in the *Assembly-Bundles* header. The start levels of the bundles
+will be set according to the *startlevel* parameter. The bundles will not
+be started. If installation of one or more of the bundles fails, _Assembly
+Manager_ logs an error message.
+* *Resolved* - The Assembly bundle is resolved, that is all imported
+packages are wired into the framework. The _Assembly Manager_ does not
+handle this state change, rather the installed bundles will be resolved by
+the framework either automatically after installation or when started
+* *Started* - The Assembly bundle has been started by calling the
+*Bundle.start()* method. The _Assembly Manager_ will start all newly
+installed and resolved bundles. Depending on the start level set on the
+bundle(s) and the current system start level, the bundles will only be
+permanently marked to start while actually starting the bundles may be
+delayed until the system enters the respective start level. If any bundle
+fails to start, an error message is logged.
+* *Stopped* - The Assembly bundle has been stopped by calling the
+*Bundle.stop()* method. All bundles belong to the Assembly and linked to
+the Assembly are also stopped.
+* *Unresolved* - The Assembly bundle has been unresolved by the system for
+any reason, possibly any missing dependencies. Assembly bundles entering
+this state are ignored by the _Assembly Manager_.
+* *Uninstalled* - The Assembly bundle is being uninstalled by calling the
+*Bundle.uninstall()* method. The _Assembly Manager_ will (try to)
+uninstall all bundles listed in the *Assembly-Bundles* header.
+* *Updated* - The Assembly bundle will update all bundles installed
+previously according to the *Assembly-Bundles* header. If this header
+omits any bundle listed in the previous bundle version, the respective
+bundle is uninstalled from the system. If a bundle is already installed
+with the correct version, the installed bundle is not touched (It may
+though be uninstalled together with the Assembly Bundle if the Assembly
+Bundle is uninstalled).
+<a name="Assembly-BundlesreferencedbymultipleAssemblyBundles"></a>
+### Bundles referenced by multiple Assembly Bundles
+It is conceivable, that bundles are listed in the *Assembly-Bundles*
+header of more than one Assembly Bundle. If this is the case, the following
+collision resolution takes place:
+   * If the version of the bundle installed by the first Assembly bundle
+handled matches the version specification of any later Assembly Bundle, the
+installed bundle is not touched. Otherwise, if the later Assembly Bundle
+lists a version specification, which is acceptable for the first Assembly
+Bundle, the installed bundle is updated to the required version. If the
+version specifications may not be matched one way or the other, the later
+Assembly Bundle fails to install.
+   * If the bundle is installed with a defined start level, the later
+Assembly Bundle will not overwrite the already set start level. If the
+start level has not been set yet it is set to the specified start level.
+   * Bundles installed through Assembly Bundles remain installed as long as
+there is at least one Assembly Bundle listing the bundle in the
+*Assembly-Bundles* header. As soon as there is no referring Assembly
+Bundle anymore, the bundle is uninstalled.
+   * Bundles not referred to by any Assembly Bundle are ignored by the
+_Assembly Manager_.
+   * Bundles installed through the _Assembly Manager_ may be updated and/or
+uninstalled independently from their defining Assembly Bundle. If a bundle
+has been installed it will be reinstalled the next time the Assembly Bundle
+enters the _installed_ state. If a bundle has been updated, it is not
+touched by the _Assembly Manager_ as long as the updated version matches
+the version specification of the Assembly Bundle.
+<a name="Assembly-BundleInstallation"></a>
+### Bundle Installation
+When an Assembly is installed into the framework, the _Assembly Manager_
+checks to see whether the Assembly needs to be deployed. This is done by
+checking the bundles listed in the *Assembly-Bundles* header whether they
+are installed or not. All bundles not installed will be installed and
+started if requested so.
+The following BNF defines the syntax =Assembly-Bundles= header value:
+    Assembly-Bundles = Bundle { "," Bundle } .
+    Bundle = Symbolic-Name { ";" Parameter } .
+    Symbolic-Name = // The Bundle symbolic name 
+    Parameter = ParameterName "=" ParameterValue .
+To control the selection and installation of bundles, the following
+parameters may be used:
+* *version* - The version of the bundle to install. This is a version range
+specification as per chapter 3.2.5 Version Ranges of the OSGi core
+specification. When this parameter is declared as a single version - eg.
+_1.2.3_ - it is interpreted as the version range _~[1.2.3, &infin;~)_. The
+default value is _~[0.0.0,&infin;~)_ to install the most recent version of
+the bundle available.
+* *startlevel* - The start level to set for the bundle. This may be any
+positive integer value. Default value is undefined to use the current
+initial bundle start level of the framework.
+* *entry* - The path of the Assembly Bundle entry providing the data to be
+* *linked* - Defines whether the bundle should be started and stopped
+together with the Assembly to which the bundle belongs. Default value is
+If resolving the bundles results in more bundles to be downloaded from the
+bundle repository to resolve the dependency, these bundles are always
+automatically started and assigned a startlevel which is smaller than the
+smallest startlevel of any of the bundles listed.
+<a name="Assembly-BundleLocation"></a>
+### Bundle Location
+Generally bundles to be installed with an Assembly Bundle are retrieved
+from an OSGi Bundle Repository. The *Assembly-BundleRepository* header
+may list additional URLs which will be temporarily used to resovle the
+bundles. Otherwise the system default bundle repositories will be used
+If a bundle is defined in the *Assembly-Bundles* header with an *entry*
+parameter, the respective entry is first looked for in the Assembly Bundle.
+If the entry exists, it is used as the bundle source to install. If no
+*entry* parameter is present for a declared bundle or the entry is
+missing, the OSGi Bundle Repository is used.
+Restrictions when packaging bundles with the Assembly:
+* *Dependency Resolution* - Any missing dependencies of the bundles to be
+installed will not be resolved. That is, if the bundles fail to resolve,
+the Assembly fails to install.
+* **version* Parameter* - The *version* parameter of the bundle
+installation declaration is ignored because any JAR file whose name matches
+the bundle symbolic name to be installed, is installed.
+If the *Assembly-BundleRepository* header contains a comma-separated list
+of URL to OSGi Bundle Repository descriptors and the OSGi Bundle Repository
+Service is available in the framework, the bundles declared in the
+*Assembly-Bundles* header are resolved through the OSGi Bundle Repository
+Service using the URL from the *Assembly-BundleRepository* header.
+If the bundles declare any dependencies, which may not be resolved by
+bundles already installed in the framework or by any of the bundles to be
+installed, the OSGi Bundle Repository is used to try to resolve these
+missing dependencies. If this resolution succeeds, installation of the
+Assembly succeeds. Any bundles not declared in the Assembly but installed
+due to this dependency resolution will not be assumed to belong to the
+Assembly. Hence, these bundles will not be uninstalled (or updated) if the
+Assembly is uninstalled (or updated).
+* *Example* - Assume the *Assembly-Bundles* header is set to
+*;entry=path.jar,*. The
+bundle ** is then installed from the Assembly
+Bundle entry *path.jar*, while the bundle ** is
+resolved in the OSGi Bundle Repository.
+<a name="Assembly-BestPractices"></a>
+## Best Practices
+<a name="Assembly-SizeofBundles"></a>
+### Size of Bundles
+There is no fixed formula to calculate the best size for a bundle: It all
+depends on the contents and the intentions of the bundle and its
+programmer. The following list provides some hints:
+   * For ease of development follow the idea of _One Bundle - One Project_
+   * Don't pack too much into a bundle but do not pack a single class into
+a bundle (unless you have a very good reason of course :-) )
+   * Do not mix and match everything into a bundle. Rather bundle things
+together which belong together, for example create separate bundles for a
+HTTP Client implementation and DB support classes
+   * Use similar heuristics to decide on the contents of a bundle as you
+would for the contents of a plain old JAR file.
+<a name="Assembly-NomenestOmen"></a>
+### Nomen est Omen
+The symbolic name of a bundle should reflect its contents. A bundle should
+generally only contain a single subtree in the virtual package tree. The
+symbolic name of the bundle should be the root package contained within.
+For example, consider a bundle containing the packages
+**, **,
+**. The bundle would the be named

View raw message