GhostPostProcessor.java 6.85 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.wcm.msm.api.LiveRelationship
 *  com.day.cq.wcm.msm.api.LiveRelationshipManager
 *  com.day.cq.wcm.msm.api.LiveStatus
 *  com.day.text.Text
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.Session
 *  javax.jcr.nodetype.NodeDefinition
 *  javax.jcr.nodetype.NodeType
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.resource.LoginException
 *  org.apache.sling.api.resource.NonExistingResource
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.servlets.post.Modification
 *  org.apache.sling.servlets.post.ModificationType
 *  org.apache.sling.servlets.post.SlingPostProcessor
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.msm.impl.postprocessing;

import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.msm.api.LiveRelationshipManager;
import com.day.cq.wcm.msm.api.LiveStatus;
import com.day.cq.wcm.msm.impl.LiveRelationshipManagerImpl;
import com.day.text.Text;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.ModificationType;
import org.apache.sling.servlets.post.SlingPostProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
public class GhostPostProcessor
implements SlingPostProcessor {
    private static final Logger log = LoggerFactory.getLogger(GhostPostProcessor.class);
    private static final String PROCESSOR_ROOT = "/content";
    @Reference
    private LiveRelationshipManager liveRelationshipManager = null;

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void process(SlingHttpServletRequest slingHttpServletRequest, List<Modification> modifications) throws Exception {
        HashSet<String> processed = new HashSet<String>();
        ArrayList<Modification> addedModifications = new ArrayList<Modification>();
        for (int modIdx = modifications.size() - 1; modIdx >= 0; --modIdx) {
            String targetPath;
            Modification mod = modifications.get(modIdx);
            String string = targetPath = mod.getDestination() != null ? mod.getDestination() : mod.getSource();
            if (GhostPostProcessor.filter(mod) && !processed.contains(targetPath)) {
                log.debug("Process Modification {}", (Object)mod);
                String sourcePath = mod.getSource();
                ResourceResolver resourceResolver = slingHttpServletRequest.getResourceResolver();
                NonExistingResource modResource = new NonExistingResource(resourceResolver, sourcePath);
                LiveRelationship relationship = this.liveRelationshipManager.getLiveRelationship((Resource)modResource, false);
                if (relationship != null && relationship.getStatus().isSourceExisting()) {
                    Node parent;
                    log.debug("Modification is an inherited Component at {}", (Object)mod.getSource());
                    Session session = (Session)resourceResolver.adaptTo(Session.class);
                    String parentPath = Text.getRelativeParent((String)sourcePath, (int)1);
                    if (session.nodeExists(parentPath) && !session.nodeExists(sourcePath) && (parent = session.getNode(parentPath)).getDefinition().getDeclaringNodeType().hasOrderableChildNodes()) {
                        String position = null;
                        ResourceResolver clone = slingHttpServletRequest.getResourceResolver().clone(null);
                        try {
                            if (clone.getResource(sourcePath).adaptTo(Property.class) != null) {
                                log.debug("Deleted Item is a Property: no action");
                            }
                            position = GhostPostProcessor.findPosition((Resource)modResource, clone);
                        }
                        finally {
                            clone.close();
                        }
                        Node ghostNode = parent.addNode(modResource.getName(), "nt:unstructured");
                        ghostNode.setProperty("sling:resourceType", "wcm/msm/components/ghost");
                        parent.orderBefore(modResource.getName(), position);
                        LiveRelationshipManagerImpl.markRelationship(ghostNode, false);
                        this.liveRelationshipManager.cancelRelationship(resourceResolver, this.liveRelationshipManager.getLiveRelationship((Resource)modResource, false), false, false);
                        addedModifications.add(Modification.onCreated((String)ghostNode.getPath()));
                        log.debug("Replaced Inherited Component at{} with a Ghost", (Object)mod.getSource());
                    }
                }
            }
            processed.add(targetPath);
        }
        modifications.addAll(addedModifications);
    }

    private static boolean filter(Modification modification) {
        return Text.isDescendant((String)"/content", (String)modification.getSource()) && modification.getType() == ModificationType.DELETE && modification.getSource().contains("/jcr:content/");
    }

    private static String findPosition(Resource resource, ResourceResolver clone) throws LoginException {
        String path = resource.getPath();
        boolean foundSelf = false;
        for (Resource child : clone.getResource(Text.getRelativeParent((String)path, (int)1)).getChildren()) {
            if (foundSelf && resource.getParent().getChild(child.getName()) != null) {
                return child.getName();
            }
            foundSelf |= child.getPath().equals(path);
        }
        return null;
    }

    protected void bindLiveRelationshipManager(LiveRelationshipManager liveRelationshipManager) {
        this.liveRelationshipManager = liveRelationshipManager;
    }

    protected void unbindLiveRelationshipManager(LiveRelationshipManager liveRelationshipManager) {
        if (this.liveRelationshipManager == liveRelationshipManager) {
            this.liveRelationshipManager = null;
        }
    }
}