ContentCopyActionFactory.java 14.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.jcr.JcrUtil
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMException
 *  com.day.cq.wcm.msm.api.LiveAction
 *  com.day.cq.wcm.msm.api.LiveRelationship
 *  com.day.cq.wcm.msm.api.LiveStatus
 *  com.day.cq.wcm.msm.api.RolloutManager
 *  com.day.cq.wcm.msm.commons.BaseActionFactory
 *  com.day.cq.wcm.msm.commons.FilteredAction
 *  com.day.cq.wcm.msm.commons.ItemFilterImpl
 *  com.day.cq.wcm.msm.commons.ItemFilterUtil
 *  com.day.text.Text
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.PropertyIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.nodetype.NodeDefinition
 *  javax.jcr.nodetype.NodeType
 *  javax.jcr.nodetype.PropertyDefinition
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Modified
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.PropertyOption
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.commons.osgi.PropertiesUtil
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.msm.impl.actions;

import com.day.cq.commons.jcr.JcrUtil;
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.LiveAction;
import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.msm.api.LiveStatus;
import com.day.cq.wcm.msm.api.RolloutManager;
import com.day.cq.wcm.msm.commons.BaseActionFactory;
import com.day.cq.wcm.msm.commons.FilteredAction;
import com.day.cq.wcm.msm.commons.ItemFilterImpl;
import com.day.cq.wcm.msm.commons.ItemFilterUtil;
import com.day.cq.wcm.msm.impl.Utils;
import com.day.text.Text;
import java.util.Calendar;
import java.util.Dictionary;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyOption;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, label="%cq.wcm.msm.impl.actions.contentcopy.label", description="%cq.wcm.msm.impl.actions.contentcopy.description")
@Service
public class ContentCopyActionFactory
extends BaseActionFactory<FilteredAction> {
    @Deprecated
    @Property(name="cq.wcm.msm.action.rank", propertyPrivate=1)
    private static final int RANK = 302;
    @Deprecated
    @Property(name="cq.wcm.msm.action.title", propertyPrivate=1)
    private static final String TITLE = "Copy content";
    @Deprecated
    @Property(name="cq.wcm.msm.action.parameter", propertyPrivate=1)
    private static final String PARAMETER = "msm:actionContentCopy";
    @Deprecated
    @Property(name="actiontype", propertyPrivate=1)
    private static final String ACTION_TYPE = "contentcopy";
    @Property(name="cq.wcm.msm.action.excludednodetypes")
    private static final String[] DEFAULT_FILTER_NODE_TYPES = ItemFilterUtil.EMPTY_PROPERTIES;
    @Property(name="cq.wcm.msm.action.excludedparagraphitems")
    private static final String[] DEFAULT_EXCLUDED_PARAGRAPH_ITEMS = ItemFilterUtil.EMPTY_PROPERTIES;
    @Property(name="cq.wcm.msm.action.excludedprops")
    private static final String[] DEFAULT_EXCLUDED_PROPERTIES = ItemFilterUtil.EMPTY_PROPERTIES;
    @Property(name="liveActionName", propertyPrivate=1)
    private static final String[] LIVE_ACTION_NAME = new String[]{ContentCopyAction.class.getSimpleName(), "contentCopy"};
    @Reference
    private RolloutManager rolloutManager = null;
    private Dictionary properties;
    private static final String PROP_ORDERSTYLE_DEFAULT = "default";
    private static final String PROP_ORDERSTYLE_PRE54 = "pre54";
    @Property(value={"default"}, options={@PropertyOption(name="default", value="%contentcopyaction.order.style.optionDefault"), @PropertyOption(name="pre54", value="%contentcopyaction.order.style.optionPre54")})
    private static final String PROP_ORDERSTYLE = "contentcopyaction.order.style";
    private String orderStyle = "default";

    public String createsAction() {
        return LIVE_ACTION_NAME[0];
    }

    protected ContentCopyAction newActionInstance(ValueMap config) {
        return new ContentCopyAction(config, this);
    }

    @Activate
    @Modified
    protected void configure(ComponentContext componentContext) {
        this.properties = componentContext.getProperties();
        Dictionary props = componentContext.getProperties();
        this.orderStyle = PropertiesUtil.toString(props.get("contentcopyaction.order.style"), (String)"default");
    }

    protected Dictionary getFactoryConfig() {
        return this.properties;
    }

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

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

    static final class ContentCopyAction
    extends FilteredAction {
        private static final Logger log = LoggerFactory.getLogger(ContentCopyAction.class);
        private final boolean legacyOrdering;

        protected ContentCopyAction(ValueMap config, ContentCopyActionFactory factory) {
            super(config, ItemFilterUtil.createPageFilter((ValueMap)config, (RolloutManager)factory.rolloutManager), ItemFilterUtil.createComponentFilter((ValueMap)config, (RolloutManager)factory.rolloutManager), (BaseActionFactory)factory);
            String orderStyle = this.getConfig() == null ? factory.orderStyle : (String)this.getConfig().get("contentcopyaction.order.style", (Object)factory.orderStyle);
            this.legacyOrdering = "pre54".equals(orderStyle);
        }

        protected boolean doHandle(Resource source, Resource target, LiveRelationship relation, boolean resetRollout) throws RepositoryException {
            Node slaveNode;
            LiveStatus status = relation.getStatus();
            if (status.isTargetExisting()) {
                return false;
            }
            Node node = slaveNode = target != null ? Utils.getWorkingNode((Node)target.adaptTo(Node.class)) : null;
            if (slaveNode != null) {
                log.warn("Skipped execution of {}: Target to copy exists at {}", (Object)this.getName(), (Object)relation.getTargetPath());
                return false;
            }
            if (!status.isSourceExisting()) {
                log.debug("Skipped execution of {}: No source to copy at {}", (Object)this.getName(), (Object)relation.getSourcePath());
                return false;
            }
            Node masterNode = Utils.getWorkingNode((Node)source.adaptTo(Node.class));
            if (masterNode == null) {
                log.warn("Skipped execution of {}: No source to copy at {}, though status indicated it exists", (Object)this.getName(), (Object)relation.getSourcePath());
                return false;
            }
            PageManager pageManager = (PageManager)source.getResourceResolver().adaptTo(PageManager.class);
            if (pageManager == null) {
                log.warn("Can't apply action {} on {}: no pageManger", (Object)this.getName(), (Object)relation.getTargetPath());
                return false;
            }
            return true;
        }

        protected void doExecute(Resource source, Resource target, LiveRelationship relation, boolean reset) throws RepositoryException, WCMException {
            Node slaveNode;
            Node masterNode = Utils.getWorkingNode((Node)source.adaptTo(Node.class));
            Node node = slaveNode = target != null ? Utils.getWorkingNode((Node)target.adaptTo(Node.class)) : null;
            if (slaveNode == null) {
                String slavePath = Utils.getPagePath(relation.getTargetPath());
                Resource parent = source.getResourceResolver().getResource(Text.getRelativeParent((String)slavePath, (int)1));
                if (parent != null && parent.adaptTo(Node.class) != null) {
                    this.createCopy(parent.getResourceResolver(), slavePath, masterNode, relation, (Node)parent.adaptTo(Node.class));
                } else {
                    log.debug("Can't create new target at {}, as its parent does not exist", (Object)slavePath);
                }
            } else {
                log.debug("Do not create missing LiveCopy resource at {}: Inheritance has been skipped", (Object)relation.getTargetPath());
            }
        }

        private void createCopy(ResourceResolver resolver, String path, Node masterNode, LiveRelationship relation, Node parentNode) throws RepositoryException, WCMException {
            Node newNode;
            if (masterNode.getParent().isNodeType("cq:Page")) {
                PageManager pageManager = (PageManager)resolver.adaptTo(PageManager.class);
                newNode = (Node)pageManager.copy(pageManager.getPage(masterNode.getParent().getPath()), path, Utils.findFollowingSibling(masterNode.getParent(), parentNode), true, false, false).getContentResource().adaptTo(Node.class);
                if (newNode != null) {
                    this.applyFilters(newNode.getParent(), false);
                }
            } else {
                if (!Utils.getPagePath(masterNode.getPath()).equals(masterNode.getPath())) {
                    masterNode = masterNode.getParent();
                }
                newNode = JcrUtil.copy((Node)masterNode, (Node)parentNode, (String)masterNode.getName());
                this.applyFilters(newNode, true);
                if (parentNode.getPrimaryNodeType().hasOrderableChildNodes()) {
                    if (!this.legacyOrdering) {
                        String previousSibling = ContentCopyAction.findPreviousSibling(masterNode, newNode);
                        if (previousSibling == null) {
                            parentNode.orderBefore(newNode.getName(), parentNode.hasNodes() ? parentNode.getNodes().nextNode().getName() : null);
                        } else {
                            parentNode.orderBefore(newNode.getName(), previousSibling);
                            parentNode.orderBefore(previousSibling, newNode.getName());
                        }
                    } else {
                        String orderBefore = this.findFollowingSibling(masterNode, parentNode);
                        if (orderBefore != null && parentNode.getPrimaryNodeType().hasOrderableChildNodes()) {
                            parentNode.orderBefore(newNode.getName(), orderBefore);
                        }
                    }
                }
                if (newNode != null) {
                    Page page;
                    PageManager pm = (PageManager)resolver.adaptTo(PageManager.class);
                    Page page2 = page = pm == null ? null : pm.getContainingPage(newNode.getPath());
                    if (page != null) {
                        pm.touch((Node)page.adaptTo(Node.class), true, Calendar.getInstance(), false);
                    }
                }
            }
            if (newNode != null) {
                Utils.detachLiveCopy(newNode, true, false);
                log.debug("Created Resource at {} for {}", (Object)newNode.getPath(), (Object)relation.getSourcePath());
            }
        }

        protected void applyFilters(Node node, boolean deep) throws RepositoryException {
            ItemFilterImpl filter = this.getFilter(node);
            if (filter.excludes(node) && !node.getDefinition().isProtected()) {
                node.remove();
                return;
            }
            if (node.hasNode("jcr:content")) {
                this.applyFilters(node.getNode("jcr:content"), true);
                return;
            }
            PropertyIterator properties = node.getProperties();
            while (properties.hasNext()) {
                javax.jcr.Property property = properties.nextProperty();
                if (!filter.excludes(property) || property.getDefinition().isProtected() || property.getDefinition().isAutoCreated()) continue;
                property.remove();
            }
            if (deep) {
                NodeIterator children = node.getNodes();
                while (children.hasNext()) {
                    Node child = children.nextNode();
                    if ("jcr:content".equals(child.getName())) continue;
                    this.applyFilters(child, deep);
                }
            }
        }

        private String findFollowingSibling(Node masterNode, Node slaveParent) throws RepositoryException {
            if (slaveParent != null) {
                Node masterParent = masterNode.getParent();
                NodeIterator ni = masterParent.getNodes();
                while (ni.hasNext() && !masterNode.getName().equals(ni.nextNode().getName())) {
                }
                while (ni.hasNext()) {
                    String nextSibling = ni.nextNode().getName();
                    if (!slaveParent.hasNode(nextSibling)) continue;
                    return nextSibling;
                }
            }
            return null;
        }

        private static String findPreviousSibling(Node sourceNode, Node targetNode) throws RepositoryException {
            String previousSibling = null;
            if (sourceNode != null) {
                String name;
                Node node;
                Node masterParent = sourceNode.getParent();
                String sourceName = sourceNode.getName();
                NodeIterator ni = masterParent.getNodes();
                while (ni.hasNext() && !(name = (node = ni.nextNode()).getName()).equals(sourceName)) {
                    if (targetNode.getParent() == null || !targetNode.getParent().hasNode(name)) continue;
                    previousSibling = node.getName();
                }
            }
            return previousSibling;
        }
    }

}