com.adaptris.core.jms.activemq.BlobMessageTranslator.java Source code

Java tutorial

Introduction

Here is the source code for com.adaptris.core.jms.activemq.BlobMessageTranslator.java

Source

/*
 * Copyright 2015 Adaptris Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package com.adaptris.core.jms.activemq;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.jms.JMSException;
import javax.jms.Message;

import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.BlobMessage;
import org.apache.commons.io.IOUtils;

import com.adaptris.annotation.DisplayOrder;
import com.adaptris.core.AdaptrisMessage;
import com.adaptris.core.CoreException;
import com.adaptris.core.jms.AutoConvertMessageTranslator;
import com.adaptris.core.jms.JmsUtils;
import com.adaptris.core.jms.MessageTypeTranslatorImp;
import com.adaptris.core.lms.FileBackedMessage;
import com.adaptris.core.util.LifecycleHelper;
import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * <p>
 * Translates between {@link com.adaptris.core.AdaptrisMessage} and {@link org.apache.activemq.BlobMessage}.
 * </p>
 * <p>
 * In outbound scenarios (i.e. writing to ActiveMQ), there are two ways in which this translator
 * works with the {@link com.adaptris.core.AdaptrisMessage}.
 * </p>
 * <ol>
 * <li>If {@link #setMetadataUrlKey(String)} <strong>has been set</strong>, then the value
 * associated with that metadata key is used to create a URL object so that
 * {@link ActiveMQSession#createBlobMessage(URL)} can be used. If you are intending to use this,
 * then the data will already have been written to this URL (by the adapter or otherwise). If the
 * metadata key does not exist, then it assumes the next scenario.</li>
 * <li>If {@link #setMetadataUrlKey(String)} <strong>has not been set</strong>, then the contents of
 * the AdaptrisMessage object are used to form the BlobMessage, either by using
 * {@link ActiveMQSession#createBlobMessage(java.io.File)} or
 * {@link ActiveMQSession#createBlobMessage(InputStream)} depending on the underlying type of
 * AdaptrisMessage. If you are intending to use this, then you will have already configured ActiveMQ
 * / underlying OS platform (e.g. for WebDAV/FTP) appropriately for handling out of band transfers.
 * </li>
 * </ol>
 * <p>
 * For inbound scenarios, {@link BlobMessage#getInputStream()} is used, this may create additional
 * connections to remote servers from the machine where the adapter is running.
 * </p>
 * 
 * @config activemq-blob-message-translator
 * 
 */
@SuppressWarnings("deprecation")
@XStreamAlias("activemq-blob-message-translator")
@DisplayOrder(order = { "metadataUrlKey", "metadataFilter", "moveMetadata", "moveJmsHeaders", "reportAllErrors" })
public final class BlobMessageTranslator extends MessageTypeTranslatorImp {

    private String metadataUrlKey;
    private transient AutoConvertMessageTranslator fallback;

    public BlobMessageTranslator() {
        super();
        fallback = new AutoConvertMessageTranslator();
    }

    /**
     * @see #setMetadataUrlKey(String)
     *
     */
    public BlobMessageTranslator(String metadataKey) {
        this();
        setMetadataUrlKey(metadataKey);
    }

    /**
     * <p>
     * Translates an <code>AdaptrisMessage</code> into a <code>BlobMessage</code>.
     * </p>
     *
     * @param msg the <code>AdaptrisMessage</code> to translate
     * @return a new {@link org.apache.activemq.BlobMessage}
     * @throws JMSException on error.
     * @see ActiveMQSession#createBlobMessage(URL)
     * @see ActiveMQSession#createBlobMessage(java.io.File)
     * @see ActiveMQSession#createBlobMessage(InputStream)
     */
    @Override
    public Message translate(AdaptrisMessage msg) throws JMSException {
        BlobMessage jmsMsg = null;
        try {
            if (metadataUrlKey != null && msg.containsKey(metadataUrlKey)) {
                jmsMsg = ((ActiveMQSession) session)
                        .createBlobMessage(new URL(msg.getMetadataValue(metadataUrlKey)));
            } else {
                if (msg instanceof FileBackedMessage) {
                    jmsMsg = ((ActiveMQSession) session)
                            .createBlobMessage(((FileBackedMessage) msg).currentSource());
                } else {
                    jmsMsg = ((ActiveMQSession) session).createBlobMessage(msg.getInputStream());
                }
            }
        } catch (IOException e) {
            JmsUtils.rethrowJMSException("Failed to create BlobMessage", e);

        }
        return helper.moveMetadata(msg, jmsMsg);
    }

    /**
     * <p>
     * Translates a <code>BlobMessage</code> into an <code>AdaptrisMessage</code>
     * .
     * </p>
     *
     * @param msg the <code>BlobMessage</code> to translate
     * @return an <code>AdaptrisMessage</code>
     * @throws JMSException on exception
     */
    @Override
    public AdaptrisMessage translate(Message msg) throws JMSException {
        OutputStream out = null;
        InputStream in = null;
        AdaptrisMessage result = currentMessageFactory().newMessage();
        try {
            if (msg instanceof BlobMessage) {
                in = ((BlobMessage) msg).getInputStream();
                if (in == null) {
                    log.warn("BlobMessage [{}] has no content", msg.getJMSMessageID());
                } else {
                    out = result.getOutputStream();
                    IOUtils.copy(in, out);
                    out.flush();
                }
            } else {
                result = fallback.translate(msg);
            }
        } catch (IOException e) {
            JmsUtils.rethrowJMSException("Failed to translate BlobMessage", e);
        } finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
        }
        return helper.moveMetadata(msg, result);
    }

    @Override
    public void init() throws CoreException {
        super.init();
        init(fallback);
    }

    private void init(MessageTypeTranslatorImp m) throws CoreException {
        m.registerSession(currentSession());
        m.registerMessageFactory(currentMessageFactory());
        m.setMoveJmsHeaders(getMoveJmsHeaders());
        m.setMetadataFilter(getMetadataFilter());
        m.setReportAllErrors(getReportAllErrors());
        LifecycleHelper.init(m);
    }

    @Override
    public void start() throws CoreException {
        LifecycleHelper.start(fallback);
        super.start();
    }

    @Override
    public void stop() {
        super.stop();
        LifecycleHelper.stop(fallback);
    }

    @Override
    public void close() {
        super.close();
        LifecycleHelper.close(fallback);
    }

    /**
     * Get the metadata key that will be used to generate the URL.
     *
     * @see ActiveMQSession#createBlobMessage(URL)
     * @return the metadata key.
     */
    public String getMetadataUrlKey() {
        return metadataUrlKey;
    }

    /**
     * Set the metadata key that will be used to generate the URL.
     * <p>
     * This setting only has effect when the framework invokes
     * {@link #translate(AdaptrisMessage)} (during the produce of the message).
     * </p>
     *
     * @see ActiveMQSession#createBlobMessage(URL)
     * @param metadataKey
     */
    public void setMetadataUrlKey(String metadataKey) {
        metadataUrlKey = metadataKey;
    }
}