CQ62Html5SmartFileUpgrade.java 8.93 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.Workspace
 *  javax.jcr.nodetype.NodeType
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  javax.jcr.query.QueryResult
 *  org.apache.jackrabbit.commons.JcrUtils
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.compat.codeupgrade.impl.cq62;

import com.day.cq.compat.codeupgrade.internal.api.ProgressInfoProvider;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeType;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.jackrabbit.commons.JcrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CQ62Html5SmartFileUpgrade
implements ProgressInfoProvider {
    private static final String QUERY_COMPONENT = "SELECT parent.* FROM [cq:Component] AS parent INNER JOIN [cq:Widget] AS child ON ISDESCENDANTNODE(child,parent) WHERE ( CONTAINS(child.xtype, 'html5smartfile') )";
    private static final String INHERITANCE_CANCELLED_PROP = "cq:propertyInheritanceCancelled";
    private final Logger log;
    private final List<String> resourceTypePrefixes;
    private String progressInfo;

    public CQ62Html5SmartFileUpgrade() {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.resourceTypePrefixes = new ArrayList<String>(){};
    }

    @Override
    public String getProgressInfo() {
        return this.progressInfo;
    }

    void setProgressInfo(String info) {
        this.progressInfo = info;
        this.log.info(this.progressInfo);
    }

    void doUpgrade(Session session) {
        this.setProgressInfo("Migrating html5smartfile resources");
        int num = this.upgradeTargetResources(session);
        this.setProgressInfo(String.format("%s html5smartfile resources migrated.", num));
    }

    int upgradeTargetResources(Session session) {
        NodeIterator nodeIterator = this.getAffectedComponents(session);
        int count = 0;
        if (nodeIterator == null) {
            this.log.debug("No component dialogs with html5smartfile widget found");
            return count;
        }
        while (nodeIterator.hasNext()) {
            Node component = nodeIterator.nextNode();
            NodeIterator pageContentItr = this.getPageContentNodes(component);
            if (pageContentItr == null) continue;
            Set<String> dialogPropertyNames = this.getHtml5PropertyNames(component);
            while (pageContentItr.hasNext()) {
                Node pageContent = pageContentItr.nextNode();
                String pageContentPath = "";
                if (!this.convertStructure(dialogPropertyNames, pageContent)) continue;
                try {
                    pageContentPath = pageContent.getPath();
                    this.save(session);
                    ++count;
                }
                catch (RepositoryException e) {
                    this.log.error("Could not save changes for {} ", (Object)pageContentPath, (Object)e);
                }
            }
        }
        return count;
    }

    private NodeIterator getAffectedComponents(Session session) {
        NodeIterator nodeIterator = null;
        try {
            QueryManager qm = session.getWorkspace().getQueryManager();
            Query q = qm.createQuery("SELECT parent.* FROM [cq:Component] AS parent INNER JOIN [cq:Widget] AS child ON ISDESCENDANTNODE(child,parent) WHERE ( CONTAINS(child.xtype, 'html5smartfile') )", "JCR-SQL2");
            nodeIterator = q.execute().getNodes();
        }
        catch (RepositoryException e) {
            this.log.error("Could not query for components with html5smartfile widget", (Throwable)e);
        }
        return nodeIterator;
    }

    private NodeIterator getPageContentNodes(Node component) {
        NodeIterator nodeIterator = null;
        try {
            QueryManager qm = component.getSession().getWorkspace().getQueryManager();
            String resourceType = component.getPath();
            for (String prefix : this.resourceTypePrefixes) {
                if (!resourceType.startsWith(prefix)) continue;
                resourceType = resourceType.substring(prefix.length());
                break;
            }
            String contentQuery = "select * from [cq:PageContent] where [sling:resourceType] = '" + resourceType + "'";
            Query q = qm.createQuery(contentQuery, "JCR-SQL2");
            nodeIterator = q.execute().getNodes();
        }
        catch (RepositoryException e) {
            this.log.error("Could not query for page content nodes", (Throwable)e);
        }
        return nodeIterator;
    }

    private Set<String> getHtml5PropertyNames(Node component) {
        Node dialog = null;
        HashSet<String> names = new HashSet<String>();
        String componentPath = "";
        try {
            componentPath = component.getPath();
            NodeIterator childIter = component.getNodes();
            if (childIter != null) {
                while (childIter.hasNext()) {
                    Node child = childIter.nextNode();
                    if (!"cq:Dialog".equals(child.getPrimaryNodeType().toString())) continue;
                    dialog = child;
                    break;
                }
                if (dialog != null) {
                    LinkedList<Node> queue = new LinkedList<Node>();
                    queue.add(dialog);
                    while (!queue.isEmpty()) {
                        Node pop = (Node)queue.poll();
                        if ("cq:Widget".equals(pop.getPrimaryNodeType().toString()) && pop.hasProperty("xtype") && "html5smartfile".equals(pop.getProperty("xtype").getString())) {
                            names.add(pop.getProperty("name").getString());
                        }
                        NodeIterator iterator = pop.getNodes();
                        while (iterator.hasNext()) {
                            queue.add(iterator.nextNode());
                        }
                    }
                }
            }
        }
        catch (RepositoryException e) {
            this.log.error("Could not get html5 smartfile property names for {}", (Object)componentPath);
        }
        return names;
    }

    private boolean convertStructure(Set<String> dialogPropertyNames, Node pageContent) {
        boolean converted = false;
        try {
            if (pageContent.hasProperty("cq:propertyInheritanceCancelled")) {
                Property cancelledProps = pageContent.getProperty("cq:propertyInheritanceCancelled");
                Value[] values = cancelledProps.getValues();
                ArrayList<String> newValues = new ArrayList<String>();
                if (values != null) {
                    for (Value value : cancelledProps.getValues()) {
                        boolean toRemove = false;
                        for (String fullName : dialogPropertyNames) {
                            if (!fullName.endsWith("/" + value.getString())) continue;
                            String fileNodePath = fullName.substring(fullName.indexOf(47) + 1);
                            if (fileNodePath.indexOf(47) != -1) {
                                fileNodePath = fileNodePath.substring(0, fileNodePath.lastIndexOf("/"));
                            }
                            Node fileContainerNode = JcrUtils.getOrCreateByPath((Node)pageContent, (String)fileNodePath, (boolean)false, (String)"nt:unstructured", (String)"nt:unstructured", (boolean)false);
                            fileContainerNode.setProperty("cq:isCancelledForChildren", true);
                            fileContainerNode.addMixin("cq:LiveSyncCancelled");
                            converted = true;
                            toRemove = true;
                            break;
                        }
                        if (toRemove) continue;
                        newValues.add(value.getString());
                    }
                    if (newValues.size() > 0) {
                        pageContent.setProperty("cq:propertyInheritanceCancelled", newValues.toArray(new String[newValues.size()]));
                    } else {
                        pageContent.getProperty("cq:propertyInheritanceCancelled").remove();
                    }
                }
            }
        }
        catch (RepositoryException e) {
            this.log.error("Could not convert the node structure ", (Throwable)e);
        }
        return converted;
    }

    private void save(Session session) throws RepositoryException {
        if (session.hasPendingChanges()) {
            session.save();
        }
    }

}