Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a custom AdapterFactory for Sling Resource?

The Adobe AEM software provides several classes which can take an apache Sling Resource and adapt it to another class like so:

Page page = resource.adaptTo(Page.class);

To use this syntax with classes that you author and control this boils down to simply implementing the Adaptable interface.

However, if you want to enable a Resource to adaptTo your new custom class, is seems that you have to implement the AdapterFactory interface and register it in OSGI.

This is how the Adobe website describes it:

By an AdapterFactory, which can map arbitrary objects. The objects must still implement the Adaptable interface and must extend SlingAdaptable (which passes the adaptTo call to a central adapter manager). This allows hooks into the adaptTo mechanism for existing classes, such as Resource.

I have walked through the SlingScriptAdapterFactory code, but ultimately I am not connecting the dots here. Basically I want to do this:

MyClass myClass = Resource.adaptTo(MyClass.class);

Do I create a class that implements AdapterFactory and simply deploy it with the package expecting that Sling will just find it by type or is there more to it?

like image 628
jedatu Avatar asked Jun 28 '13 21:06

jedatu


People also ask

What is the adapterfactory interface in sling?

To cope with such extensibility requirements two interfaces and an abstract base class are defined: The AdapterFactory interface defines the service interface and API for factories supporting extensible adapters for SlingAdaptable objects. The interface has a single method: /** * Adapt the given object to the adaptable type.

How to adapt resource to slingscript objects using adapter factory?

This way, the script manager can provide an adapter factory to adapt Resource to SlingScript objects. The Adaptable interface defines the API to be implemented by a class providing adaptability to another class. The single method defined by this interface is This method is called to get a view of the same object in terms of another class.

What is the adaptable interface in slingscript?

To enable adapting objects to classes which are not foreseen by the original implementation, a factory mechanism is used. This way, the script manager can provide an adapter factory to adapt Resource to SlingScript objects. The Adaptable interface defines the API to be implemented by a class providing adaptability to another class.

How do I translate an object to another class in sling?

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.


2 Answers

Here is a little bit better documentation https://sling.apache.org/documentation/the-sling-engine/adapters.html

So you should implement the Adaptable interface, as you already described. Then create a properly annotated AdapterFactory:

@Component
@Service(value=org.apache.sling.api.adapter.AdapterFactory.class)
@Properties({
   @Property(name = "adaptables", value = { "org.apache.sling.api.resource.Resource" }),
   @Property(name = "adapters", value = { "org.sling.MyClass" })
})
public class MyAdapterFactory implements AdapterFactory{
    public  <AdapterType> AdapterType getAdapter(final Object adaptable, Class<AdapterType> type){
          return new MyClassAdapter(adaptable);   
    }     
}
like image 101
notdang Avatar answered Sep 18 '22 17:09

notdang


Note that I've been working on a simpler way to create Sling adapters, by annotating methods with a new @Adapter annotation, as in

  @Component
  @Service
  public class C implements AdapterMethodsProvider {
    @Adapter
    public CustomerRecord convert(Resource r) { ... }

    @Adapter
    public Person adaptToPerson(Resource r) { ... }
  }

See https://issues.apache.org/jira/browse/SLING-2938 for details, but note that this is not even in the Sling trunk yet, so it will take some time before it's released and available in AEM/CQ.

like image 29
Bertrand Delacretaz Avatar answered Sep 20 '22 17:09

Bertrand Delacretaz