incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling > Everything is a Resource
Date Mon, 30 Nov 2009 11:26:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=SLING&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/SLING/Everything+is+a+Resource">Everything
is a Resource</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~fmeschbe">Felix
Meschberger</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h1><a name="EverythingisaResource-IntroducingtheSlingParadigm%3AEverythingisaResource"></a>Introducing
the Sling Paradigm: Everything is a Resource</h1>



<p>Status: IMPLEMENTED<br/>
Created: 22. December 2007<br/>
Author: fmeschbe</p>

<div>
<ul>
    <li><a href='#EverythingisaResource-1CurrentState'>1 Current State</a></li>
    <li><a href='#EverythingisaResource-2EntertheSlingParadigm'>2 Enter the Sling
Paradigm</a></li>
    <li><a href='#EverythingisaResource-3ImplementingtheSlingParadigm'>3 Implementing
the Sling Paradigm</a></li>
<ul>
    <li><a href='#EverythingisaResource-3.1ResourceProvisioning'>3.1 Resource
Provisioning</a></li>
    <li><a href='#EverythingisaResource-3.2Adapters'>3.2 Adapters</a></li>
<ul>
    <li><a href='#EverythingisaResource-3.2.1Adaptable'>3.2.1 Adaptable</a></li>
    <li><a href='#EverythingisaResource-3.2.1SlingAdaptable'>3.2.1 SlingAdaptable</a></li>
    <li><a href='#EverythingisaResource-3.2.1AdapterFactory'>3.2.1 AdapterFactory</a></li>
    <li><a href='#EverythingisaResource-3.2.1AdapterManager'>3.2.1 AdapterManager</a></li>
</ul>
    <li><a href='#EverythingisaResource-3.3ChangeEvents'>3.3 Change Events</a></li>
    <li><a href='#EverythingisaResource-3.4ResourceEnumeration'>3.4 Resource Enumeration</a></li>
</ul>
    <li><a href='#EverythingisaResource-4EmployingtheSlingParadigm'>4 Employing
the Sling Paradigm</a></li>
<ul>
    <li><a href='#EverythingisaResource-4.1ResourcesinBundles'>4.1 Resources in
Bundles</a></li>
    <li><a href='#EverythingisaResource-4.2Servlets'>4.2 Servlets</a></li>
    <li><a href='#EverythingisaResource-4.3Filters'>4.3 Filters</a></li>
<ul>
    <li><a href='#EverythingisaResource-4.3.1FilterServices'>4.3.1 Filter Services</a></li>
    <li><a href='#EverythingisaResource-4.3.2FilterScripts'>4.3.2 Filter Scripts</a></li>
</ul>
    <li><a href='#EverythingisaResource-4.4ScriptsfromResource'>4.4 Scripts from
Resource</a></li>
</ul>
    <li><a href='#EverythingisaResource-5ChangestotheCode'>5 Changes to the Code</a></li>
<ul>
    <li><a href='#EverythingisaResource-5.1SlingAPI'>5.1 Sling API</a></li>
    <li><a href='#EverythingisaResource-5.2OSGiCommons'>5.2 OSGi Commons</a></li>
    <li><a href='#EverythingisaResource-5.3Merge%7B%7Bscripting%2Fresolver%7D%7Dinto%7B%7Bsling%2Fservletresolver%7D%7D'>5.3
Merge <tt>scripting/resolver</tt> into <tt>sling/servlet-resolver</tt></a></li>
    <li><a href='#EverythingisaResource-5.4SeparateObjectContentMappingfromResourceResolution'>5.4
Separate Object Content Mapping from Resource Resolution</a></li>
    <li><a href='#EverythingisaResource-5.5EnhanceSlingConsole'>5.5 Enhance Sling
Console</a></li>
    <li><a href='#EverythingisaResource-5.6CreateNewAdapterProject'>5.6 Create
New Adapter Project</a></li>
</ul>
</ul></div>


<h2><a name="EverythingisaResource-1CurrentState"></a>1 Current State</h2>

<p>Currently Sling uses resources, servlets and scripts as follows:</p>

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


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

<ul>
	<li>Allow scripting of request processing filters. Implementing this requires special
filter wrappers, which may select filter scripts.</li>
	<li>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 <tt>ScriptResolver</tt>
implementation.</li>
</ul>



<h2><a name="EverythingisaResource-2EntertheSlingParadigm"></a>2 Enter the
Sling Paradigm</h2>

<p>To overcome the limitations we introduce the Sling paradigm</p>

