MoveLiveCopyResourceConflictHandler.java 9.94 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageEvent
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.PageModification
 *  com.day.cq.wcm.api.WCMException
 *  com.day.cq.wcm.api.components.Component
 *  com.day.cq.wcm.api.components.ComponentManager
 *  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.ResourceNameRolloutConflictHandler
 *  com.day.cq.wcm.msm.api.RolloutManager
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.nodetype.NodeType
 *  org.apache.sling.api.resource.NonExistingResource
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.osgi.service.event.Event
 *  org.osgi.service.event.EventAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.msm.impl;

import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageEvent;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.PageModification;
import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentManager;
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.ResourceNameRolloutConflictHandler;
import com.day.cq.wcm.msm.api.RolloutManager;
import com.day.cq.wcm.msm.impl.RolloutManagerImpl;
import com.day.cq.wcm.msm.impl.Utils;
import java.util.Iterator;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeType;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MoveLiveCopyResourceConflictHandler
implements ResourceNameRolloutConflictHandler {
    static final String MSM_MOVED_POSTFIX = "_msm_moved";
    static final String NT_VANITY_PATH = "sling:VanityPath";
    static final String PN_VANITY_PATH = "sling:vanityPath";
    private final EventAdmin eventAdmin;
    private final LiveRelationshipManager relationshipManager;
    private final RolloutManager rolloutManager;
    private static final Logger log = LoggerFactory.getLogger(MoveLiveCopyResourceConflictHandler.class);

    MoveLiveCopyResourceConflictHandler(RolloutManagerImpl rolloutManager, LiveRelationshipManager relationshipManager, EventAdmin eventAdmin) {
        this.rolloutManager = rolloutManager;
        this.relationshipManager = relationshipManager;
        this.eventAdmin = eventAdmin;
    }

    public boolean handleNameConflict(LiveRelationship relation, ResourceResolver resourceResolver, boolean isReset) throws WCMException {
        Resource target = resourceResolver.getResource(relation.getTargetPath());
        if (!Utils.resourceHasNode(target)) {
            return false;
        }
        try {
            boolean result;
            if (relation.getStatus().isPage()) {
                PageManager pm = (PageManager)resourceResolver.adaptTo(PageManager.class);
                if (pm == null) {
                    throw new IllegalStateException("PageManager not available");
                }
                result = this.handleConflict(pm.getContainingPage(relation.getTargetPath()), relation, isReset);
            } else {
                result = this.handleConflict(target, relation, isReset);
            }
            return result;
        }
        catch (RepositoryException e) {
            throw new WCMException((Throwable)e);
        }
        catch (PersistenceException e) {
            throw new WCMException((Throwable)e);
        }
    }

    private boolean handleConflict(Page target, LiveRelationship relation, boolean isReset) throws PersistenceException, RepositoryException, WCMException {
        boolean result;
        if (isReset) {
            PageManager pm = target.getPageManager();
            pm.delete(target, false, false);
            log.debug("Removed manually created Page {} on reset", (Object)relation.getTargetPath());
            result = true;
        } else {
            log.debug("Move a manually created Resource that blocks a roll-out at {}", (Object)relation.getTargetPath());
            ResourceResolver resourceResolver = target.getContentResource().getResourceResolver();
            Session session = (Session)resourceResolver.adaptTo(Session.class);
            if (session == null) {
                throw new IllegalStateException("Can't move, need a JCR Repository Resource");
            }
            String oldPagePath = target.getPath();
            String targetPath = MoveLiveCopyResourceConflictHandler.getAvailablePath(session, target.getParent().getPath() + "/" + target.getName());
            session.move(oldPagePath, targetPath);
            log.debug("Moved manually created Page to {}", (Object)targetPath);
            LiveRelationship newRelation = this.relationshipManager.getLiveRelationship((Resource)new NonExistingResource(resourceResolver, Utils.appendPath(oldPagePath, "jcr:content")), true);
            this.rolloutManager.rollout(resourceResolver, newRelation, false, false);
            Resource targetAfter = resourceResolver.getResource(oldPagePath);
            if (targetAfter == null) {
                session.refresh(false);
                result = false;
            } else {
                Page rolledOut = (Page)targetAfter.adaptTo(Page.class);
                this.cleanup(session, rolledOut, rolledOut.getPageManager().getPage(targetPath));
                resourceResolver.commit();
                PageModification mod = PageModification.moved((String)oldPagePath, (String)targetPath, (String)null, (String)resourceResolver.getUserID());
                PageEvent pe = new PageEvent(mod);
                this.eventAdmin.postEvent(pe.toEvent());
                result = true;
            }
        }
        return result;
    }

    private boolean handleConflict(Resource target, LiveRelationship relation, boolean isReset) throws PersistenceException, RepositoryException {
        ResourceResolver resourceResolver = target.getResourceResolver();
        if (isReset) {
            resourceResolver.delete(target);
            log.debug("Removed manually created Resource of Component at {}", (Object)relation.getTargetPath());
        } else {
            ComponentManager cmpManager = (ComponentManager)resourceResolver.adaptTo(ComponentManager.class);
            if (cmpManager != null && cmpManager.getComponentOfResource(target) == null) {
                resourceResolver.delete(target);
                log.debug("Removed manually created Resource at {}", (Object)relation.getTargetPath());
            } else {
                Session session = (Session)resourceResolver.adaptTo(Session.class);
                String destPath = MoveLiveCopyResourceConflictHandler.getAvailablePath(session, target.getPath());
                session.move(target.getPath(), destPath);
                log.debug("Moved manually created Component to {}", (Object)destPath);
            }
        }
        return true;
    }

    private static String getAvailablePath(Session session, String pathHint) throws RepositoryException {
        int i = 0;
        String destPath = pathHint + "_msm_moved";
        while (session.nodeExists(destPath)) {
            Object[] arrobject = new Object[]{pathHint, "_msm_moved", i++};
            destPath = String.format("%s%s_%s", arrobject);
        }
        return destPath;
    }

    private void cleanup(Session session, Page oldTarget, Page copy) throws RepositoryException {
        String parent = oldTarget.getPath();
        Iterator children = copy.listChildren();
        while (children.hasNext()) {
            Page child = (Page)children.next();
            session.move(child.getPath(), parent + "/" + child.getName());
        }
        if (oldTarget.hasContent() && copy.hasContent()) {
            Node targetProp = (Node)oldTarget.getContentResource().adaptTo(Node.class);
            Node copyProp = (Node)copy.getContentResource().adaptTo(Node.class);
            for (String propName : new String[]{"cq:lastReplicated", "cq:lastReplicatedBy", "cq:lastReplicationAction"}) {
                if (!copyProp.hasProperty(propName)) continue;
                Property prop = copyProp.getProperty(propName);
                targetProp.setProperty(propName, prop.getValue());
                prop.remove();
            }
            if (copyProp.isNodeType("sling:VanityPath")) {
                boolean copyVanityPath = false;
                if (targetProp.isNodeType("sling:VanityPath") || targetProp.canAddMixin("sling:VanityPath")) {
                    if (!targetProp.isNodeType("sling:VanityPath")) {
                        targetProp.addMixin("sling:VanityPath");
                    }
                    copyVanityPath = true;
                }
                for (String propName2 : new String[]{"sling:vanityPath", "sling:vanityOrder"}) {
                    if (!copyProp.hasProperty(propName2)) continue;
                    Property prop = copyProp.getProperty(propName2);
                    if (copyVanityPath) {
                        targetProp.setProperty(propName2, prop.getValue());
                    }
                    prop.remove();
                }
                for (String type : copyProp.getMixinNodeTypes()) {
                    if (!type.getName().equals("sling:VanityPath")) continue;
                    copyProp.removeMixin("sling:VanityPath");
                    break;
                }
            }
        }
    }
}