AEM 6580 - Assets Download Version from Timeline

Goal

AEM Assets provides version preview in the timeline, this post extends it to download specific asset version..

Not tested for performance, please test and improve for big asset version downloads....

Demo | Package Install | Github



Solution

1) Create a servlet apps.experienceaem.assets.AssetVersionDownloadServlet to download the specific version...

package apps.experienceaem.assets;

import opennlp.tools.util.StringUtil;
import org.apache.commons.io.IOUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.mime.MimeTypeService;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Node;
import javax.servlet.Servlet;
import java.io.InputStream;
import java.io.OutputStream;

@Component(
        service = Servlet.class,
        property = {
                Constants.SERVICE_DESCRIPTION + "= Experience AEM Download Asset Version Servlet",
                "sling.servlet.methods=" + HttpConstants.METHOD_GET,
                "sling.servlet.paths=" + "/bin/eaem/downloadVersion"
        }
)
public class AssetVersionDownloadServlet extends SlingAllMethodsServlet {
    private static final Logger log = LoggerFactory.getLogger(AssetVersionDownloadServlet.class);

    @Reference
    transient MimeTypeService mimeTypeService;

    protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) {
        ResourceResolver resolver = request.getResourceResolver();
        String resPath = request.getParameter("resource");

        Resource assetPathResource = resolver.getResource(resPath + "/jcr:frozenNode/jcr:content/renditions/original/jcr:content");

        if(assetPathResource == null){
            response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }

        Node fileNode = assetPathResource.adaptTo(Node.class);
        Resource jcrContent = resolver.getResource(resPath + "/jcr:frozenNode/jcr:content");
        String mimeType = getMIMEType(jcrContent);

        InputStream is = null;

        try{
            is = fileNode.getProperty("jcr:data").getBinary().getStream();

            String fileName = jcrContent.getValueMap().get("cq:name", "");

            if(StringUtil.isEmpty(fileName)){
                response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }

            response.setContentType(mimeType);
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

            final OutputStream out = response.getOutputStream();

            IOUtils.copy(is, out);

            out.close();

            is.close();
        }catch(Exception e){
            log.error("Error retrieving the version for " + resPath, e);
            response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    private String getMIMEType(Resource resource){
        String cqName = resource.getValueMap().get("cq:name", "");
        return mimeTypeService.getMimeType(cqName.substring(cqName.indexOf('.') + 1));
    }
}


2) Create a clientlib /apps/eaem-assets-download-version/clientlib with categories=cq.gui.coral.common.admin.timeline to add the Download Version button and necessary download logic...

(function($, $document) {
    var TIME_LINE_EVENT_CSS = ".cq-common-admin-timeline-event",
        EAEM_VERSION_CSS = "eaem-version",
        REVERT_TO_VERSION_SEL = ".cq-common-admin-timeline-event-button";

    $document.on("click", TIME_LINE_EVENT_CSS, addDownloadVersion);

    function addDownloadVersion(){
        var $timeLineButton = $(this).find(REVERT_TO_VERSION_SEL),
            $timelineForm = $timeLineButton.closest("form");

        if(!_.isEmpty($timelineForm.find("." + EAEM_VERSION_CSS))){
            return;
        }

        $(getDownloadButtonHtml()).appendTo($timelineForm).click(downloadVersion);
    }

    function downloadVersion(){
        var $dataPreview = $(this).closest("[data-preview]"),
            versionPath = $dataPreview.data("preview");

        versionPath = versionPath.substring(0, versionPath.indexOf("/jcr:frozenNode"));

        window.open("/bin/eaem/downloadVersion?resource=" + versionPath, '_blank');
    }

    function getDownloadButtonHtml(){
        return '<button is="coral-button" class="coral3-Button coral3-Button--secondary ' + EAEM_VERSION_CSS +
                    '" type="button" size="M" variant="secondary" style="width:100%; margin-top: 0.2rem;">' +
                    '<coral-button-label>Download Version</coral-button-label>' +
                '</button>'
    }
})(jQuery, jQuery(document));


No comments:

Post a Comment