Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7F775DA78 for ; Wed, 12 Dec 2012 09:19:02 +0000 (UTC) Received: (qmail 45364 invoked by uid 500); 12 Dec 2012 09:19:02 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 45289 invoked by uid 500); 12 Dec 2012 09:19:02 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 45234 invoked by uid 99); 12 Dec 2012 09:19:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Dec 2012 09:19:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Dec 2012 09:18:55 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E97622388CA6 for ; Wed, 12 Dec 2012 09:17:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r841833 [25/28] - in /websites/staging/sling/trunk/content: ./ site/ site/46-line-blog.data/ site/authentication.data/ site/documentation.data/ site/first-steps.data/ site/getting-and-building-sling.data/ site/how-to-manage-events-in-sling.... Date: Wed, 12 Dec 2012 09:17:17 -0000 To: commits@sling.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121212091731.E97622388CA6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: websites/staging/sling/trunk/content/site/servlets.html ============================================================================== --- websites/staging/sling/trunk/content/site/servlets.html (added) +++ websites/staging/sling/trunk/content/site/servlets.html Wed Dec 12 09:16:44 2012 @@ -0,0 +1,204 @@ + + + + + Apache Sling - Servlets + + + + + +
+ +
+ + Apache + +
+
+ +
+ +

Servlets and Scripts

+ +

Servlets can be registered as OSGi services. The following service reference properties are defined for Servlets defined as OSGi services of type javax.servlet.Servlet:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name Description
sling.servlet.paths A list of absolute paths under which the servlet is accessible as a Resource. The property value must either be a single String, an array of Strings or a Vector of Strings.
+A servlet using this property might be ignored unless its path is included in the Execution Paths (servletresolver.paths) configuration setting of the SlingServletResolver service.
+Creating a resource at the desired path, with a resource type that maps to a servlet, provides the same result in most cases while taking advantage of more Sling built-in features.
sling.servlet.resourceTypes The resource type(s) supported by the servlet. The property value must either be a single String, an array of Strings or a Vector of Strings. This property is ignored if the sling.servlet.paths property is set.
sling.servlet.selectors The request URL selectors supported by the servlet. The selectors must be configured as they would be specified in the URL that is as a list of dot-separated strings such as <em>print.a4</em>. The property value must either be a single String, an array of Strings or a Vector of Strings. This property is ignored if the sling.servlet.paths property is set.
sling.servlet.extensions The request URL extensions supported by the servlet for requests. The property value must either be a single String, an array of Strings or a Vector of Strings. This property is ignored if the sling.servlet.paths property is set.
sling.servlet.methods The request methods supported by the servlet. The property value must either be a single String, an array of Strings or a Vector of Strings. This property is ignored if the sling.servlet.paths property is set. If this property is missing, the value defaults to GET, regardless of which methods are actually implemented/handled by the servlet.
sling.servlet.prefix The prefix or numeric index to make relative paths absolute. If the value of this property is a number (int), it defines the index of the search path entries from the resource resolver to be used as the prefix. The defined search path is used as a prefix to mount this servlet. The number can be -1 which always points to the last search entry. If the specified value is higher than than the highest index of the search paths, the last entry is used. The index starts with 0. If the value of this property is a string and parseable as a number, the value is treated as if it would be a number. If the value of this property is a string starting with "/", this value is applied as a prefix, regardless of the configured search paths! If the value is anything else, it is ignored. If this property is not specified, it defaults to the default configuration of the sling servlet resolver.
+
+ + +

A SlingServletResolver listens for Servletservices and - given the correct service registration properties - provides the servlets as resources in the (virtual) resource tree. Such servlets are provided as ServletResource instances which adapt to the javax.servlet.Servlet class.

+ +

For a Servlet registered as an OSGi service to be used by the Sling Servlet Resolver, the either or both of the sling.servlet.paths or the sling.servlet.resourceTypes service reference properties must be set. If neither is set, the Servlet service is ignored.

+ +

Each path to be used for registration - either from the sling.servlet.paths property or constructed from the other sling.servlet.* properties - must be absolute. Any relative path is made absolute by prefixing it with a root path. This prefix may be set with the sling.servlet.prefix service registration property. If this property is not set, the first entry in the ResourceResolver search path for the ResourceResolver.getResource(String) method is used as the prefix. If this entry cannot be derived, a simpe slash - / - is used as the prefix.

+ +

If sling.servlet.methods is not specified, the servlet is only registered for handling GET requests. Make sure to list all methods you want to be handled by this servlet.

+ +

Automated tests

+

The launchpad/test-services module contains test servlets that use various combinations of the above properties.

+ +

The launchpad/integration-tests module contains a number of tests (like the ExtensionServletTest for example) that verify the results.

+ +

Such tests run as part of our continuous integration process, to demonstrate and verify the behavior of the various servlet registration mechanisms, in a way that's guaranteed to be in sync with the actual Sling core code. If you have an idea for additional tests, make sure to let us know!

+ +

Example: Registration by Path

