ReplicatePageProcess.java 12.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.workflow.collection.ResourceCollection
 *  com.adobe.granite.workflow.collection.ResourceCollectionManager
 *  com.day.cq.replication.ReplicationActionType
 *  com.day.cq.replication.ReplicationException
 *  com.day.cq.replication.ReplicationOptions
 *  com.day.cq.replication.Replicator
 *  com.day.cq.workflow.WorkflowException
 *  com.day.cq.workflow.WorkflowSession
 *  com.day.cq.workflow.exec.HistoryItem
 *  com.day.cq.workflow.exec.WorkItem
 *  com.day.cq.workflow.exec.Workflow
 *  com.day.cq.workflow.exec.WorkflowData
 *  com.day.cq.workflow.exec.WorkflowProcess
 *  com.day.cq.workflow.metadata.MetaDataMap
 *  com.day.cq.workflow.model.WorkflowNode
 *  javax.jcr.AccessDeniedException
 *  javax.jcr.Credentials
 *  javax.jcr.Item
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.SimpleCredentials
 *  javax.jcr.security.AccessControlManager
 *  javax.jcr.security.Privilege
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.osgi.service.event.Event
 *  org.osgi.service.event.EventAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.workflow.process;

import com.adobe.granite.workflow.collection.ResourceCollection;
import com.adobe.granite.workflow.collection.ResourceCollectionManager;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.ReplicationException;
import com.day.cq.replication.ReplicationOptions;
import com.day.cq.replication.Replicator;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.HistoryItem;
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.exec.WorkflowProcess;
import com.day.cq.workflow.metadata.MetaDataMap;
import com.day.cq.workflow.model.WorkflowNode;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(componentAbstract=1)
public abstract class ReplicatePageProcess
implements WorkflowProcess {
    private static final Logger log = LoggerFactory.getLogger(ReplicatePageProcess.class);
    public static final String TYPE_JCR_PATH = "JCR_PATH";
    public static final String TYPE_JCR_UUID = "JCR_UUID";
    private static final String DEVICE_IDENTIFICATION_SERVICE = "device-identification-service";
    @Reference
    protected Replicator replicator;
    @Reference
    protected EventAdmin eventAdmin;
    @Reference
    protected ResourceCollectionManager rcManager;
    @Reference
    private SlingRepository repository;

    public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException {
        block18 : {
            Session participantSession = null;
            Session replicationSession = null;
            Session serviceSession = null;
            try {
                String approverId;
                Session session = workflowSession.getSession();
                if (this.replicateAsParticipant(args) && (approverId = this.resolveParticipantId(workItem, workflowSession)) != null) {
                    participantSession = this.getParticipantSession(approverId, workflowSession);
                }
                replicationSession = participantSession != null ? participantSession : session;
                WorkflowData data = workItem.getWorkflowData();
                String path = null;
                String type = data.getPayloadType();
                if (type.equals("JCR_PATH") && data.getPayload() != null) {
                    String payloadData = (String)data.getPayload();
                    if (session.itemExists(payloadData)) {
                        path = payloadData;
                    }
                } else if (data.getPayload() != null && type.equals("JCR_UUID")) {
                    Node node = session.getNodeByUUID((String)data.getPayload());
                    path = node.getPath();
                }
                ReplicationOptions opts = null;
                String rev = (String)data.getMetaDataMap().get("resourceVersion", String.class);
                if (rev != null) {
                    opts = new ReplicationOptions();
                    opts.setRevision(rev);
                }
                opts = this.prepareOptions(opts);
                if (path != null) {
                    serviceSession = this.repository.loginService("device-identification-service", null);
                    List rcCollections = this.rcManager.getCollectionsForNode((Node)serviceSession.getItem(path));
                    List<String> paths = this.getPaths(path, rcCollections);
                    for (String aPath : paths) {
                        if (this.canReplicate(replicationSession, aPath)) {
                            if (opts != null) {
                                this.replicator.replicate(replicationSession, this.getReplicationType(), aPath, opts);
                                continue;
                            }
                            this.replicator.replicate(replicationSession, this.getReplicationType(), aPath);
                            continue;
                        }
                        log.debug(session.getUserID() + " is not allowed to replicate " + "this page/asset " + aPath + ". Issuing request for 'replication");
                        Hashtable<String, String> properties = new Hashtable<String, String>();
                        properties.put("path", aPath);
                        properties.put("replicationType", (String)this.getReplicationType());
                        properties.put("userId", session.getUserID());
                        Event event = new Event("com/day/cq/wcm/workflow/req/for/activation", properties);
                        this.eventAdmin.sendEvent(event);
                    }
                    break block18;
                }
                log.warn("Cannot activate page or asset because path is null for this workitem: " + workItem.toString());
            }
            catch (RepositoryException e) {
                throw new WorkflowException((Throwable)e);
            }
            catch (ReplicationException e) {
                throw new WorkflowException((Throwable)e);
            }
            finally {
                if (participantSession != null && participantSession.isLive()) {
                    participantSession.logout();
                    participantSession = null;
                }
                if (serviceSession != null && serviceSession.isLive()) {
                    serviceSession.logout();
                    serviceSession = null;
                }
            }
        }
    }

    private boolean replicateAsParticipant(MetaDataMap args) {
        String processArgs = (String)args.get(Arguments.PROCESS_ARGS.getArgumentName(), String.class);
        if (processArgs != null && !processArgs.equals("")) {
            String[] arguments;
            for (String argument : arguments = processArgs.split(",")) {
                String[] split = argument.split("=");
                if (split.length != 2) continue;
                String key = split[0];
                String value = split[1];
                if (!key.equalsIgnoreCase(Arguments.REPLICATE_AS_PARTICIPANT.getArgumentName())) continue;
                return Boolean.parseBoolean(value);
            }
            return false;
        }
        return (Boolean)args.get(Arguments.REPLICATE_AS_PARTICIPANT.getArgumentName(), (Object)Boolean.FALSE);
    }

    private Session getParticipantSession(String participantId, WorkflowSession workflowSession) {
        try {
            return this.repository.impersonateFromService("device-identification-service", (Credentials)new SimpleCredentials(participantId, new char[0]), null);
        }
        catch (Exception e) {
            log.warn(e.getMessage());
            return null;
        }
    }

    private String resolveParticipantId(WorkItem workItem, WorkflowSession workflowSession) {
        List history = new ArrayList();
        try {
            history = workflowSession.getHistory(workItem.getWorkflow());
            for (int index = history.size() - 1; index >= 0; --index) {
                HistoryItem previous = (HistoryItem)history.get(index);
                String type = previous.getWorkItem().getNode().getType();
                if (type == null || !type.equals("PARTICIPANT") && !type.equals("DYNAMIC_PARTICIPANT")) continue;
                return previous.getUserId();
            }
            return null;
        }
        catch (Exception e) {
            log.warn(e.getMessage());
            return null;
        }
    }

    private List<String> getPaths(String path, List<ResourceCollection> rcCollections) {
        ArrayList<String> paths = new ArrayList<String>();
        if (rcCollections == null || rcCollections.size() == 0) {
            paths.add(path);
        } else {
            log.debug("ResourceCollections detected");
            for (ResourceCollection rcCollection : rcCollections) {
                try {
                    List members = rcCollection.list(new String[]{"cq:Page", "dam:Asset"});
                    for (Node member : members) {
                        String mPath = member.getPath();
                        paths.add(mPath);
                    }
                    continue;
                }
                catch (RepositoryException re) {
                    log.error("Cannot build path list out of the resource collection " + rcCollection.getPath());
                    continue;
                }
            }
        }
        return paths;
    }

    public abstract ReplicationActionType getReplicationType();

    protected ReplicationOptions prepareOptions(ReplicationOptions opts) {
        return opts;
    }

    protected boolean canReplicate(Session session, String path) throws AccessDeniedException {
        try {
            AccessControlManager acMgr = session.getAccessControlManager();
            return acMgr.hasPrivileges(path, new Privilege[]{acMgr.privilegeFromName("{http://www.day.com/crx/1.0}replicate")});
        }
        catch (RepositoryException e) {
            return false;
        }
    }

    protected void bindReplicator(Replicator replicator) {
        this.replicator = replicator;
    }

    protected void unbindReplicator(Replicator replicator) {
        if (this.replicator == replicator) {
            this.replicator = null;
        }
    }

    protected void bindEventAdmin(EventAdmin eventAdmin) {
        this.eventAdmin = eventAdmin;
    }

    protected void unbindEventAdmin(EventAdmin eventAdmin) {
        if (this.eventAdmin == eventAdmin) {
            this.eventAdmin = null;
        }
    }

    protected void bindRcManager(ResourceCollectionManager resourceCollectionManager) {
        this.rcManager = resourceCollectionManager;
    }

    protected void unbindRcManager(ResourceCollectionManager resourceCollectionManager) {
        if (this.rcManager == resourceCollectionManager) {
            this.rcManager = null;
        }
    }

    protected void bindRepository(SlingRepository slingRepository) {
        this.repository = slingRepository;
    }

    protected void unbindRepository(SlingRepository slingRepository) {
        if (this.repository == slingRepository) {
            this.repository = null;
        }
    }

    private static enum Arguments {
        PROCESS_ARGS("PROCESS_ARGS"),
        REPLICATE_AS_PARTICIPANT("replicateAsParticipant");
        
        private String argumentName;

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

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

}