You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bu...@apache.org on 2014/01/22 20:21:28 UTC

svn commit: r895140 - in /websites/staging/sling/trunk/content: ./ documentation/bundles.html documentation/bundles/models.html

Author: buildbot
Date: Wed Jan 22 19:21:27 2014
New Revision: 895140

Log:
Staging update by buildbot for sling

Added:
    websites/staging/sling/trunk/content/documentation/bundles/models.html
Modified:
    websites/staging/sling/trunk/content/   (props changed)
    websites/staging/sling/trunk/content/documentation/bundles.html

Propchange: websites/staging/sling/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan 22 19:21:27 2014
@@ -1 +1 @@
-1560479
+1560484

Modified: websites/staging/sling/trunk/content/documentation/bundles.html
==============================================================================
--- websites/staging/sling/trunk/content/documentation/bundles.html (original)
+++ websites/staging/sling/trunk/content/documentation/bundles.html Wed Jan 22 19:21:27 2014
@@ -114,6 +114,7 @@
 <li><a href="/documentation/bundles/sling-scripting-jsp-taglib.html">Scripting JSP Taglib</a></li>
 <li><a href="/documentation/bundles/sling-settings-org-apache-sling-settings.html">Sling Settings (org.apache.sling.settings)</a></li>
 <li><a href="/documentation/bundles/caching-services.html">Caching Services</a></li>
+<li><a href="/documentation/bundles/models.html">Model Objects</a></li>
 </ul>
 <h2 id="content-presentation">Content Presentation</h2>
 <ul>
@@ -133,7 +134,7 @@
 <li><a href="/documentation/bundles/discovery-api-and-impl.html">Discovery API and its Implementations (discovery.api, discovery.impl)</a></li>
 </ul>
       <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
-        Rev. 1560479 by justin on Wed, 22 Jan 2014 19:06:13 +0000
+        Rev. 1560484 by justin on Wed, 22 Jan 2014 19:21:21 +0000
       </div>
       <div class="trademarkFooter"> 
         Apache Sling, Sling, Apache, the Apache feather logo, and the Apache Sling project