+ +
+
sling.servlet.paths = \[ "/libs/sling/sample/html", "/libs/sling/sample/txt" \]
+sling.servlet.resourceTypes = \[ "sling/unused" \]
+sling.servlet.selectors = \[ "img" \]
+sling.servlet.extensions = \[ "html", "txt", "json" \]
+
+
+ +

A Servlet service registered with these properties is registered under the following paths:

+ +
    +
  • /libs/sling/sample/html
  • +
  • /libs/sling/sample/txt
  • +
+ + +

The registration properties sling.servlet.resourceTypes, sling.servlet.selectors and sling.servlet.extensions are ignored because the sling.servlet.paths property is set.

+ + +

Example: Registration by Resource Type etc.

+ +
+
sling.servlet.resourceTypes = \[ "sling/unused" \]
+sling.servlet.selectors = \[ "img", "tab" \]
+sling.servlet.extensions = \[ "html", "txt", "json" \]
+
+
+ +

A Servlet service registered with these properties is registered under the following paths:

+ +
    +
  • prefix/sling/unused/img/html
  • +
  • prefix/sling/unused/img/txt
  • +
  • prefix/sling/unused/img/json
  • +
  • prefix/sling/unused/tab/html
  • +
  • prefix/sling/unused/tab/txt
  • +
  • prefix/sling/unused/tab/json
  • +
+ + +

As explained the Servlet is registered for each permutation of the resource types, selectors and extension. See above For an explanation of how prefix is defined.

+ + +

Scripts are Servlets

+ + +

The Sling API defines a SlingScript interface which is used to represent (executable) scripts inside of Sling. This interface is implemented in the scripting/core bundle in the DefaultSlingScript class which also implements the javax.servlet.Servlet.

+ +

To further simplify the access to scripts from the Resource tree, the scripting/core bundle registers an AdapterFactory to adapt Resources to Scripts and Servlets (the SlingScriptAdapterFactory). In fact the adapter factory returns instances of the DefaultSlingScript class for both Scripts and Servlets.

+ +

From the perspective of the Servlet resolver, scripts and servlets are handled exactly the same. In fact, internally, Sling only handles with Servlets, whereas scripts are packed inside a Servlet wrapping and representing the script.

+ + +

+ + +

Default Servlet(s)

+ +

As explained in the Resolution Process section above, a default Servlet is selected if no servlet (or script) for the current resource type can be found. To make the provisioning of a default Servlet as versatile as provisioning per resource type Servlets (or scripts), the default Servlet is selected with just a special resource type sling/servlet/default.

+ +

The actual Servlet or Script called as the default Servlet is resolved exactly the same way as for any resource type. That is, also for the default Servlet selection, the request selectors and extension or method are considered. Also, the Servlet may be a Servlet registered as an OSGi service or it may be a Script stored in the repository or provided by any bundle.

+ +

Finally, if not even a registered default Servlet may be resolved for the request, because none has been registered, the servlets/resolver bundle provides a fall back the DefaultServlet with the following functionality:

+ +
    +
  • If an NonExistingResource was created for the request the DefaultServlet sends a 404 (Not Found)
  • +
  • Otherwise the DefaultServlet sends a 500 (Internal Server Error), because normally at least a NonExistingResource should be created
  • +
+ + +

OptingServlet interface

+

If a registered servlet implements the OptingServlet interface, Sling uses that servlet's accepts(SlingHttpServletRequest request) method to refine the servlet resolution process.

+ +

In this case, the servlet is only selected for processing the current request if its accept method returns true.

+ + +

Error Handler Servlet(s) or Scripts

+ +

Error handling support is now described on the Errorhandling page.

+
+Last modified by bdelacretaz on Thu May 10 15:11:36 EDT 2012 +
+
+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. +
+
+ + + Added: websites/staging/sling/trunk/content/site/sling-api-redesign.html ============================================================================== --- websites/staging/sling/trunk/content/site/sling-api-redesign.html (added) +++ websites/staging/sling/trunk/content/site/sling-api-redesign.html Wed Dec 12 09:16:44 2012 @@ -0,0 +1,267 @@ + + + + + Apache Sling - Sling API Redesign + + + + + +
+ +
+ + Apache Incubator + +
+
+ +
+

Redesign of the Sling API

+ +

There have been a number of threads on the Sling Dev Mailing List on simplifying the current Component API and turn it into a new Sling API. This page starts at the current state of the discussion as of Oct. 10, 2007, and tries to summarize what has been discussed and to resolve this into a modified proposal.

+ + + + +

References

+ + + + + + +

Current State

+ +

Currently, request processing is controlled by the sling-core bundle using two sets of filters: one set called at the time the client request enters Sling - so called request level filters - and the other set called for each Content object processed during request processing - so called content level filters.

+ +

Amongst the request level filters is the ContentResolverFilter which takes the request URL and finds a Content object for the URL. This filter implements the ContentResolver interface and is also registered as this service. So other parts of the system may use the same mechanism to resolve paths to Content objects. The ContentResolver also implements the default content loading described here.

+ +

Amongst the content level filters is the ComponentResolverFilter which asks the Content object for its component ID and resolves this ID using the registered {{Component}}s. This filter also implements the default component resolution described here.

+ +

To manage content Sling provides two interfaces:

