Everything is a Resource has been edited by Felix Meschberger (Dec 22, 2007).

(View changes)

Content:

Introducing the Sling Paradigm: Everything is a Resource

Status: DRAFT, work in progress
Created: 22. December 2007
Author: fmeschbe

1 Current State

Currently Sling uses resources, servlets and scripts as follows:

  • The Resource interface is mainly used to abstract JCR Node instances
  • The ServletResolver uses an internal registration of servlets registered as OSGi services with the interface javax.servlet.Servlet and selects the servlet based on the resource type of the Resource of the request only.
  • The ScriptResolver uses the ResourceResolver to find request handling scripts based on the resource type of the Resource of the request, the request selector string and the request method or request extension.
  • Request processing filters are based on OSGi services registered with the interface name javax.servlet.Filter
  • Error handling is implemented in the ServletResolver implementation using the same mechanism to find a servlet (or script) based on the response status code or the caught Throwable as the pseudo request method name and using a different default error handling servlet.

This mechanism works rather good, but there are currently enhancement requests, which may not easily be implemented with the current concepts:

  • Allow scripting of request processing filters. Implementing this requires special filter wrappers, which may select filter scripts.
  • Enhance servlet selection to include the same parameters as script resolution, namely the request selector string and the request method or request extension. Implementing this would require replicating much of the code of the current ScriptResolver implementation.

2 Enter the Sling Paradigm

To overcome the limitations we introduce the Sling paradigm

Everything is a Resource

The Sling paradigm brings the paradigm of Java Content Repository API (JCR) Everything is Content to Sling.

This means, that every script, servlet, filter, error handler, etc. is available from the ResourceResolver just like normal content providing data to be rendered upon requests. To enable this resource resolution and resources have to provide certain functionality:

  • Allow registration of resources with the resource resolver. This is required to access servlets and filters registered as OSGi services through the resource resolver.
  • Provide eventing mechanism to support caching and cache management
  • Extend resource adapter mechanism, that is to provide extension to the Resource.adaptTo(Class<?>) method
  • Extend resource enumeration to include resources from various sources

3 Implementing the Sling Paradigm

3.1 Resource Provisioning

To be able to access resources from different locations through a single resource resolver, a new ResourceProvider interface is added. A resource provider is able to provide resources below a certain location in the (virtual) resource tree. The resource resolver selects a resource provider to ask for a resource looking for a longest match amongst the root paths of the providers. If the longest match resource provider cannot find the requested resource, the provider with the second longest match is asked, and so forth.

Accessing the JCR repository is also implemented in the form of a resource provider. This JCR resource provider is registered at the root – / – of the (virtual) resource tree. Thus the JCR repository is always asked if, no more specific resource provider has the requested resource.

The ResourceProvider interface is defined as follows:

package org.apache.sling.api.resource;

public class ResourceProvider {

    /**
     * The name of the service registration property containing the root paths
     * of the resources provided by this provider (value is "provider.roots").
     */
    static final String ROOTS = "provider.roots";

    /**
     * Returns a resource from this resource provider or <code>null</code> if
     * the resource provider cannot find it. The path should have one of the
     * [EMAIL PROTECTED] #getRoots()} strings as its prefix.
     *
     * @throws Exception may be thrown in case of any problem creating the
     *             <code>Resource</code> instance.
     */
    Resource getResource(ResourceResolver ResourceResolver, String path)
            throws Exception;

}

Resource providers are registered as OSGi services under the name org.apache.sling.api.resource.ResourceProvider providing the list of resource path roots as a service registration property with the name provider.roots.

3.2 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 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 org.apache.sling.api.script.SlingScript 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.

3.3 Change Events

The Sling ResourceResolver implementation defines events to be fired on changes in the (virtual) resource tree:

  • All repository events are forwarded
  • Resource provider addition and removal events are generated

Events are transmitted using the OSGi EventTracker specification. That is interested parties must register as OSGi event listener services.

4 Employing the Sling Paradigm

4.1 Scripts in Bundles

4.2 Servlets

4.3 Filters

5 Changes to the Code

5.1 Sling API

  1. Add org.apache.sling.api.adapter.Adaptable interface
  2. Resource and RespourceResolver interfaces extend the Adaptable interface
  3. Add org.apache.sling.api.resource.ResourceProvider interface
  4. Merge SlingScriptResolver and ServletResolver

5.2 OSGi Commons

The org.apache.sling.osgi.commons bundle is a new project providing the following functionality:

  • ServiceLocator implementation (moved from sling/core project
  • SlingAdaptable class implementing Adaptable and leveraging adapter factories
  • AdapterFactory interface
  • AdapterManager selecting AdapterFactory instances on behalf of SlingAdaptable objects

5.3 Merge scripting/resolver into sling/servlet-resolver

The SlingScriptResolver and ServletResolver interfaces are merged into a single ServletResolver interface, which has a resolve(SlingHttpServletRequest) and a find(ResourceResolver, String relPath) method. The implementation of this method will apply the alogirthm of the current scripting/resolver implementation of the SlingScriptResolver.

Any script (or servlet or actually code) may call any script or servlet by just resolving the script or servlet to a Resource and adapting the resource found to a SlingScript or Servlet.

Reply via email to