Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

AdapterFactory, SlingAdaptable and caching

baptisteg119505
Level 1
Level 1

I struggle to understand how the built-in caching mechanism of Sling works when using AdapterFactory.

 

Here is my first AdapterFactory:

 

@component(
        property = {
                AdapterFactory.ADAPTABLE_CLASSES + "=org.apache.sling.api.SlingHttpServletRequest",
                AdapterFactory.ADAPTER_CLASSES + "=com.example.Foo"
        }
)
public final class FooAdapterFactory implements AdapterFactory {
    @Override
    public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> adapterTypeClass) {
        SlingHttpServletRequest request = (SlingHttpServletRequest) adaptable;
        return Optional.ofNullable(request.getResourceResolver().adaptTo(PageManager.class))
                .map(pageManager -> pageManager.getContainingPage(request.getResource()))
                .map(page -> page.getContentResource())
                // the following line is not cached:
                .map(contentResource -> contentResource.adaptTo(Bar.class))
                // continue the chain with the Bar instance
                .map(...)
                .orElse(null);
    }
}

 

 

And the my second AdapterFactory:

 

@component(service = AdapterFactory.class,
        property = {
                AdapterFactory.ADAPTABLE_CLASSES + "=org.apache.sling.api.resource.Resource",
                AdapterFactory.ADAPTER_CLASSES + "=com.example.Bar"
        }
)
public final class BarAdapterFactory implements AdapterFactory {
    @Override
    public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> adapterTypeClass) {
        Resource resource = (Resource) adaptable;
        // perform costly operation using the resource
        // ...
    }
}

 

 

From the sightly template, I call the FooAdapterFactory from various locations (multiple components on the same page use Foo) with:

 

<sly data-sly-use.foo="com.example.Foo" />

 

 

For a single HTTP request to /content/example/mypage.html, I would expect the second call (and the following ones) to contentResource.adaptTo(Bar.class) to be cached as contentResource is a JcrNodeResource, which extends SlingAdaptable. and therefore should be cached by Sling from what I understand.
However, this is not the case and my costly operation done in BarAdapterFactory.getAdapter() is called for each call to <sly data-sly-use.foo="com.example.Foo" />.

Can someone point out what I am missing here please? Or is there a better to achieve what I am trying to do? 
Thanks in advance

1 Reply