+ +
    +
  • ContentManager - Basic interface allowing CRUD operations using Content objects. This interface is completely agnostic of the actual persistence used.
  • +
  • JcrContentManager - Extends the ContentManager interface integrating with the Jackrabbit OCM ObjectContentManager interface. This provides the API actually used by the ContentResolverFilter to load Content objects from the JCR repository according to the request URL.
  • +
+ + + +

If components would want to create, update and delete content, they would access the ContentManager by retrieving the org.apache.sling.jcr.content_manager request attribute. If JCR tasks would have to be executed, that retrieved object would be cast to JcrContentManager and the session retrieved.

+ +

Examples:

+ +
Update Modified Content
+ +

After having modified the content, a component might do the following to persisted the modified content:

+ +
+
Content content = componentRequest.getContent();
+
+// modify content
+
+ContentManager contentManager = (ContentManager) componentRequest.getAttribute("org.apache.sling.jcr.content_manager");
+contentManager.store(content);
+contentManager.save();
+
+ + +
JCR based Operations
+ +

To operate on a JCR level or to directly access the JCR Node underlying the request Content the following might be done:

+ +
+
// get the JCR content manager
+JcrContentManager jcrContentManager = (JcrContentManager) componentRequest.getAttribute("org.apache.sling.jcr.content_manager");
+
+// get the session
+Session session = jcrContentManager.getSession();
+
+// access the node addressed by the request URL
+String contentPath = componentRequest.getContent().getPath();
+Node contentNode = (Node) session.getItem(contentPath);
+
+ + +

Arguably, this is tedious. So a first simplification proposal suggested to move the JCR agnostic ContentManager interface to the Sling API and to provide a getter method on the ComponentRequest interface. The returned object might also be cast to a JcrContentManager to then access the repository.

+ +

This proposal sparked a series of reactions (see references above) and so based on Bertrands thoughts, we propose the following change.

+ + + +

Replace Content by Resource

+ +

The "problem" of the current Component API is that is centered around a Content interface which presumably is data provided to the component loaded from the persistence (the JCR repository of course) actually hiding the repository. This also predefines how data is acquired and used, namely by using Object Content Mapping.

+ +

Starting off this situation, we propose replacing the (fully loaded) Content by a data representation we will call Resource:

+ +
+
public interface Resource {
+
+  // the original request URL leading to the resource
+  // this is not necessairily the same as ServletRequest.getRequestURL as
+  // it may have been processed by some URL mapping and folding
+  String getOriginalURI();
+
+  // the path to the actual resource providing the data
+  // from the point of view of Sling this is just a string
+  String getURI();
+
+  // the selectors of the request or empty array if none
+  // the selectors are dot-separated strings after the part of
+  // original URI addressing the resource upto the extension
+  // Examples:
+  //    - /a/b/c has no selectors for resource /a/b/c
+  //    - /a/b/c.html has no selectors for resource /a/b/c
+  //    - /a/b/c.s1.s2.html has selectors [ s1, s2 ] for resource /a/b/c
+  //    - /a/b/c.s.html/suffix has selector [ s ] for resource /a/b/c
+  String[] getSelectors();
+
+  // the extension of the request or empty string if none
+  // the extension is a string after the last dot after the
+  // part of the original URI addressing the resource upto the
+  // end of the original URI or a slash
+  // Examples:
+  //    - /a/b/c has no extension for resource /a/b/c
+  //    - /a/b/c.html has extension html for resource /a/b/c
+  //    - /a/b/c.s1.s2.html has extension html for resource /a/b/c
+  //    - /a/b/c.s.html/suffix has extension html for resource /a/b/c
+  String getExtension();
+
+  // the suffix of the request or empty string if none
+  // the suffix is the string after the next slash after the part
+  // of the original URI addressing the resource
+  // Examples:
+  //    - /a/b/c has no suffix for resource /a/b/c
+  //    - /a/b/c.html has no suffix for resource /a/b/c
+  //    - /a/b/c.s1.s2.html has no suffix for resource /a/b/c
+  //    - /a/b/c.s.html/suffix has suffix suffix for resource /a/b/c
+  String getSuffix();
+
+}
+
+ +

The ComponentRequest interface would be modified as follows:

+ +
    +
  • The getExtension(), getSelector(int), getSelectors(), getSelectorString() and getSuffix() methods are removed as this information can now be obtained from the Resource directly.
  • +
  • The getContent(), getContent(String), getChildren(Content) and getRequestDispatcher(Content) methods are replaced as follows:
  • +
+ + +
+
public interface ComponentRequest extends HttpServletRequest {
+
+  ...
+
+  // Returns the Resource to which the getRequestURL method maps
+  Resource getResource();
+
+  // Returns a Resource to which the given URI String maps
+  // Implicit: getResource().equals(getResource(getRequestURL()))
+  Resource getResource(String uri);
+
+  // Returns an Enumeration child Resources of the given Resource
+  // If resource parameter is null, getResource() is used as parent
+  // (use Enumeration to stay in line with the HttpServletRequest)
+  Enumeration<Resource> getChildren(Resource resource);
+
+  // Gets a RequestDispatcher to include the given resource
+  RequestDispatcher getRequestDispatcher(Resource resource);
+
+  ...
+
+}
+
+ + +

