PagesUpdateHandler.java 13.1 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.DownloadResource
 *  com.day.cq.commons.jcr.JcrUtil
 *  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.api.RenditionPicker
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMMode
 *  com.day.cq.wcm.foundation.Download
 *  com.day.cq.wcm.foundation.Image
 *  com.day.cq.wcm.foundation.WCMRenditionPicker
 *  com.day.text.Text
 *  javax.jcr.Node
 *  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.day.cq.wcm.contentsync.impl.handler;

import com.day.cq.commons.DownloadResource;
import com.day.cq.commons.jcr.JcrUtil;
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.api.RenditionPicker;
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.contentsync.PathRewriterOptions;
import com.day.cq.wcm.contentsync.impl.handler.ResourceVisitor;
import com.day.cq.wcm.foundation.Download;
import com.day.cq.wcm.foundation.Image;
import com.day.cq.wcm.foundation.WCMRenditionPicker;
import com.day.text.Text;
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.Node;
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/pages", inherit=1)
public class PagesUpdateHandler
extends AbstractSlingResourceUpdateHandler {
    private static final Logger log = LoggerFactory.getLogger(PagesUpdateHandler.class);
    @Property(value={"foundation/components/image"}, cardinality=Integer.MAX_VALUE)
    private static final String IMAGE_RESOURCE_TYPES = "cq.pagesupdatehandler.imageresourcetypes";
    private static final String EXTENSION_CONFIG_PROPERTY = "extension";
    private static final String SELECTOR_CONFIG_PROPERTY = "selector";
    private static final String DEEP_CONFIG_PROPERTY = "deep";
    private static final String IMAGES_CONFIG_PROPERTY = "includeImages";
    private static final String DEFAULT_REWRITE_MODE = PathRewriterOptions.RewriteMode.REWRITE_RELATIVE.name();
    private PathRewriterOptions options;
    private Map<String, Object> params;
    private String[] imageResourceTypes;

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

    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);
        this.createPathRewritingOptions(configEntry, resolver);
        this.createParameterMap(configEntry, resolver);
        try {
            String uri = PagesUpdateHandler.buildURI(configEntry, rootPage);
            if (this.isModified(rootPage, uri, lastUpdated, configCacheRoot, admin)) {
                this.renderResource(uri, configCacheRoot, admin, session);
                if (includeImages) {
                    this.collectImages(rootPage, configCacheRoot, admin, session);
                }
                admin.save();
                modified = true;
            }
            if (deep) {
                modified = this.renderChildren(configEntry, rootPage.listChildren(), lastUpdated, configCacheRoot, admin, session, includeImages) || 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)rewrite.get("links", (Object)DEFAULT_REWRITE_MODE)), PathRewriterOptions.RewriteMode.valueOf((String)rewrite.get("clientlibs", (Object)DEFAULT_REWRITE_MODE)), PathRewriterOptions.RewriteMode.valueOf((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) throws Exception {
        boolean modified = false;
        while (children.hasNext()) {
            String uri;
            Page childPage = children.next();
            if (this.isModified(childPage, uri = PagesUpdateHandler.buildURI(configEntry, childPage), lastUpdated, configCacheRoot, admin)) {
                this.renderResource(uri, configCacheRoot, admin, session);
                if (includeImages) {
                    this.collectImages(childPage, configCacheRoot, admin, session);
                }
                session.save();
                modified = true;
            }
            modified = this.renderChildren(configEntry, childPage.listChildren(), lastUpdated, configCacheRoot, admin, session, includeImages) || modified;
        }
        return modified;
    }

    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 collectImages(Page page, String configCacheRoot, Session admin, Session session) throws RepositoryException {
        ComponentVisitor visitor = new ComponentVisitor(configCacheRoot, admin, session);
        visitor.visit(page.getContentResource());
    }

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

    private class ComponentVisitor
    extends ResourceVisitor {
        private static final String DOWNLOAD_RESOURCE_TYPE = "foundation/components/download";
        private String configCacheRoot;
        private Session admin;
        private Session session;
        private ResourceResolver resolver;

        public ComponentVisitor(String configCacheRoot, Session admin, Session session) {
            this.configCacheRoot = configCacheRoot;
            this.admin = admin;
            this.session = session;
            this.resolver = PagesUpdateHandler.this.resolverFactory.getResourceResolver(session);
        }

        @Override
        protected void accept(Resource res) {
            try {
                if (this.isA(res, PagesUpdateHandler.this.imageResourceTypes)) {
                    Image image = new Image(res);
                    image.setSelector(".img");
                    this.updateImageResource(image);
                } else if (ResourceUtil.isA((Resource)res, (String)"foundation/components/download")) {
                    Download download = new Download(res);
                    this.updateDownloadResource((DownloadResource)download);
                }
            }
            catch (RepositoryException e) {
                log.error("Updating page dependencies failed: ", (Throwable)e);
            }
        }

        private void updateImageResource(Image image) {
            try {
                PagesUpdateHandler.this.renderResource(image.getHref(), this.configCacheRoot, this.admin, this.session);
            }
            catch (Exception e) {
                log.error("Rendering image resource failed: ", (Throwable)e);
            }
        }

        private void updateDownloadResource(DownloadResource download) throws RepositoryException {
            if (download.hasContent()) {
                String srcPath = download.getFileReference();
                if (!srcPath.equals("")) {
                    Rendition rendition;
                    Resource srcRes = this.resolver.getResource(srcPath);
                    if (srcRes != null && srcRes.adaptTo(Asset.class) != null && (rendition = ((Asset)srcRes.adaptTo(Asset.class)).getRendition((RenditionPicker)new WCMRenditionPicker())) != null && rendition.adaptTo(Node.class) != null) {
                        String cacheParentPath = this.configCacheRoot + Text.getRelativeParent((String)download.getHref(), (int)1);
                        Node parent = JcrUtil.createPath((String)cacheParentPath, (String)"sling:Folder", (Session)this.session);
                        JcrUtil.copy((Node)((Node)rendition.adaptTo(Node.class)), (Node)parent, (String)Text.getName((String)download.getHref()));
                    }
                } else {
                    srcPath = download.getFileNodePath();
                    Resource srcRes = this.resolver.getResource(srcPath);
                    if (srcRes != null) {
                        String cacheParentPath = this.configCacheRoot + Text.getRelativeParent((String)download.getHref(), (int)1);
                        Node parent = JcrUtil.createPath((String)cacheParentPath, (String)"sling:Folder", (Session)this.session);
                        JcrUtil.copy((Node)((Node)srcRes.adaptTo(Node.class)), (Node)parent, (String)Text.getName((String)download.getHref()));
                    }
                }
            }
        }

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

}