DMImageProcess.java 10.9 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.cq.dam.dm.process.api.PTiffManager
 *  com.adobe.cq.dam.dm.process.api.PTiffMetadata
 *  com.adobe.cq.dam.dm.process.api.PTiffRendition
 *  com.adobe.granite.workflow.WorkflowException
 *  com.adobe.granite.workflow.WorkflowSession
 *  com.adobe.granite.workflow.exec.WorkItem
 *  com.adobe.granite.workflow.exec.WorkflowData
 *  com.adobe.granite.workflow.exec.WorkflowProcess
 *  com.adobe.granite.workflow.metadata.MetaDataMap
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.Rendition
 *  com.day.cq.dam.commons.util.DamUtil
 *  com.scene7.is.util.RectInt
 *  com.scene7.is.util.SizeInt
 *  com.scene7.is.util.collections.CollectionUtil
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceMetadata
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.jcr.resource.JcrPropertyMap
 *  org.jetbrains.annotations.NotNull
 *  org.jetbrains.annotations.Nullable
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.dam.dm.process.workflow;

import com.adobe.cq.dam.dm.process.api.PTiffManager;
import com.adobe.cq.dam.dm.process.api.PTiffMetadata;
import com.adobe.cq.dam.dm.process.api.PTiffRendition;
import com.adobe.cq.dam.dm.process.workflow.InsetCropParser;
import com.adobe.cq.dam.dm.process.workflow.InvalidInsetCrop;
import com.adobe.cq.dam.s7imaging.impl.ProfilerUtil;
import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.WorkflowData;
import com.adobe.granite.workflow.exec.WorkflowProcess;
import com.adobe.granite.workflow.metadata.MetaDataMap;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import com.day.cq.dam.commons.util.DamUtil;
import com.scene7.is.util.RectInt;
import com.scene7.is.util.SizeInt;
import com.scene7.is.util.collections.CollectionUtil;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.JcrPropertyMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service
@Property(name="process.label", value={"Processes assets for use with Dynamic Media Imaging"})
public class DMImageProcess
implements WorkflowProcess {
    private static final Logger log = LoggerFactory.getLogger(DMImageProcess.class);
    private static final String OPTION_CROP = "crop";
    @Reference
    private PTiffManager ptiffManager;
    private static final Set<String> IGNORED_PROPERTIES = CollectionUtil.hashSetOf((Object[])new String[]{"jcr:primaryType"});

    public void execute(WorkItem item, WorkflowSession wfSession, MetaDataMap args) throws WorkflowException {
        if (!this.ptiffManager.isEnabled()) {
            log.debug("Skipping because Dynamic Media is not enabled");
            return;
        }
        Session session = (Session)wfSession.adaptTo(Session.class);
        Asset asset = DMImageProcess.getAssetFromPayload(wfSession, item.getWorkflowData());
        if (asset == null) {
            log.debug("Skipping work item, since it's not an asset: {}", (Object)item);
            return;
        }
        ValueMap options = DMImageProcess.getProcessingOptions(session, asset);
        ProfilerUtil profilerUtil = new ProfilerUtil();
        try {
            asset.setBatchMode(true);
            profilerUtil.start("createPTiffRendition");
            PTiffRendition ptiff = this.createPTiffRendition(asset, options);
            if (ptiff != null) {
                profilerUtil.start("updateImageModifiers");
                this.updateImageModifiers(asset, ptiff, options);
                profilerUtil.start("updateLegacyProperties");
                this.updateLegacyProperties(asset, ptiff);
            }
            profilerUtil.start("session.save");
            session.save();
            log.debug("Completed: {} {}", (Object)asset.getPath(), (Object)profilerUtil.print());
        }
        catch (RepositoryException e) {
            throw new WorkflowException((Throwable)e);
        }
        catch (IOException e) {
            throw new WorkflowException((Throwable)e);
        }
    }

    @Nullable
    private PTiffRendition createPTiffRendition(@NotNull Asset asset, @NotNull ValueMap options) throws IOException {
        PTiffRendition newPTiff = null;
        Rendition rendition = asset.getImagePreviewRendition();
        if (rendition != null) {
            PTiffRendition existingPTiff = this.ptiffManager.getPTiffRendition(asset);
            if (!DMImageProcess.regeneratePTiff(rendition, existingPTiff)) {
                log.debug("PTIFF rendition is up-to-date, skipping PTIFF generation: {}", (Object)asset.getPath());
                return existingPTiff;
            }
            newPTiff = this.ptiffManager.createPTiffRendition(rendition, asset, options);
        }
        if (newPTiff == null) {
            log.debug("Unable to generate PTIFF for asset: {}", (Object)asset.getPath());
            this.ptiffManager.removePTiffRendition(asset);
        }
        return newPTiff;
    }

    private static boolean regeneratePTiff(@NotNull Rendition image, @Nullable PTiffRendition ptiff) {
        if (ptiff == null) {
            return true;
        }
        long originalLastMod = image.getResourceMetadata().getModificationTime();
        if (originalLastMod < 0) {
            return true;
        }
        long ptiffLastMod = ptiff.getResourceMetadata().getModificationTime();
        return ptiffLastMod < originalLastMod;
    }

    private void updateImageModifiers(@NotNull Asset asset, @NotNull PTiffRendition ptiff, @NotNull ValueMap options) throws IOException {
        ModifiableValueMap modifiers;
        PTiffMetadata metadata = ptiff.getMetadata();
        SizeInt tiffDim = SizeInt.sizeInt((int)metadata.getWidth(), (int)metadata.getHeight());
        Resource jcrContent = DMImageProcess.getJcrContent(asset);
        ResourceResolver resolver = jcrContent.getResourceResolver();
        Resource modifierFolder = jcrContent.getChild("modifier");
        if (modifierFolder == null) {
            modifierFolder = resolver.create(jcrContent, "modifier", Collections.singletonMap("jcr:primaryType", "nt:unstructured"));
        }
        if ((modifiers = (ModifiableValueMap)modifierFolder.adaptTo(ModifiableValueMap.class)) == null) {
            throw new IOException("Unable to modify properties of " + modifierFolder.getPath());
        }
        if (metadata.isOriginal()) {
            DMImageProcess.addCropModifier(asset, tiffDim, options, modifiers);
        } else {
            modifiers.remove((Object)"crop");
        }
        if (!DMImageProcess.hasModifiers((ValueMap)modifiers)) {
            resolver.delete(modifierFolder);
        }
    }

    private static void addCropModifier(@NotNull Asset asset, @NotNull SizeInt tiffDim, @NotNull ValueMap options, @NotNull ModifiableValueMap modifiers) {
        try {
            String cropInset = (String)options.get("crop", (Object)"");
            RectInt rect = RectInt.rectInt((SizeInt)tiffDim);
            RectInt crop = InsetCropParser.parseInsetCrop(cropInset, rect);
            if (crop.equals((Object)RectInt.rectInt())) {
                log.warn("Crop ignored since it results in to an empty image " + asset.getPath());
                modifiers.remove((Object)"crop");
            } else if (crop.equals((Object)rect)) {
                modifiers.remove((Object)"crop");
            } else {
                modifiers.put((Object)"crop", (Object)crop.toString());
            }
        }
        catch (InvalidInsetCrop e) {
            log.warn("Crop ignored while processing asset " + asset.getPath(), (Throwable)e);
        }
    }

    private static boolean hasModifiers(@NotNull ValueMap map) {
        for (String key : map.keySet()) {
            if (IGNORED_PROPERTIES.contains(key)) continue;
            return true;
        }
        return false;
    }

    private void updateLegacyProperties(@NotNull Asset asset, @NotNull PTiffRendition ptiff) throws IOException {
        Resource jcrContent = DMImageProcess.getJcrContent(asset);
        ModifiableValueMap map = (ModifiableValueMap)jcrContent.adaptTo(ModifiableValueMap.class);
        if (map == null) {
            throw new IOException("Unable to modify properties of " + jcrContent.getPath());
        }
        if (!map.containsKey((Object)"dam:s7damType")) {
            map.put((Object)"dam:s7damType", (Object)"Image");
        }
    }

    @NotNull
    private static Resource getJcrContent(@NotNull Asset asset) throws IOException {
        Resource jcrContent;
        Resource resource = (Resource)asset.adaptTo(Resource.class);
        if (resource != null && (jcrContent = resource.getChild("jcr:content")) != null) {
            return jcrContent;
        }
        throw new IOException("Unable to access jcr:content node under " + asset.getPath());
    }

    @NotNull
    private static ValueMap getProcessingOptions(@NotNull Session session, @NotNull Asset asset) {
        Node imageProfileNode = DamUtil.getApplicableProfile((Asset)asset, (String)"imageProfile", (Session)session);
        if (imageProfileNode != null) {
            return new JcrPropertyMap(imageProfileNode);
        }
        return ValueMap.EMPTY;
    }

    @Nullable
    private static Asset getAssetFromPayload(@NotNull WorkflowSession wfSession, @NotNull WorkflowData data) {
        ResourceResolver resolver;
        Resource resource;
        if (data.getPayloadType().equals("JCR_PATH") && (resource = (resolver = (ResourceResolver)wfSession.adaptTo(ResourceResolver.class)).getResource(data.getPayload().toString())) != null) {
            return DamUtil.resolveToAsset((Resource)resource);
        }
        return null;
    }

    protected void bindPtiffManager(PTiffManager pTiffManager) {
        this.ptiffManager = pTiffManager;
    }

    protected void unbindPtiffManager(PTiffManager pTiffManager) {
        if (this.ptiffManager == pTiffManager) {
            this.ptiffManager = null;
        }
    }
}