Added: websites/staging/sling/trunk/content/documentation/bundles/models.html
==============================================================================
--- websites/staging/sling/trunk/content/documentation/bundles/models.html (added)
+++ websites/staging/sling/trunk/content/documentation/bundles/models.html Wed Jan 22 19:21:27 2014
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Sling - Sling Models</title>
+    <link rel="icon" href="/res/favicon.ico">
+    <link rel="stylesheet" href="/res/site.css" type="text/css" media="all">
+    <link rel="stylesheet" href="/res/codehilite.css" type="text/css" media="all">
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+  </head>
+  <body>
+    <div class="title">
+      <div class="logo">
+        <a href="http://sling.apache.org/">
+          <img border="0" alt="Apache Sling" src="/res/logo.png">
+        </a>
+      </div>
+      <div class="header">
+        <a href="http://www.apache.org/">
+          <img border="0" alt="Apache" src="/res/apache.png">
+        </a>
+      </div>
+    </div>
+    
+    <div class="menu"> 
+      <p><strong><a href="/documentation.html">Documentation</a></strong> <br />
+<a href="/documentation/getting-started.html">Getting Started</a> <br />
+<a href="/documentation/the-sling-engine.html">The Sling Engine</a> <br />
+<a href="/documentation/development.html">Development</a> <br />
+<a href="/documentation/bundles.html">Bundles</a> <br />
+<a href="/documentation/tutorials-how-tos.html">Tutorials &amp; How-Tos</a> <br />
+<a href="/documentation/configuration.html">Configuration</a> <br />
+<a href="http://s.apache.org/sling.wiki">Wiki</a> <br />
+<a href="http://s.apache.org/sling.faq">FAQ</a> <br />
+<a href="/sitemap.html">Site Map</a></p>
+<p><strong>API Docs</strong>  <br />
+<a href="/apidocs/sling6/index.html">Sling 6</a> <br />
+<a href="/apidocs/sling5/index.html">Sling 5</a>   </p>
+<p><strong>Project info</strong> <br />
+<a href="/downloads.cgi">Downloads</a> <br />
+<a href="http://www.apache.org/licenses/">License</a> <br />
+<a href="/contributing.html">Contributing</a> <br />
+<a href="/news.html">News</a> <br />
+<a href="/links.html">Links</a> <br />
+<a href="/project-information.html">Project Information</a> <br />
+<a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a> <br />
+<a href="http://svn.apache.org/viewvc/sling/trunk">Browse Source Repository</a> <br />
+<a href="/project-information/security.html">Security</a>   </p>
+<p><strong>Sponsorship</strong> <br />
+<a href="http://www.apache.org/foundation/thanks.html">Thanks</a> <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a> <br />
+<a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a>   </p>
+<!-- no valid ads for now, we'll  reactivate this when needed
+<iframe 
+    src="http://www.apache.org/ads/button.html"
+    style="border-width:0; float: left" frameborder="0" 
+    scrolling="no"
+    width="135" 
+    height="135">
+</iframe>
+-->
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/documentation.html">Documentation</a>&nbsp;&raquo&nbsp;<a href="/documentation/bundles.html">Bundles</a>
+      </div>
+
+      
+      
+      <h1>Sling Models</h1>
+      <p>Many Sling projects want to be able to create model objects - POJOs which are automatically mapped from Sling objects, typically resources, but also request objects. Sometimes these POJOs need OSGi services as well.</p>
+<h1 id="design-goals">Design Goals</h1>
+<ul>
+<li>Entirely annotation driven. "Pure" POJOs.</li>
+<li>Use standard annotations where possible.</li>
+<li>Pluggable</li>
+<li>OOTB, support resource properties (via ValueMap), SlingBindings, OSGi services, request attributes</li>
+<li>Adapt multiple objects - minimal required Resource and SlingHttpServletRequest</li>
+<li>Client doesn't know/care that these objects are different than any other adapter factory</li>
+<li>Support both classes and interfaces.</li>
+<li>Work with existing Sling infrastructure (i.e. not require changes to other bundles).</li>
+</ul>
+<h1 id="basic-usage">Basic Usage</h1>
+<p>In the simplest case, the class is annotated with <code>@Model</code> and the adaptable class. Fields which need to be injected are annotated with <code>@Inject</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">String</span> <span class="n">propertyName</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In this case, a property named "propertyName" will be looked up from the Resource (after first adapting it to a <code>ValueMap</code>) and it is injected.</p>
+<p>For an interface, it is similar:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="n">String</span> <span class="nf">getPropertyName</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In order for these classes to be picked up, there is a header which must be added to the bundle's manifest:</p>
+<div class="codehilite"><pre><span class="nt">&lt;Sling-Model-Packages&gt;</span>
+  org.apache.sling.models.it.models
+<span class="nt">&lt;/Sling-Model-Packages&gt;</span>
+</pre></div>
+
+
+<h1 id="client-code">Client Code</h1>
+<p>Client code doesn't need to be aware that YAMF is being used. It just uses the Sling Adapter framework:</p>
+<div class="codehilite"><pre><span class="n">MyModel</span> <span class="n">model</span> <span class="o">=</span> <span class="n">resource</span><span class="o">.</span><span class="na">adaptTo</span><span class="o">(</span><span class="n">MyModel</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+</pre></div>
+
+
+<p>Or</p>
+<div class="codehilite"><pre><span class="nt">&lt;sling:adaptTo</span> <span class="na">adaptable=</span><span class="s">&quot;${resource}&quot;</span>          <span class="na">adaptTo=</span><span class="s">&quot;org.apache.sling.models.it.models.MyModel&quot;</span> <span class="na">var=</span><span class="s">&quot;model&quot;</span><span class="nt">/&gt;</span>
+</pre></div>
+
+
+<p>Or
+    ::jsp
+    ${sling:adaptTo(resource, 'org.apache.sling.yamf.it.models.MyModel')}</p>
+<p>As with other AdapterFactories, if the adaptation can't be made for any reason, <code>adaptTo()</code> returns null.</p>
+<h1 id="other-options">Other Options</h1>
+<p>If the field or method name doesn't exactly match the property name, <code>@Named</code> can be used:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span> <span class="nd">@Named</span><span class="o">(</span><span class="s">&quot;secondPropertyName&quot;</span><span class="o">)</span>
+    <span class="kd">private</span> <span class="n">String</span> <span class="n">otherName</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p><code>@Inject</code>ed fields/methods are assumed to be required. To mark them as optional, use <code>@Optional</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span> <span class="nd">@Optional</span>
+    <span class="kd">private</span> <span class="n">String</span> <span class="n">otherName</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>A default value can be provided (for Strings &amp; primitives):</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span> <span class="nd">@Default</span><span class="o">(</span><span class="n">values</span><span class="o">=</span><span class="s">&quot;defaultValue&quot;</span><span class="o">)</span>
+    <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Defaults can also be arrays:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span> <span class="nd">@Default</span><span class="o">(</span><span class="n">intValues</span><span class="o">={</span><span class="mi">1</span><span class="o">,</span><span class="mi">2</span><span class="o">,</span><span class="mi">3</span><span class="o">,</span><span class="mi">4</span><span class="o">})</span>
+    <span class="kd">private</span> <span class="kt">int</span><span class="o">[]</span> <span class="n">integers</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>OSGi services can be injected:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">ResourceResolverFactory</span> <span class="n">resourceResolverFactory</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In this case, the name is not used -- only the class name. Lists and arrays are supported:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Servlet</span><span class="o">&gt;</span> <span class="n">servlets</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>OSGi injection can be filtered:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">SlingHttpServletRequest</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">PrintWriter</span> <span class="n">out</span><span class="o">;</span>
+
+    <span class="nd">@Inject</span>
+    <span class="nd">@Named</span><span class="o">(</span><span class="s">&quot;log&quot;</span><span class="o">)</span>
+    <span class="kd">private</span> <span class="n">Logger</span> <span class="n">logger</span><span class="o">;</span>
+
+    <span class="nd">@Inject</span>
+    <span class="nd">@Filter</span><span class="o">(</span><span class="s">&quot;(paths=/bin/something)&quot;</span><span class="o">)</span>
+    <span class="kd">private</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Servlet</span><span class="o">&gt;</span> <span class="n">servlets</span><span class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The <code>@PostConstruct</code> annotation can be used to add methods which are invoked upon completion of all injections:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">SlingHttpServletRequest</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">PrintWriter</span> <span class="n">out</span><span class="o">;</span>
+
+    <span class="nd">@Inject</span>
+    <span class="nd">@Named</span><span class="o">(</span><span class="s">&quot;log&quot;</span><span class="o">)</span>
+    <span class="kd">private</span> <span class="n">Logger</span> <span class="n">logger</span><span class="o">;</span>
+
+    <span class="nd">@PostConstruct</span>
+    <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">sayHello</span><span class="o">()</span> <span class="o">{</span>
+         <span class="n">logger</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">&quot;hello&quot;</span><span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p><code>@PostConstruct</code> methods in a super class will be invoked first.</p>
+<p>If the injection should be based on a JavaBean property of the adaptable, you can indicate this using the <code>@Via</code> annotation:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">SlingHttpServletRequest</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="c1">// will return request.getResource().adaptTo(ValueMap.class).get(&quot;propertyName&quot;, String.class)</span>
+    <span class="nd">@Inject</span> <span class="nd">@Via</span><span class="o">(</span><span class="s">&quot;resource&quot;</span><span class="o">)</span>
+    <span class="n">String</span> <span class="nf">getPropertyName</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>If there is ambiguity where a given injection could be handled by more than one injector, the <code>@Source</code> annotation can be used to define which injector is responsible:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">SlingHttpServletRequest</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="c1">// Ensure that &quot;resource&quot; is retrived from the bindings, not a request attribute </span>
+    <span class="nd">@Inject</span> <span class="nd">@Source</span><span class="o">(</span><span class="s">&quot;script-bindings&quot;</span><span class="o">)</span>
+    <span class="n">Resource</span> <span class="nf">getResource</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>If the injected object does not match the desired type and the object implements the <code>Adaptable</code> interface, Sling Models will try to adapt it. This provides the ability to create rich object graphs. For example:</p>
+<div class="codehilite"><pre><span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">MyModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="n">ImageModel</span> <span class="nf">getImage</span><span class="o">();</span>
+<span class="o">}</span>
+
+<span class="nd">@Model</span><span class="o">(</span><span class="n">adaptables</span><span class="o">=</span><span class="n">Resource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">ImageModel</span> <span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="n">String</span> <span class="nf">getPath</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>When a resource is adapted to <code>MyModel</code>, a child resource named <code>image</code> is automatically adapted to an instance of <code>ImageModel</code>.</p>
+<h1 id="annotation-reference">Annotation Reference</h1>
+<dl>
+<dt><code>@Model</code></dt>
+<dd>
+<dl>
+<dt>declares a model class or interface</dt>
+<dt><code>@Inject</code></dt>
+<dd>
+<dl>
+<dt>marks a field or method as injectable</dt>
+<dt><code>@Named</code></dt>
+<dd>
+<dl>
+<dt>declare a name for the injection (otherwise, defaults based on field or method name).</dt>
+<dt><code>@Optional</code></dt>
+<dd>
+<dl>
+<dt>marks a field or method injection as optional</dt>
+<dt><code>@Source</code></dt>
+<dd>
+<dl>
+<dt>explictly tie an injected field or method to a particular injector (by name). Can also be on other annotations.</dt>
+<dt><code>@Filter</code></dt>
+<dd>
+<dl>
+<dt>an OSGi service filter</dt>
+<dt><code>@PostConstruct</code></dt>
+<dd>
+<dl>
+<dt>methods to call upon model option creation (only for model classes)</dt>
+<dt><code>@Via</code></dt>
+<dd>
+<dl>
+<dt>use a JavaBean property of the adaptable as the source of the injection</dt>
+<dt><code>@Default</code></dt>
+<dd>set default values for a field or method</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+<h1 id="available-injectors">Available Injectors</h1>
+<p>Title   Name (for @Source)  Description Applicable To (including using @Via)    Notes
+Value Map   valuemap    Gets a property from a Value Map    Any object which is or can be adapted to a ValueMap 
+OSGI Services   osgi-services   Lookup services based on class name Any object  Effectively ignores name.
+Script Bindings script-bindings Lookup objects in the script bindings object    A ServletRequest object which has the Sling Bindings attribute defined<br />
+Child Resources child-resources Gets a child resource by name   Resource objects  <br />
+Request Attributes  request-attributes  Get a request attribute ServletRequest objects  </p>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1560484 by justin on Wed, 22 Jan 2014 19:21:21 +0000
+      </div>
+      <div class="trademarkFooter"> 
+        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.
+      </div>
+    </div>
+  </body>
+</html>