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

com.amazon.sqs.javamessaging.message.SQSBytesMessage Maven / Gradle / Ivy

Go to download

The Amazon SQS Java Messaging Library holds the Java Message Service compatible classes, that are used for communicating with Amazon Simple Queue Service.

There is a newer version: 2.1.4
Show newest version
/*
 * Copyright 2010-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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.amazon.sqs.javamessaging.message;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MessageEOFException;
import javax.jms.MessageFormatException;
import javax.jms.MessageNotReadableException;
import javax.jms.MessageNotWriteableException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amazon.sqs.javamessaging.acknowledge.Acknowledger;
import com.amazonaws.util.Base64;

import com.amazonaws.services.sqs.model.Message;

/**
 * This class borrows from ActiveMQStreamMessage, which is also
 * licensed under Apache2.0. Its methods are based largely on those found in
 * java.io.DataInputStream and
 * java.io.DataOutputStream.
 * 
 * @see org.apache.activemq.command.ActiveMQStreamMessage
 */
public class SQSBytesMessage extends SQSMessage implements BytesMessage {
    private static final Log LOG = LogFactory.getLog(SQSBytesMessage.class);

    private byte[] bytes;

    private ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();

    private DataInputStream dataIn;
    
    private DataOutputStream dataOut = new DataOutputStream(bytesOut);

