Search code examples
aemsling

Why ContentFragment.adaptTo() return null?


I want to create a custom sling model which can be adapted from com.adobe.cq.dam.cfm.ContentFragment like below,

import com.adobe.cq.dam.cfm.ContentFragment;

@Model(adaptables = ContentFragment.class, adapters = EventInfo.class)
public class EventInfoImpl implements EventInfo{
  @Self
  ContentFragment cf;
  
  @Override
  public String getTitle(){
    return cf.getElement("title").getContent();
  }
}

but in a caller class,

EventInfo e = contentFragment.adaptTo(EventInfo.class);

adaptTo() returns null.(variable "e" is null)

Why adaptTo() returns null? and How do I adapt correctly in this case?


Solution

  • Sling models can only be adapted from Resource or SlingHttpServletRequest. For anything else you need a classic AdapterFactory.

    https://sling.apache.org/apidocs/sling11/org/apache/sling/api/adapter/AdapterFactory.html

    How to implement a custom AdapterFactory for Sling Resource?


    You can see it in the Sling source code of the ModelAdapterFactory. There is the method createModel:

    <ModelType> ModelType createModel(@NotNull Object adaptable, @NotNull Class<ModelType> type)
    

    https://github.com/apache/sling-org-apache-sling-models-impl/blob/master/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java

    If you dig down, the real filtering happens in the helper-class AdapterImplementations (line 258-268)

    https://github.com/apache/sling-org-apache-sling-models-impl/blob/master/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java

         if (adaptableType == Resource.class) {
             map = resourceTypeMappingsForResources;
             resourceTypeRemovalLists = resourceTypeRemovalListsForResources;
         } else if (adaptableType == SlingHttpServletRequest.class) {
             map = resourceTypeMappingsForRequests;
             resourceTypeRemovalLists = resourceTypeRemovalListsForRequests;
         } else {
             log.warn("Found model class {} with resource type {} for adaptable {}. Unsupported type for resourceType binding.",
                     new Object[] { clazz, resourceType, adaptableType });
             return;
         }