SyncContentProcess.java 10.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.dam.commons.process.AbstractAssetWorkflowProcess
 *  com.day.cq.dam.commons.util.DamUtil
 *  com.day.cq.workflow.PayloadMap
 *  com.day.cq.workflow.WorkflowException
 *  com.day.cq.workflow.WorkflowSession
 *  com.day.cq.workflow.exec.WorkItem
 *  com.day.cq.workflow.exec.Workflow
 *  com.day.cq.workflow.exec.WorkflowData
 *  com.day.cq.workflow.metadata.MetaDataMap
 *  com.day.cq.workflow.model.WorkflowModel
 *  com.day.text.Text
 *  javax.jcr.Item
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.Service
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.core.process;

import com.day.cq.dam.commons.process.AbstractAssetWorkflowProcess;
import com.day.cq.dam.commons.util.DamUtil;
import com.day.cq.workflow.PayloadMap;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.exec.Workflow;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.metadata.MetaDataMap;
import com.day.cq.workflow.model.WorkflowModel;
import com.day.text.Text;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.lang.StringUtils;
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.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
@Property(name="process.label", value={"Synchronize Content"})
public class SyncContentProcess
extends AbstractAssetWorkflowProcess {
    private static final Logger log = LoggerFactory.getLogger(SyncContentProcess.class);
    @Reference(policy=ReferencePolicy.STATIC)
    private PayloadMap payloadMap;

    public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaData) throws WorkflowException {
        String[] args = this.buildArguments(metaData);
        try {
            Node node;
            Session session;
            String mode = null;
            if (this.getValuesFromArgs("mode", args).size() > 0) {
                mode = (String)this.getValuesFromArgs("mode", args).get(0);
            }
            String wfModelId = null;
            if (this.getValuesFromArgs("wfModelId", args).size() > 0) {
                wfModelId = (String)this.getValuesFromArgs("wfModelId", args).get(0);
            }
            if ((node = this.getNodeFromPayload(workItem, session = workflowSession.getSession())) != null && mode != null && wfModelId != null) {
                if (mode.equals("sync")) {
                    this.sync(node, workflowSession, wfModelId);
                }
            } else if (mode != null && mode.equals("cleanup")) {
                String path;
                String string = path = workItem.getWorkflowData().getPayloadType().equals("JCR_PATH") ? workItem.getWorkflowData().getPayload().toString() : null;
                while (path != null && !session.itemExists(path)) {
                    path = Text.getRelativeParent((String)path, (int)1);
                }
                this.cleanup((Node)session.getItem(path));
            } else {
                log.debug("execute: referenced payload node does not exist; work item [{}].", (Object)workItem.getId());
            }
            if (session.hasPendingChanges()) {
                session.save();
            }
        }
        catch (RepositoryException e) {
            log.error("execute: error while syncing structure; work item [{}]: ", (Object)workItem.getId(), (Object)e);
        }
    }

    private void sync(Node parentNode, WorkflowSession wfSession, String wfModelId) throws RepositoryException {
        if (parentNode.isNodeType("nt:folder")) {
            this.checkFolder(parentNode);
            Session session = parentNode.getSession();
            NodeIterator itr = parentNode.getNodes();
            while (itr.hasNext()) {
                Node node = itr.nextNode();
                if (node.isNodeType("nt:file")) {
                    String path = DamUtil.binaryToAssetPath((String)node.getPath());
                    if (!session.itemExists(path)) {
                        if (!path.contains("/._")) {
                            if (!this.isAlreadyInSameWorkflow(node, wfModelId)) {
                                this.startWorkflow(node.getPath(), wfModelId, wfSession);
                                log.debug("sync: asset for [{}] does not exist, syncing with destination [{}]...", (Object)this.safeGetPath(node), (Object)path);
                                continue;
                            }
                            log.info("sync: skipping sync of [{}].", (Object)path);
                            continue;
                        }
                        log.debug("sync: skipping sync of [{}].", (Object)path);
                        continue;
                    }
                    log.debug("sync: asset for [{}] already exists at [{}].", (Object)this.safeGetPath(node), (Object)path);
                    continue;
                }
                if (node.isNodeType("nt:folder")) {
                    this.checkFolder(node);
                    this.sync(node, wfSession, wfModelId);
                    continue;
                }
                log.debug("sync: skipping sync for [{}].", (Object)this.safeGetPath(node));
            }
        } else {
            log.debug("sync: skipping sync for [{}].", (Object)this.safeGetPath(parentNode));
        }
    }

    private boolean isAlreadyInSameWorkflow(Node node, String wfModelId) throws RepositoryException {
        if (this.payloadMap.isInWorkflow(node.getPath(), true)) {
            List wfs = this.payloadMap.getWorkflowInstances(node.getPath(), true);
            for (Workflow wf : wfs) {
                if (!wf.getWorkflowModel().getId().equals(wfModelId)) continue;
                return true;
            }
        }
        return false;
    }

    private void checkFolder(Node node) throws RepositoryException {
        String dest = this.getDest(node);
        if (!node.getSession().itemExists(dest)) {
            Node destNode = (Node)node.getSession().getItem(Text.getRelativeParent((String)dest, (int)1));
            destNode.addNode(node.getName(), "sling:OrderedFolder");
        }
    }

    protected void startWorkflow(String assetPath, String workflowId, WorkflowSession wfSession) {
        try {
            WorkflowModel model = wfSession.getModel(workflowId);
            WorkflowData wfData = wfSession.newWorkflowData("JCR_PATH", (Object)assetPath);
            wfSession.startWorkflow(model, wfData);
        }
        catch (Exception e) {
            log.warn("startWorkflow: cannot start workflow for [{}]: ", (Object)assetPath, (Object)e);
        }
    }

    private String getDest(Node node) throws RepositoryException {
        return DamUtil.binaryToAssetPath((String)node.getPath());
    }

    private void cleanup(Node node) throws RepositoryException {
        try {
            if (node.getSession().itemExists(this.getDest(node))) {
                Node contentFolder = (Node)node.getSession().getItem(this.getDest(node));
                log.debug("cleanup: starting cleanup for [{}]...", (Object)this.safeGetPath(contentFolder));
                NodeIterator itr = contentFolder.getNodes();
                while (itr.hasNext()) {
                    Node contentNode = itr.nextNode();
                    if (node.hasNode(contentNode.getName())) continue;
                    try {
                        String path = this.safeGetPath(contentNode);
                        contentNode.remove();
                        log.info("cleanup: removed [{}].", (Object)path);
                    }
                    catch (RepositoryException re) {
                        log.debug("cleanup: failed to remove [{}]: ", (Object)this.safeGetPath(node));
                    }
                }
            }
        }
        catch (RepositoryException e) {
            log.debug("cleanup: failed to clean [{}]: ", (Object)this.safeGetPath(node));
        }
    }

    public String[] buildArguments(MetaDataMap metaData) {
        String processArgs = (String)metaData.get(Arguments.PROCESS_ARGS.name(), String.class);
        if (processArgs != null && !processArgs.equals("")) {
            return processArgs.split(",");
        }
        ArrayList<String> arguments = new ArrayList<String>();
        String currentMode = (String)metaData.get(Arguments.MODE.name(), String.class);
        String wfModelId = (String)metaData.get(Arguments.WF_MODEL_ID.name(), String.class);
        if (StringUtils.isNotBlank((String)currentMode)) {
            arguments.add(Arguments.MODE.getArgumentPrefix() + currentMode);
        }
        if (StringUtils.isNotBlank((String)wfModelId)) {
            arguments.add(Arguments.WF_MODEL_ID.getArgumentPrefix() + wfModelId);
        }
        return arguments.toArray(new String[arguments.size()]);
    }

    protected void bindPayloadMap(PayloadMap payloadMap) {
        this.payloadMap = payloadMap;
    }

    protected void unbindPayloadMap(PayloadMap payloadMap) {
        if (this.payloadMap == payloadMap) {
            this.payloadMap = null;
        }
    }

    public static enum Modes {
        sync,
        cleanup;
        

        private Modes() {
        }
    }

    public static enum Arguments {
        PROCESS_ARGS("PROCESS_ARGS"),
        MODE("mode"),
        WF_MODEL_ID("wfModelId");
        
        private String argumentName;

        private Arguments(String argumentName) {
            this.argumentName = argumentName;
        }

        public String getArgumentName() {
            return this.argumentName;
        }

        public String getArgumentPrefix() {
            return this.argumentName + ":";
        }
    }

}