MobilePageAssetsUpdateHandler.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.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.foundation.Download
 *  com.day.cq.wcm.foundation.Image
 *  com.day.cq.wcm.foundation.WCMRenditionPicker
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.servlet.ServletException
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.jackrabbit.util.Text
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceResolverFactory
 *  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.mobile.platform.impl.contentsync.handler;

import com.adobe.cq.mobile.platform.impl.contentsync.handler.ResourceVisitor;
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.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.foundation.Download;
import com.day.cq.wcm.foundation.Image;
import com.day.cq.wcm.foundation.WCMRenditionPicker;
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 javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
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/mobilepageassets", inherit=1)
@Service
public class MobilePageAssetsUpdateHandler
extends AbstractSlingResourceUpdateHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(MobilePageAssetsUpdateHandler.class);
    private static String DEFAULT_IMAGE_SELECTOR = ".img";
    protected static final String PN_INCLUDE_PAGE_THUMB = "includePageThumbnail";
    @Property(value={"foundation/components/image"}, cardinality=Integer.MAX_VALUE)
    private static final String IMAGE_RESOURCE_TYPES = "cq.pagesupdatehandler.imageresourcetypes";
    private String[] imageResourceTypes;

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

    public boolean updateCacheEntry(ConfigEntry configEntry, Long lastUpdated, String configCacheRoot, Session adminSession, Session userSession) {
        configCacheRoot = this.getConfigCacheRoot(configEntry, configCacheRoot);
        boolean modified = false;
        try {
            HashMap<String, Session> bits = new HashMap<String, Session>(1);
            bits.put("user.jcr.session", userSession);
            ResourceResolver resolver = this.resourceResolverFactory.getResourceResolver(bits);
            Page rootPage = ((PageManager)resolver.adaptTo(PageManager.class)).getPage(this.getResolvedContentPath(configEntry));
            boolean deep = true;
            ValueMap configOptions = ResourceUtil.getValueMap((Resource)resolver.getResource(configEntry.getPath()));
            boolean includePageImage = (Boolean)configOptions.get("includePageThumbnail", (Object)true);
            if (this.isModified(rootPage, lastUpdated, configCacheRoot, adminSession)) {
                boolean bl = modified = this.collectAssets(rootPage, includePageImage, configCacheRoot, adminSession, userSession) || modified;
            }
            if (deep) {
                boolean bl = modified = this.updateCacheEntryWithChildren(rootPage, includePageImage, lastUpdated, configCacheRoot, adminSession, adminSession) || modified;
            }
            if (modified) {
                adminSession.save();
            }
        }
        catch (Exception ex) {
            LOGGER.error("Unexpected error while updating cache for config: " + configEntry.getPath(), (Throwable)ex);
        }
        return modified;
    }

    private boolean updateCacheEntryWithChildren(Page parentPage, boolean includePageImage, Long lastUpdated, String configCacheRoot, Session adminSession, Session userSession) throws Exception {
        boolean modified = false;
        Iterator children = parentPage.listChildren();
        while (children.hasNext()) {
            Page childPage = (Page)children.next();
            if (this.isModified(childPage, lastUpdated, configCacheRoot, adminSession)) {
                modified = this.collectAssets(childPage, includePageImage, configCacheRoot, adminSession, userSession) || modified;
            }
            modified = this.updateCacheEntryWithChildren(childPage, includePageImage, lastUpdated, configCacheRoot, adminSession, adminSession) || modified;
        }
        return modified;
    }

    private boolean isModified(Page page, Long lastUpdated, String configCacheRoot, Session session) throws RepositoryException {
        if (page.getContentResource().getResourceType() == null || page.getContentResource().getResourceType().equals("cq:PageContent")) {
            return false;
        }
        if (!session.nodeExists(configCacheRoot + page.getPath())) {
            return true;
        }
        Calendar cal = page.getLastModified();
        if (cal == null) {
            String ct = page.getContentResource().getResourceType();
            cal = (Calendar)page.getProperties().get("jcr:created", Calendar.class);
        }
        if (cal != null) {
            long lastModified = cal.getTime().getTime();
            return lastUpdated < lastModified || lastModified == -1;
        }
        return true;
    }

    private boolean collectAssets(Page page, boolean includePageImage, String configCacheRoot, Session adminSession, Session userSession) throws RepositoryException {
        boolean modified = false;
        if (includePageImage) {
            try {
                Download download;
                Resource pageImageResource = page.getContentResource("./image");
                if (pageImageResource != null && ((download = new Download(pageImageResource)).hasContent() || StringUtils.isNotEmpty((String)download.getFileReference()))) {
                    String path = page.getPath() + ".img.png";
                    modified = this.renderResource(path, configCacheRoot, adminSession, userSession) || modified;
                }
            }
            catch (Exception ex) {
                LOGGER.error("Failed to extract page image", (Throwable)ex);
            }
        }
        ComponentVisitor visitor = new ComponentVisitor(configCacheRoot, adminSession, userSession);
        visitor.visit(page.getContentResource());
        return modified || visitor.madeChanges();
    }

    private boolean isA(Resource resource, String[] resourceTypes) {
        for (String type : resourceTypes) {
            LOGGER.debug("Testing resource against image type " + type + " for " + resource.getPath());
            if (!ResourceUtil.isA((Resource)resource, (String)type)) continue;
            LOGGER.debug("Resource was an image of type " + type + " for " + resource.getPath());
            return true;
        }
        LOGGER.debug("Resource was not an image of type " + resource.getResourceType() + " for " + resource.getPath());
        return false;
    }

    protected String getTargetPath(String path) {
        String newPath = StringUtils.replace((String)path, (String)"jcr:content", (String)"jcr_content");
        LOGGER.debug("Changing path: " + path + " to:" + newPath);
        return newPath;
    }

    private class ComponentVisitor
    extends ResourceVisitor {
        private static final String DOWNLOAD_RESOURCE_TYPE = "foundation/components/download";
        private String configCacheRoot;
        private Session adminSession;
        private Session userSession;
        private ResourceResolver resolver;
        private boolean madeChanges;

        public ComponentVisitor(String configCacheRoot, Session adminSession, Session userSession) {
            this.madeChanges = false;
            this.configCacheRoot = configCacheRoot;
            this.adminSession = adminSession;
            this.userSession = userSession;
            this.resolver = MobilePageAssetsUpdateHandler.this.resolverFactory.getResourceResolver(userSession);
        }

        boolean madeChanges() {
            return this.madeChanges;
        }

        @Override
        protected void accept(Resource res) {
            try {
                if (MobilePageAssetsUpdateHandler.this.isA(res, MobilePageAssetsUpdateHandler.this.imageResourceTypes)) {
                    LOGGER.debug("Image check passed for resource " + res.getPath());
                    Image image = new Image(res);
                    String selector = DEFAULT_IMAGE_SELECTOR;
                    LOGGER.debug("Adding image to content using selector " + selector + " for " + res.getPath());
                    image.setSelector(selector);
                    this.updateImageResource(image);
                } else if (ResourceUtil.isA((Resource)res, (String)"foundation/components/download")) {
                    Download download = new Download(res);
                    this.updateDownloadResource((DownloadResource)download);
                } else {
                    LOGGER.debug("Image check failed for resource " + res.getPath());
                }
            }
            catch (RepositoryException e) {
                LOGGER.error("Updating page dependencies failed: ", (Throwable)e);
            }
        }

        private void updateImageResource(Image image) {
            try {
                this.madeChanges = MobilePageAssetsUpdateHandler.this.renderResource(image.getHref(), this.configCacheRoot, this.adminSession, this.userSession) || this.madeChanges;
            }
            catch (Exception e) {
                LOGGER.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.userSession);
                        JcrUtil.copy((Node)((Node)rendition.adaptTo(Node.class)), (Node)parent, (String)Text.getName((String)download.getHref()));
                        this.madeChanges = true;
                    }
                } 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.userSession);
                        JcrUtil.copy((Node)((Node)srcRes.adaptTo(Node.class)), (Node)parent, (String)Text.getName((String)download.getHref()));
                        this.madeChanges = true;
                    }
                }
            }
        }
    }

}