OffersUpdateHandler.java 10.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.contentsync.config.ConfigEntry
 *  com.day.cq.wcm.api.Page
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Workspace
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  javax.jcr.query.QueryResult
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 */
package com.adobe.cq.mobile.platform.impl.contentsync.handler;

import com.adobe.cq.mobile.platform.impl.contentsync.handler.AbstractPagesUpdateHandler;
import com.day.cq.contentsync.config.ConfigEntry;
import com.day.cq.wcm.api.Page;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;

@Component(metatype=1, factory="com.day.cq.contentsync.handler.ContentUpdateHandler/mobileappoffers", inherit=1)
public class OffersUpdateHandler
extends AbstractPagesUpdateHandler {
    public static final String RT_OFFERPROXY = "cq/personalization/components/offerproxy";
    public static final String[] DEFAULT_PAGE_TYPES = new String[]{"cq/personalization/components/teaserpage", "cq/personalization/components/offerproxy"};
    private static final String PN_LOCATION_ROOT = "locationRoot";
    private static final String SKIP_CLIENT_CONTEXT = "skipClientContext";
    private ProxyRequest proxyRequest;
    private Map<String, String> locationMapping = new HashMap<String, String>();

    @Override
    protected HttpServletRequest createRequest(String uri) {
        return super.createRequest(uri);
    }

    @Override
    protected void setRewriteOptions(HttpServletRequest request) {
        super.setRewriteOptions(request);
        request.setAttribute("skipClientContext", (Object)true);
    }

    @Override
    protected void initialize(ConfigEntry configEntry, Session adminSession, Session userSession) {
        String path = configEntry.getContentPath();
        QueryManager qm = null;
        try {
            qm = adminSession.getWorkspace().getQueryManager();
            Query q = qm.createQuery("SELECT * FROM [cq:PageContent] WHERE ISDESCENDANTNODE([" + path + "]) AND location is not null OR location = ''", "JCR-SQL2");
            QueryResult res = q.execute();
            NodeIterator iter = res.getNodes();
            while (iter.hasNext()) {
                Node pageContentNode = iter.nextNode();
                Property locationProperty = pageContentNode.getProperty("location");
                String guid = locationProperty.getString();
                if (!StringUtils.isNotBlank((CharSequence)guid)) continue;
                this.locationMapping.put(guid, pageContentNode.getPath());
            }
        }
        catch (RepositoryException e) {
            this.log.error("Unable to query out locations", (Throwable)e);
        }
    }

    @Override
    protected boolean isModified(Page page, String uri, Long lastUpdated, ConfigEntry configEntry, String configCacheRoot, Session session) throws RepositoryException {
        boolean modified = true;
        if (this.includeOnlyModifiedPages(configEntry)) {
            if (!session.nodeExists(configCacheRoot + uri)) {
                return true;
            }
            modified = this.isModified(page, lastUpdated, 0);
        }
        return modified;
    }

    @Override
    public void setupPageTypes(ConfigEntry configEntry) {
        this.includedPageTypes = configEntry.getValues("includedPageTypes");
        this.excludedPageTypes = configEntry.getValues("excludedPageTypes");
        if (this.includedPageTypes == null) {
            this.includedPageTypes = DEFAULT_PAGE_TYPES;
        }
    }

    @Override
    protected boolean includePage(ConfigEntry configEntry, Page pageToTest) {
        boolean includePage = super.includePage(configEntry, pageToTest);
        if (includePage) {
            includePage = false;
            List<String> locationRootFilters = this.getLocationRoots(configEntry);
            for (String locationRootFilter : locationRootFilters) {
                String path;
                String location = (String)pageToTest.getProperties().get("location", String.class);
                if (StringUtils.isNotBlank((CharSequence)location) && location.startsWith("/")) {
                    if (location == null || !location.startsWith(locationRootFilter)) continue;
                    includePage = true;
                    break;
                }
                if (!this.locationMapping.containsKey(location) || !(path = this.locationMapping.get(location)).startsWith(configEntry.getContentPath())) continue;
                includePage = true;
                break;
            }
        }
        return includePage;
    }

    @Override
    protected boolean collectAssets(Page page, String configCacheRoot, Session admin, Session session) throws RepositoryException {
        ResourceResolver resourceResolver = ((Resource)page.adaptTo(Resource.class)).getResourceResolver();
        if (this.proxyRequest != null) {
            Resource offerResource = resourceResolver.getResource(this.proxyRequest.getOfferPath());
            page = (Page)offerResource.adaptTo(Page.class);
            this.proxyRequest.setProcessingAssets(true);
        }
        return super.collectAssets(page, configCacheRoot, admin, session);
    }

    @Override
    protected String buildURI(ConfigEntry entry, Page page) {
        String pathToOffer;
        if (page == null) {
            return null;
        }
        if ("cq/personalization/components/offerproxy".equals(page.getContentResource().getResourceType()) && StringUtils.isNotBlank((CharSequence)(pathToOffer = (String)page.getContentResource().getValueMap().get("offerPath", String.class)))) {
            ResourceResolver resourceResolver = ((Resource)page.adaptTo(Resource.class)).getResourceResolver();
            Resource resource = resourceResolver.getResource(pathToOffer);
            if (resource != null) {
                this.proxyRequest = new ProxyRequest(pathToOffer, super.buildURI(entry, page));
                page = (Page)resource.adaptTo(Page.class);
                String uri = page.getPath() + ".tandt";
                if (entry.getValue("extension") != null) {
                    uri = uri + "." + entry.getValue("extension");
                }
                return uri;
            }
            this.log.warn("The referenced offer {} no longer exists", (Object)pathToOffer);
            return null;
        }
        this.proxyRequest = null;
        return super.buildURI(entry, page);
    }

    @Override
    protected String getTargetPath(String uri) {
        if (this.proxyRequest != null && !this.proxyRequest.isProcessingAssets()) {
            uri = this.proxyRequest.getCachePath();
        }
        return super.getTargetPath(uri);
    }

    protected boolean isModified(Page page, Long lastUpdated, int currentDepth) throws RepositoryException {
        boolean modified = false;
        if (page.getContentResource().getResourceType() == null || page.getContentResource().getResourceType().equals("cq:PageContent")) {
            this.log.debug("No sling resource type detected, ignoring page" + page.getPath());
        } else {
            Calendar cal = page.getLastModified();
            if (cal == null) {
                this.log.debug("No lastmodified set on page: " + page.getPath());
                cal = (Calendar)page.getProperties().get("jcr:created", Calendar.class);
            }
            if (cal != null) {
                long lastModified = cal.getTime().getTime();
                boolean bl = modified = lastUpdated < lastModified || lastModified == -1;
                if (modified) {
                    return modified;
                }
            }
        }
        Iterator children = page.listChildren();
        while (children.hasNext()) {
            Page childPage = (Page)children.next();
            boolean bl = this.isModified(childPage, lastUpdated, currentDepth + 1) || modified;
            modified = bl;
            if (!modified) continue;
            return modified;
        }
        return modified;
    }

    private List<String> getLocationRoots(ConfigEntry configEntry) {
        ArrayList<String> locationPathFilters = new ArrayList<String>();
        String[] locationRoots = configEntry.getValues("locationRoot");
        if (locationRoots != null) {
            for (String locationPath : locationRoots) {
                locationPath = this.resolvePath(configEntry, locationPath);
                locationPathFilters.add(locationPath);
            }
        }
        return locationPathFilters;
    }

    private String resolvePath(ConfigEntry configEntry, String path) {
        String contentPath = path;
        if (path.startsWith("..") || path.startsWith(".")) {
            contentPath = configEntry.getPath() + "/" + path;
            this.log.debug("Configured path '" + path + "' resolved to '" + contentPath + "'");
        }
        return contentPath;
    }

    private class ProxyRequest {
        private String offerPath;
        private String cachePath;
        private boolean processingImages;

        public ProxyRequest(String offerPath, String cachePath) {
            this.processingImages = false;
            this.offerPath = offerPath;
            this.cachePath = cachePath;
        }

        public String getCachePath() {
            return this.cachePath;
        }

        public String getOfferPath() {
            return this.offerPath;
        }

        public void setProcessingAssets(boolean processingImages) {
            this.processingImages = processingImages;
        }

        public boolean isProcessingAssets() {
            return this.processingImages;
        }
    }

}