Extensions to the Resource interface

+ +

The Resource interface may be extended depending on the way, the resource is acquired. For example, there might be a MappedContentResource which would return an object mapped from any persistence layer, a JcrResource may encapsulate a JCR based resource. A resolver loading content from a JCR repository using Jackrabbit OCM might return a resource which implements both the MappedContentResource and the JcrResource interfaces.

+ +
MappedContentResource
+
public interface MappedContentResource extends Resource {
+
+  // Returns the mapped data object
+  Object getObject();
+
+}
+
+ +
JcrResource
+
public interface JcrResource extends Resource {
+
+  // Returns the JCR session used to acquire the Node
+  // (this is actually convenience as getNode().getSession()
+  // must return the same session)
+  Session getSession();
+
+  // Returns the JCR Node addressed by the Resource URI
+  // this is the same as getSession().getItem(getURI());
+  Node getNode();
+
+}
+
+ + +

The existing ContentResolver will be retargeted to the Resource interface and return an object implementing the MappedContentResource and the JcrResource interfaces if a mapping exists. Otherwise an object just implementing the JcrResource interface is returned providing just the resolved node.

+ + +

Open Issues

+ +

This above definition leaves a series of issues open.

+ + +

Resolving the Servlet

+ +
+

The Component interface is removed and the Servlet interface is used.

+ +

Currently the Content interface defines a method getComponentId() which returns the identifier of a Component to which processing of the request is dispatched. With the new Resource interface, no such method exists any more.

+ +

The intent is, that Servlet resolver would know about the concrete implementations of the Resource interface and could handle the respective resources. For example the Sling standard servlet resolver could try the following:

+ +
    +
  1. If the Resource is a JcrResource check the sling:servletId property of the resource node. If such a property exists and denotes a registered Servlet service, that servlet is used.
  2. +
  3. Otherwise, if the Resource is a MappedContentResource, find a Servlet service willing to handle requests for the actual object class of the mapped object. The Servlet service could be registered with a service property listing the names of the mapped object classes supported.
  4. +
  5. Otherwise try to find a registered Servlet interface willing to handle the request using the resource path, selectors and/or extensions.
  6. +
+ + +

Alternatively, the Resource interface might have a getServletId() method providing the identifier of the servlet to use. It might well be that the first solution is the better one.

+
+ + + Added: websites/staging/sling/trunk/content/site/sling-api.html ============================================================================== --- websites/staging/sling/trunk/content/site/sling-api.html (added) +++ websites/staging/sling/trunk/content/site/sling-api.html Wed Dec 12 09:16:44 2012 @@ -0,0 +1,466 @@ + + + + + Apache Sling - Sling API + + + + + +
+ +
+ + Apache + +
+
+ +
+ +

The Sling API

+ + +
Work In Progress
The contents of this page is being created at the moment. It contains incomplete and partially wrong information as the text is adapted from the contents of the Component API documentation page.
+ + +

Introduction

+ +

The Sling API defines a presentation framework to build Web Applications. As such the Sling API builds upon the Servlet API but extends the latter with new functionality:

+ +
    +
  • A web page may be built from many different pieces. This aggregation of different pieces is comparable to the functionality provided by the Portlet API. In contrast to the latter, though, the pieces may themselves be aggregates of yet more pieces. So a single web page response may consist of a tree of pieces.
  • +
  • Just like the Servlet API and the Portlet API the Sling API mainly defines a Java based framework. Yet the Sling API comes with the intention of supporting scripting built.
  • +
  • In contrast to the Servlet API and the Portlet API, the Sling API is resource centric. That is, the request URL does not address a servlet or a portlet but a resource represented by an instance of the org.apache.sling.api.resource.Resource interface. From this resource the implementation of the Sling API will derive a javax.servlet.Servlet or org.apache.sling.api.scripting.SlingScript instance, which is used to handle the request.
  • +
+ + +

An implementation of the presentation framework defined by the Sling API is called a Sling Framework. The Apache Sling project actually contains two implementations of this API: microsling and Sling. microsling (note the lowercase m) implements the same request processing mechanisms as Sling but is very hardcoded. It serves well as a rapid development environment as it is quickly set up, easy to handle and shows results very easily. Sling on the other hand is based on an OSGi framework and very flexible, allowing the extension of the system in various ways.

+ + + +

Going Resource Centric

+ +

Traditional web applications are built around the notion of a traditional application which is converted into an application which may be used using a Web Browser. Web applications consist of a series of servlets and JSP scripts, which are called based on configuration in the web application deployment descriptor. Such applications are generally based on some internal database or some static filesystem content.

+ +

The Sling API on the other hand looks more like a traditional web server from the outside, which delivers more or less static content. Thus, while the traditional web application uses the request URL to select a piece of code to execute, the Sling API uses the URL to select a resource to be delivered.

+ + + +

Comparsion to the Servlet API

+ +

The Sling API builds upon the Servlet API. Generally a Sling Framework will run inside a Servlet Container and be manifested towards the Servlet Container as a single Servlet, which dispatches requests to the Servlets and Scripts depending on the request URLs.