<div class="panel" style="border-width: 1px;"><div class="panelContent">
<p>Everything is a Resource</p>
</div></div>

<p>The Sling paradigm brings the paradigm of Java Content Repository API (JCR) <em>Everything
is Content</em> to Sling.</p>

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

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




<h2><a name="EverythingisaResource-3ImplementingtheSlingParadigm"></a>3
Implementing the Sling Paradigm</h2>

<h3><a name="EverythingisaResource-3.1ResourceProvisioning"></a>3.1 Resource
Provisioning</h3>

<p>To be able to access resources from different locations through a single resource
resolver, a new <tt>ResourceProvider</tt> 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.</p>

<p>Accessing the JCR repository is also implemented in the form of a resource provider.
This JCR resource provider is registered at the root &#8211; <tt>/</tt> &#8211;
of the (virtual) resource tree. Thus the JCR repository is always asked if, no more specific
resource provider has the requested resource.</p>

<p>The <tt>ResourceProvider</tt> interface is defined as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.sling.api.resource;

<span class="code-keyword">public</span> class ResourceProvider {

    /**
     * The name of the service registration property containing the root paths
     * of the resources provided by <span class="code-keyword">this</span> provider
(value is <span class="code-quote">"provider.roots"</span>).
     */
    <span class="code-keyword">static</span> <span class="code-keyword">final</span>
<span class="code-object">String</span> ROOTS = <span class="code-quote">"provider.roots"</span>;

    /**
     * Returns a resource from <span class="code-keyword">this</span> resource
provider or &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt;
<span class="code-keyword">if</span>
     * the resource provider cannot find it. The path should have one of the
     * {@link #getRoots()} strings as its prefix.
     * &lt;p&gt;
     * This method is called to resolve a resource <span class="code-keyword">for</span>
the given request. The
     * properties of the request, such as request parameters, may be use to
     * parametrize the resource resolution. An example of such parametrization
     * is support <span class="code-keyword">for</span> a JSR-311 style resource
provider to support the
     * parametrized URL patterns.
     * 
     * @<span class="code-keyword">throws</span> SlingException may be thrown
in <span class="code-keyword">case</span> of any problem creating the
     *             &lt;code&gt;Resource&lt;/code&gt; instance.
     */
    Resource getResource(/* ResourceResolver resourceResolver, */
          HttpServletRequest request, <span class="code-object">String</span>
path) <span class="code-keyword">throws</span> SlingException;

    /**
     * Returns a resource from <span class="code-keyword">this</span> resource
provider or &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt;
<span class="code-keyword">if</span>
     * the resource provider cannot find it. The path should have one of the
     * {@link #getRoots()} strings as its prefix.
     *
     * @<span class="code-keyword">throws</span> SlingException may be thrown
in <span class="code-keyword">case</span> of any problem creating the
     *             &lt;code&gt;Resource&lt;/code&gt; instance.
     */
    Resource getResource(<span class="code-object">String</span> path) <span
class="code-keyword">throws</span> SlingException;

    /**
     * Returns an &lt;code&gt;Iterator&lt;/code&gt; of {@link Resource} objects
loaded
     * from the children of the given &lt;code&gt;Resource&lt;/code&gt;.
     * &lt;p&gt;
     * This method is only called <span class="code-keyword">for</span> resource
providers whose root path list
     * contains an entry which is a prefix <span class="code-keyword">for</span>
the path of the parent resource.
     * 
     * @param parent The {@link Resource Resource} whose children are requested.
     * @<span class="code-keyword">return</span> An &lt;code&gt;Iterator&lt;/code&gt;
of {@link Resource} objects or
     *         &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt;
<span class="code-keyword">if</span> the resource provider has no children <span
class="code-keyword">for</span>
     *         the given resource.
     * @<span class="code-keyword">throws</span> NullPointerException If &lt;code&gt;parent&lt;/code&gt;
is
     *             &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt;.
     * @<span class="code-keyword">throws</span> SlingException If any error occurs
acquiring the child resource
     *             iterator.
     */
    Iterator&lt;Resource&gt; listChildren(Resource parent) <span class="code-keyword">throws</span>
SlingException;
}
</pre>
</div></div>

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


<h3><a name="EverythingisaResource-3.2Adapters"></a>3.2 Adapters</h3>

