Using Sling Adapters using-sling-adapters
Sling offers an Adapter pattern to conveniently translate objects that implement the Adaptable interface. This interface provides a generic adaptTo() method that translates the object to the class type being passed as the argument.
For example, to translate a Resource object to the corresponding Node object, you can simply do:
Node node = resource.adaptTo(Node.class);
Use Cases use-cases
There are the following use cases:
-
Get implementation-specific objects.
For example, a JCR-based implementation of the generic
Resource
interface provides access to the underlying JCRNode
. -
Shortcut creation of objects that require internal context objects to be passed.
For example, the JCR-based
ResourceResolver
holds a reference to the request’sJCR Session
, which in turn is needed for many objects that work based on that request session, such as thePageManager
orUserManager
. -
Shortcut to services.
A rare case -
sling.getService()
is simple as well.
Null Return Value null-return-value
adaptTo()
Can return null.
There are various reasons for the null return, including the following:
- the implementation does not support the target type
- an adapter factory handling this case is not active (for example, due to missing service references)
- internal condition failed
- service is not available
It is important that you handle the null case gracefully. For jsp renderings, it might be acceptable to have the jsp fail if it results in an empty piece of content.
Caching caching
To improve performance, implementations are free to cache the object returned from a obj.adaptTo()
call. If the obj
is the same, the returned object is the same.
This caching is performed for all AdapterFactory
based cases.
However, there is no general rule - the object could be either a new instance or an existing one. As such, it means that you cannot rely on either behavior. Hence it is important, especially inside AdapterFactory
, that objects are reusable in this scenario.
How it works how-it-works
There are various ways that Adaptable.adaptTo()
can be implemented:
-
By the object itself; implementing the method itself and mapping to certain objects.
-
By an
AdapterFactory
, which can map arbitrary objects.The objects must still implement the
Adaptable
interface and must extendSlingAdaptable
(which passes theadaptTo
call to a central adapter manager).This method allows hooks into the
adaptTo
mechanism for existing classes, such asResource
. -
A combination of both.
For the first case, the Java™ docs can state what adaptTo-targets
are possible. However, for specific subclasses such as the JCR-based Resource, this statement is often not possible. In the latter case, implementations of AdapterFactory
are typically part of the private classes of a bundle and thus not exposed in a client API, nor listed in Java™ docs. Theoretically, it is possible to access all AdapterFactory
implementations from the OSGi service runtime and look at their “adaptables” (sources and targets) configurations, but not to map them to each other. In the end, it depends on the internal logic, which must be documented. Hence this reference.
Reference reference
Sling sling
Resource adapts to:
ResourceResolver adapts to:
SlingHttpServletRequest adapts to:
No targets yet, but implements Adaptable and could be used as source in a custom AdapterFactory.
SlingHttpServletResponse adapts to:
WCM wcm
Page adapts to:
Component adapts to:
Template adapts to:
Security security
Authorizable, User, and Group adapt to:
DAM dam
Asset adapts to:
Tagging tagging
Tag adapts to:
Other other
Furthermore Sling / JCR / OCM also provides an AdapterFactory
for custom OCM (Object Content Mapping) objects.