+ +

Response rendering may itself be a multi-step operation. Depending on the Servlets and Scripts, the rendering may include dispatching for child (or even foreign) Resources.

+ + + +

Comparision to the Portlet API

+ +

Unlike the Portlet API, which defines one single level of portlet hierarchy - portlets are just pieces residing besides each other - the Sling API allows for hierarchic structuring of Resources and hence Servlet and Script renderings. To support this structuring, the Sling Framework does not control the rendering process of all elements on the page like the Portlet Container does for the portlets. Instead only the Resource addressed by the request URL is processed and it is left to the Servlet or Script rendering that Resource to dispatch other Resource/Servlet/Script tupels to add more data to the response.

+ + +

To Iterator or To Enumeration

+ +

With the advent of the Java Collection framework in Java 2, the Enumeration has been superceded by the Iterator. So the natural choice for the Sling API for methods to return enumeratable collection of objects would have be to declare the use of Iterator instances. But because the Servlet API defines to use Enumeration instances, the Sling API will also declare the use of Enumeration instances for consistency with the Servlet API extended by the Sling API.

+ + + + +

Request Processing

+ +

Unlike traditional Servlet API request processing, a Sling API request is processed by the Sling Framework in three basic steps:

+ +
    +
  1. Resource Resolution - The Sling Framework derives a Resource instance from the client request URL. The details of how to resolve the Resource. One possible solution would be to map the request URL to a Java Content Repository Node and return a Resource representing that Node.
  2. +
  3. Servlet and Script Resolution - From the Resource created in the first step, the Servlet or Script is resolved based on the type of the Resource. The resource type is a simple string, whose semantics is defined by the Sling Framework. One possible definition could be for the resource type to be the primary node type of the Node underlying the Resource.
  4. +
  5. Input Processing and Response Generation - After getting the Resource and the Servlet or Script, the service() method is called or the script is evaluated to process any user supplied input and send the response to the client. To structure the rendered response page, this method is responsible to include other resources. See Dispatching Requests below for details. See Error Handling below for a discussion on how exceptions and HTTP stati are handled.
  6. +
+ + + + +

URL decomposition

+ +

During the Resource Resolution step, the client request URL is decomposed into the following parts:

+ +
    +
  1. Resource Path - The longest substring of the request URL resolving to a Resource such that the resource path is either the complete request URL or the next character in the request URL after the resource path is either a dot (.) or a slash (/).
  2. +
  3. Selectors - If the first character in the request URL after the resource path is a dot, the string after the dot upto but not including the last dot before the next slash character or the end of the request URL. If the resource path spans the complete request URL or if a slash follows the resource path in the request URL, no seletors exist. If only one dot follows the resource path before the end of the request URL or the next slash, no selectors exist.
  4. +
  5. Extension - The string after the last dot after the resource path in the request URL but before the end of the request URL or the next slash after the resource path in the request URL. If a slash follows the resource path in the request URL, the extension is empty.
  6. +
  7. Suffix Path - If the request URL contains a slash character after the resource path and optional selectors and extension, the path starting with the slash upto the end of the request URL is the suffix path. Otherwise, the suffix path is empty.
  8. +
+ + +

Examples: Assume there is a Resource at /a/b, which has no children.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
URI Resource Path Selectors Extension Suffix
/a/b /a/b null null null
/a/b.html /a/b null html null
/a/b.s1.html /a/b s1 html null
/a/b.s1.s2.html /a/b s1.s2 html null
/a/b/c/d /a/b null null /c/d
/a/b.html/c/d /a/b null html /c/d
/a/b.s1.html/c/d /a/b s1 html /c/d
/a/b.s1.s2.html/c/d /a/b s1.s2 html /c/d
/a/b/c/d.s.txt /a/b null null /c/d.s.txt
/a/b.html/c/d.s.txt /a/b null html /c/d.s.txt
/a/b.s1.html/c/d.s.txt /a/b s1 html /c/d.s.txt
/a/b.s1.s2.html/c/d.s.txt /a/b s1.s2 html /c/d.s.txt
+
+ + +
Automated tests and examples
The SlingRequestPathInfoTest demonstrates and tests this decomposition. Feel free to suggest additional tests that help clarify how this works!
+ +

The SlingHttpServletRequest

+ +

The org.apache.sling.api.SlingHttpServletRequest interface defines the basic data available from the client request to both action processing and response rendering. The SlingHttpServletRequest extends the javax.servlet.http.HTTPServletRequest.

+ +

This section describes the data available from the SlingHttpServletRequest. For a complete and normative description of the methods, refer to the Sling API JavaDoc. The following information is represented for reference. In the case of differences between the following descriptions and the Sling API JavaDoc, the latter takes precedence.

