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

com.day.cq.dam.commons.thumbnail.XapThumbnailsProcessor Maven / Gradle / Ivy

/*
 * Copyright 1997-2009 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.thumbnail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPIterator;
import com.adobe.xmp.XMPMeta;
import com.adobe.xmp.XMPMetaFactory;
import com.adobe.xmp.options.IteratorOptions;
import com.adobe.xmp.properties.XMPProperty;
import com.adobe.xmp.properties.XMPPropertyInfo;
import com.day.cq.dam.api.Context;
import com.day.cq.dam.api.Processor;
import com.day.cq.dam.api.ProcessorException;
import com.day.cq.dam.commons.handler.FilterStateListener;
import com.day.cq.dam.commons.handler.Filter;
import com.day.cq.dam.commons.handler.XPacketFilter;
import com.day.cq.dam.commons.metadata.XmpFilter;
import com.day.image.Layer;
import org.apache.commons.codec.binary.Base64;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Process bytes, extract thumbnails found in <xap:Thumbnails> tags
 * and add them to a {@link com.day.cq.dam.api.Context}.
 *
 * @author dpfister
 */
public class XapThumbnailsProcessor implements Processor, FilterStateListener {

    /**
     * XMP Basic schema namespace.
     */
    private static final String XMP_SCHEMA_NS = "http://ns.adobe.com/xap/1.0/";

    /**
     * Thumbnails array property name.
     */
    private static final String PN_THUMBNAILS = "Thumbnails";

    /**
     * XMP Image schema namespace.
     */
    private static final String XMPIMG_SCHEMA_NS = "http://ns.adobe.com/xap/1.0/g/img/";

    /**
     * Image property name.
     */
    private static final String PN_IMAGE = "image";

    /**
     * Context.
     */
    private Context context;

    /**
     * XPacket filter.
     */
    private XPacketFilter xmpFilter;

    /**
     * Create a new instance of this class.
     *
     * @param context context
     */
    public XapThumbnailsProcessor(Context context) {
        this.context = context;

        xmpFilter = new XPacketFilter();
        xmpFilter.setFilterStateListener(this);
        xmpFilter.setAutoReset(true);
    }

    //---------------------------------------------------------------- Processor

    /**
     * {@inheritDoc}
     */
    public final void process(byte[] buf, int off, int len) throws IOException {
        xmpFilter.filter(buf, off, len);
    }

    //------------------------------------------------------ FilterStateListener

    /**
     * {@inheritDoc}
     */
    public OutputStream started(Filter filter) {
        return new ByteArrayOutputStream(8192);
    }

    /**
     * {@inheritDoc}
     */
    public void ended(Filter filter, OutputStream out) {
        ByteArrayOutputStream bos = (ByteArrayOutputStream) out;
        byte[] data = bos.toByteArray();

        XMPMeta xmp = null;
        BundleContext bundleContext = getBundleContext();
        ServiceReference filterRef = getServiceReference(bundleContext);

        try {
            if (filterRef != null) {
                XmpFilter xmpFilter = bundleContext.getService(filterRef);
                if (xmpFilter != null) {
                    xmp = XMPMetaFactory.parse(xmpFilter.filter(new ByteArrayInputStream(data)));
                } else {
                    String msg = "Unable to get XMPFilter service.";
                    context.addException(new ProcessorException(msg, new Exception(msg), this));
                    return;
                }
            } else {
                String msg = "Unable to get XMPFilter service.";
                context.addException(new ProcessorException(msg, new Exception(msg), this));
                return;
            }
        } catch (XMPException | IOException e) {
            String msg = "Unable to get XMP object from input";
            context.addException(new ProcessorException(msg, e, this));
            return;
        } finally {
            if (filterRef != null) {
                bundleContext.ungetService(filterRef);
            }
        }

        try {
            XMPIterator iter = xmp.iterator(XMP_SCHEMA_NS, PN_THUMBNAILS,
                    new IteratorOptions().setJustChildren(true));
            while (iter.hasNext()) {
                XMPPropertyInfo thumbnail = (XMPPropertyInfo) iter.next();
                XMPProperty image = xmp.getStructField(XMP_SCHEMA_NS,
                        thumbnail.getPath(), XMPIMG_SCHEMA_NS, PN_IMAGE);
                if (image != null) {
                    byte[] encoded = ((String) image.getValue()).getBytes();
                    byte[] decoded = Base64.decodeBase64(encoded);

                    context.addThumbnail(new Layer(
                            new ByteArrayInputStream(decoded)).getImage());
                }
            }
        } catch (XMPException | IOException e) {
            String msg = "Unable to locate image inside thumbnail";
            context.addException(new ProcessorException(msg, e, this));
        }
    }

    BundleContext getBundleContext() {
        return FrameworkUtil.getBundle(this.getClass()).getBundleContext();
    }

    ServiceReference getServiceReference(BundleContext bundleContext) {
        return bundleContext.getServiceReference(XmpFilter.class);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy