ChannelsUpdateHandler.java 17.1 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.contentsync.config.ConfigEntry
 *  com.day.cq.contentsync.handler.AbstractSlingResourceUpdateHandler
 *  com.day.cq.contentsync.handler.util.RequestResponseFactory
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.Rendition
 *  com.day.cq.dam.video.VideoProfile
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMMode
 *  com.day.cq.wcm.api.designer.Design
 *  com.day.cq.wcm.api.designer.Designer
 *  com.day.cq.wcm.api.designer.Style
 *  com.day.cq.wcm.contentsync.PathRewriterOptions
 *  com.day.cq.wcm.contentsync.PathRewriterOptions$RewriteMode
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.servlet.ServletException
 *  javax.servlet.ServletRequest
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  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.OsgiUtil
 *  org.apache.sling.jcr.resource.JcrResourceResolverFactory
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.screens.impl.handler;

import com.day.cq.contentsync.config.ConfigEntry;
import com.day.cq.contentsync.handler.AbstractSlingResourceUpdateHandler;
import com.day.cq.contentsync.handler.util.RequestResponseFactory;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import com.day.cq.dam.video.VideoProfile;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMMode;
import com.day.cq.wcm.api.designer.Design;
import com.day.cq.wcm.api.designer.Designer;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.contentsync.PathRewriterOptions;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
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.OsgiUtil;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, factory="com.day.cq.contentsync.handler.ContentUpdateHandler/channels", inherit=1)
public class ChannelsUpdateHandler
extends AbstractSlingResourceUpdateHandler {
    private static final Logger log = LoggerFactory.getLogger(ChannelsUpdateHandler.class);
    @Property(value={"screens/core/components/content/image"}, cardinality=Integer.MAX_VALUE)
    private static final String IMAGE_RESOURCE_TYPES = "cq.pagesupdatehandler.imageresourcetypes";
    @Property(value={"screens/core/components/content/product"}, cardinality=Integer.MAX_VALUE)
    private static final String PRODUCT_RESOURCE_TYPES = "cq.pagesupdatehandler.productresourcetypes";
    @Property(value={"screens/core/components/content/video"}, cardinality=Integer.MAX_VALUE)
    private static final String VIDEO_RESOURCE_TYPES = "cq.pagesupdatehandler.videoresourcetypes";
    private static final String IMAGES_CONFIG_PROPERTY = "includeImages";
    private static final String PRODUCTS_CONFIG_PROPERTY = "includeProducts";
    private static final String VIDEOS_CONFIG_PROPERTY = "includeVideos";
    private static final String EXTENSION_CONFIG_PROPERTY = "extension";
    private static final String SELECTOR_CONFIG_PROPERTY = "selector";
    private static final String SUFFIX_CONFIG_PROPERTY = "pathSuffix";
    private static final String DEEP_CONFIG_PROPERTY = "deep";
    private static final String DEFAULT_REWRITE_MODE = PathRewriterOptions.RewriteMode.REWRITE_RELATIVE.name();
    private PathRewriterOptions options;
    private Map<String, Object> params;
    private String[] imageResourceTypes;
    private String[] productResourceTypes;
    private String[] videoResourceTypes;

    @Activate
    protected void activate(ComponentContext context) {
        this.imageResourceTypes = OsgiUtil.toStringArray(context.getProperties().get("cq.pagesupdatehandler.imageresourcetypes"));
        this.productResourceTypes = OsgiUtil.toStringArray(context.getProperties().get("cq.pagesupdatehandler.productresourcetypes"));
        this.videoResourceTypes = OsgiUtil.toStringArray(context.getProperties().get("cq.pagesupdatehandler.videoresourcetypes"));
    }

    protected HttpServletRequest createRequest(String uri) {
        HttpServletRequest request = this.requestResponseFactory.createRequest("GET", uri, this.params);
        WCMMode.DISABLED.toRequest((ServletRequest)request);
        request.setAttribute("pathRewritingOptions", (Object)this.options);
        return request;
    }

    public boolean updateCacheEntry(ConfigEntry configEntry, Long lastUpdated, String configCacheRoot, Session admin, Session session) {
        configCacheRoot = this.getConfigCacheRoot(configEntry, configCacheRoot);
        ResourceResolver resolver = this.resolverFactory.getResourceResolver(session);
        Page rootPage = ((PageManager)resolver.adaptTo(PageManager.class)).getPage(configEntry.getContentPath());
        boolean modified = false;
        ValueMap configOptions = ResourceUtil.getValueMap((Resource)resolver.getResource(configEntry.getPath()));
        boolean deep = (Boolean)configOptions.get("deep", (Object)true);
        boolean includeImages = (Boolean)configOptions.get("includeImages", (Object)true);
        boolean includeProducts = (Boolean)configOptions.get("includeProducts", (Object)true);
        boolean includeVideos = (Boolean)configOptions.get("includeVideos", (Object)true);
        this.createPathRewritingOptions(configEntry, resolver);
        this.createParameterMap(configEntry, resolver);
        try {
            String uri = ChannelsUpdateHandler.buildURI(configEntry, rootPage);
            if (this.isModified(rootPage, uri, lastUpdated, configCacheRoot, admin)) {
                this.renderResource(uri, configCacheRoot, admin, session);
                this.collectAssets(includeImages, includeProducts, includeVideos, rootPage, configCacheRoot, admin, session);
                admin.save();
                modified = true;
            }
            if (deep) {
                modified = this.renderChildren(configEntry, rootPage.listChildren(), lastUpdated, configCacheRoot, admin, session, includeImages, includeProducts, includeVideos) || modified;
            }
        }
        catch (Exception e) {
            log.error("Rendering page failed: ", (Throwable)e);
        }
        return modified;
    }

    private void createPathRewritingOptions(ConfigEntry configEntry, ResourceResolver resolver) {
        ValueMap rewrite = ResourceUtil.getValueMap((Resource)resolver.getResource(configEntry.getPath() + "/rewrite"));
        this.options = new PathRewriterOptions(PathRewriterOptions.RewriteMode.valueOf((String)((String)rewrite.get("links", (Object)DEFAULT_REWRITE_MODE))), PathRewriterOptions.RewriteMode.valueOf((String)((String)rewrite.get("clientlibs", (Object)DEFAULT_REWRITE_MODE))), PathRewriterOptions.RewriteMode.valueOf((String)((String)rewrite.get("images", (Object)DEFAULT_REWRITE_MODE))));
    }

    private void createParameterMap(ConfigEntry configEntry, ResourceResolver resolver) {
        ValueMap values = ResourceUtil.getValueMap((Resource)resolver.getResource(configEntry.getPath() + "/parameters"));
        this.params = new HashMap<String, Object>();
        for (String key : values.keySet()) {
            if (key.startsWith("jcr:")) continue;
            String value = (String)values.get(key, String.class);
            if (value != null) {
                this.params.put(key, value);
                continue;
            }
            this.params.put(key, values.get(key, String[].class));
        }
    }

    private boolean renderChildren(ConfigEntry configEntry, Iterator<Page> children, Long lastUpdated, String configCacheRoot, Session admin, Session session, boolean includeImages, boolean includeProducts, boolean includeVideos) throws Exception {
        boolean modified = false;
        while (children.hasNext()) {
            String uri;
            Page childPage = children.next();
            if (this.isModified(childPage, uri = ChannelsUpdateHandler.buildURI(configEntry, childPage), lastUpdated, configCacheRoot, admin)) {
                this.renderResource(uri, configCacheRoot, admin, session);
                this.collectAssets(includeImages, includeProducts, includeVideos, childPage, configCacheRoot, admin, session);
                session.save();
                modified = true;
            }
            modified = this.renderChildren(configEntry, childPage.listChildren(), lastUpdated, configCacheRoot, admin, session, includeImages, includeProducts, includeVideos) || modified;
        }
        return modified;
    }

    private static String buildURI(ConfigEntry entry, Page page) {
        String uri = page.getPath();
        if (entry.getValue("pathSuffix") != null) {
            uri = uri + entry.getValue("pathSuffix");
        }
        if (entry.getValue("selector") != null) {
            uri = uri + "." + entry.getValue("selector");
        }
        if (entry.getValue("extension") != null) {
            uri = uri + "." + entry.getValue("extension");
        }
        return uri;
    }

    private boolean isModified(Page page, String uri, Long lastUpdated, String configCacheRoot, Session session) throws RepositoryException {
        if (!session.nodeExists(configCacheRoot + uri)) {
            return true;
        }
        Calendar cal = page.getLastModified();
        if (cal != null) {
            long lastModified = cal.getTime().getTime();
            return lastUpdated < lastModified || lastModified == -1;
        }
        return true;
    }

    private void collectAssets(boolean includeImages, boolean includeProducts, boolean includeVideos, Page page, String configCacheRoot, Session admin, Session session) throws RepositoryException {
        if (!includeImages && !includeVideos) {
            return;
        }
        AssetComponentVisitor visitor = new AssetComponentVisitor(includeImages ? this.imageResourceTypes : null, includeProducts ? this.productResourceTypes : null, includeVideos ? this.videoResourceTypes : null, page, configCacheRoot, admin, session);
        visitor.visit(page.getContentResource());
    }

    private class AssetComponentVisitor {
        private String[] imageResourceTypes;
        private String[] productResourceTypes;
        private String[] videoResourceTypes;
        private Page page;
        private String configCacheRoot;
        private Session admin;
        private Session session;
        private ResourceResolver resolver;

        AssetComponentVisitor(String[] imageResourceTypes, String[] productResourceTypes, String[] videoResourceTypes, Page page, String configCacheRoot, Session admin, Session session) {
            this.imageResourceTypes = imageResourceTypes;
            this.productResourceTypes = productResourceTypes;
            this.videoResourceTypes = videoResourceTypes;
            this.page = page;
            this.configCacheRoot = configCacheRoot;
            this.admin = admin;
            this.session = session;
            this.resolver = ChannelsUpdateHandler.this.resolverFactory.getResourceResolver(session);
        }

        private boolean isA(Resource resource, String[] resourceTypes) {
            for (String type : resourceTypes) {
                if (!this.resolver.isResourceType(resource, type)) continue;
                return true;
            }
            return false;
        }

        private void visit(Resource res) {
            if (res != null) {
                this.accept(res);
                this.traverseChildren(res.listChildren());
            }
        }

        private void traverseChildren(Iterator<Resource> children) {
            while (children.hasNext()) {
                Resource child = children.next();
                this.accept(child);
                this.traverseChildren(child.listChildren());
            }
        }

        private void accept(Resource res) {
            ValueMap properties;
            if (this.imageResourceTypes != null && this.isA(res, this.imageResourceTypes)) {
                properties = (ValueMap)res.adaptTo(ValueMap.class);
                if (properties == null) {
                    return;
                }
                String imagePath = (String)properties.get("fileReference", String.class);
                if (imagePath == null) {
                    return;
                }
                try {
                    ChannelsUpdateHandler.this.renderResource(imagePath, this.configCacheRoot, this.admin, this.session);
                }
                catch (Exception e) {
                    log.error("Rendering image resource failed: ", (Throwable)e);
                }
            }
            if (this.productResourceTypes != null && this.isA(res, this.productResourceTypes)) {
                properties = (ValueMap)res.adaptTo(ValueMap.class);
                if (properties == null) {
                    return;
                }
                String[] productPaths = (String[])properties.get("products", String[].class);
                if (productPaths == null) {
                    String productPath = (String)properties.get("product", String.class);
                    if (productPath == null) {
                        return;
                    }
                    productPaths = new String[]{productPath};
                }
                for (String productPath : productPaths) {
                    Resource productImageResource = this.resolver.getResource(productPath + "/image");
                    if (productImageResource == null) {
                        return;
                    }
                    ValueMap productImageProperties = (ValueMap)productImageResource.adaptTo(ValueMap.class);
                    if (productImageProperties == null) {
                        return;
                    }
                    String productImagePath = (String)productImageProperties.get("fileReference", String.class);
                    if (productImagePath == null) {
                        return;
                    }
                    try {
                        ChannelsUpdateHandler.this.renderResource(productImagePath, this.configCacheRoot, this.admin, this.session);
                        continue;
                    }
                    catch (Exception e) {
                        log.error("Rendering image resource failed: ", (Throwable)e);
                    }
                }
            }
            if (this.videoResourceTypes != null && this.isA(res, this.videoResourceTypes)) {
                Style currentStyle;
                properties = (ValueMap)res.adaptTo(ValueMap.class);
                if (properties == null) {
                    return;
                }
                String videoPath = (String)properties.get("asset", String.class);
                if (videoPath == null) {
                    return;
                }
                Resource videoResource = this.resolver.getResource(videoPath);
                if (videoResource == null) {
                    return;
                }
                Asset videoAsset = (Asset)videoResource.adaptTo(Asset.class);
                if (videoAsset == null) {
                    return;
                }
                Designer designer = (Designer)this.resolver.adaptTo(Designer.class);
                Design currentDesign = designer == null ? null : designer.getDesign(this.page);
                Style style = currentStyle = currentDesign == null ? null : currentDesign.getStyle(res);
                if (currentStyle == null) {
                    return;
                }
                for (String profile : (String[])currentStyle.get("profiles", (Object)new String[0])) {
                    Rendition rendition;
                    VideoProfile videoProfile = VideoProfile.get((ResourceResolver)this.resolver, (String)profile);
                    if (videoProfile == null || (rendition = videoProfile.getRendition(videoAsset)) == null) continue;
                    try {
                        ChannelsUpdateHandler.this.renderResource(videoProfile.getHtmlSource(rendition), this.configCacheRoot, this.admin, this.session);
                        continue;
                    }
                    catch (Exception e) {
                        log.error("Rendering video resource failed: ", (Throwable)e);
                    }
                }
            }
        }
    }

}