+ +
    +
  1. Resource access - Resources may be accessed from the SlingHttpServletRequest object through the following methods: getResource(), getResourceResolver().
  2. +
  3. Request URL information - In addition to the standard HttpServletRequest information the SlingHttpServletRequest provides access to the selectors, extension and suffix through the getRequestPathInfo() method. Note that the Resource path is not directly available form the SlingHttpServletRequest object. Instead it is available through the Resource.getPath() method of the Resource object retrieved through SlingHttpServletRequest.getResource().
  4. +
  5. Request Parameters - To support user input submitted as multipart/form-data encoded POST parameters, the Sling API intrduces the RequestParameter interface allowing file uploads. Request parameters represented as RequestParameter objects are returned by the following methods: getRequestParameter(String name), getRequestParameterMap(), getRequestParameters(String name).
  6. +
  7. Request Dispatching - In addition to standard Serlvet API request dispatching, the Sling API supports dispatching requests to render different Resources using RequestDispatcher objects returned by the methods: getRequestDispatcher(Resource resource) and getRequestDispatcher(Resource resource, RequestDispatcherOptions options).
  8. +
  9. Miscellaneous - Finally the ComponentRequest interface provides the following methods: getCookie(String name), getRequestProgressTracker(), getResponseContentType(), getResponseContentTypes(), getResourceBundle(Locale locale), getServiceLocator().
  10. +
+ + +

The SlingHttpServletRequest objects are only valid during the time of request processing. Servlets and Scripts must not keep references for later use. As such, the SlingHttpServletRequest interface and its extensions are defined to not be thread safe.

+ +

A note on HTTP Sessions: The SlingHttpServletRequest extends the HttpSerlvetRequest and thus supports standard HTTP sessions. Be aware, though that Sessions are server side sessions and hence violate the sessionless principle of REST and therefore should be used with care. It is almost always possible to not use sessions.

+ + +

The SlingHttpServletResponse

+ +

The org.apache.sling.api.SlingHttpServletResponse interface extends the javax.servet.http.HttpServletResponse interface and is currently empty. It merely exists for symmetry with the SlingHttpServletRequest.

+ + + + +

The Resource

+ +

The org.apache.sling.resource.Resource represents the data addressed by the request URL. Resources may also be retrieved through the org.apache.sling.api.resource.ResourceResolver. Usually this interface is not implemented by clients. In certain use cases we call synthetic Resource if may be usefull to define a simple object implementing the Resource interface. The Sling Framework does not care about the concrete implementation of the Resource interface and rather uses the defined methods to access required information. The interface defines the following methods:

+ +
    +
  1. getResourceType() - Returns the type of the resource. This resource type is used to resolve the Servlet or Script used to handle the request for the resource.
  2. +
  3. getPath() - Returns the path derived from the client request URL which led to the creation of the Resource instance. See the URL_decomposition URL decomposition section above for more information. It is not required, that the Resource path be a part of the original client request URL. The request URL may also have been mapped to some internal path.
  4. +
  5. getResourceMetadata() - Returns meta data information about the resource in a ResourceMetadata object.
  6. +
  7. adaptTo(Class<AdapterType> type) - Returns alternative representations of the Resource. The concrete supported classes to which the Resource may be adapted depends on the implementation. For example a Resource based on a JCR Node may support being adapted to the underlying Node, an InputStream, an URL or even to a mapped object through JCR Object Content Mapping.
  8. +
+ + +
+ + + +

The Component

+ +

The org.apache.sling.component.Component interface defines the API implemented to actually handle requests. As such the Component interface is comparable to the =javax.servlet.Servlet= interface. Like those other interfaces, the Component interface provides methods for life cycle management: init(ComponentContext context), destroy().

+ + + +

Processing the Request

+ +

The Component Framework calls the service(ComponentRequest request, ComponentResponse response) method of the Component to have the component process the request optionally processing user input, rendering the response and optionally dispatch to other Content/Component tuples to provide more response data.

+ + + +

Content and its Component

+ +

The Content object and a Component form a pair, in which the Content object takes the passive part of providing data to the Component and the Component takes the active part of acting upon the Content object. As a consequence, there always exists a link between a given implementation of the Content interface and a given implementation of the Component interface.

+ +

This link is manifested by the Component identifier available from the Content object through the Content.getComponentId() method on the one hand. On the other hand, the link is manifested by the getContentClassName() and createContentInstance() methods of the Component interface.

+ + + +

Component Lifecylce

+ +

When a Component instance is created and added to the Component framework, the init(ComponentContext) method is called to prepare and initialize the Component. If this method terminates abnormally by throwing an exception, the Component is not used. The Component Framework implementation may try at a later time to recreate the Component, intialize it and use it. If the Component Framework tries to recreate the Component a new instance of the Component must be created to be initialized and used.

+ +

When the Component has successfully been initialized, it may be referred to by Content objects. When a client request is to be processed, the Content object is resolved and the service method on the Component to which the Content object refers is called. The service method may - and generally will - be called simultaneously to handle different requests in different threads. As such, implementations of these methods must be thread safe.

+ +

When the Component Framework decides to take a Component out of service, the destroy() method is called to give the Component a chance to cleanup any held resources. The destroy method must only be called by the Component Framework when no more request processing is using the Component, that is no thread may be in the service method of a Component to be destroyed. Irrespective of whether the destroy method terminated normally or abnormally, the Component will not be used again.

+ +