    /**
     * Convert received SQSMessage into BytesMessage.
     */
    public SQSBytesMessage(Acknowledger acknowledger, String queueUrl, Message sqsMessage) throws JMSException {
        super(acknowledger, queueUrl, sqsMessage);
        try {
            /** Bytes is set by the reset() */
            dataOut.write(Base64.decode(sqsMessage.getBody()));
            /** Makes it read-only */
            reset();
        } catch (IOException e) {
            LOG.error("IOException: Message cannot be written", e);
            throw convertExceptionToJMSException(e);
        } catch (Exception e) {
            LOG.error("Unexpected exception: ", e);
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Create new empty BytesMessage to send.
     */
    public SQSBytesMessage() throws JMSException {
        super();
    }
    
    /**
     * Gets the number of bytes of the message body when the message is in
     * read-only mode. The value returned can be used to allocate a byte array.
     * The value returned is the entire length of the message body, regardless
     * of where the pointer for reading the message is currently located.
     * 
     * @return number of bytes in the message
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public long getBodyLength() throws JMSException {
        checkCanRead();
        return bytes.length;
    }
    
    /**
     * Reads a boolean from the bytes message stream.
     * 
     * @return the boolean value
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public boolean readBoolean() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readBoolean();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a signed 8-bit value from the bytes message stream.
     * 
     * @return the next byte from the bytes message stream as a signed 8-bit
     *         byte
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public byte readByte() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readByte();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads an unsigned 8-bit value from the bytes message stream.
     * 
     * @return the next byte from the bytes message stream, interpreted as an
     *         unsigned 8-bit number
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public int readUnsignedByte() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readUnsignedByte();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a signed 16-bit number from the bytes message stream.
     * 
     * @return the next two bytes from the bytes message stream, interpreted as
     *         a signed 16-bit number
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public short readShort() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readShort();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads an unsigned 16-bit number from the bytes message stream.
     * 
     * @return the next two bytes from the bytes message stream, interpreted as
     *         an unsigned 16-bit integer
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public int readUnsignedShort() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readUnsignedShort();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a Unicode character value from the bytes message stream. 
     * 
     * @return a Unicode character from the bytes message stream
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public char readChar() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readChar();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a 32-bit integer from the bytes message stream.
     * 
     * @return the next four bytes from the bytes message stream, interpreted as an int
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public int readInt() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readInt();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a 64-bit integer from the bytes message stream.
     * 
     * @return a 64-bit integer value from the bytes message stream, interpreted as a long
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public long readLong() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readLong();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a float from the bytes message stream.
     * 
     * @return a float value from the bytes message stream
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public float readFloat() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readFloat();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a double from the bytes message stream. 
     * 
     * @return a double value from the bytes message stream
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public double readDouble() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readDouble();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a string that has been encoded using a UTF-8 format from
     * the bytes message stream
     * 
     * @return a Unicode string from the bytes message stream
     * @throws JMSException
     *             If the JMS provider fails to read the message due to some
     *             internal error.
     * @throws MessageEOFException
     *             If unexpected end of bytes stream has been reached.
     * @throws MessageNotReadableException
     *             If the message is in write-only mode.
     */
    @Override
    public String readUTF() throws JMSException {
        checkCanRead();
        try {
            return dataIn.readUTF();
        } catch (EOFException e) {
            throw new MessageEOFException(e.getMessage());
        } catch (IOException e) {
            throw convertExceptionToJMSException(e);
        }
    }
    
    /**
     * Reads a byte array from the bytes message stream.
     * 

* If the length of array value is less than the number of bytes remaining * to be read from the stream, the array should be filled. A subsequent call * reads the next increment, and so on. *

* If the number of bytes remaining in the stream is less than the length of * array value, the bytes should be read into the array. The return value of * the total number of bytes read will be less than the length of the array, * indicating that there are no more bytes left to be read from the stream. * The next read of the stream returns -1. * * @param value * The buffer into which the data is read * @return the total number of bytes read into the buffer, or -1 if there is * no more data because the end of the stream has been reached * @throws JMSException * If the JMS provider fails to read the message due to some * internal error. * @throws MessageNotReadableException * If the message is in write-only mode. */ @Override public int readBytes(byte[] value) throws JMSException { return readBytes(value, value.length); } /** * Reads a portion of the bytes message stream. *

* If the length of array value is less than the number of bytes remaining * to be read from the stream, the array should be filled. A subsequent call * reads the next increment, and so on. *

* If the number of bytes remaining in the stream is less than the length of * array value, the bytes should be read into the array. The return value of * the total number of bytes read will be less than the length of the array, * indicating that there are no more bytes left to be read from the stream. * The next read of the stream returns -1. *

* If length is negative, then an IndexOutOfBoundsException is * thrown. No bytes will be read from the stream for this exception case. * * @param value * The buffer into which the data is read * @param length * The number of bytes to read; must be less than or equal to * value.length * @return the total number of bytes read into the buffer, or -1 if there is * no more data because the end of the stream has been reached * @throws JMSException * If the JMS provider fails to read the message due to some * internal error. * @throws MessageNotReadableException * If the message is in write-only mode. */ @Override public int readBytes(byte[] value, int length) throws JMSException { if (length < 0) { throw new IndexOutOfBoundsException("Length bytes to read can't be smaller than 0 but was " + length); } checkCanRead(); try { /** * Almost copy of readFully implementation except that EOFException * is not thrown if the stream is at the end of file and no byte is * available */ int n = 0; while (n < length) { int count = dataIn.read(value, n, length - n); if (count < 0) { break; } n += count; } /** * JMS specification mentions that the next read of the stream * returns -1 if the previous read consumed the byte stream and * there are no more bytes left to be read from the stream */ if (n == 0 && length > 0) { n = -1; } return n; } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a boolean to the bytes message stream * * @param value * The boolean value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeBoolean(boolean value) throws JMSException { checkCanWrite(); try { dataOut.writeBoolean(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a byte to the bytes message stream * * @param value * The byte value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeByte(byte value) throws JMSException { checkCanWrite(); try { dataOut.writeByte(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a short to the bytes message stream * * @param value * The short value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeShort(short value) throws JMSException { checkCanWrite(); try { dataOut.writeShort(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a char to the bytes message stream * * @param value * The char value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeChar(char value) throws JMSException { checkCanWrite(); try { dataOut.writeChar(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a int to the bytes message stream * * @param value * The int value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeInt(int value) throws JMSException { checkCanWrite(); try { dataOut.writeInt(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a long to the bytes message stream * * @param value * The long value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeLong(long value) throws JMSException { checkCanWrite(); try { dataOut.writeLong(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a float to the bytes message stream * * @param value * The float value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeFloat(float value) throws JMSException { checkCanWrite(); try { dataOut.writeFloat(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a double to the bytes message stream * * @param value * The double value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeDouble(double value) throws JMSException { checkCanWrite(); try { dataOut.writeDouble(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a string that has been encoded using a UTF-8 format to the bytes * message stream * * @param value * The String value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeUTF(String value) throws JMSException { checkCanWrite(); try { dataOut.writeUTF(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a byte array to the bytes * message stream * * @param value * The byte array value to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeBytes(byte[] value) throws JMSException { checkCanWrite(); try { dataOut.write(value); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes a portion of a byte array to the bytes message stream. * * @param value * The portion of byte array value to be written * @param offset * The initial offset within the byte array * @param length * The number of bytes to use * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. */ @Override public void writeBytes(byte[] value, int offset, int length) throws JMSException { checkCanWrite(); try { dataOut.write(value, offset, length); } catch (IOException e) { throw convertExceptionToJMSException(e); } } /** * Writes an object to the bytes message stream. *

* This method works only for the boxed primitive object types * (Integer, Double, Long ...), String objects, and byte arrays. * * @param value * The Java object to be written * @throws JMSException * If the JMS provider fails to write the message due to some * internal error. * @throws MessageNotWriteableException * If the message is in read-only mode. * @throws MessageFormatException * If the object is of an invalid type. * @throws NullPointerException * If the object is null. */ @Override public void writeObject(Object value) throws JMSException { if (value == null) { throw new NullPointerException("Cannot write null value of object"); } if (value instanceof Boolean) { writeBoolean((Boolean) value); } else if (value instanceof Character) { writeChar((Character) value); } else if (value instanceof Byte) { writeByte((Byte) value); } else if (value instanceof Short) { writeShort((Short) value); } else if (value instanceof Integer) { writeInt((Integer) value); } else if (value instanceof Long) { writeLong((Long) value); } else if (value instanceof Float) { writeFloat((Float) value); } else if (value instanceof Double) { writeDouble((Double) value); } else if (value instanceof String) { writeUTF(value.toString()); } else if (value instanceof byte[]) { writeBytes((byte[]) value); } else { throw new MessageFormatException("Cannot write non-primitive type: " + value.getClass()); } } /** * Puts the message body in read-only mode and repositions the stream of * bytes to the beginning. */ @Override public void reset() throws JMSException { if (dataOut != null) { bytes = bytesOut.toByteArray(); dataOut = null; bytesOut = null; } dataIn = new DataInputStream(new ByteArrayInputStream(bytes)); } /** * When the message is first created, and when clearBody is called, the body * of the message is in write-only mode. After the first call to reset is * made, the message body goes to read-only mode. when the message is sent, * the sender can retain and modify it without affecting the sent message. * If clearBody is called on a message, when it is in read-only mode, the * message body is cleared and the message goes to write-only mode. */ @Override public void clearBody() throws JMSException { bytes = null; dataIn = null; bytesOut = new ByteArrayOutputStream(); dataOut = new DataOutputStream(bytesOut); setBodyWritePermissions(true); } /** * Reads the body of message, which can be either the body returned from the * the receives message as bytes or the bytes put in bytesOut if it is a * sent message. * * @return value The body returned as byte array */ public byte[] getBodyAsBytes() throws JMSException { if (bytes != null) { return Arrays.copyOf(bytes, bytes.length); } else { return bytesOut.toByteArray(); } } void checkCanRead() throws JMSException { if (bytes == null) { throw new MessageNotReadableException("Message is not readable"); } } void checkCanWrite() throws JMSException { if (dataOut == null) { throw new MessageNotWriteableException("Message is not writeable"); } } /* * Unit Test Utility Function */ void setDataIn(DataInputStream dataIn) { this.dataIn = dataIn; } void setDataOut(DataOutputStream dataOut) { this.dataOut = dataOut; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy