SyncVarProcess.java 10.2 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.jcr.JcrUtil
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.Rendition
 *  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.WorkflowData
 *  com.day.cq.workflow.metadata.MetaDataMap
 *  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.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.core.process;

import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
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.WorkflowData;
import com.day.cq.workflow.metadata.MetaDataMap;
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.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

    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);
            }
            if ((node = this.getNodeFromPayload(workItem, session = workflowSession.getSession())) != null && mode != null) {
                if (mode.equals("sync")) {
                    this.sync(node, this.getResourceResolver(session));
                }
            } 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);
        }
    }

    public void execute(WorkItem workItem, WorkflowSession workflowSession) throws Exception {
    }

    private void sync(Node node, ResourceResolver resolver) throws RepositoryException {
        Session session = node.getSession();
        if (node.isNodeType("sling:OrderedFolder")) {
            JcrUtil.createPath((String)this.getDest(node), (String)"nt:folder", (String)"nt:folder", (Session)session, (boolean)false);
            this.cleanup(node);
            NodeIterator itr = node.getNodes();
            while (itr.hasNext()) {
                Node n = itr.nextNode();
                if (n.isNodeType("dam:Asset")) {
                    log.debug("sync: syncing asset [{}]...", (Object)this.safeGetPath(n));
                    Asset asset = (Asset)resolver.getResource(n.getPath()).adaptTo(Asset.class);
                    if (null != asset) {
                        String dest = this.getDest(node);
                        if (session.itemExists(this.getDest(n)) || this.getDest(n).contains("/._") || this.payloadMap.isInWorkflow(dest + "/" + asset.getName(), true)) continue;
                        JcrUtil.copy((Node)((Node)asset.getOriginal().adaptTo(Node.class)), (Node)((Node)session.getItem(dest)), (String)asset.getName(), (boolean)true);
                        continue;
                    }
                    log.warn("sync: asset [{}] doesn't exist, cannot sync.");
                    continue;
                }
                if (!node.isNodeType("sling:OrderedFolder") || n.getParent().isNodeType("dam:Asset") || n.getName().equals("jcr:content")) continue;
                log.debug("sync: syncing folder [{}]...", (Object)this.safeGetPath(n));
                String dest = this.getDest(n);
                if (!session.itemExists(dest)) {
                    Node destNode = (Node)session.getItem(this.getDest(node));
                    destNode.addNode(n.getName(), "nt:folder");
                }
                this.sync(n, resolver);
            }
        } else if (node.isNodeType("dam:Asset")) {
            Asset asset = (Asset)resolver.getResource(node.getPath()).adaptTo(Asset.class);
            String dest = this.getDest(node.getParent());
            if (!(session.itemExists(this.getDest(node)) || this.payloadMap.isInWorkflow(dest + "/" + asset.getName(), true) || node.getParent().getName().equals("subassets"))) {
                JcrUtil.copy((Node)((Node)asset.getOriginal().adaptTo(Node.class)), (Node)((Node)session.getItem(dest)), (String)asset.getName(), (boolean)true);
            }
        }
    }

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

    private void cleanup(Node node) throws RepositoryException {
        block8 : {
            try {
                if (!node.getSession().itemExists(this.getDest(node))) break block8;
                Node varFolder = (Node)node.getSession().getItem(this.getDest(node));
                log.debug("cleanup: starting cleanup for [{}]...", (Object)this.safeGetPath(varFolder));
                boolean isReady = false;
                long kizSize = 0;
                long count = 5;
                do {
                    try {
                        Thread.sleep(200);
                    }
                    catch (InterruptedException e) {
                        log.debug("cleanup: caught interrupt for [{}].", (Object)this.safeGetPath(varFolder));
                        break;
                    }
                    long currentSize = varFolder.getNodes().getSize();
                    boolean bl = isReady = currentSize == kizSize;
                    if (isReady && count == 0) break;
                    count = isReady ? --count : 5;
                    kizSize = currentSize;
                } while (true);
                NodeIterator itr = varFolder.getNodes();
                while (itr.hasNext()) {
                    Node varNode = itr.nextNode();
                    if (node.hasNode(varNode.getName()) || this.payloadMap.isInWorkflow(varNode.getPath(), true) || varNode.getPath().contains("/._")) continue;
                    log.info("cleanup: removing folder [{}]...", (Object)this.safeGetPath(varNode));
                    try {
                        varNode.remove();
                    }
                    catch (RepositoryException e) {
                        log.debug("cleanup: failed to remove [{}]: ", (Object)this.safeGetPath(node), (Object)e);
                    }
                }
            }
            catch (RepositoryException e) {
                log.warn("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);
        if (StringUtils.isNotBlank((String)currentMode)) {
            arguments.add(Arguments.MODE.getArgumentPrefix() + currentMode);
        }
        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");
        
        private String argumentName;

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

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

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

}