LiveRelationshipServlet.java 16.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.TidyJSONWriter
 *  com.day.cq.commons.jcr.JcrUtil
 *  com.day.cq.commons.servlets.AbstractPredicateServlet
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMException
 *  com.day.cq.wcm.msm.api.LiveRelationship
 *  com.day.cq.wcm.msm.api.LiveRelationshipManager
 *  com.day.cq.wcm.msm.api.LiveStatus
 *  com.day.cq.wcm.msm.api.RolloutConfig
 *  com.day.cq.wcm.msm.api.RolloutManager
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.nodetype.NodeType
 *  javax.servlet.ServletException
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.commons.collections.Predicate
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.sling.SlingServlet
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.apache.sling.servlets.post.HtmlResponse
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.msm.impl.servlets;

import com.day.cq.commons.TidyJSONWriter;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.commons.servlets.AbstractPredicateServlet;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;
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.api.RolloutConfig;
import com.day.cq.wcm.msm.api.RolloutManager;
import com.day.cq.wcm.msm.impl.LiveCopyManagerImpl;
import com.day.cq.wcm.msm.impl.LiveCopyServiceImpl;
import com.day.cq.wcm.msm.impl.LiveRelationshipEditingUtil;
import com.day.cq.wcm.msm.impl.LiveRelationshipManagerImpl;
import com.day.cq.wcm.msm.impl.Utils;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.io.JSONWriter;
import org.apache.sling.servlets.post.HtmlResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(resourceTypes={"sling/servlet/default"}, selectors={"msm"}, extensions={"conf", "json"}, methods={"POST", "GET"})
public class LiveRelationshipServlet
extends AbstractPredicateServlet {
    private static final long serialVersionUID = 6998256767756827528L;
    private static final Logger log = LoggerFactory.getLogger(LiveRelationshipServlet.class);
    private static final String TIDY_PARAM = "tidy";
    private static final String ADVANCED_STATUS_PARAM = "advancedStatus";
    private static final String RESET_CONFIG_PARAM = "resetConfig";
    private static final String REMOVE_LC_MARKERS_PARAM = "removeLCMarkers";
    private static final String REMOVE_ORPHAN_GHOSTS_PARAM = "removeOrphanGhosts";
    private static final String RT_GHOST = "wcm/msm/components/ghost";
    public static final String PN_RESOURCE_TYPE = "sling:resourceType";
    @Reference
    private LiveRelationshipManager relationshipManager = null;
    @Reference
    private RolloutManager rolloutManager = null;
    @Reference
    private LiveCopyServiceImpl liveCopyService = null;

    protected void doGet(SlingHttpServletRequest req, SlingHttpServletResponse resp, Predicate predicate) throws ServletException, IOException {
        Resource resource = req.getResource();
        StringWriter buf = new StringWriter();
        TidyJSONWriter writer = new TidyJSONWriter((Writer)buf);
        writer.setTidy("true".equals(req.getParameter("tidy")));
        boolean advancedStatus = "true".equals(req.getParameter("advancedStatus"));
        try {
            LiveRelationship relation = this.relationshipManager.getLiveRelationship(resource, advancedStatus);
            if (relation != null) {
                relation.write((JSONWriter)writer);
            }
        }
        catch (Exception e) {
            log.error("Error computing relationship", (Throwable)e);
        }
        resp.setContentType("application/json");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print(buf.getBuffer().toString());
    }

    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        HtmlResponse htmlResponse = new HtmlResponse();
        try {
            if ("true".equals(request.getParameter("removeLCMarkers")) || "true".equals(request.getParameter("removeOrphanGhosts")) || "true".equals(request.getParameter("resetConfig"))) {
                this.processFromFlags(request);
            } else if (!StringUtils.isEmpty((String)request.getParameter("cmd"))) {
                this.processFromCMDParam(request, request.getParameter("cmd"));
            } else {
                LiveRelationshipEditingUtil.processCancel(request, this.relationshipManager);
                String sourcePath = request.getParameter("msm:sourcePath");
                if (!StringUtils.isEmpty((String)sourcePath)) {
                    this.processConfigChange(request);
                }
            }
            htmlResponse.setStatus(200, "Live relationship updated");
        }
        catch (Exception e) {
            log.error("Error while updating relationship", (Throwable)e);
            htmlResponse.setError((Throwable)e);
        }
        htmlResponse.send((HttpServletResponse)response, true);
    }

    private void processConfigChange(SlingHttpServletRequest request) throws WCMException, RepositoryException {
        Resource resource = request.getResource();
        ResourceResolver resolver = resource.getResourceResolver();
        LiveRelationship currentRelation = this.relationshipManager.getLiveRelationship(resource, false);
        if (currentRelation == null) {
            return;
        }
        String[] submittedConfigs = request.getParameterValues("cq:rolloutConfigs");
        List currentConfigs = currentRelation.getRolloutConfigs();
        String[] configsToSave = null;
        if (submittedConfigs != null && (currentConfigs == null || currentConfigs.size() == 0)) {
            configsToSave = submittedConfigs;
        } else if (submittedConfigs != null && currentConfigs.size() != submittedConfigs.length) {
            configsToSave = submittedConfigs;
        } else if (submittedConfigs != null) {
            List<String> set = Arrays.asList(submittedConfigs);
            for (RolloutConfig rc : currentConfigs) {
                if (set.contains(rc.getPath())) continue;
                configsToSave = submittedConfigs;
                break;
            }
        }
        LiveRelationshipEditingUtil.editLiveCopy(resolver, this.liveCopyService.createLiveCopyManager(resolver), this.relationshipManager, currentRelation, Boolean.valueOf(request.getParameter("msm:isDeep")), configsToSave);
    }

    /*
     * Enabled aggressive block sorting
     */
    private void processFromCMDParam(SlingHttpServletRequest request, String command) throws WCMException, RepositoryException, PersistenceException {
        Resource resource = request.getResource();
        LiveRelationship currentRelation = this.relationshipManager.getLiveRelationship(resource, true);
        if ("attach".equals(command)) {
            if (currentRelation == null || currentRelation.getStatus().getAdvancedStatus("msm:isTargetManuallyCreated").booleanValue() && currentRelation.getStatus().isSourceExisting()) {
                boolean isDeep = "true".equals(request.getParameter("deep"));
                this.attachLiveCopy(currentRelation, (Page)resource.adaptTo(Page.class), isDeep);
                resource.getResourceResolver().commit();
                return;
            }
            String msg = String.format("Can not attach Resource at %s either already a LiveCopy or no Source", resource.getPath());
            throw new IllegalStateException(msg);
        }
        if (currentRelation == null || currentRelation.getStatus().getAdvancedStatus("msm:isTargetManuallyCreated").booleanValue()) {
            log.error("Request to edit PropertyInheritance of non LiveRelation at {}: abort", (Object)resource.getPath());
            String msg = String.format("Can not attach Resource at %s either already a LiveCopy or no Source", resource.getPath());
            throw new IllegalStateException(msg);
        }
        if ("cancelPropertyInheritance".equals(command)) {
            String[] props = request.getParameterValues("msm:propertyName");
            this.relationshipManager.cancelPropertyRelationship(request.getResourceResolver(), currentRelation, props, true);
            return;
        }
        if (!"reenablePropertyInheritance".equals(command)) {
            log.debug("Illegal Command received {}: No action", (Object)command);
            return;
        }
        String[] props = request.getParameterValues("msm:propertyName");
        ResourceResolver resolver = request.getResourceResolver();
        this.relationshipManager.reenablePropertyRelationship(resolver, currentRelation, props, false);
        if (currentRelation.getStatus().isPage()) {
            Page page;
            PageManager pm = (PageManager)resolver.adaptTo(PageManager.class);
            Page page2 = page = pm == null ? null : pm.getContainingPage(resource);
            if (page != null && page.hasContent()) {
                ModifiableValueMap pageProps = (ModifiableValueMap)page.getContentResource().adaptTo(ModifiableValueMap.class);
                pageProps.remove((Object)"cq:lastRolledout");
            }
        }
        resolver.commit();
    }

    private void processFromFlags(SlingHttpServletRequest request) throws WCMException, RepositoryException, PersistenceException {
        Resource resource = request.getResource();
        if ("true".equals(request.getParameter("removeLCMarkers"))) {
            Node currentNode = (Node)resource.adaptTo(Node.class);
            if (currentNode != null) {
                Utils.detachLiveCopy(currentNode, true, true);
                log.debug("Detached Relation from {}", (Object)resource.getPath());
            }
        } else if ("true".equals(request.getParameter("removeOrphanGhosts"))) {
            Node currentNode = (Node)resource.adaptTo(Node.class);
            if (currentNode != null) {
                Utils.removeOrphanGhosts(this.relationshipManager, resource, true, true);
                log.debug("Removed orphaned Ghost at {}", (Object)resource.getPath());
            }
        } else if ("true".equals(request.getParameter("resetConfig"))) {
            LiveCopyManagerImpl.LiveCopyImpl lc;
            String editPath = resource.getPath();
            log.debug("Try to Rest RolloutConfiguration for {}", (Object)editPath);
            ResourceResolver resolver = resource.getResourceResolver();
            LiveCopyManagerImpl lcManager = this.liveCopyService.createLiveCopyManager(resolver);
            LiveCopyManagerImpl.LiveCopyImpl liveCopyImpl = lc = lcManager == null ? null : lcManager.get(editPath);
            if (lc == null) {
                log.debug("Could not Reset RolloutConfiguration, LiveCopy not found for {}", (Object)editPath);
            } else {
                if (!lc.isRoot() && lc.isDeep() && lc.getMoveTarget() == null) {
                    lcManager.remove(lc.getPath());
                } else {
                    lc.setRolloutConfigs(new String[0]);
                }
                resolver.commit();
                log.debug("Reset RolloutConfiguration for {}", (Object)lc.getPath());
            }
        }
    }

    private void attachLiveCopy(LiveRelationship relationship, Page page, boolean deep) throws RepositoryException, WCMException {
        Resource content;
        Resource resource = content = page.hasContent() ? page.getContentResource() : null;
        if (content != null) {
            Node contentNode = (Node)content.adaptTo(Node.class);
            LiveRelationshipManagerImpl.markRelationship(contentNode, false);
            LiveRelationshipServlet.attachLevel(content, this.relationshipManager.getLiveRelationship(content, false), this.relationshipManager, this.rolloutManager);
            page.getPageManager().touch(contentNode.getParent(), true, Calendar.getInstance(), false);
        }
        if (deep) {
            Iterator iter = page.listChildren();
            while (iter.hasNext()) {
                Page child = (Page)iter.next();
                LiveRelationship childShip = this.relationshipManager.getLiveRelationship((Resource)child.adaptTo(Resource.class), false);
                if (childShip == null || !childShip.getStatus().isSourceExisting()) continue;
                this.attachLiveCopy(childShip, child, deep);
            }
        }
        log.debug("Attached {} to {}", (Object)page.getPath(), (Object)relationship.getSourcePath());
    }

    private static void attachLevel(Resource level, LiveRelationship relationship, LiveRelationshipManager relationshipManager, RolloutManager rolloutManager) throws RepositoryException, WCMException {
        ResourceResolver resolver = level.getResourceResolver();
        Resource sourceResource = resolver.getResource(relationship.getSourcePath());
        Node targetNode = (Node)level.adaptTo(Node.class);
        Iterator sourceResources = resolver.listChildren(sourceResource);
        while (sourceResources.hasNext()) {
            Node source;
            Resource par = (Resource)sourceResources.next();
            String srcName = par.getName();
            if (resolver.getResource(level.getPath() + "/" + srcName) != null || (source = (Node)par.adaptTo(Node.class)).isNodeType("cq:LiveSyncConfig")) continue;
            Node target = JcrUtil.copy((Node)source, (Node)targetNode, (String)srcName);
            String orderBefore = Utils.findFollowingSibling(source, targetNode);
            if (orderBefore != null && targetNode.getPrimaryNodeType().hasOrderableChildNodes()) {
                targetNode.orderBefore(target.getName(), orderBefore);
            }
            LiveRelationshipManagerImpl.markRelationship(target, false);
            rolloutManager.updateRolloutInfo(target, false, false);
            target.setProperty("sling:resourceType", "wcm/msm/components/ghost");
        }
        Iterator targetResources = level.listChildren();
        while (targetResources.hasNext()) {
            Resource par = (Resource)targetResources.next();
            LiveRelationship parlr = relationshipManager.getLiveRelationship(par, true);
            if (parlr == null || !parlr.getStatus().isSourceExisting()) continue;
            Node parNode = (Node)par.adaptTo(Node.class);
            LiveRelationshipManagerImpl.markRelationship(parNode, false);
            LiveRelationshipServlet.attachLevel(par, parlr, relationshipManager, rolloutManager);
        }
    }

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

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

    protected void bindRolloutManager(RolloutManager rolloutManager) {
        this.rolloutManager = rolloutManager;
    }

    protected void unbindRolloutManager(RolloutManager rolloutManager) {
        if (this.rolloutManager == rolloutManager) {
            this.rolloutManager = null;
        }
    }

    protected void bindLiveCopyService(LiveCopyServiceImpl liveCopyServiceImpl) {
        this.liveCopyService = liveCopyServiceImpl;
    }

    protected void unbindLiveCopyService(LiveCopyServiceImpl liveCopyServiceImpl) {
        if (this.liveCopyService == liveCopyServiceImpl) {
            this.liveCopyService = null;
        }
    }
}