MobilePageVideoAssetsUpdateHandler.java 11.8 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.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.foundation.Download
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.ValueFactory
 *  javax.servlet.ServletException
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Service
 *  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.jcr.resource.JcrResourceResolverFactory
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.mobile.platform.impl.contentsync.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.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.foundation.Download;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.servlet.ServletException;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
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.jcr.resource.JcrResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(factory="com.day.cq.contentsync.handler.ContentUpdateHandler/videoassetsupdatehandler", inherit=1)
@Service
public class MobilePageVideoAssetsUpdateHandler
extends AbstractSlingResourceUpdateHandler {
    protected static final String VIDEO_FILE_SUFFIX = ".original.mp4";
    protected static final String VIDEO_POSTER_FILE_SUFFIX = ".thumb.100.140.png";
    private static final Logger log = LoggerFactory.getLogger(MobilePageVideoAssetsUpdateHandler.class);
    private static final String COMPONENT_VIDEO = "mobileapps/components/mobilevideo";
    private static Set<String> COMPONENTS_TO_SUPPORT = new HashSet<String>();
    private static final String PN_ASSET_REFERENCE_URL_OVERRIDE = "asset";
    private boolean updated = false;
    private String fileNameBase = null;

    public boolean updateCacheEntry(ConfigEntry configEntry, Long lastUpdated, String configCacheRoot, Session adminSession, Session userSession) {
        log.debug("Updating cache @ " + configCacheRoot + " as user " + userSession.getUserID());
        configCacheRoot = this.getConfigCacheRoot(configEntry, configCacheRoot);
        boolean modified = false;
        try {
            ResourceResolver resolver = this.resolverFactory.getResourceResolver(userSession);
            Page rootPage = ((PageManager)resolver.adaptTo(PageManager.class)).getPage(this.getResolvedContentPath(configEntry));
            this.updateCache(rootPage, configCacheRoot, adminSession, userSession);
            if (this.updated) {
                adminSession.save();
                modified = true;
            }
        }
        catch (Exception ex) {
            log.error("Unexpected error while updating cache for config: " + configEntry.getPath(), (Throwable)ex);
        }
        return modified;
    }

    protected String getTargetPath(String path) {
        return "/" + this.fileNameBase + ".thumb.100.140.png";
    }

    private void updateCache(Page page, String configCacheRoot, Session adminSession, Session userSession) throws RepositoryException {
        log.debug("Extracting assets from page {}:{}", (Object)page.getName(), (Object)page.getPath());
        this.collectAssets(page, configCacheRoot, adminSession, userSession);
        Iterator childPagesIter = page.listChildren();
        while (childPagesIter.hasNext()) {
            Page childPage = (Page)childPagesIter.next();
            log.debug("Extracting assets from sub page {}:{}", (Object)childPage.getName(), (Object)childPage.getPath());
            this.updateCache(childPage, configCacheRoot, adminSession, userSession);
        }
    }

    private void collectAssets(Page page, String configCacheRoot, Session adminSession, Session userSession) throws RepositoryException {
        ComponentVisitor visitor = new ComponentVisitor(configCacheRoot, adminSession, userSession);
        visitor.visit(page.getContentResource());
    }

    static {
        COMPONENTS_TO_SUPPORT.add("mobileapps/components/mobilevideo");
    }

    private class ComponentVisitor
    extends ResourceVisitor {
        private String configCacheRoot;
        private Session adminSession;
        private Session userSession;
        private ResourceResolver resolver;

        public ComponentVisitor(String configCacheRoot, Session adminSession, Session userSession) {
            super();
            this.configCacheRoot = configCacheRoot;
            this.adminSession = adminSession;
            this.userSession = userSession;
            this.resolver = MobilePageVideoAssetsUpdateHandler.this.resolverFactory.getResourceResolver(userSession);
        }

        @Override
        protected void accept(Resource resource) {
            try {
                for (String componentPath : COMPONENTS_TO_SUPPORT) {
                    if (ResourceUtil.isA((Resource)resource, (String)componentPath)) {
                        ValueMap properties = (ValueMap)resource.adaptTo(ValueMap.class);
                        boolean copyToDevice = (Boolean)properties.get("copyToDevice", (Object)false);
                        log.debug("Extracting {} : {}", (Object)componentPath, (Object)resource.getPath());
                        Download download = new Download(resource);
                        this.addToExportCache((DownloadResource)download, copyToDevice);
                        MobilePageVideoAssetsUpdateHandler.this.updated = true;
                        continue;
                    }
                    log.debug("Ignoring resource " + resource.getPath());
                }
            }
            catch (RepositoryException ex) {
                log.error("Updating export data failed: ", (Throwable)ex);
            }
        }

        private void addToExportCache(DownloadResource download, boolean includeVideo) throws RepositoryException {
            if (!download.hasContent()) {
                download.setItemName("fileReference", "asset");
            }
            if (download.hasContent()) {
                Resource srcRes;
                String srcDAMPath = download.getFileReference();
                if (srcDAMPath != null && !srcDAMPath.equals("") && (srcRes = this.resolver.getResource(srcDAMPath)) != null && srcRes.adaptTo(Node.class) != null) {
                    String mimeType;
                    Node renditionNode;
                    String resourcePath = download.getResource().getParent().getPath();
                    MobilePageVideoAssetsUpdateHandler.this.fileNameBase = download.getResource().getName();
                    resourcePath = resourcePath.replaceAll("/jcr:content/", "/jcr_content/");
                    String cacheParentPath = this.configCacheRoot + resourcePath;
                    Asset asset = (Asset)srcRes.adaptTo(Asset.class);
                    Rendition rendition = asset.getRendition("cq5dam.video.iehq.mp4");
                    if (rendition == null) {
                        rendition = ((Asset)srcRes.adaptTo(Asset.class)).getOriginal();
                    }
                    Node parent = JcrUtil.createPath((String)cacheParentPath, (String)"sling:Folder", (Session)this.adminSession);
                    if (includeVideo && !this.videoAlreadyExists((renditionNode = (Node)rendition.adaptTo(Node.class)).getNode("jcr:content"), parent, MobilePageVideoAssetsUpdateHandler.this.fileNameBase + ".original.mp4")) {
                        Node videoNode = JcrUtil.copy((Node)renditionNode, (Node)parent, (String)(MobilePageVideoAssetsUpdateHandler.this.fileNameBase + ".original.mp4"));
                        this.adminSession.save();
                        this.updateLastModifiedBy(videoNode.getNode("jcr:content"));
                    }
                    if ((mimeType = rendition.getMimeType()) != null && mimeType.startsWith("video")) {
                        String assetPath = srcRes.getPath() + ".thumb.100.140.png";
                        log.debug("Adding video to content using selector " + assetPath + " for " + srcRes.getPath());
                        this.updateVideoResource(cacheParentPath, assetPath);
                    }
                }
            } else {
                log.debug("Nothing to export from " + download.getPath());
            }
            MobilePageVideoAssetsUpdateHandler.this.fileNameBase = null;
        }

        private void updateVideoResource(String cacheDestination, String videoURL) {
            try {
                MobilePageVideoAssetsUpdateHandler.this.renderResource(videoURL, cacheDestination, this.adminSession, this.userSession);
            }
            catch (Exception e) {
                log.error("Rendering video resource failed: ", (Throwable)e);
            }
        }

        private void updateLastModifiedBy(Node contentNode) {
            try {
                ValueFactory valueFactory = this.adminSession.getValueFactory();
                Value now = valueFactory.createValue(Calendar.getInstance());
                contentNode.setProperty("jcr:lastModified", now);
                Value userId = valueFactory.createValue(this.userSession.getUserID());
                contentNode.setProperty("jcr:lastModifiedBy", userId);
                this.adminSession.save();
            }
            catch (Exception ex) {
                log.error("Rendering video resource last-modified property' failed: ", (Throwable)ex);
            }
        }

        private boolean videoAlreadyExists(Node sourceContent, Node parentNode, String fileName) {
            boolean sameVideoExists = true;
            try {
                if (!parentNode.hasNode(fileName)) {
                    sameVideoExists = false;
                } else {
                    Node fileNode = parentNode.getNode(fileName);
                    Calendar srcLastModified = sourceContent.getProperty("jcr:lastModified").getDate();
                    Calendar dstLastModified = fileNode.getNode("jcr:content").getProperty("jcr:lastModified").getDate();
                    sameVideoExists = dstLastModified.compareTo(srcLastModified) >= 0;
                }
            }
            catch (Exception ex) {
                log.error("Error occurred comparing source and destination video: " + fileName, (Throwable)ex);
            }
            return sameVideoExists;
        }
    }

    public abstract class ResourceVisitor {
        public 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());
            }
        }

        protected abstract void accept(Resource var1);
    }

}