Using Sling Adapters
- Topics:
- Developing
CREATED FOR:
- Developer
Sling offers an Adapter pattern to conveniently translate objects that implement the Adaptable interface. This interface provides a generic adaptTo() method that will translate 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
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 will 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
adaptTo()
can return null.
There are various reasons for this, including:
- the implementation does not support the target type
- an adapter factory handling this case is not active (eg. 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 that will result in an empty piece of content.
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. This 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
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 allows hooks into the
adaptTo
mechanism for existing classes, such asResource
. -
A combination of both.
For the first case, the javadocs can state what adaptTo-targets
are possible. However, for specific subclasses such as the JCR-based Resource, often this is 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 javadocs. Theoretically, it would be 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, this depends on the internal logic, which must be documented. Hence this reference.
ResourceUtil.getValueMap(Resource)
(handles null case, etc.).Note: multiple persistable maps do not share their values.
resource (if this is a JCR-node-based resource and the node type is nt:file
or nt:resource
; if this is a bundle resource; file content if this is a file system resource) or the data of a binary JCR propertyresource.
(Jackrabbit)
AuthorizableResourceProvider
in org.apache.sling.jackrabbit.usermanager
, under /system/userManager
).cq:Page
(or cq:PseudoPage
).cq:Component
node resource.cq:Page
, typically under/etc/designs).
cq:Template
node resource.cq:Page
node resource (more specific checks possible in the future).cq:Tag
node resource.cq:Preferences
node resource for a valid user/group.cq/security/components/profile).
(cq-security)
(cq-security)
cq:ContentSyncConfig
node resource.cq:ContentSyncConfig
node resource.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:
(XML)
WCM
Page adapts to:
Component adapts to:
Template adapts to:
Security
Authorizable, User and Group adapt to:
DAM
Asset adapts to:
Tagging
Tag adapts to:
Other
Furthermore Sling / JCR / OCM also provides an [AdapterFactory](https://sling.apache.org/site/adapters.html#Adapters-AdapterFactory)
for custom OCM (Object Content Mapping) objects.