AEM Cloud Service - Delegate Annotation for Extending AEM Core component Internal Sling Models

Goal

Sometimes everything provided by the Core Component Sling Models is just fine except you need a minor tweak. Say, you want alt of an image to show file name appended to alt text entered by user in dialog. Instead of creating a new sling model for the component and as you cannot extend the core component internal class com.adobe.cq.wcm.core.components.internal.models.v3.ImageImpl, create a delegate and override just the method you need eg. in this post public String getAlt()

Demo | Package Install | Github

Solution

1) Add Project Lombok Maven dependency in eaem-image-comp-sling-delegate\pom.xml

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>compile</scope>
</dependency>


2) Add sling model apps.experienceaem.sites.core.models.ImageAltDelegate for the component eaem-image-comp-sling-delegate/components/image and override just the public String getAlt() method...

package apps.experienceaem.sites.core.models;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.models.Image;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.via.ResourceSuperType;
import lombok.experimental.Delegate;

@Model(
adaptables = {SlingHttpServletRequest.class},
adapters = {Image.class, ComponentExporter.class},
resourceType = { ImageAltDelegate.RESOURCE_TYPE }
)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class ImageAltDelegate implements Image {
public static final String RESOURCE_TYPE = "eaem-image-comp-sling-delegate/components/image";

@SlingObject
protected Resource resource;

@Self
@Via(type = ResourceSuperType.class)
@Delegate(excludes = DelegationExclusion.class)
private Image delegate;

@ValueMapValue(
name = "alt",
injectionStrategy = InjectionStrategy.OPTIONAL
)
protected String alt;

@ValueMapValue(
name = "fileReference",
injectionStrategy = InjectionStrategy.OPTIONAL
)
protected String fileReference;

@Override
public String getAlt() {
return delegate.getAlt() + "-" + fileReference.substring(fileReference.lastIndexOf("/") + 1);
}

private interface DelegationExclusion {
String getAlt();
}
}

No comments:

Post a Comment