SegmentImporter.java 12.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.polling.importer.ImportException
 *  com.day.cq.polling.importer.Importer
 *  com.day.cq.wcm.webservicesupport.Configuration
 *  com.day.cq.wcm.webservicesupport.ConfigurationManager
 *  com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  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.analytics.testandtarget.impl;

import com.day.cq.analytics.testandtarget.ListSegmentsRequest;
import com.day.cq.analytics.testandtarget.Segment;
import com.day.cq.analytics.testandtarget.TestandtargetException;
import com.day.cq.analytics.testandtarget.TestandtargetService;
import com.day.cq.analytics.testandtarget.impl.ListSegmentsRequestImpl;
import com.day.cq.polling.importer.ImportException;
import com.day.cq.polling.importer.Importer;
import com.day.cq.wcm.webservicesupport.Configuration;
import com.day.cq.wcm.webservicesupport.ConfigurationManager;
import com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
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="Day CQ Analytics Segment Importer", description="Imports segments defined in Test and Target into the CQ instance.")
@Service
@Property(name="importer.scheme", value={"adobe-target-segments"}, propertyPrivate=1)
public class SegmentImporter
implements Importer {
    private static final boolean DEFAULT_ENABLED = true;
    private static final String PN_SEGMENT_ORIGIN = "source";
    private static final String PN_SEGMENT_HIDDEN = "hidden";
    private static final String PN_SEGMENT_TYPE = "type";
    private static final String PN_SEGMENT_SOURCE_PRODUCT = "sourceProductName";
    private static final String PN_SEGMENT_EDIT_URL = "editURL";
    private static final String PN_SEGMENT_AUDIENCE_JSON = "audienceJson";
    private static final String PN_CLOUD_CONFIG_PATH = "cloudConfigurationPath";
    private static final String PN_LAST_SUCCESSFUL_IMPORT_TIMESTAMP = "lastSuccessfulImportTimestamp";
    private static final String TYPE_REUSABLE = "reusable";
    @Property(label="Enabled", description="Controls whether this importer is enabled or not. Defaults to true on author instances and false on publish instances.", boolValue={1})
    private static final String PROPERTY_ENABLED = "cq.analytics.testandtarget.segmentimporter.enabled";
    private static final Logger log = LoggerFactory.getLogger(SegmentImporter.class);
    @Reference
    private TestandtargetService testandtargetService;
    @Reference
    private ConfigurationManagerFactory configurationManagerFactory;
    private boolean enabled;

    protected void activate(ComponentContext ctx) {
        this.enabled = PropertiesUtil.toBoolean(ctx.getProperties().get("cq.analytics.testandtarget.segmentimporter.enabled"), (boolean)true);
    }

    public void importData(String scheme, String dataSource, Resource target) throws ImportException {
        if (!this.enabled) {
            log.debug("Component is not enabled, skipping import.");
            return;
        }
        ResourceResolver resourceResolver = target.getResourceResolver();
        log.info("Importing in {} with dataSource {}", (Object)target.getPath(), (Object)dataSource);
        Resource cloudConfig = resourceResolver.getResource(dataSource);
        if (cloudConfig == null) {
            log.warn("Unable to import segments at {} since there is no resource at path {}", (Object)target.getPath(), (Object)dataSource);
            return;
        }
        ConfigurationManager configurationManager = this.configurationManagerFactory.getConfigurationManager(resourceResolver);
        Configuration config = configurationManager.getConfiguration(cloudConfig.getPath());
        if (config == null) {
            log.warn("Unable to import segments at {} since the resource at {} can not be adapted to a '{}'", new Object[]{target.getPath(), cloudConfig.getPath(), Configuration.class.getName()});
            return;
        }
        try {
            ValueMap targetProps = (ValueMap)target.adaptTo(ModifiableValueMap.class);
            long lastImported = targetProps != null ? (Long)targetProps.get("lastSuccessfulImportTimestamp", (Object)0) : 0;
            Date importFrom = null;
            Date importTo = null;
            ListSegmentsRequestImpl listSegmentsRequest = new ListSegmentsRequestImpl();
            if (lastImported > 0) {
                Calendar importCalender = Calendar.getInstance();
                importCalender.setTimeInMillis(lastImported);
                importCalender.add(6, -1);
                importFrom = importCalender.getTime();
                importCalender.add(6, 2);
                importTo = importCalender.getTime();
                listSegmentsRequest = listSegmentsRequest.modifiedFrom(importFrom).modifiedTo(importTo);
            }
            List<Segment> segments = this.testandtargetService.listSegments(config, listSegmentsRequest);
            List<Segment> deletedSegments = null;
            ArrayList<String> segmentIds = new ArrayList<String>();
            for (Segment segment : segments) {
                String segmentId = String.valueOf(segment.getId());
                segmentIds.add(segmentId);
                SegmentImporter.writeSegment(target, segment, cloudConfig.getPath(), null);
            }
            if (lastImported > 0) {
                listSegmentsRequest = new ListSegmentsRequestImpl().deletedFrom(importFrom).deletedTo(importTo).withStatus("deleted");
                deletedSegments = this.testandtargetService.listSegments(config, listSegmentsRequest);
            }
            Resource localTargetResource = resourceResolver.getResource(target.getPath());
            ModifiableValueMap modifiableTargetProps = (ModifiableValueMap)localTargetResource.adaptTo(ModifiableValueMap.class);
            modifiableTargetProps.put((Object)"lastSuccessfulImportTimestamp", (Object)Calendar.getInstance().getTimeInMillis());
            resourceResolver.commit();
            log.info("Wrote {} segments under {}", (Object)segments.size(), (Object)target.getPath());
            this.removeDeletedSegments(target, deletedSegments);
        }
        catch (TestandtargetException e) {
            throw new ImportException("Failed importing segments for config at " + config.getPath(), (Throwable)e);
        }
        catch (PersistenceException e) {
            throw new ImportException("Failed importing segments for config at " + config.getPath(), (Throwable)e);
        }
    }

    public static void writeSegment(Resource target, Segment segment, String targetConfigPath, String audienceJson) throws PersistenceException {
        Map<String, String> segmentMACMetadata;
        ResourceResolver resolver = target.getResourceResolver();
        String segmentId = String.valueOf(segment.getId());
        Resource segmentRes = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(target.getPath() + "/" + segmentId), SegmentImporter.mapOfPrimaryType("cq:Page"), (String)null, (boolean)false);
        HashMap<String, String> props = new HashMap<String, String>();
        props.put("cq:template", "/libs/cq/personalization/templates/segment");
        props.put("sling:resourceType", "cq/personalization/components/segmentpage");
        Resource segmentContent = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(segmentRes.getPath() + "/" + "jcr:content"), props, (String)null, (boolean)false);
        ModifiableValueMap segmentMap = (ModifiableValueMap)segmentContent.adaptTo(ModifiableValueMap.class);
        segmentMap.put((Object)"jcr:title", (Object)segment.getName());
        segmentMap.put((Object)"source", (Object)(segment.getSource() != null ? segment.getSource() : ""));
        String segmentType = segment.getType();
        boolean isHidden = StringUtils.isNotEmpty((String)segmentType) ? !"reusable".equals(segmentType) : segment.getHidden();
        segmentMap.put((Object)"hidden", (Object)isHidden);
        if (StringUtils.isNotEmpty((String)audienceJson)) {
            segmentMap.put((Object)"audienceJson", (Object)audienceJson);
        }
        if (StringUtils.isNotEmpty((String)targetConfigPath)) {
            segmentMap.put((Object)"cloudConfigurationPath", (Object)targetConfigPath);
        }
        if (segment.getDescription() != null) {
            segmentMap.put((Object)"jcr:description", (Object)segment.getDescription());
        }
        if (StringUtils.isNotEmpty((String)segmentType)) {
            segmentMap.put((Object)"type", (Object)segment.getType());
        }
        if ((segmentMACMetadata = segment.getMarketingCloudMetadata()) != null) {
            segmentMap.put((Object)"sourceProductName", (Object)segmentMACMetadata.get("sourceProductName"));
            segmentMap.put((Object)"editURL", (Object)segmentMACMetadata.get("editURL"));
        }
        Resource traits = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(segmentContent.getPath() + "/" + "traits"), (String)"cq/personalization/components/traits/logic/and", (String)null, (boolean)false);
        Resource and = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(traits.getPath() + "/" + "andpar"), (String)"foundation/components/parsys", (String)null, (boolean)false);
        HashMap<String, String> tandtMap = new HashMap<String, String>();
        tandtMap.put("sling:resourceType", "cq/personalization/components/traits/tandt");
        tandtMap.put("externalId", segmentId);
        Resource traitResource = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(and.getPath() + "/" + "tandt"), tandtMap, (String)null, (boolean)false);
        ModifiableValueMap traitMap = (ModifiableValueMap)traitResource.adaptTo(ModifiableValueMap.class);
        traitMap.put((Object)"jcr:title", (Object)segment.getName());
    }

    private void removeDeletedSegments(Resource target, List<Segment> deletedSegments) throws PersistenceException {
        int deletionCount = 0;
        if (deletedSegments == null) {
            return;
        }
        for (Segment deletedSegment : deletedSegments) {
            Resource segmentResource = target.getChild(String.valueOf(deletedSegment.getId()));
            if (segmentResource == null) continue;
            segmentResource.getResourceResolver().delete(segmentResource);
            ++deletionCount;
        }
        if (deletionCount != 0) {
            log.info("Deleted {} segments under {}", (Object)deletionCount, (Object)target.getPath());
            target.getResourceResolver().commit();
        }
    }

    private static Map<String, Object> mapOfPrimaryType(String primaryType) {
        return Collections.singletonMap("jcr:primaryType", primaryType);
    }

    protected void bindTestandtargetService(TestandtargetService testandtargetService) {
        this.testandtargetService = testandtargetService;
    }

    protected void unbindTestandtargetService(TestandtargetService testandtargetService) {
        if (this.testandtargetService == testandtargetService) {
            this.testandtargetService = null;
        }
    }

    protected void bindConfigurationManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
        this.configurationManagerFactory = configurationManagerFactory;
    }

    protected void unbindConfigurationManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
        if (this.configurationManagerFactory == configurationManagerFactory) {
            this.configurationManagerFactory = null;
        }
    }
}