Cq61CloudServicesContentUpgrade.java 16 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.ValueFactory
 *  javax.jcr.nodetype.NodeType
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.compat.codeupgrade.impl.cq61;

import com.day.cq.compat.codeupgrade.internal.api.ProgressInfoProvider;
import java.util.ArrayList;
import java.util.HashSet;
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.ValueFactory;
import javax.jcr.nodetype.NodeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Cq61CloudServicesContentUpgrade
implements ProgressInfoProvider {
    private static final String NN_PUBLIC = "public";
    private static final String PN_SLING_RESOURCE_TYPE = "sling:resourceType";
    private final Logger log;
    private String progressInfo;

    public Cq61CloudServicesContentUpgrade() {
        this.log = LoggerFactory.getLogger(this.getClass());
    }

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

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

    void doUpgrade(Session sess) throws Exception {
        Node root = this.findBackupMergerRepositoryRoot(sess);
        if (root == null) {
            return;
        }
        this.log.info("Starting migration");
        this.migrateAnalyticsConfiguration(sess, root);
        this.migrateAudienceManagerConfiguration(sess, root);
        this.migrateDTMConfiguation(sess, root);
        this.migrateTargetConfigurations(sess, root);
        this.migrateTranslationConfigurations(sess, root);
        this.log.info("Completed migration");
    }

    private void migrateTranslationConfigurations(Session sess, Node root) throws RepositoryException {
        if (!root.hasNode("etc/cloudservices/machine-translation")) {
            this.log.info("No etc/cloudservices/machine-translation hence skipping migration for translation cloud configs.");
            return;
        }
        this.setProgressInfo("Migrating Translation cloud configurations");
        Node etcTranslationRoot = root.getNode("etc/cloudservices/machine-translation");
        Node etcRoot = root.getNode("etc/cloudservices");
        this.log.info("Starting migration of {}", (Object)etcTranslationRoot.getPath());
        etcTranslationRoot.getSession().move(etcTranslationRoot.getPath(), etcRoot.getPath() + "/translation");
        this.migrateTranslationCloudConfigProperties(etcTranslationRoot);
        this.migrateTranslationCloudConfigForNode(root);
        sess.save();
        this.log.info("Completed migration of Translation Cloud Config");
    }

    private void migrateTranslationCloudConfigProperties(Node etcTranslationNode) throws RepositoryException {
        if (etcTranslationNode != null) {
            Property prop;
            if (etcTranslationNode.hasProperty("sling:resourceType") && (prop = etcTranslationNode.getProperty("sling:resourceType")) != null && prop.getType() == 1 && "cq/translation/components/mt-cloudconfig".equals(prop.getString())) {
                this.log.info("Migrating node with path {}", (Object)etcTranslationNode.getPath());
                this.log.info("setting properties assets_translationWorkflow, sites_translationWorkflow to machineTranslation");
                etcTranslationNode.setProperty("assets_translationWorkflow", "machineTranslation");
                etcTranslationNode.setProperty("sites_translationWorkflow", "machineTranslation");
                this.copyPropertyValue(etcTranslationNode, "defaultTranslationProvider", "assets_defaultTranslationProvider", "sites_defaultTranslationProvider");
                this.copyPropertyValue(etcTranslationNode, "defaultCategory", "assets_defaultCategory", "sites_defaultCategory");
            }
            NodeIterator childNodes = etcTranslationNode.getNodes();
            while (childNodes.hasNext()) {
                this.migrateTranslationCloudConfigProperties(childNodes.nextNode());
            }
        }
    }

    private /* varargs */ void copyPropertyValue(Node node, String strPropertyName, String ... newPropArray) throws RepositoryException {
        Property prop;
        if (node != null && node.hasProperty(strPropertyName) && (prop = node.getProperty(strPropertyName)) != null) {
            for (String strNewProperty : newPropArray) {
                this.log.info("Copying property {}, to {}", (Object)strPropertyName, (Object)strNewProperty);
                node.setProperty(strNewProperty, prop.getValue());
            }
        }
    }

    private void migrateTranslationCloudConfigForNode(Node node) throws RepositoryException {
        if (node != null) {
            Property prop;
            if (node.hasProperty("cq:cloudserviceconfigs") && (prop = node.getProperty("cq:cloudserviceconfigs")) != null && prop.isMultiple()) {
                Value[] values = prop.getValues();
                String strNewConfigPath = null;
                HashSet<Value> newValues = new HashSet<Value>();
                for (Value value : values) {
                    if (value.getType() == 1 && value.getString().indexOf("/etc/cloudservices/machine-translation") == 0) {
                        String strOldVal = value.getString();
                        strNewConfigPath = "/etc/cloudservices/translation" + strOldVal.substring("/etc/cloudservices/machine-translation".length());
                        String strInfoMessage = String.format("Migrating old translation cloud config from <%s> to <%s>. Changing cq:cloudserviceconfigs property for node path %s", strOldVal, strNewConfigPath, node.getPath());
                        this.log.info(strInfoMessage);
                        continue;
                    }
                    newValues.add(value);
                }
                if (strNewConfigPath != null && strNewConfigPath.length() > 0) {
                    ValueFactory factory = node.getSession().getValueFactory();
                    newValues.add(factory.createValue(strNewConfigPath));
                    node.setProperty("cq:cloudserviceconfigs", newValues.toArray((T[])new Value[newValues.size()]));
                }
            }
            NodeIterator childNodes = node.getNodes();
            while (childNodes.hasNext()) {
                this.migrateTranslationCloudConfigForNode(childNodes.nextNode());
            }
        }
    }

    private void migrateAnalyticsConfiguration(Session sess, Node root) throws RepositoryException {
        if (!root.hasNode("etc/cloudservices/sitecatalyst")) {
            return;
        }
        this.setProgressInfo("Migrating Adobe Analytics cloud configurations");
        Node targetRoot = root.getNode("etc/cloudservices/sitecatalyst");
        NodeIterator configNodes = targetRoot.getNodes();
        while (configNodes.hasNext()) {
            Node maybeConfig = configNodes.nextNode();
            Node configContent = this.getJcrContentIfPageNodeWithoutPublicNode(maybeConfig);
            if (configContent == null) continue;
            this.log.info("Starting migration of {}", (Object)maybeConfig.getPath());
            Node configPublicNode = configContent.addNode("public");
            this.moveItem(configContent, configPublicNode, "useAppMeasurement");
            this.moveItem(configContent, configPublicNode, "disableTrackingCode");
            NodeIterator frameworkNodes = maybeConfig.getNodes();
            while (frameworkNodes.hasNext()) {
                Node frameworkContent = this.getJcrContentIfPageNodeWithoutPublicNode(frameworkNodes.nextNode());
                if (frameworkContent == null) continue;
                Node frameworkPublicNode = frameworkContent.addNode("public");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:trackingServer");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:trackingServerSecure");
                this.moveItem(frameworkContent, frameworkPublicNode, "reportsuites");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:adhocLinkTracking");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:variables");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:visitorNamespace");
                this.moveItem(frameworkContent, frameworkPublicNode, "cq:configCode");
                this.moveItem(frameworkContent, frameworkPublicNode, "mappings");
            }
            sess.save();
            this.log.info("Completed migration of {}", (Object)maybeConfig.getPath());
        }
    }

    private void migrateAudienceManagerConfiguration(Session sess, Node root) throws RepositoryException {
        if (!root.hasNode("etc/cloudservices/audiencemanager")) {
            return;
        }
        this.setProgressInfo("Migrating Adobe Audience Manager cloud configurations");
        Node targetRoot = root.getNode("etc/cloudservices/audiencemanager");
        NodeIterator configNodes = targetRoot.getNodes();
        while (configNodes.hasNext()) {
            Node maybeConfig = configNodes.nextNode();
            Node configContent = this.getJcrContentIfPageNodeWithoutPublicNode(maybeConfig);
            if (configContent == null) continue;
            this.log.info("Starting migration of {}", (Object)maybeConfig.getPath());
            if (!configContent.hasProperty("cq:cloudservicename")) {
                configContent.setProperty("cq:cloudservicename", "audiencemanager");
            }
            Node configPublicNode = configContent.addNode("public");
            this.moveItem(configContent, configPublicNode, "partner");
            this.moveItem(configContent, configPublicNode, "container");
            NodeIterator frameworkNodes = maybeConfig.getNodes();
            while (frameworkNodes.hasNext()) {
                Node frameworkContent = this.getJcrContentIfPageNodeWithoutPublicNode(frameworkNodes.nextNode());
                if (frameworkContent == null) continue;
                Node frameworkPublicNode = frameworkContent.addNode("public");
                this.moveItem(frameworkContent, frameworkPublicNode, "mappings");
            }
            sess.save();
            this.log.info("Completed migration of {}", (Object)maybeConfig.getPath());
        }
    }

    private void migrateDTMConfiguation(Session sess, Node root) throws RepositoryException {
        if (!root.hasNode("etc/cloudservices/dynamictagmanagement")) {
            return;
        }
        this.setProgressInfo("Migrating Adobe Dynamic Tag Management cloud configurations");
        Node targetRoot = root.getNode("etc/cloudservices/dynamictagmanagement");
        NodeIterator configNodes = targetRoot.getNodes();
        while (configNodes.hasNext()) {
            Node maybeConfig = configNodes.nextNode();
            Node configContent = this.getJcrContentIfPageNodeWithoutPublicNode(maybeConfig);
            if (configContent == null) continue;
            this.log.info("Starting migration of {}", (Object)maybeConfig.getPath());
            Node configPublicNode = configContent.addNode("public");
            this.moveItem(configContent, configPublicNode, "productionHeaderCode");
            this.moveItem(configContent, configPublicNode, "productionFooterCode.js");
            this.moveItem(configContent, configPublicNode, "stagingHeaderCode");
            this.moveItem(configContent, configPublicNode, "stagingFooterCode");
            this.moveItem(configContent, configPublicNode, "productionUseSelfHosting");
            this.moveItem(configContent, configPublicNode, "stagingUseSelfHosting");
            this.moveItem(configContent, configPublicNode, "productionDTMMainScriptPath");
            this.moveItem(configContent, configPublicNode, "stagingDTMMainScriptPath");
            sess.save();
            this.log.info("Completed migration of {}", (Object)maybeConfig.getPath());
        }
    }

    private void migrateTargetConfigurations(Session sess, Node root) throws RepositoryException {
        if (!root.hasNode("etc/cloudservices/testandtarget")) {
            return;
        }
        this.setProgressInfo("Migrating Adobe Target cloud configurations");
        Node targetRoot = root.getNode("etc/cloudservices/testandtarget");
        NodeIterator configNodes = targetRoot.getNodes();
        while (configNodes.hasNext()) {
            Node maybeConfig = configNodes.nextNode();
            Node configContent = this.getJcrContentIfPageNodeWithoutPublicNode(maybeConfig);
            if (configContent == null) continue;
            this.log.info("Starting migration of {}", (Object)maybeConfig.getPath());
            Node configPublicNode = configContent.addNode("public");
            this.moveItem(configContent, configPublicNode, "clientcode");
            this.moveItem(configContent, configPublicNode, "mbox.js");
            this.moveItem(configContent, configPublicNode, "useDtm");
            NodeIterator frameworkNodes = maybeConfig.getNodes();
            while (frameworkNodes.hasNext()) {
                Node frameworkContent = this.getJcrContentIfPageNodeWithoutPublicNode(frameworkNodes.nextNode());
                if (frameworkContent == null) continue;
                Node frameworkPublicNode = frameworkContent.addNode("public");
                this.moveItem(frameworkContent, frameworkPublicNode, "mappings");
            }
            sess.save();
            this.log.info("Completed migration of {}", (Object)maybeConfig.getPath());
        }
    }

    private Node findBackupMergerRepositoryRoot(Session sess) throws RepositoryException {
        ArrayList<Node> matchingNodes = new ArrayList<Node>();
        Node mainRoot = sess.getNode("/var/upgrade/PreUpgradeBackup");
        NodeIterator it = mainRoot.getNodes();
        while (it.hasNext()) {
            Node child = it.nextNode();
            if (!child.hasNode("to-process")) continue;
            matchingNodes.add(child.getNode("to-process"));
        }
        if (matchingNodes.size() == 0) {
            this.log.info("No backup node matching {} found under {}, no content to upgrade", (Object)"to-process", (Object)mainRoot.getPath());
            return null;
        }
        if (matchingNodes.size() > 1) {
            this.log.error("Multiple backup nodes found, please delete the extraneous ones are rerun this upgrade component: {}", matchingNodes);
            return null;
        }
        return (Node)matchingNodes.get(0);
    }

    private Node getJcrContentIfPageNodeWithoutPublicNode(Node candidate) throws RepositoryException {
        this.log.info("Inspecting {}", (Object)candidate.getPath());
        if (!candidate.getPrimaryNodeType().getName().equals("cq:Page")) {
            this.log.info("{} is not a cq:Page, not migrating", (Object)candidate.getPath());
            return null;
        }
        if (!candidate.hasNode("jcr:content")) {
            this.log.info("{} does not have a jcr:content node, not migrating", (Object)candidate.getPath());
            return null;
        }
        Node configContent = candidate.getNode("jcr:content");
        if (configContent.hasNode("public")) {
            this.log.info("A node named 'public' already exists for cloud configuration {}, skipping migration", (Object)configContent.getPath());
            return null;
        }
        return configContent;
    }

    private void moveItem(Node source, Node target, String itemName) throws RepositoryException {
        if (source.hasNode(itemName)) {
            source.getSession().move(source.getPath() + "/" + itemName, target.getPath() + "/" + itemName);
            return;
        }
        if (!source.hasProperty(itemName)) {
            return;
        }
        Property sourceProperty = source.getProperty(itemName);
        if (sourceProperty.isMultiple()) {
            target.setProperty(itemName, sourceProperty.getValues(), sourceProperty.getType());
        } else {
            target.setProperty(itemName, sourceProperty.getValue(), sourceProperty.getType());
        }
        sourceProperty.remove();
    }
}