com.adobe.cq.contentinsight.ActivityResourceVisitor Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2013 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.contentinsight;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.AbstractResourceVisitor;
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.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.analytics.testandtarget.util.OfferHelper;
import com.day.cq.personalization.TargetedContentManager;
/**
* An resource visitor that collects all activities (formerly campaigns) that
* have been published to Adobe Target.
*/
public class ActivityResourceVisitor extends AbstractResourceVisitor {
private static final Logger log = LoggerFactory.getLogger(ActivityResourceVisitor.class);
private static final String PN_PUBLISH_CAMPAIGN_ID = "publishCampaignId";
private static final String TARGET_COMPONENT = "cq/personalization/components/target";
private List activities = new ArrayList();
private String pagePath = "";
private TargetedContentManager targetedContentManager;
public ActivityResourceVisitor(String pagePath, TargetedContentManager targetedContentManager) {
if (!pagePath.endsWith(JcrConstants.JCR_CONTENT)) {
pagePath += "/" + JcrConstants.JCR_CONTENT;
}
this.pagePath = pagePath;
this.targetedContentManager = targetedContentManager;
if (targetedContentManager == null) {
log.warn("No TargetedContentManager available, will not be able to determine campaigns used on the current page!");
}
}
/**
* If resource is of activity resource type, add it to the collection.
*/
protected void visit(Resource res) {
ValueMap properties = ResourceUtil.getValueMap(res);
if(ResourceUtil.isA(res, OfferHelper.RT_CAMPAIGN) && properties.get(PN_PUBLISH_CAMPAIGN_ID, String.class) != null) {
// only include campaigns that are used on the current page path
if (matchesPage(res)) {
activities.add(res);
}
}
}
/**
* Return the list of collected activity resources. This list is empty
* when {@link ActivityResourceVisitor#accept(Resource)} has not been
* called before.
*/
public List getActivityResources() {
return activities;
}
/**
* Determines if the given campaign resource is targeted to the visitor's pagePath
*
* @param campaignResource points to the campaign
* @return {@code Boolean} true if the given campaign is used on the page identified by pagePath
*/
private boolean matchesPage(Resource campaignResource) {
boolean matchesPage = false;
ResourceResolver resolver = campaignResource.getResourceResolver();
Resource pageRes = resolver.getResource(this.pagePath);
if (pageRes != null && campaignResource != null) {
String campaignPathPrefix = campaignResource.getParent().getPath() + "/";
// drill into page's children to see if there's a target component
// that has associated this campaign
List targetResources = getTargetComponents(pageRes, null);
try {
for (Resource targetResource : targetResources) {
// use TargetContentManager API to determine if the campaign
// resource is used on the page
ValueMap targetResProps = targetResource.adaptTo(ValueMap.class);
String locationProp = targetResProps.get("location", null);
String locationID = StringUtils.isNotBlank(locationProp)
? locationProp : targetResource.getPath();
JSONObject teaserInfo = targetedContentManager.getTeaserInfo(resolver, null, locationID);
JSONArray allTeasers = teaserInfo.getJSONArray("allTeasers");
for(int i = 0; i < allTeasers.length(); i++) {
// check if teaser belongs to currently tested campaign (see CQ-16460)
JSONObject teaser = allTeasers.getJSONObject(i);
if(teaser.getString("path").startsWith(campaignPathPrefix)) {
matchesPage = true;
break;
}
}
}
}
catch (JSONException e) {
log.error("Could not determine if page {} uses campaign {}!", new Object[]{pageRes.getPath(), campaignResource.getPath()});
log.error("", e);
}
}
return matchesPage;
}
/**
* Finds all children of {@code Resource} rootResource that have the
* cq/personalization/components/target resource type
*
* @param rootResource
* a {@code Resource} where to start looking for target res types
* @param resList
* a {@code List} to add matching resources to. If null} is
* passed a new list instance will be automatically created
*
* @return the {@code List} containing target resource types that have the rootResource as an ancestor
*/
private List getTargetComponents(Resource rootResource, List resList) {
if (resList == null) {
resList = new ArrayList();
}
for(Resource child : rootResource.getChildren()){
if (child.isResourceType(TARGET_COMPONENT)) {
resList.add(child);
} else {
getTargetComponents(child, resList);
}
}
return resList;
}
}