<p>The <tt>Resource</tt> and <tt>ResourceResolver</tt> interfaces
are defined with a method <tt>adaptTo</tt>, which adapts the object to other classes.
Using this mechanism the JCR session of the resource resolver calling the <tt>adaptTo</tt>
method with the <tt>javax.jcr.Session</tt> class object. Likewise the node on
which a resource is based can be retrieved by calling the <tt>Resource.adaptTo</tt>
method with the <tt>javax.jcr.Node</tt> class object.</p>

<p>To use resources as scripts, the <tt>Resource.adaptTo</tt> method must
support being called with the <tt>org.apache.sling.api.script.SlingScript</tt>
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 <tt>Resource</tt> to <tt>SlingScript</tt> objects.</p>


<h4><a name="EverythingisaResource-3.2.1Adaptable"></a>3.2.1 Adaptable</h4>

<p>The <tt>Adaptable</tt> interface defines the API to be implemented by
a class providing adaptability to another class. The single method defined by this interface
is</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
/**
 * Adapts the adaptable to another type.
 *
 * @param &lt;AdapterType&gt; The <span class="code-keyword">generic</span>
type to which <span class="code-keyword">this</span> resource is adapted
 *            to
 * @param type The <span class="code-object">Class</span> object of the target
type, such as
 *            &lt;code&gt;Node.class&lt;/code&gt;
 * @<span class="code-keyword">return</span> The adapter target or &lt;code&gt;<span
class="code-keyword">null</span>&lt;/code&gt; <span class="code-keyword">if</span>
the resource cannot
 *         adapt to the requested type
 */
&lt;AdapterType&gt; AdapterType adaptTo(<span class="code-object">Class</span>&lt;AdapterType&gt;
type);
</pre>
</div></div>

<p>This method is called to get a view of the same object in terms of another class.
Examples of implementations of this method is the Sling <tt>ResourceResolver</tt>
implementation providing adapting to a JCR session and the Sling JCR based <tt>Resource</tt>
implementation providing adapting to a JCR node.</p>


<h4><a name="EverythingisaResource-3.2.1SlingAdaptable"></a>3.2.1 SlingAdaptable</h4>

<p>The <tt>SlingAdaptable</tt> class is an implementation of the <tt>Adaptable</tt>
interface, calls the <tt>AdapterManager</tt> (see below) to provider an adapter
to the <tt>SlingAdaptable</tt> object to the requested class. This class may be
extended to have extensible adapters not foreseen at the time of the class development.</p>

<p>An example of extending the <tt>SlingAdaptable</tt> class will be the
Sling JCR based <tt>Resource</tt> implementation. This way, such a resource may
be adapted to a <tt>SlingScript</tt> by means of an appropriatley programmed <tt>AdapterFactory</tt>
(see below).</p>


<h4><a name="EverythingisaResource-3.2.1AdapterFactory"></a>3.2.1 AdapterFactory</h4>

<p>The <tt>AdapterFactory</tt> interface defines the service interface and
API for factories supporting extensible adapters for <tt>SlingAdaptable</tt> objects.
The interface has a single method:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
/**
 * Adapt the given adaptble 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 on of the classes listed in the {@link #ADAPTER_CLASSES}
 * service registration properties.
 *
 * @param &lt;AdapterType&gt;
 * @param adaptable
 * @param type
 * @<span class="code-keyword">return</span>
 */
&lt;AdapterType&gt; AdapterType getAdapter(<span class="code-object">Object</span>
adaptable,
        <span class="code-object">Class</span>&lt;AdapterType&gt; type);
</pre>
</div></div>

<p>This method is called by the <tt>AdapterManager</tt> on behalf of the
<tt>SlingAdaptable</tt> object providing the <tt>SlingAdaptable</tt>
as the <tt>adaptable</tt> parameter the requested class as the <tt>type</tt>
parameter. Implementations of this interface are registered as OSGi services providing two
lists: The list of classes wich may be adapted and the list of classes to which the adapted
class may be adapted.</p>


<h4><a name="EverythingisaResource-3.2.1AdapterManager"></a>3.2.1 AdapterManager</h4>

<p>The <tt>AdapterManager</tt> is an internal class used by the <tt>SlingAdaptable</tt>
objects to find an <tt>AdapterFactory</tt> to delegate the <tt>adaptTo</tt>
method call to. To make the <tt>AdapterManager</tt> available globally, it is
actually defined as a service interface. Thus the adapter manager may be retrieved from the
service registry to try to adapt whatever object that needs to be adapted - provided appropriate
adapters exist.</p>

