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

com.day.cq.dam.commons.handler.AbstractAssetHandler Maven / Gradle / Ivy

/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.dam.commons.handler;

import static com.day.cq.commons.jcr.JcrConstants.JCR_CONTENT;
import static com.day.cq.dam.api.DamConstants.DC_FORMAT;
import static com.day.cq.dam.api.DamConstants.ORIGINAL_FILE;
import static com.day.cq.dam.api.DamConstants.PREFIX_ASSET_THUMBNAIL;
import static com.day.cq.dam.api.DamConstants.RENDITIONS_FOLDER;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.granite.asset.api.AssetRelation;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.AssetHandlerException;
import com.day.cq.dam.api.AssetManager;
import com.day.cq.dam.api.DamConstants;
import com.day.cq.dam.api.ProcessorException;
import com.day.cq.dam.api.Rendition;
import com.day.cq.dam.api.cache.BufferedImageCache;
import com.day.cq.dam.api.handler.AssetHandler;
import com.day.cq.dam.api.metadata.ExtractedMetadata;
import com.day.cq.dam.api.thumbnail.ThumbnailConfig;
import com.day.cq.dam.commons.thumbnail.ThumbnailGenerator;
import com.day.cq.dam.commons.util.DamUtil;

/**
 * The AbstractAssetHandler serves as basis for all other asset handler implementations and provides common
 * used functionality.
 */
@Component(componentAbstract = true, metatype = false)
public abstract class AbstractAssetHandler implements AssetHandler {

    /**
     * Logger instance for this class.
     */
    private static final Logger log = LoggerFactory.getLogger(AbstractAssetHandler.class);

    /**
     * The property for deactivated mime types.
     */
    public static String PROPERTY_DEACTIVATED_MIME_TYPES = "dam.assethandler.deactivateMimeTypes";

    @Reference(policy = ReferencePolicy.STATIC)
    private JcrResourceResolverFactory jcrResolverFactory;

    @Reference(policy = ReferencePolicy.STATIC)
    private BufferedImageCache imageCache;

    // ----------------------< AssetHandler >-----------------------------------
    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public void createThumbnails(Node asset, Node renditionFolder, Session session, List dimensions) {

        final Resource assetResource = getResourceResolver(session).getResource(safeGetPath(asset));
        if (null != assetResource) {
            final Asset a = DamUtil.resolveToAsset(assetResource);
            if (null != a) {
                try {
                    createThumbnails(a, ThumbnailGenerator.getConfigs(dimensions));
                } catch (IOException e) {
                    log.error("createThumbnails: I/O error while creating thumbnails for [{}]: ", a.getPath(), e);
                }
            } else {
                log.error("createThumbnails: could not find asset [{}] to create thumbnails for.",
                        assetResource.getPath());
            }
        } else {
            log.error("createThumbnails: could not find resource [{}] to create thumbnails for.", safeGetPath(asset));
        }
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public void createThumbnailsExt(Node asset, Node renditionFolder,
                                    Session session, List> thumbnailConfigs)
            throws IOException {

        final Resource assetResource = getResourceResolver(session).getResource(safeGetPath(asset));
        if (null != assetResource) {
            final Asset a = DamUtil.resolveToAsset(assetResource);
            if (null != a) {
                try {

                    final Set configs = new HashSet();
                    for (final Map entry : thumbnailConfigs) {
                        final String width = (String) entry.get(ThumbnailConfig.PN_WIDTH);
                        final String height = (String) entry.get(ThumbnailConfig.PN_HEIGHT);
                        final String doCenter = (String) entry.get(ThumbnailConfig.PN_DOCENTER);
                        final String configStr = width + ":" + height + ":" + doCenter;
                        final ThumbnailConfig config = ThumbnailGenerator.parseConfig(configStr);
                        if (null != config) {
                            configs.add(config);
                        } else {
                            log.error("createThumbnailsExt: cannot add invalid thumbnail config [{}] for asset [{}]",
                                    configStr,
                                    safeGetPath(asset));
                        }
                    }

                    createThumbnails(a, configs);
                } catch (IOException e) {
                    log.error("createThumbnails: I/O error while creating thumbnails for [{}]: ", a.getPath(), e);
                }
            } else {
                log.error("createThumbnails: could not find asset [{}] to create thumbnails for.",
                        assetResource.getPath());
            }
        } else {
            log.error("createThumbnails: could not find resource [{}] to create thumbnails for.", safeGetPath(asset));
        }
    }

    /**
     * {@inheritDoc}
     */
    public void createThumbnails(final Asset asset, final Collection configs) throws IOException {
        createThumbnails(asset, asset.getOriginal(), configs);
    }

    /**
     * {@inheritDoc}
     */
    public void createThumbnails(final Asset asset) throws IOException {
        createThumbnails(asset, asset.getOriginal(), getThumbnailConfigs(asset));
    }

    /**
     * {@inheritDoc}
     */
    public void createThumbnails(final Asset asset, final Rendition rendition,
                                 final Collection configs) throws IOException {
        if (rendition == null) {
            throw new IOException("cannot create  thumbnail for for asset [" + asset.getPath() + "]: " 
                    + "rendition doesn't exist.");
        }
        BufferedImageCache.Entry image = imageCache.getImage(rendition, this);
        try {
            if (image != null && image.getImage() != null) {
                final ThumbnailGenerator generator = new ThumbnailGenerator(asset, image.getImage());
                generator.generate(configs);
            } else {
                log.error("createThumbnails: cannot create thumbnails for asset [{}], " +
                        "failed loading graphical representation for rendition [{}].",
                        asset.getPath(), rendition.getPath());
            }
        } catch (RepositoryException re) {
            throw new IOException("createThumbnails: error while storing " +
                    "thumbnail(s) for asset [" + asset.getPath() + "]: ");
        } finally {
            if (image != null) {
                image.release();
            }
        }
    }

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

    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public List processSubAssets(Node asset, Session session) {
        // noop
        log.debug("processSubAssets: no subassets to process for asset [{}].", safeGetPath(asset));
        return new ArrayList();
    }

    public List processSubAssets(final Asset asset) {
        // noop
        log.debug("processSubAssets: no subassets to process for asset [{}].", asset.getPath());
        return new ArrayList();
    }

    public Iterator processRelated(final Asset asset) {
        // noop
        log.debug("processReferences: no references to process for asset [{}].", asset.getPath());
        return Collections.emptyList().iterator();
    }

    public BufferedImage getImage(final Rendition rendition) throws IOException {
        // noop
        return null;
    }

    public BufferedImage getImage(Rendition rendition, Dimension maxDimension) throws IOException {
        return getImage(rendition);
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public void exportAsset(Node asset, OutputStream stream) throws AssetHandlerException {
        try {
            final Resource assetResource = getResourceResolver(asset.getSession()).getResource(safeGetPath(asset));
            if (null != assetResource) {
                final Asset a = DamUtil.resolveToAsset(assetResource);
                if (null != a) {
                    exportAsset(a, stream);
                } else {
                    log.error("exportAsset: cannot export, asset [{}] doesn't exist.", safeGetPath(asset));
                }
            }
        } catch (Exception e) {
            throw new AssetHandlerException("Cannot export asset: " + e.getMessage(), e);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void exportAsset(final Asset asset, final OutputStream stream) throws AssetHandlerException {
        try {
            final InputStream is = asset.getOriginal().getStream();
            IOUtils.copy(is, stream);
            is.close();
        } catch (Exception e) {
            throw new AssetHandlerException("Cannot export asset: " + e.getMessage(), e);
        }
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public ExtractedMetadata extractMetadata(final Node asset) {
        try {
            final Resource assetResource = getResourceResolver(asset.getSession()).getResource(safeGetPath(asset));
            if (null != assetResource) {
                final Asset a = assetResource.adaptTo(Asset.class);
                if (null != a) {
                    return extractMetadata(a);
                }
            }
        } catch (RepositoryException e) {
            log.error("extractMetadata: error while extracting metadata for asset [{}]: ", safeGetPath(asset), e);
        }
        return null;
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated
     */
    //todo: remove for CQ 5.5
    public BufferedImage getImage(Node file) throws IOException {
        // no op
        return null;
    }

    /**
     * This method is responsible to create a thumbnail image out of the passed asset. The image has to be returned as
     * {@link BufferedImage}
     *
     * @param asset Asset/file of which the thumbnail is generated
     * @return Generated thumbnail or null in case the handler is unable to create a thumbnail.
     * @deprecated use {@link AssetHandler#getImage(Rendition)} instead
     */
    //todo: remove for CQ 5.5
    protected BufferedImage getThumbnailImage(Node asset) {
        try {
            final Resource resource = getResourceResolver(asset.getSession()).getResource(safeGetPath(asset));
            if (null != resource) {
                Rendition rendition = null;
                if (DamUtil.isAsset(resource)) {
                    rendition = resource.adaptTo(Asset.class).getOriginal();
                } else if (DamUtil.isRendition(resource)) {
                    rendition = resource.adaptTo(Rendition.class);
                }
                if (null != rendition) {
                    return getImage(rendition);
                } else {
                    log.error("getThumbnailImage: could not get image, resource [{}] doesn't exist.",
                            safeGetPath(asset));
                }
            }
        } catch (RepositoryException e) {
            log.error("getThumbnailImage: error while access repository: ", e);
        } catch (IOException e) {
            log.error("getThumbnailImage: I/O error: ", e);
        }

        return null;
    }

    protected ResourceResolver getResourceResolver(final Session session) {
        return jcrResolverFactory.getResourceResolver(session);
    }

    protected AssetManager getAssetManager(final Session session) {
        return getResourceResolver(session).adaptTo(AssetManager.class);
    }

    /**
     * Returns {@link InputStream} of passed file or asset node.
     *
     * @param file file node
     * @return binary data as {@link InputStream}
     */
    protected InputStream getInputStream(Node file) {
        try {
            String dataPath = (file.isNodeType(DamConstants.NT_DAM_ASSET)) ?
                    JCR_CONTENT + "/" + RENDITIONS_FOLDER +
                            "/" + ORIGINAL_FILE + "/" + JCR_CONTENT +
                            "/" + JcrConstants.JCR_DATA :
                    JCR_CONTENT + "/" + JcrConstants.JCR_DATA;
            if (file.hasProperty(dataPath)) {
                return file.getProperty(dataPath).getBinary().getStream();
            }
        } catch (RepositoryException e) {
            log.warn("getInputStream: repository error while getting stream for file [{}]: ", safeGetPath(file), e);
        }
        return new ByteArrayInputStream(new byte[0]);
    }

    protected void setMimetype(final ExtractedMetadata metadata, final Asset asset) {
        Rendition original = asset.getOriginal();
        if (original != null) {
            metadata.setMetaDataProperty(DC_FORMAT, original.getMimeType());
        }
    }

    /**
     * Return the path of an asset node or the literal (unknown) if getting the path fails.
     *
     * @param node node
     * @return path or null
     */
    protected String safeGetPath(Node node) {
        try {
            return node.getPath();
        } catch (RepositoryException e) {
            log.warn("safeGetPath: error while getting path from node: ", e);
            return "(unknown)";
        }
    }

    protected Collection getThumbnailConfigs(final Asset asset) {
        final Set set = new HashSet();

        final List renditions = asset.getRenditions();
        for (final Rendition rendition : renditions) {
            final String name = rendition.getName();
            if (name.startsWith(PREFIX_ASSET_THUMBNAIL + ".")) {
                final String fragments[] = name.split("\\.");
                final String width = fragments[2];
                final String height = fragments[3];
                final String configStr = width + ":" + height + ":true";
                final ThumbnailConfig config = ThumbnailGenerator.parseConfig(configStr);
                if (null != config) {
                    set.add(config);
                } else {
                    log.error("getThumbnailConfigs: cannot add invalid config [{}] for asset [{}].",
                            configStr,
                            asset.getPath());
                }
            }
        }

        return set;
    }

    /**
     * Generic processor to scan for metadata
     * @param is input stream to extract from
     * @param metadata for which xmp needs to be set
     * */
    protected void execGenericProcessor(final InputStream is, final ExtractedMetadata metadata) {
        try {
            InputStream xmp = XMPProcessor.process(is);
            if (xmp != null) {
                metadata.setXmp(xmp);
            }
        }catch (IOException e) {
            log.error("I/O error while getting metadata", e);
        } catch (ProcessorException e) {
            log.error("Failed to extract metadata : {}", e.getMessage());
            if (log.isDebugEnabled()) {
                log.debug("Stack trace.", e);
            }
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy