sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Adapters
Date Sun, 06 Feb 2011 17:21:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2036/9/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Adapters">Adapters</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~fmeschbe">Felix
Meschberger</a>
    </h4>
        <br/>
                         <h4>Changes (26)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >/** <br> * Adapts the adaptable
to another type. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
* &lt;p&gt; <br> * Please not that it is explicitly left as an implementation
detail whether <br> * each call to this method with the same &lt;code&gt;type&lt;/code&gt;
yields the same <br> * object or a new object on each call. <br> * &lt;p&gt;
<br> * Implementations of this method should document their adapted types as <br>
* well as their behaviour with respect to returning newly created or not <br> * instance
on each call. <br></td></tr>
            <tr><td class="diff-unchanged" > * <br> * @param &lt;AdapterType&gt;
The generic type to which this resource is adapted <br> *            to <br> *
@param type The Class object of the target type, such as <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
*            &lt;code&gt;javax.jcr.Node.class&lt;/code&gt; or <br></td></tr>
            <tr><td class="diff-changed-lines" >*            <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">&lt;code&gt;Node.class&lt;/code&gt;</span>
<span class="diff-added-words"style="background-color: #dfd;">&lt;code&gt;java.io.File.class&lt;/code&gt;</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > * @return The adapter target or &lt;code&gt;null&lt;/code&gt;
if the resource cannot <br> *         adapt to the requested type <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >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 node. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">But
to be clear: Any object can be adapted even if it does NOT implement the {{Adaptable}} interface,
if an {{AdapterFactory}} service delivers an {{getAdapter()}} method which adapts an object
to another one. To check if there&#39;s any existing {{AdapterFactory}} which can adapt
a given object to another one the {{AdapterManager}} service with it&#39;s {{getAdapter()}}
method does the job. So the {{Adaptable}} interface merely is an indicator that the object
provides built-in support for beeing adapted. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
SlingAdaptable <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Extending Adapters <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
{{SlingAdaptable}} class is an implementation of the {{Adaptable}} interface, calls the {{AdapterManager}}
(see below) to provide an adapter to the {{SlingAdaptable}} object to the requested class.
This class may be extended to have extensible adapters not foreseen at the time of the class
development. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">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: <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">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). <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
 * {{AdapterManager}} <br>  * {{AdapterFactory}} <br>  * {{SlingAdaptable}} <br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br>/** <br></td></tr>
            <tr><td class="diff-changed-lines" >* Adapt the given <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">adaptble</span>
object to the adaptable type. The adaptable <span class="diff-added-words"style="background-color:
#dfd;">object is</span> <br>* <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">object
is</span> guaranteed to be an instance of one of the classes listed in <span class="diff-added-words"style="background-color:
#dfd;">the</span> <br>* <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the</span>
{@link #ADAPTABLE_CLASSES} services registration property. The type <br>* parameter
is <span class="diff-changed-words">on<span class="diff-added-chars"style="background-color:
#dfd;">e</span></span> of the classes listed in the {@link #ADAPTER_CLASSES}
<br></td></tr>
            <tr><td class="diff-unchanged" > * service registration properties.
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
* &lt;p&gt; <br> * This method may return &lt;code&gt;null&lt;/code&gt;
if the adaptable object cannot <br> * be adapted to the adapter (target) type for any
reason. In this case, the <br> * implementation should log a message to the log facility
noting the cause <br> * for not being able to adapt. <br> * &lt;p&gt;
<br> * Note that the &lt;code&gt;adaptable&lt;/code&gt; object is not
required to implement <br> * the &lt;code&gt;Adaptable&lt;/code&gt;
interface, though most of the time this method <br> * is called by means of calling
the {@link Adaptable#adaptTo(Class)} <br> * method. <br></td></tr>
            <tr><td class="diff-unchanged" > * <br></td></tr>
            <tr><td class="diff-changed-lines" >* @param &lt;AdapterType&gt;
<span class="diff-added-words"style="background-color: #dfd;">The generic type of the
adapter (target) type.</span> <br>* @param adaptable <span class="diff-added-words"style="background-color:
#dfd;">The object to adapt to the adapter type.</span> <br>* @param type <span
class="diff-added-words"style="background-color: #dfd;">The type to which the object is
to be adapted.</span> <br>* @return <span class="diff-added-words"style="background-color:
#dfd;">The adapted object or &lt;code&gt;null&lt;/code&gt; if this factory
instance</span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
*         cannot adapt the object. <br></td></tr>
            <tr><td class="diff-unchanged" > */ <br>&lt;AdapterType&gt;
AdapterType getAdapter(Object adaptable, <br>        Class&lt;AdapterType&gt;
type); <br>{code} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">This
method is called by the {{AdapterManager}} on behalf of the {{SlingAdaptable}} object providing
the {{SlingAdaptable}} as the {{adaptable}} parameter the requested class as the {{type}}
parameter. 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}}. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">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}}. <br> <br>{{AdapterFactory}}
services are gathered by a {{AdapterManager}} implementation for use by consumers. Consumers
should not care for {{AdapterFactory}} services. <br> <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. AdapterManager <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
{{AdapterManager}} is an internal class used by the {{SlingAdaptable}} objects to find an
{{AdapterFactory}} to delegate the {{adaptTo}} method call to. To make the {{AdapterManager}}
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. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">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. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The {{AdapterManager}}
interface is defined as follows: <br> <br>{code} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">public
interface AdapterManager { <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">/**
<br> * Returns an adapter object of the requested &lt;code&gt;AdapterType&lt;/code&gt;
for <br> * the given &lt;code&gt;adaptable&lt;/code&gt; object. <br>
* &lt;p&gt; <br> * The &lt;code&gt;adaptable&lt;/code&gt; object
may be any non-&lt;code&gt;null&lt;/code&gt; object <br> * and is not
required to implement the &lt;code&gt;Adaptable&lt;/code&gt; interface. <br>
* <br> * @param &lt;AdapterType&gt; The generic type of the adapter (target)
type. <br> * @param adaptable The object to adapt to the adapter type. <br> *
@param type The type to which the object is to be adapted. <br> * @return The adapted
object or &lt;code&gt;null&lt;/code&gt; if no factory exists to <br>
*         adapt the &lt;code&gt;adaptable&lt;/code&gt; to the &lt;code&gt;AdapterType&lt;/code&gt;
<br> *         or if the &lt;code&gt;adaptable&lt;/code&gt; cannot be
adapted for any other <br> *         reason. <br> */ <br>&lt;AdapterType&gt;
AdapterType getAdapter(Object adaptable, <br>        Class&lt;AdapterType&gt;
type); <br>{code} <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
   /** <br>     * Returns an adapter object of the requested &lt;code&gt;AdapterType&lt;/code&gt;
for <br>     * the given &lt;code&gt;adaptable&lt;/code&gt; object.
<br>     * &lt;p&gt; <br>     * The &lt;code&gt;adaptable&lt;/code&gt;
object may be any non-&lt;code&gt;null&lt;/code&gt; <br>     * object
and is not required to implement the &lt;code&gt;Adaptable&lt;/code&gt; <br>
    * interface. <br>     * <br>     * @param &lt;AdapterType&gt; The
generic type of the adapter (target) type. <br>     * @param adaptable The object to
adapt to the adapter type. <br>     * @param type The type to which the object is to
be adapted. <br>     * @return The adapted object or &lt;code&gt;null&lt;/code&gt;
if no factory exists to <br>     *         adapt the &lt;code&gt;adaptable&lt;/code&gt;
to the <br>     *         &lt;code&gt;AdapterType&lt;/code&gt; or if
the &lt;code&gt;adaptable&lt;/code&gt; <br>     *         cannot be
adapted for any other reason. <br>     */ <br>    &lt;AdapterType&gt;
AdapterType getAdapter(Object adaptable, <br>            Class&lt;AdapterType&gt;
type); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">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&#39;s any existing {{AdapterFactory}} which
can adapt a given object to another one the {{AdapterManager}} service with it&#39;s {{getAdapter()}}
method does the job. So the {{Adaptable}} interface merely is an indicator that the object
provides built-in support for beeing adapted. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">}</span>
<span class="diff-added-words"style="background-color: #dfd;"> </span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
SlingAdaptable <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">{code}</span>
<span class="diff-added-words"style="background-color: #dfd;"> </span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">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. <br> <br>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). <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="Adapters-Adapters"></a>Adapters</h1>

<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 JCR 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>


<h2><a name="Adapters-Adaptable"></a>Adaptable</h2>

<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.
 * &lt;p&gt;
 * Please not that it is explicitly left as an implementation detail whether
 * each call to <span class="code-keyword">this</span> method with the same &lt;code&gt;type&lt;/code&gt;
yields the same
 * object or a <span class="code-keyword">new</span> object on each call.
 * &lt;p&gt;
 * Implementations of <span class="code-keyword">this</span> method should document
their adapted types as
 * well as their behaviour with respect to returning newly created or not
 * instance on each call.
 *
 * @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;javax.jcr.Node.class&lt;/code&gt; or
 *            &lt;code&gt;java.io.File.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>


<h2><a name="Adapters-ExtendingAdapters"></a>Extending Adapters</h2>

<p>Sometimes an <tt>Adaptable</tt> implementation cannot foresee future
uses and requirements. To cope with such extensibility requirements two interfaces and an
abstract base class are defined:</p>

<ul>
	<li><tt>AdapterManager</tt></li>
	<li><tt>AdapterFactory</tt></li>
	<li><tt>SlingAdaptable</tt></li>
</ul>



<h2><a name="Adapters-AdapterFactory"></a>AdapterFactory</h2>

<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 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.
 * &lt;p&gt;
 * This method may <span class="code-keyword">return</span> &lt;code&gt;<span
class="code-keyword">null</span>&lt;/code&gt; <span class="code-keyword">if</span>
the adaptable object cannot
 * be adapted to the adapter (target) type <span class="code-keyword">for</span>
any reason. In <span class="code-keyword">this</span> <span class="code-keyword">case</span>,
the
 * implementation should log a message to the log facility noting the cause
 * <span class="code-keyword">for</span> not being able to adapt.
 * &lt;p&gt;
 * Note that the &lt;code&gt;adaptable&lt;/code&gt; object is not required
to implement
 * the &lt;code&gt;Adaptable&lt;/code&gt; <span class="code-keyword">interface</span>,
though most of the time <span class="code-keyword">this</span> method
 * is called by means of calling the {@link Adaptable#adaptTo(<span class="code-object">Class</span>)}
 * method.
 *
 * @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>
<span class="code-keyword">this</span> factory instance
 *         cannot adapt the object.
 */
&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>Implementations of this interface are registered as OSGi services providing two lists:
The list of classes wich may be adapted (property named <em>adaptables</em>) and
the list of classes to which the adapted class may be adapted (property named <em>adapters</em>).
A good example of an Class implementing <tt>AdapterFactory</tt> is the <tt>SlingScriptAdapterFactory</tt>.</p>

<p><tt>AdapterFactory</tt> services are gathered by a <tt>AdapterManager</tt>
implementation for use by consumers. Consumers should not care for <tt>AdapterFactory</tt>
services.</p>


<h2><a name="Adapters-AdapterManager"></a>AdapterManager</h2>

<p>The <tt>AdapterManager</tt> is defines the service interface for the
genralized and extensible use of <tt>AdapterFactory</tt> services. Thus the adapter
manager may be retrieved from the service registry to try to adapt whatever object that needs
to be adapted - provided appropriate adapters exist.</p>

<p>The <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">
/**
 * 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>

<p>Any object can theoretically be adapted to any class even if it does not implement
the <tt>Adaptable</tt> interface, if an <tt>AdapterFactory</tt> service
delivers a <tt>getAdapter()</tt> method which adapts an object to another one.
To check if there's any existing <tt>AdapterFactory</tt> which can adapt a given
object to another one the <tt>AdapterManager</tt> service with it's <tt>getAdapter()</tt>
method does the job. So the <tt>Adaptable</tt> interface merely is an indicator
that the object provides built-in support for beeing adapted.</p>


<h2><a name="Adapters-SlingAdaptable"></a>SlingAdaptable</h2>

<p>The <tt>SlingAdaptable</tt> class is an implementation of the <tt>Adaptable</tt>
interface which provides built-in support to call the <tt>AdapterManager</tt>
to provide an adapter from the <tt>Adaptable</tt> object to the requested class.</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>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Adapters">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=121672&revisedVersion=4&originalVersion=3">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Adapters?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message