All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.dam.handler.standard.keynote.KeynoteHandler Maven / Gradle / Ivy

package com.day.cq.dam.handler.standard.keynote;

import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.DamConstants;
import com.day.cq.dam.api.Rendition;
import com.day.cq.dam.api.metadata.ExtractedMetadata;
import com.day.cq.dam.commons.handler.AbstractAssetHandler;
import com.day.image.Layer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

import javax.jcr.Node;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * The KeynoteHandler  is able to extract keynote 5 slides.
 */
@Component(inherit = true, metatype = false)
@Service
public class KeynoteHandler extends AbstractAssetHandler {

    /**
     * the default logger
     */
    private static final Logger log = LoggerFactory.getLogger(KeynoteHandler.class);

    /**
     * Mime type(s)
     */
    public static final String[] CONTENT_MIMETYPES = {
            "application/x-iWork-keynote-sffkey",
            "application/x-iwork-keynote-sffkey",
            "application/vnd.apple.keynote"};

    // ----------------------< AssetHandler >-----------------------------------
    /**
     * {@inheritDoc}
     */
    public ExtractedMetadata extractMetadata(final Asset asset) {
        ExtractedMetadata metadata = new ExtractedMetadata();
        log.debug("extractMetadata: importing asset [{}]", asset.getPath());

        // extract metadata
        InputStream is = asset.getOriginal().getStream();

        try {
            KeynotePresentation preso = new KeynotePresentation(is);
            metadata.setMetaDataProperty("tiff:ImageLength", preso.getHeight());
            metadata.setMetaDataProperty("tiff:ImageWidth", preso.getWidth());
            metadata.setMetaDataProperty("Slide Count", preso.getSlides().size());
        } catch (SAXException e) {
            log.warn("extractMetadata: error while extracting metadata from Keynote [{}]: ", asset.getPath(), e);
        } catch (IOException e) {
            log.warn("extractMetadata: error while extracting metadata from Keynote [{}]: ", asset.getPath(), e);
        } catch (ParserConfigurationException e) {
            log.warn("extractMetadata: error while extracting metadata from Keynote [{}]: ", asset.getPath(), e);
        } finally {
            IOUtils.closeQuietly(is);
        }

        //Get XMP
        execGenericProcessor(asset.getOriginal().getStream(), metadata);

        setMimetype(metadata, asset);
        return metadata;
    }

    /**
     * {@inheritDoc}
     */
    public boolean canHandleSubAssets() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public List processSubAssets(final Asset asset) {
        List subAssets = new ArrayList();
        if (asset.isSubAsset()) {
            // we do not continue processing here, otherwise we would enter an endless
            // processing stack
            return subAssets;
        }

        InputStream is = asset.getOriginal().getStream();
        InputStream isp = null;
        ByteArrayOutputStream out = null;
        InputStream ois = null;

        try {
            KeynotePresentation preso = new KeynotePresentation(is);
            List slides = preso.getSlides();

            // changes made to the asset are not saved until manually later on.
            final boolean oldBatchMode = asset.isBatchMode();
            asset.setBatchMode(true);

            int i = 0;
            for (KeynoteSlide slide : slides) {

                if (!slide.isHidden()) {
                    i++;

                    isp = asset.getOriginal().getStream();
                    KeynotePresentation p = new KeynotePresentation(isp);
                    List pslides = p.getSlides();
                    for (KeynoteSlide s: pslides) {
                        if (!slide.getId().equals(s.getId())) {
                            p.removeSlide(s);
                        }
                    }

                    out = new ByteArrayOutputStream();
                    p.save(out);
                    ois = new ByteArrayInputStream(out.toByteArray());

                    // create subasset
                    final String fileName = "page" + (i + 1) + ".key";
                    final Asset subAsset = asset.addSubAsset(fileName, CONTENT_MIMETYPES[0], ois);
                    subAssets.add(subAsset.getPath());
                }
            }

            // now save the changes made to the asset.
            asset.adaptTo(Node.class).getSession().save();
            asset.setBatchMode(oldBatchMode);

        } catch (Exception e) {
            log.warn("processSubAssets: error while creating sub assets for asset [{}]: ", asset.getPath(), e);
        } finally {
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(isp);
            IOUtils.closeQuietly(out);
            IOUtils.closeQuietly(ois);
        }
        return subAssets;
    }

    /**
     * {@inheritDoc}
     */
    public String[] getMimeTypes() {
        return CONTENT_MIMETYPES;
    }

    /**
     * {@inheritDoc}
     */
    public BufferedImage getImage(final Rendition rendition) throws IOException {
        return getImage(rendition, null);
    }
    /**
     * {@inheritDoc}
     */
    public BufferedImage getImage(final Rendition rendition, Dimension dim) throws IOException {
        final InputStream is = rendition.getStream();

        try {
            KeynotePresentation preso = new KeynotePresentation(is);

            Layer layer;
            // workaround since the gfx lib sometimes is not able to resize images (BufferedImage!!)
            FileOutputStream itout = null;
            InputStream iis = null;
            File imageTmpFile = null;
            try {
                imageTmpFile = File.createTempFile("image", ".tmp");
                layer = new Layer(preso.getThumbnail());
                itout = FileUtils.openOutputStream(imageTmpFile);
                layer.write(DamConstants.THUMBNAIL_MIMETYPE, 1.0, itout);
                iis = FileUtils.openInputStream(imageTmpFile);
                return (new Layer(iis, dim)).getImage();
            } catch (Exception e) {
                log.info("getImage: cannot extract image for file [{}]: ", rendition.getPath(), e);
            } finally {
                IOUtils.closeQuietly(iis);
                IOUtils.closeQuietly(itout);
                FileUtils.deleteQuietly(imageTmpFile);
            }
        } catch (Exception e) {
            log.warn("getImage: error while creating image from Keynote [{}]: ", rendition.getPath(), e);
        } finally {
            IOUtils.closeQuietly(is);
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy