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 com.day.cq.dam.api.renditions.RenditionMaker;
import com.day.cq.dam.api.renditions.RenditionTemplate;
import com.day.cq.dam.commons.thumbnail.ThumbnailConfigImpl;
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.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
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;

/**
 * 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 ResourceResolverFactory jcrResolverFactory;

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

    // ----------------------< AssetHandler >-----------------------------------

    /**
     * {@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) {
                // for each thumbnail config, create a rendition template
                RenditionTemplate[] templates = createRenditionTemplates(asset, configs.toArray(new ThumbnailConfig[]{}), renditionMaker);

                // create thumbnail renditions
                renditionMaker.generateRenditions(asset, templates);
            } else {
                log.error("createThumbnails: cannot create thumbnails for asset [{}], " +
                        "failed loading graphical representation for rendition [{}].",
                        asset.getPath(), rendition.getPath());
            }
        } finally {
            if (image != null) {
                image.release();
            }
        }
    }
	
    private RenditionTemplate[] createRenditionTemplates(Asset asset, ThumbnailConfig[] thumbnails, RenditionMaker renditionMaker) {
        RenditionTemplate[] templates = new RenditionTemplate[thumbnails.length];
        for (int i = 0; i < thumbnails.length; i++) {
            ThumbnailConfig thumb = thumbnails[i];
            templates[i] = renditionMaker.createThumbnailTemplate(asset, thumb.getWidth(), thumb.getHeight(), thumb.doCenter());
        }
        return templates;
    }

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

    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}
     */
    public void exportAsset(final Asset asset, final OutputStream stream) throws AssetHandlerException {
        InputStream is = null;
        try {
            is = asset.getOriginal().getStream();
            IOUtils.copy(is, stream);
        } catch (Exception e) {
            throw new AssetHandlerException("Cannot export asset: " + e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    protected ResourceResolver getResourceResolver(final Session session) {
        try {
            return jcrResolverFactory.getResourceResolver(Collections.singletonMap("user.jcr.session", (Object) session));
        } catch (LoginException e) {
            throw new RuntimeException("can not create resolver from session", e);
        }
    }

    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 Integer width = Integer.valueOf(fragments[0]);
                final Integer height = Integer.valueOf(fragments[1]);

                boolean doCenter = false;
                if (fragments.length > 2) {
                    doCenter = Boolean.valueOf(fragments[2]);
                }
                final ThumbnailConfig config = new ThumbnailConfigImpl(width, height, doCenter);
                if (null != config) {
                    set.add(config);
                } else {
                    log.error("getThumbnailConfigs: cannot add invalid config [{}] for asset [{}].",
                            name,
                            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