The addition and removal of Components is at the discretion of the Component Framework. A Component may be loaded at framework start time or on demand and my be removed at any time. But only one single Component instance with the same Component identifier may be active at the same time within a single Component Framework instance.

+ + + +

The ComponentExtension

+ +

To enhance the core functionality of Components, each Component may have zero, one ore more Component Extensions attached. A Component Extensions is a Java object implementing the org.apache.sling.component.ComponentExtension interface. This interface just defines a getName() method to identify extensions.

+ +

The concrete implementation as well as instantiation and management of Component Extensions is left to the Component Framework implementation with one restriction though: The extensions must be available to the Component at the time the init(ComponentContext) method is called may only be dropped after the destroy() method terminates.

+ +

The Component interface defines two methods to access Extensions: The getExtensions() method returns a java.util.Enumeration of all ComponentExtension objects attached to the component. If no Component Extension are attached to the Component, an empty enumeration is returned. The getExtension(String name) returns the named Component Extension attached to the Component or null if no such Component Extension is attached to the Component.

+ +

Component Frameworks are allowed to share Component Extension instances of the same name between different Component instances. Regardless of whether Component Extensions are shared or not, they must be thread safe, as any Component Extension may be used within the service method, which themselves may be called concurrently.

+ + + + +

Request Processing Filters

+ +

Similar to the Servlet API providing filters for filtering requests and/or responses the Component API provides the org.apache.sling.component.ComponentFilter interface. The filters are called by a ComponentFilterChain and either handle the request, manipulate the request and/or response object and finally forward the request and response optionally wrapped to the ComponentFilterChain.doFilter(ComponentRequest, ComponentResponse) method.

+ +

Like the Component}}s filters have a defined lifecycle manifested by {{init and destroy methods. When the filter enters the system, the Component Framework calls the ComponentFilter.init(ComponentContext) method. Only when this method completes successfully will the filter be put into action and be used during request processing. When the filter leaves the system, the Component Framework removes the filter from being used in filter chains and calls the ComponentFilter.destroy() method. This method is not expected to throw any exceptions. The filter may be removed from the Component Framework at the discretion of the Component Framework or because the filter is being unregistered from the Component Framework by some means outside this specification.

+ +

This specification does not define how ComponentFilter objects are registered with the Component Framework nor is it specified how the order in which the filters are called is defined. Likewise it is outside this specification how the filter instances registered with the Component Framework are configured.

+ + + +

Sessions

+ + +

The org.apache.sling.component.ComponentSession interface provides a way to identify a user across more than one request and to store transient information about that user.

+ +

A component can bind an object attribute into a ComponentSession by name. The ComponentSession interface defines two scopes for storing objects: APPLICATION_SCOPE, COMPONENT_SCOPE. All objects stored in the session using the APPLICATION_SCOPE must be available to all the components, servlets and JSPs that belong to the same component application and that handle a request identified as being a part of the same session. Objects stored in the session using the COMPONENT_SCOPE must be available to the component during requests for the same content that the objects where stored from. Attributes stored in the COMPONENT_SCOPE are not protected from other web components of the component application. They are just conveniently namespaced.

+ +

The component session extends the Servlet API HttpSession. Therefore all HttpSession listeners do apply to the component session and attributes set in the component session are visible in the HttpSession and vice versa.

+ +

The attribute accessor methods without the scope parameter always refer to COMPONENT_SCOPE attributes. To access APPLICATION_SCOPE attributes use the accessors taking an explicit scope parameter.

+ +

A final note on Sessions: Sessions are server side sessions and hence violate the sessionless principle of REST and therefore should be used with care. It is almost always possible to not use sessions.

+ + + +

Dispatching Requests

+ +

To include renderings of child Content objects, a org.apache.sling.component.ComponentRequestDispatcher object may be retrieved from the ComponentContext with which the Component has been initialized or from the ComponentRequest provided to the service method. Using this dispatcher the reponse of rendering the Content may be included by calling the ComponentRequestDispatcher.include(ComponentRequest, ComponentResponse) method.

+ +

This method is comparable to the RequestDispatcher.include(ServletRequest, ServletResponse method of the Servlet API but dispatching by the ComponentRequestDispatcher does not go through the servlet container and stays within the Component Framework.

+ +

The service method of included Components are called with an instance of the ComponentRequest interface whose getContent() returns the Content object for the included Content.

+ +

When a Component is included by another component the following request attributes are set:

+ +
+ + + + + + + + + + + + + + + + +
Request Attributes Type Description
org.apache.sling.component.request.content String The Content instance to which the client URL resolved. This attribute is set when included Components are being rendered and it is not set for the Component directly addressed by the client request.
org.apache.sling.component.request.component String The Component instance for the Content object to which the client URL resolved. This attribute is set when included Components are being rendered and it is not set for the Component directly addressed by the client request.
+
+ + + +

Error Handling

+ +

While processing requests, the service methods called may have problems. Components have multiple options of reporting issues during processing to the client:

+ +
    +
  • Set the status of the HTTP response calling the ComponentResponse.setStatus method
  • +
  • Send an error page calling the ComponentResponse.sendError method
  • +
  • Throw an exception
  • +
+ + + +

If such an exception is thrown, the Component Framework must act upon the exception in one of the following ways:

+ +
    +
  • If the request is processed through Servlet API request inclusion, the exception must be given back to the servlet container. A ComponentException is just forwarded as a ServletException. This is a requirement of the Servlet API specification which states for included requests:
  • +
+ + +
+

SRV.8.5 Error Handling
If the servlet that is the target of a request dispatcher throws a runtime exception or a checked exception of type ServletException or IOException, it should be propagated to the calling servlet. All other exceptions should be wrapped as ServletExceptions and the root cause of the exception set to the original exception, as it should not be propagated.

+ +
    +
  • Otherwise, the Component Framework may handle the error itself in a manner similar to the error handling approach defined the Servlet API specification (Section SRV 9.9 Error Handling of the Java Servlet Specification 2.4). Specifically the request attributes defined by the Servlet API specification must be set for the error handler:
  • +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Request Attributes Type Description
javax.servlet.error.status_code java.lang.Integer The status code of the response. In the case of an exception thrown from the service, the code is defined by the Component Framework.
javax.servlet.error.exception_type java.lang.Class The fully qualified name of the exception class thrown. This attribute does not exist, if error handling does not result from an exception. This attribute is maintained for backwards compatibility according to the Servlet API Specification.
javax.servlet.error.message java.lang.String The message of the exception thrown. This attribute does not exist, if error handling does not result from an exception. This attribute is maintained for backwards compatibility according to the Servlet API Specification.
javax.servlet.error.exception java.lang.Throwable The exception thrown. This attribute does not exist, if error handling does not result from an exception.
javax.servlet.error.request_uri java.lang.String The request URL whose processing resulted in the error.
javax.servlet.error.servlet_name java.lang.String The name of the servlet which yielded the error. The servlet name will generally not have any significance inside the Component Framework.
org.apache.sling.component.error.componentId java.lang.String The identifier of the Component whose service method has caused the error. This attribute does not exist, if the Component Framework itself caused the error processing.
+
+ +
    +
  • If the Component Framework decides to not handle the error itself, the exception must be forwarded to the servlet container as a ComponentException wrapping the original exception as its root cause.
  • +
+ + +

This specification does not define, how error handlers are configured and used if the Component Framework provides error handling support. Likewise the Component Framework may or may not implement support to handle calls to the ComponentResponse.sendError method. The Component Framework may also use its own error handling also for errors resulting from request processing failures, for example if authentication is required or if the request URL cannot be resolved to a Content object.

+
+Last modified by bdelacretaz on 2009-08-25 02:28:57.0 +
+
+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. +
+
+ + + Added: websites/staging/sling/trunk/content/site/sling-settings-orgapacheslingsettings.html ============================================================================== --- websites/staging/sling/trunk/content/site/sling-settings-orgapacheslingsettings.html (added) +++ websites/staging/sling/trunk/content/site/sling-settings-orgapacheslingsettings.html Wed Dec 12 09:16:44 2012 @@ -0,0 +1,138 @@ + + + + + Apache Sling - Sling Settings (org.apache.sling.settings) + + + + + +
+ +
+ + Apache + +
+
+ +
+ +

Overview

+ +

The Sling Settings Bundle exposes the SlingSettingsService which allows access to the following information pertinent to a Sling instance:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Method Bundle Context Property Description
String getSlingId() A unique identifier of the running Sling instance. This value is created when Sling is first started and may be used to identify the instance, for example if multiple Sling instances are running on top of a Jackrabbit Repository Cluster
String getSlingHomePath() sling.home The absolute filesystem path to the directory where Sling stores all its content
URL getSlingHome() sling.home.url The Sling Home path as an java.net.URL instance
Set<String> getRunModes() sling.run.modes The active Run Modes of the running Sling instance
+
+ + +

The new Sling Settings Bundle replaces the former Run Modes (org.apache.sling.runmode) Bundle and the SlingSettingsService previously provided by the Sling Engine bundle.

+ + +

Run Modes

+ +

Run modes are meant to define different sets of configuration parameters for various Sling instances.

+ +

In a web publishing environment, for example, one could use run modes like staging, production, dev, dmz or combinations of such values.

+ + +

Configuration

+ +

Run modes can only be configured using a system property, or via the sling.properties file.

+ +

Using -Dsling.run.modes=foo,bar on the JVM command-line, for example, activates the foo and bar run modes.

+ +

This command-line parameter takes precedence over a similar definition (sling.run.modes=dev,staging) that might be present in the sling.properties file found in the Sling home directory.

+ + +

Getting the Run Modes of the Sling instance

+ +

The SlingSettings service provides the Run Modes of the running Sling instance, examples:

+ +
RunMode examples
+
+SlingSettings settings = ...get from BundleContext...
+Set<String> currentRunModes = settings.getRunModes();
+
+Set<String> expectedRunModes = new HashSet<String>(){{ add("foo");add("wii"); }};
+if(expectedRunModes.removeAll(currentRunModes)) {
+  // at least one of (foo,wii) run modes
+  // is active
+}
+
+
+
+Last modified by fmeschbe on 2010-08-27 01:50:26.0 +
+
+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. +
+
+ + +