CQCON 2013: five Sling features you should know
Olaf Otto
1: Write custom tag libraries
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"> <taglib><uri>http://www.corp.com/taglibs/mytaglib/1.0</uri>
... </taglib>
META-INF/<name>.tld
Version your API! Fully qualified identifier Use current XSDTaglibs are not exactly the latest trend, but they get the job done properly –
re-usable, testable
implementations for view-related tasks such as rich
text transformation, i18n, date formatting etc.
Multiple TLDs allowed
1.1 Talking of versioned taglibs:
<sling:include /> <sling:forward /> <sling:defineObjects /> http://sling.apache.org/taglibs/sling/1.0 <sling:call /><sling:eval /> http://sling.apache.org/taglibs/sling/1.2
Current
${sling:adaptTo(from, to)}
${sling:findResources(resolver, query, language)} ${sling:getRelativeResource(resource, path)}
${sling:getResource(resolver, path)} ${sling:listChildren(resource)}
<sling:getProperty /> <sling:getResource />
http://sling.apache.org/taglibs/sling/1.3 Coming
2: Enriching the view
@Service@Component(immediate = true)
public class Provider implements BindingsValuesProvider {
@Override
public void addBindings(Bindings bindings) { } } View (JSP) anything Map<String, ?> ${bindings.key}
The BindingsValuesProvider allows you to inject anything into any view and thus aides in
de-coupling view and backend layer. © computing.co.uk
2.1 By the way: Semantic Annotations
@SlingServlet(paths = "/bin/myservlet")
public class MyServlet extends SlingSafeMethodsServlet {
@Override
public void doGet(…) { }
}
@SlingFilter
public class MyFilter implements Filter {
@Override
public void doFilter(…) { }
}
Use typesafe Java 5 annotations (not the JAVADoc ones). SlingFilter and SlingServlet are part of
felix-scr-annotations and supported by the maven-scr-plugin.
Click to edit Master title style
++complexity
Sling has a simple generic resource model (Resource, ValueMap), which
may not suffice when resources require complex operations on their
3: When
Resource
is not enough
CUG protection Persistence Sitemap entry Page cq:Page Properties LinkThese are independent aspects of the cq:Page resource type taken from
an actual project. Each aspect requires an
3.1 .adaptTo(TheRescue)
No more util-class projects, please.
{
data, Operations
} : Mode
l
.adaptTo(X)
Best pratice for Sling: write a POJO for an aspect and .adaptTo it.
.adaptTo’s most valueable application is adaptation to type safe representations of aspects of resources
Please do not implement such aspects in static util functions. This is a terrible
3.2: .adaptTo & OSGi best practices
© dadcando.com Implementation API Feature .adaptTo Provides API implementation + AdapterFactory Clean separation.adapTo is a perfect match for OSGi best practices. Refer to
http://www.ibm.com/developerworks/websphere/techjournal/1007_charters/1007_charter s.html#sec5 Contains adapter interface © computing.co.uk
3.3: Boilerplate, anyone?
@Component
@Service
@Properties({
@Property(name = "adaptables",
value = "org.apache.sling.api.resource.Resource"),
@Property(name = "adapters",
value = "fully.qualified.type.Name")
})
public class MyFactory implements AdapterFactory {
public <T> T getAdapter(Object from, Class<T> toType) {
… } } = from = to If () else if () … Stringly typed
Such boilerplate may well be the reason developers avoid
3.4: Choices!
Generic Adapterfactory Improve declaration
© onespoonatatime.com
Luckily, boilerplate can be circumvented by either simplifying declaration or programmatically publishing
a generic adapter factory
Note: AdapterFactories are excellent extension points for
Spring integration. When obtaining the Adapter from the Spring bean factory, you can transparently adapt to a
Spring bean at any time
from anywhere in you
3.5 Custom SCR annotation for adapter factories
@Adapts(from = Resource.class, to = Name.class)
public class MyFactory implements AdapterFactory {
public <T> T getAdapter(Object from, Class<T> toType) { …
} }
How? SCR plugin / task + AnnotationProcessor
Typesafe!
The simple most approach is to exchange the boilerplate SCR
metadata with a semantic annotation
Refer to: http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/extending-scr-annotations.html
4: Decorating resources
• Manipulation of any Resource
• Transparent (.adaptTo, Views)
@Service
@Component(immediate = true)
public class Decorator implements ResourceDecorator {
@Override
public Resource decorate(Resource resource) { }
} Note: This is one of the most powerful
extension points allowing manipulating any resource – even script and servlets
(everything is a resource!).
Sample application: Resources with a specific property (e.g. inherit=true) are wrapped with a resource that provides an InhertianceVauleMap. This way, you can enable transparent inheritance for any resource at any time without changing a single line of code. Source from CQCON, see: http://www.cqcon.eu/2013/en/speakers/olaf-otto.html
5: Providing custom resources
ResourceProvider /custom /custom/<child> JCR /content /site Refer to http://sling.apache.org/documentation/the-sling-engine/resources.html , «Providing Resources»• Bad fit for thirdparty integration (tight coupling!). Better:
• Good fit for local integration (DBs, Filesystem…). Upcoming Sling version features provider for MongoDB.
5.1: The pros an cons
soaml ESB
Advertise Advertise
Advertise UseUseUse
Enterprise serv ice bus
Advertise
Advertise UseUse
System System System Client Client Client RESTful support – e.g. ServiceMix
JSONP for cross-domain integration
• CRUD support with PersistableValueMap
• Deployment of custom node types in bundles (CND)
• Static resource support: Serve static resource from bundles
Belpstrasse 48 3007 Bern Tel +41 31 560 12 12 Fax +41 31 560 12 13 [email protected] www.unic.com