AEM 61 - JcrPayloadPathBuilder Implementation to change Inbox Item Url from Touch to Classic

Goal


When a user clicks on Inbox item of Classic UI, by default the asset opens in Touch UI editor - /assetdetails.html

This post is on changing the url from Touch (/assetdetails.html) to Classic (/damadmin) for workflow started on assets in sample folder /content/dam/experience-aem

Demo | SourcePackage Install


Solution


1) Create a OSGI service apps.experienceaem.inbox.ClassicUIAssetUrlPathBuilder implementing com.day.cq.workflow.ui.JcrPayloadPathBuilder with much lower ranking say -1306, installed in /apps/classicui-inbox-asset-url/install

package apps.experienceaem.inbox;

import com.day.cq.dam.api.Asset;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.ui.JcrPayloadPathBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.*;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Component(metatype = false)
@Service
@Properties({
    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Experience AEM Classic UI Inbox Asset Url"),
    @Property(name = "service.ranking", intValue = -1306, propertyPrivate = false)
})
public class ClassicUIAssetUrlPathBuilder implements JcrPayloadPathBuilder {
    private static final Logger log = LoggerFactory.getLogger(ClassicUIAssetUrlPathBuilder.class);

    private static String EAEM_FOLDER = "/content/dam/experience-aem";

    @Reference
    private ResourceResolverFactory resolverFactory;

    public String buildPath(WorkItem item) {
        ResourceResolver srvResolver = null;

        try {
            if (!item.getWorkflowData().getPayloadType().equals("JCR_PATH")) {
                return null;
            }

            String path = item.getWorkflowData().getPayload().toString();

            Map<String, Object> authMap = new HashMap<String, Object>();
            authMap.put(ResourceResolverFactory.SUBSERVICE, "pathbuilder");

            srvResolver = resolverFactory.getServiceResourceResolver(authMap);

            Resource res = srvResolver.getResource(path);

            if (res == null || !StringUtils.startsWith(res.getPath(), EAEM_FOLDER)) {
                return null;
            }

            if (res.adaptTo(Asset.class) != null) {
                return "/damadmin#" + res.getPath();
            }
        } catch (Exception e) {
            log.warn("Error creating inbox asset url", e);
        } finally {
            if (srvResolver != null) {
                srvResolver.close();
            }
        }

        return null;
    }
}

2) Create a service user mapping for bundle apps.experienceaem.inbox.classicui-inbox-asset-url-bundle and sub service pathbuilder in folder /apps/classicui-inbox-asset-url/config, node org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-eaem of type sling:OsgiConfig

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="sling:OsgiConfig"
    user.mapping="[apps.experienceaem.inbox.classicui-inbox-asset-url-bundle:pathbuilder=targetservice]"/>

3) Check the component registered in http://localhost:4502/system/console/components



1 comment:

  1. Forgive me as I haven't tried implementing this yet, but simply because this service exists, the system knows to use it over the default implementation? What actually ties this to the clicking of an inbox item?

    ReplyDelete