CampaignXmlSerializer.java 19.2 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.commons.collections.MultiMap
 *  org.apache.commons.collections.map.MultiValueMap
 *  org.apache.commons.lang.StringUtils
 */
package com.day.cq.analytics.testandtarget.impl.serializer;

import com.day.cq.analytics.testandtarget.impl.TestandTargetCampaignType;
import com.day.cq.analytics.testandtarget.impl.TestandtargetCampaign;
import com.day.cq.analytics.testandtarget.impl.TestandtargetSegment;
import com.day.cq.analytics.testandtarget.impl.model.TestandtargetExperience;
import com.day.cq.analytics.testandtarget.impl.model.TestandtargetOffer;
import com.day.cq.analytics.testandtarget.impl.serializer.AbstractSerializer;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.lang.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

public class CampaignXmlSerializer
extends AbstractSerializer<TestandtargetCampaign> {
    private static final String TARGET_PARAMETER_TYPE_PROFILE = "profile";
    private static final char TARGET_MULTIVALUE_SEPARATOR = '|';
    private static final String TARGET_OPERATOR_CONTAINS_IGNORE_CASE = "containsIgnoreCase";
    private static final String CONVERSION_ACTION_NAME = "restartRandomExperience";
    private static final int BRANCH_NAME_MAX_SIZE = 20;
    private static final String HTML_CAMPAIGN_FORMAT = "<script type=\"text/javascript\">CQ_Analytics.TestTarget.pull('%s','${mbox.name}','1.0.0');</script>";
    private static final String DEFAULT_HTML_OFFER = "<script type=\"text/javascript\">CQ_Analytics.TestTarget.signalDefaultOffer('${mbox.name}');</script>";
    private static final String XML_TAG_CAMPAIGN = "campaign";
    private static final String XML_TAG_ALGORITHM = "algorithm";
    private static final String XML_TAG_NAME = "name";
    private static final String XML_TAG_START = "start";
    private static final String XML_TAG_END = "end";
    private static final String XML_TAG_BRANCHES = "branches";
    private static final String XML_TAG_BRANCH = "branch";
    private static final String XML_TAG_PERCENT_CONSTRAINT = "percentConstraint";
    private static final String XML_TAG_PERCENT = "percent";
    private static final String XML_TAG_PARAM_CONSTRAINTS = "paramConstraints";
    private static final String XML_TAG_PARAM_CONSTRAINT = "paramConstraint";
    private static final String XML_TAG_PARAMETER_TYPE = "parameterType";
    private static final String XML_TAG_MATCHER_TYPE = "matcherType";
    private static final String XML_TAG_VALUES = "values";
    private static final String XML_TAG_STRING = "string";
    private static final String XML_TAG_OFFER = "offer";
    private static final String XML_TAG_OFFERS = "offers";
    private static final String XML_TAG_DISPLAY = "display";
    private static final String XML_TAG_DISPLAYS = "displays";
    private static final String XML_TAG_MBOX = "mbox";
    private static final String XML_TAG_MBOXES = "mboxes";
    private static final String XML_TAG_LOCATION = "location";
    private static final String XML_TAG_LOCATIONS = "locations";
    private static final String XML_TAG_TYPE = "type";
    private static final String XML_TAG_STEP = "step";
    private static final String XML_TAG_STEPS = "steps";
    private static final String XML_TAG_CONTENT = "content";
    private static final String XML_TAG_REUSABLE_SEGMENTS = "reusableSegments";
    private static final String XML_TAG_REUSABLE_SEGMENT = "reusableSegment";
    private static final String XML_TAG_CONVERSION_ACTION = "action";
    private static final String XML_TAG_MAC_METADATA = "marketingCloudMetadata";
    private static final String XML_TAG_MAC_SOURCE_PRODUCT = "sourceProductName";
    private static final String XML_TAG_MAC_CAMPAIGN_URL = "editURL";
    private static final String XML_TAG_MAC_REMOTE_MODIFIED_BY = "remoteModifiedBy";
    public static final String PROFILE_PARAMETER_RESOLVED_SEGMENTS = "_cq_.resolvedSegments";
    public static final String OFFER_NAME_DEFAULT_CONTENT = "Default AEM offer";

    @Override
    public String serialize(TestandtargetCampaign campaign) {
        try {
            String algorithm;
            SAXTransformerFactory f = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
            StringWriter sw = new StringWriter();
            StreamResult sr = new StreamResult(sw);
            TransformerHandler handler = f.newTransformerHandler();
            Transformer t = handler.getTransformer();
            t.setOutputProperty("omit-xml-declaration", "yes");
            MultiValueMap mboxNameToExperience = MultiValueMap.decorate(new LinkedHashMap(), LinkedHashSet.class);
            for (TestandtargetExperience experience : campaign.getExperiences()) {
                for (TestandtargetOffer offer : experience.getOffers()) {
                    mboxNameToExperience.put((Object)offer.getLocationName(), (Object)experience);
                }
            }
            ArrayList<String> allExperienceNames = new ArrayList<String>(campaign.getExperiences().size());
            for (TestandtargetExperience experience2 : campaign.getExperiences()) {
                allExperienceNames.add(experience2.getInternalName());
            }
            handler.setResult(sr);
            handler.startDocument();
            this.startElement(handler, "campaign");
            String string = algorithm = campaign.getCampaignType() != null ? campaign.getCampaignType().getTestAndTargetAlgorithm() : null;
            if (algorithm != null) {
                this.startElement(handler, "algorithm");
                this.writeTag(handler, "type", algorithm);
                this.endElement(handler, "algorithm");
            }
            this.writeTag(handler, "name", campaign.getName());
            this.writeTag(handler, "start", campaign.getStart());
            this.writeTag(handler, "end", campaign.getEnd());
            this.startElement(handler, "marketingCloudMetadata");
            this.writeTag(handler, "sourceProductName", campaign.getSourceProductName());
            this.writeTag(handler, "editURL", campaign.getEditUrl());
            this.writeTag(handler, "remoteModifiedBy", campaign.getRemoteModifiedBy());
            this.endElement(handler, "marketingCloudMetadata");
            this.writeBranches(handler, campaign);
            this.startElement(handler, "steps");
            this.writeMboxes(handler);
            this.writeOffers(handler, (MultiMap)mboxNameToExperience, allExperienceNames);
            this.writeConversionStep(handler, campaign);
            this.endElement(handler, "steps");
            this.endElement(handler, "campaign");
            handler.endDocument();
            return sw.toString();
        }
        catch (TransformerConfigurationException e) {
            throw new RuntimeException(e);
        }
        catch (TransformerFactoryConfigurationError e) {
            throw new RuntimeException(e);
        }
        catch (SAXException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public TestandtargetCampaign deserialize(String json, Class<TestandtargetCampaign> clazz) {
        return null;
    }

    private void writeOffers(TransformerHandler handler, MultiMap mboxNameToExperience, List<String> allExperienceNames) throws SAXException {
        if (mboxNameToExperience.isEmpty()) {
            return;
        }
        this.startElement(handler, "step");
        this.writeTag(handler, "type", "display");
        this.startElement(handler, "locations");
        for (Object mboxNameEntryAsObject : mboxNameToExperience.entrySet()) {
            Map.Entry mboxNameEntry = (Map.Entry)mboxNameEntryAsObject;
            String mboxName = (String)mboxNameEntry.getKey();
            Collection mboxExperiences = (Collection)mboxNameEntry.getValue();
            this.startElement(handler, "location");
            this.startElement(handler, "mboxes");
            this.startElement(handler, "mbox");
            this.writeTag(handler, "name", mboxName);
            this.endElement(handler, "mbox");
            this.endElement(handler, "mboxes");
            this.startElement(handler, "displays");
            HashMap<String, TestandtargetExperience> experiencesByName = new HashMap<String, TestandtargetExperience>();
            for (Object experienceAsObject : mboxExperiences) {
                TestandtargetExperience experience = (TestandtargetExperience)experienceAsObject;
                experiencesByName.put(experience.getInternalName(), experience);
            }
            ArrayList<TestandtargetExperience> allExperiences = new ArrayList<TestandtargetExperience>();
            for (String experienceName : allExperienceNames) {
                TestandtargetExperience experience = (TestandtargetExperience)experiencesByName.get(experienceName);
                if (experience == null) {
                    experience = TestandtargetExperience.newSegmentBasedExperience(experienceName, new TestandtargetSegment[0]);
                    experience.addOffer(new TestandtargetOffer("Default AEM offer", mboxName, "", true));
                }
                allExperiences.add(experience);
            }
            for (TestandtargetExperience experience : allExperiences) {
                this.startElement(handler, "display");
                this.writeTag(handler, "branch", experience.getName());
                this.startElement(handler, "offers");
                for (TestandtargetOffer offer : experience.getOffers()) {
                    if (!mboxName.equals(offer.getLocationName())) continue;
                    if (offer.isDefault() && offer.isNeedsCreating()) {
                        this.startElement(handler, "offer", "type", "html");
                        this.writeTag(handler, "name", "Default AEM offer");
                        this.writeCdataTag(handler, "content", "<script type=\"text/javascript\">CQ_Analytics.TestTarget.signalDefaultOffer('${mbox.name}');</script>");
                    } else if (offer.isNeedsCreating()) {
                        this.startElement(handler, "offer", "type", "html");
                        this.writeTag(handler, "name", offer.getName());
                        this.writeCdataTag(handler, "content", this.toHtmlOfferString(offer.getContentDeliveryPath()));
                    } else {
                        this.startElement(handler, "offer");
                        this.writeTag(handler, "name", offer.getName());
                    }
                    this.endElement(handler, "offer");
                }
                this.endElement(handler, "offers");
                this.endElement(handler, "display");
            }
            this.endElement(handler, "displays");
            this.endElement(handler, "location");
        }
        this.endElement(handler, "locations");
        this.endElement(handler, "step");
    }

    private String toHtmlOfferString(String contentPath) {
        return String.format("<script type=\"text/javascript\">CQ_Analytics.TestTarget.pull('%s','${mbox.name}','1.0.0');</script>", contentPath);
    }

    private void writeMboxes(TransformerHandler handler) throws SAXException {
        this.startElement(handler, "step");
        this.writeTag(handler, "type", "entry");
        this.startElement(handler, "locations");
        this.startElement(handler, "location");
        this.startElement(handler, "mboxes");
        this.startElement(handler, "mbox");
        this.writeTag(handler, "name", "** display mboxes **");
        this.endElement(handler, "mbox");
        this.endElement(handler, "mboxes");
        this.endElement(handler, "location");
        this.endElement(handler, "locations");
        this.endElement(handler, "step");
    }

    private void writeBranches(TransformerHandler handler, TestandtargetCampaign campaign) throws SAXException {
        if (campaign.getExperiences().isEmpty()) {
            return;
        }
        this.startElement(handler, "branches");
        for (TestandtargetExperience experience : campaign.getExperiences()) {
            this.startElement(handler, "branch");
            this.writeTag(handler, "name", experience.getName());
            if (experience.getPercentageConstraint() != null) {
                this.startElement(handler, "percentConstraint");
                this.writeTag(handler, "percent", experience.getPercentageConstraint().toString());
                this.endElement(handler, "percentConstraint");
            } else {
                List<TestandtargetSegment> explicitSegments = experience.getSegment(TestandtargetSegment.Kind.VALUE);
                List<TestandtargetSegment> referenceSegments = experience.getSegment(TestandtargetSegment.Kind.REFERENCE);
                List<TestandtargetSegment> byPathSegments = experience.getSegment(TestandtargetSegment.Kind.BY_PATH);
                if (!explicitSegments.isEmpty() || !byPathSegments.isEmpty()) {
                    this.startElement(handler, "paramConstraints");
                    for (TestandtargetSegment segment2 : explicitSegments) {
                        this.startElement(handler, "paramConstraint");
                        this.writeTag(handler, "parameterType", "profile");
                        this.writeTag(handler, "name", segment2.getName().replace('/', '.'));
                        this.writeTag(handler, "matcherType", segment2.getOperator());
                        this.startElement(handler, "values");
                        for (String value : segment2.getValues()) {
                            this.writeTag(handler, "string", value);
                        }
                        this.endElement(handler, "values");
                        this.endElement(handler, "paramConstraint");
                    }
                    for (TestandtargetSegment segment2 : byPathSegments) {
                        if (segment2.getValues().size() != 1) {
                            throw new IllegalArgumentException("By-path segment does not have exactly one value : " + segment2.getValues());
                        }
                        this.startElement(handler, "paramConstraint");
                        this.writeTag(handler, "parameterType", "profile");
                        this.writeTag(handler, "name", "_cq_.resolvedSegments");
                        this.writeTag(handler, "matcherType", "containsIgnoreCase");
                        this.startElement(handler, "values");
                        this.writeTag(handler, "string", "" + '|' + segment2.getValues().get(0) + '|');
                        this.endElement(handler, "values");
                        this.endElement(handler, "paramConstraint");
                    }
                    this.endElement(handler, "paramConstraints");
                }
                if (!referenceSegments.isEmpty()) {
                    this.startElement(handler, "reusableSegments");
                    for (TestandtargetSegment segment2 : referenceSegments) {
                        this.writeTag(handler, "reusableSegment", segment2.getName());
                    }
                    this.endElement(handler, "reusableSegments");
                }
            }
            this.endElement(handler, "branch");
        }
        this.endElement(handler, "branches");
    }

    private void writeConversionStep(TransformerHandler handler, TestandtargetCampaign campaign) throws SAXException {
        this.startElement(handler, "step");
        this.writeTag(handler, "name", "Conversion on click");
        this.writeTag(handler, "type", "conversion");
        if (campaign.isForceLandingPageCampaign()) {
            HashMap<String, String> conversionActionAttrs = new HashMap<String, String>();
            conversionActionAttrs.put("type", "restartRandomExperience");
            this.writeTagWithAttributes(handler, "action", conversionActionAttrs);
            this.startElement(handler, "locations");
            this.startElement(handler, "location");
            this.startElement(handler, "mboxes");
            for (String location : campaign.getAllMboxLocations()) {
                this.startElement(handler, "mbox");
                this.writeTag(handler, "name", location);
                this.endElement(handler, "mbox");
            }
            this.endElement(handler, "mboxes");
            this.endElement(handler, "location");
            this.endElement(handler, "locations");
        } else {
            this.startElement(handler, "locations");
            this.startElement(handler, "location");
            this.startElement(handler, "mboxes");
            this.startElement(handler, "mbox");
            this.writeTag(handler, "name", StringUtils.isBlank((String)campaign.getConversionGoal()) ? "** click from display mbox **" : campaign.getConversionGoal());
            this.endElement(handler, "mbox");
            this.endElement(handler, "mboxes");
            this.endElement(handler, "location");
            this.endElement(handler, "locations");
        }
        this.endElement(handler, "step");
    }

    private void writeTag(TransformerHandler handler, String tagName, String tagValue) throws SAXException {
        handler.startElement("", tagName, tagName, null);
        handler.characters(tagValue.toCharArray(), 0, tagValue.length());
        handler.endElement("", tagName, tagName);
    }

    private void writeTagWithAttributes(TransformerHandler handler, String tagName, Map<String, String> attrs) throws SAXException {
        AttributesImpl xmlAttrs = new AttributesImpl();
        for (String attrName : attrs.keySet()) {
            xmlAttrs.addAttribute("", attrName, attrName, null, attrs.get(attrName));
        }
        handler.startElement("", tagName, tagName, xmlAttrs);
        handler.endElement("", tagName, tagName);
    }

    private void writeCdataTag(TransformerHandler handler, String tagName, String tagValue) throws SAXException {
        handler.startElement("", tagName, tagName, null);
        handler.startCDATA();
        handler.characters(tagValue.toCharArray(), 0, tagValue.length());
        handler.endCDATA();
        handler.endElement("", tagName, tagName);
    }

    private void startElement(TransformerHandler handler, String tagName) throws SAXException {
        handler.startElement("", tagName, tagName, null);
    }

    private void startElement(TransformerHandler handler, String tagName, String propertyName, String propertyValue) throws SAXException {
        AttributesImpl attr = new AttributesImpl();
        attr.addAttribute("", propertyName, propertyName, null, propertyValue);
        handler.startElement("", tagName, tagName, attr);
    }

    private void endElement(TransformerHandler handler, String tagName) throws SAXException {
        handler.endElement("", tagName, tagName);
    }
}