<p>The <tt>AdapterManager</tt> interface is defined as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
AdapterManager {

    /**
     * Returns an adapter object of the requested &lt;code&gt;AdapterType&lt;/code&gt;
<span class="code-keyword">for</span>
     * the given &lt;code&gt;adaptable&lt;/code&gt; object.
     * &lt;p&gt;
     * The &lt;code&gt;adaptable&lt;/code&gt; object may be any non-&lt;code&gt;<span
class="code-keyword">null</span>&lt;/code&gt;
     * object and is not required to implement the &lt;code&gt;Adaptable&lt;/code&gt;
     * <span class="code-keyword">interface</span>.
     * 
     * @param &lt;AdapterType&gt; The <span class="code-keyword">generic</span>
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.
     * @<span class="code-keyword">return</span> The adapted object or &lt;code&gt;<span
class="code-keyword">null</span>&lt;/code&gt; <span class="code-keyword">if</span>
no factory exists to
     *         adapt the &lt;code&gt;adaptable&lt;/code&gt; to the
     *         &lt;code&gt;AdapterType&lt;/code&gt; or <span class="code-keyword">if</span>
the &lt;code&gt;adaptable&lt;/code&gt;
     *         cannot be adapted <span class="code-keyword">for</span> any other
reason.
     */
    &lt;AdapterType&gt; AdapterType getAdapter(<span class="code-object">Object</span>
adaptable,
            <span class="code-object">Class</span>&lt;AdapterType&gt;
type);

}
</pre>
</div></div>



<h3><a name="EverythingisaResource-3.3ChangeEvents"></a>3.3 Change Events</h3>

<p>The Sling <tt>ResourceResolver</tt> implementation defines events to
be fired on changes in the (virtual) resource tree:</p>

<ul>
	<li>All repository events are forwarded</li>
	<li>Resource provider addition and removal events are generated</li>
</ul>


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


<h3><a name="EverythingisaResource-3.4ResourceEnumeration"></a>3.4 Resource
Enumeration</h3>

<p>To be help in development and debugging and also to merely visualize the (virtual)
resource tree, the resource tree must be explorable. That is, for every resource, the method
<tt>ResourceResolver.listChildren(Resource resource)</tt> method must return all
resources which may be considered children of the given resource.</p>

<p>Consider for example the following (partial) repository:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>/
+-- filters
        +-- request
                +-- FilterA.esp
                +-- FilterB.jsp
</pre>
</div></div>

<p>Further consider the filter <em>FilterC</em> registered as an OSGi service.
Thus the <tt>listChildren</tt> call for the resource at <tt>/filters/request</tt>
must return three resources <tt>/filters/request/FilterA.esp</tt>, <tt>/filters/request/FilterB.jsp</tt>
and <tt>/filters/request/FilterC</tt>. The first two will be JCR based resources,
while the latter will be  a servlet resource.</p>


<h2><a name="EverythingisaResource-4EmployingtheSlingParadigm"></a>4 Employing
the Sling Paradigm</h2>

<h3><a name="EverythingisaResource-4.1ResourcesinBundles"></a>4.1 Resources
in Bundles</h3>

<p>Resources may be located in OSGi bundles and mapped into the (virtual) resource tree
by means of a <tt>BundleResourceProvider</tt>. Bundles containing resources indicate
this fact by means of a special bundle manifest header: <tt>Sling-Bundle-Resources</tt>.
Two notes regarding bundle resources:</p>

<ol>
	<li>Bundle entries are either files or directories. To have these files and directories
be handled as if they would be file and folder nodes in a repository, bundle based files will
have a resource type <tt>nt:file</tt> and bundle based directories will have a
resource type <tt>nt:folder</tt>.</li>
	<li>Bundle resource may be anything which may be represented by a file (or directory).
That is the resources may be static content to be delivered to clients on request or resources
may be scripts to be called to handle requests (or filter scripts even).</li>
</ol>



<h3><a name="EverythingisaResource-4.2Servlets"></a>4.2 Servlets</h3>

<p>Servlets to be used for request processing are registered as OSGi services with a
series of required service registration properties:</p>

<ol>
	<li><tt>servlet.name</tt> - The name of the servlet as returned from <tt>ServletConfig.getServletName()</tt>.
If this property is not set, the <tt>component.name</tt>, <tt>service.pid</tt>
and <tt>service.id</tt> properties are checked in order.</li>
	<li><tt>servlet.path</tt> - A list of absolute paths under which the servlet
is provided in the (virtual) resource tree.</li>
	<li><tt>sling.servlet.paths</tt> - The name of the service registration
property of a Servlet registered as a service providing the absolute paths under which the
servlet is accessible as a Resource (value is "sling.servlet.paths"). The type of this property
is a String or String[] (array of strings) denoting the resource types.</li>
	<li><tt>sling.servlet.resourceTypes</tt> - The name of the service registration
property of a Servlet registered as a service containing the resource type(s) supported by
the servlet (value is "sling.servlet.resourceTypes"). The type of this property is a String
or String[] (array of strings) denoting the resource types. This property is ignored if the
<tt>SLING_SERVLET_PATHS</tt> property is set. Otherwise this property must be
set or the servlet is ignored.</li>
	<li><tt>sling.servlet.selectors</tt> - The name of the service registration
property of a Servlet registered as a service containing the request URL selectors supported
by the servlet (value is "sling.servlet.selectors"). 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 type of this property is a String or String[] (array of strings) denoting the resource
types. This property is ignored if the <tt>SLING_SERVLET_PATHS</tt> property is
set. Otherwise this property is optional and ignored if not set.</li>
	<li><tt>sling.servlet.extensions</tt> - The name of the service registration
property of a Servlet registered as a service containing the request URL extensions supported
by the servlet for GET requests (value is "sling.servlet.extensions"). The type of this property
is a String or String[] (array of strings) denoting the resource types. This property is ignored
if the <tt>SLING_SERVLET_PATHS</tt> property is set. Otherwise this property or
<tt>SLING_SERVLET_METHODS</tt> must be set or the servlet is ignored.</li>
	<li><tt>sling.servlet.methods</tt> - The name of the service registration
property of a Servlet registered as a service containing the request methods supported by
the servlet (value is "sling.servlet.methods"). The type of this property is a String or String[]
(array of strings) denoting the resource types. This property is ignored if the <tt>SLING_SERVLET_PATHS</tt>
property is set. Otherwise this property or <tt>SLING_SERVLET_EXTENSIONS</tt>
must be set or the servlet is ignored.</li>
</ol>



<p>A <tt>SlingServletResolver</tt> will listen for <tt>Servlet</tt>
services and - given the correct service registration properties - provide the servlets as
resources in the (virtual) resource tree. Such servlets are provided as <tt>ServletResource</tt>
instances which adapt to the <tt>javax.servlet.Servlet</tt> class.</p>


<h3><a name="EverythingisaResource-4.3Filters"></a>4.3 Filters</h3>

<p>Filters may be provided in two different ways: As <tt>javax.servlet.Filter</tt>
instances registered as OSGi services and as scripts located in a predefined place. When requests
are processed the filters are looked up in the (virtual) resource tree below the <tt>/filters</tt>
node. The list of filters is comprised of all the filters directly below the respective scope
&#8211; <em>request</em> or <em>resource</em> &#8211; and
the those below the respective scope and the type of the resource of the request.</p>

<p>The filters are sorted by their names. Hence a convention for the names of the filters
in the (virtual) resource tree is defined such that the names is composed of an ordering number
and the actual filter name, e.g. <em>0&#95;sample</em>.</p>

<h4><a name="EverythingisaResource-4.3.1FilterServices"></a>4.3.1 Filter
Services</h4>

<p>Filters registered as OSGi services have three required service registration properties:</p>

<ol>
	<li><tt>filter.scope</tt> - (String) Scope of the filter, which must be
either <em>request</em> or <em>resource</em></li>
	<li><tt>filter.order</tt> - (Integer) Call order of the filter used to
define the filter call sequence</li>
	<li><tt>filter.name</tt> - (String) The name of the filter as returned
<tt>FilterConfig.getFilterName()</tt>. If this property is not set, the <tt>component.name</tt>,
<tt>service.pid</tt> and <tt>service.id</tt> properties are checked
in order.</li>
	<li><tt>filter.resource.type</tt> - (String[]) The list of resource types
to which this filter applies. This property is optional. If missing, the filter applies to
all resource types. If this property is an empty list, the filter is not used as it applies
to an empty list of resource types.</li>
</ol>


<p>Such Filter services are added to the (virtual) resource tree at a path defined as
follows for each resource type <tt>resource_type</tt> listed in the <tt>filter.resource.type</tt>.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
/filters/${filter.scope}/${resource_type}/${filter.order}_${filter.name}
</pre>
</div></div>

<p>If the <tt>filter.resource.type</tt> property is missing, the filter
is added at</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
/filters/${filter.scope}/${filter.order}_${filter.name}
</pre>
</div></div>


<h4><a name="EverythingisaResource-4.3.2FilterScripts"></a>4.3.2 Filter
Scripts</h4>

<p>Filter scripts may just be added as resources in the JCR repository at the appropriate
location. For example for a request level filter applicable to <tt>nt:file</tt>
nodes only, the filter would be placed in the <tt>/filters/request/nt/file</tt>
folder.</p>


<h3><a name="EverythingisaResource-4.4ScriptsfromResource"></a>4.4 Scripts
from Resource</h3>

<p>A <tt>Resource</tt> returned from the resource resolver may be a script.
The script manager registers an <tt>AdapterFactory</tt> to adapt <tt>Resource</tt>
to <tt>SlingScript</tt>. This factory will resolve a script engine for the resource
file extension and return a <tt>SlingScript</tt> instance based on the <tt>Resource</tt>.
If no script engine exists, the <tt>Resource</tt> may not be adapted.</p>

<p>The <tt>AdapterFactory</tt> adapting to a <tt>SlingScript</tt>
is also able to adapt to <tt>Servlet</tt> by wrapping the adapted <tt>SlingScript</tt>
in a <tt>ScriptServlet</tt>.</p>


<p>h3 4.5 Object Content Mapping</p>

<p>To cope with the new extensible functionality based on the <tt>SlingAdaptable</tt>
class and adapter factories, object content mapping cannot be hard coded to just respond to
any class. Instead, the Object Content Mapping functionality is in fact provided in terms
of adapter factories, which are registered to be able to adapt instances the <tt>Resource</tt>
interface to predefined types.</p>

<p>This way, Object Content Mapping takes part in adapter resolution just like any extensible
adaption.</p>

<p>As a consequence, Object Content Mapping may probable be taken out of the current
<tt>jcr/resource</tt> project into its own project.</p>


<h2><a name="EverythingisaResource-5ChangestotheCode"></a>5 Changes to the
Code</h2>


<h3><a name="EverythingisaResource-5.1SlingAPI"></a>5.1 Sling API</h3>

<ol>
	<li>Add <tt>org.apache.sling.api.adapter.Adaptable</tt> interface</li>
	<li><tt>Resource</tt> and <tt>RespourceResolver</tt> interfaces
extend the <tt>Adaptable</tt> interface</li>
	<li>Add <tt>org.apache.sling.api.resource.ResourceProvider</tt> interface</li>
	<li>Merge <tt>SlingScriptResolver</tt> and <tt>ServletResolver</tt></li>
	<li>Add <tt>AdapterFactory</tt> and <tt>AdapterManager</tt>
service interfaces</li>
</ol>


<h3><a name="EverythingisaResource-5.2OSGiCommons"></a>5.2 OSGi Commons</h3>

<p>The <tt>org.apache.sling.osgi.commons</tt> bundle is a new project providing
the following functionality:</p>

<ul>
	<li><tt>ServiceLocator</tt> implementation (moved from <tt>sling/core</tt>
project</li>
</ul>


<h3><a name="EverythingisaResource-5.3Merge%7B%7Bscripting%2Fresolver%7D%7Dinto%7B%7Bsling%2Fservletresolver%7D%7D"></a>5.3
Merge <tt>scripting/resolver</tt> into <tt>sling/servlet-resolver</tt></h3>

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

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


<h3><a name="EverythingisaResource-5.4SeparateObjectContentMappingfromResourceResolution"></a>5.4
Separate Object Content Mapping from Resource Resolution</h3>

<p>By applying the mechanisms of adapter factories, Object Content Mapping can be broken
out of the <tt>jcr/resource</tt> project into its own project <tt>jcr/ocm</tt>.</p>


<h3><a name="EverythingisaResource-5.5EnhanceSlingConsole"></a>5.5 Enhance
Sling Console</h3>

<p>Provide a Sling Console enhancement to explore the (virtual) resource tree</p>


<h3><a name="EverythingisaResource-5.6CreateNewAdapterProject"></a>5.6 Create
New Adapter Project</h3>

<p>A new Adapter project <tt>sling/adapter</tt> takes the following classes:</p>

<ul>
	<li><tt>SlingAdaptable</tt> class implementing <tt>Adaptable</tt>
and leveraging adapter factories</li>
	<li>Implementation of the <tt>AdapterManager</tt> service also used by
<tt>SlingAdaptable</tt> class</li>
</ul>

     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/SLING/Everything+is+a+Resource">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=73171&revisedVersion=11&originalVersion=10">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/SLING/Everything+is+a+Resource?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message