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

com.swiftmq.jms.StreamMessageImpl Maven / Gradle / Ivy

/*
 * Copyright 2019 IIT Software GmbH
 *
 * IIT Software GmbH licenses this file to You 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.swiftmq.jms;

import com.swiftmq.jms.primitives.*;
import com.swiftmq.tools.dump.Dumpable;

import javax.jms.*;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

/**
 * Implementation of a StreamMessage.
 *
 * @author IIT GmbH, Bremen/Germany, Copyright (c) 2000-2002, All Rights Reserved
 */
public class StreamMessageImpl extends MessageImpl implements StreamMessage {
    static final int WRITE_ONLY = 0;
    static final int READ_ONLY = 1;
    static final int DEFAULT_SIZE = 32;
    int mode = WRITE_ONLY;
    int pos = 0;
    byte[] lastBA = null;
    int amount = 0;
    Primitive[] elements = null;
    int nElements = 0;

    protected int getType() {
        return TYPE_STREAMMESSAGE;
    }

    protected void writeBody(DataOutput out) throws IOException {
        out.writeInt(nElements);
        if (nElements > 0) {
            for (int i = 0; i < nElements; i++) {
                Dumpable d = (Dumpable) elements[i];
                out.writeInt(d.getDumpId());
                d.writeContent(out);
            }
        }
    }

    protected void readBody(DataInput in) throws IOException {
        nElements = in.readInt();
        if (nElements > 0) {
            elements = new Primitive[nElements];
            for (int i = 0; i < elements.length; i++) {
                Dumpable d = (Dumpable) PrimitiveFactory.createInstance(in.readInt());
                d.readContent(in);
                elements[i] = (Primitive) d;
            }
        }
    }

    /**
     * Return a given value at the given index; throws an JMSException if not defined.
     *
     * @param index the index of the value
     * @return the value with the given index.
     * @throws MessageEOFException if index >= vector.size
     */
    private Object getValue(int index) throws MessageEOFException {
        if (elements == null || index >= nElements) {
            throw new MessageEOFException("end-of-stream reached");
        }

        Primitive primitive = elements[index];
        Object obj = primitive.getObject();
        if (!(obj instanceof byte[])) {
            lastBA = null;
            amount = 0;
        }
        return obj;
    }

    /**
     * Read a boolean from the stream message.
     *
     * @return the boolean value read.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public boolean readBoolean() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Boolean) {
            return ((Boolean) obj).booleanValue();
        } else if (obj instanceof String) {
            try {
                return (Boolean.valueOf((String) obj)).booleanValue();
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + (String) obj
                        + " to boolean");
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to boolean");
    }

    /**
     * Read a byte value from the stream message.
     *
     * @return the next byte from the stream message as a 8-bit
     * byte.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public byte readByte() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Byte) {
            return ((Byte) obj).byteValue();
        } else if (obj instanceof String) {
            try {
                return (new Byte((String) obj).byteValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to byte");
    }

    /**
     * Read a 16-bit number from the stream message.
     *
     * @return a 16-bit number from the stream message.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public short readShort() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Short) {
            return ((Short) obj).shortValue();
        } else if (obj instanceof String) {
            try {
                return (new Short((String) obj).shortValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        } else if (obj instanceof Byte) {
            try {
                return (((Byte) obj).shortValue());
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + (Long) obj
                        + " to short");
            }
        }
        pos--;
        throw new MessageFormatException("can't convert property value to short");
    }

    /**
     * Read a Unicode character value from the stream message.
     *
     * @return a Unicode character from the stream message.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */

    public char readChar() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);
        if (obj == null) {
            pos--;
            throw new NullPointerException();
        }

        if (obj instanceof Character) {
            return ((Character) obj).charValue();
        }
        pos--;
        throw new MessageFormatException("can't convert message value to char");
    }

    /**
     * Read a 32-bit integer from the stream message.
     *
     * @return a 32-bit integer value from the stream message, interpreted
     * as a int.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public int readInt() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Integer) {
            return ((Integer) obj).intValue();
        } else if (obj instanceof String) {
            try {
                return (Integer.valueOf((String) obj).intValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        } else if (obj instanceof Short) {
            try {
                return (((Short) obj).intValue());
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to int");
            }
        } else if (obj instanceof Byte) {
            try {
                return (((Byte) obj).intValue());
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to int");
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to int");
    }

    /**
     * Read a 64-bit integer from the stream message.
     *
     * @return a 64-bit integer value from the stream message, interpreted as
     * a long.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public long readLong() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Long) {
            return ((Long) obj).longValue();
        } else if (obj instanceof String) {
            try {
                return (Long.valueOf((String) obj).longValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        } else if (obj instanceof Short) {
            try {
                return ((Short) obj).longValue();
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to long");
            }
        } else if (obj instanceof Integer) {
            try {
                return ((Integer) obj).longValue();
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to long");
            }
        } else if (obj instanceof Byte) {
            try {
                return ((Byte) obj).longValue();
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to long");
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to long");
    }

    /**
     * Read a float from the stream message.
     *
     * @return a float value from the stream message.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public float readFloat() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Float) {
            return ((Float) obj).floatValue();
        } else if (obj instanceof String) {
            try {
                return (new Float((String) obj).floatValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to float");
    }

    /**
     * Read a double from the stream message.
     *
     * @return a double value from the stream message.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public double readDouble() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj instanceof Double) {
            return ((Double) obj).doubleValue();
        } else if (obj instanceof Float) {
            try {
                return (((Float) obj).doubleValue());
            } catch (Exception e) {
                pos--;
                throw new MessageFormatException("can't convert " + obj
                        + " to double");
            }
        } else if (obj instanceof String) {
            try {
                return (new Double((String) obj).doubleValue());
            } catch (NumberFormatException e) {
                pos--;
                throw e;
            }
        }
        pos--;
        throw new MessageFormatException("can't convert message value to double");
    }

    /**
     * Read in a string from the stream message.
     *
     * @return a Unicode string from the stream message.
     * @throws JMSException                if JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public String readString() throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        Object obj = getValue(pos++);

        if (obj == null) {
            return null;
        }

        if (obj instanceof byte[])
            throw new MessageFormatException("Type conversion from byte[] to String is invalid");

        if (obj instanceof String) {
            return ((String) obj);
        }

        return obj.toString();
    }

    /**
     * Read a byte array from the stream message.
     *
     * @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 JMS fails to read message due to
     *                                     some internal JMS error.
     * @throws MessageEOFException         if an end of message stream
     * @throws MessageFormatException      if this type conversion is invalid
     * @throws MessageNotReadableException if message in write-only mode.
     */
    public int readBytes(byte[] value) throws JMSException {
        if (mode == WRITE_ONLY) {
            throw new MessageNotReadableException("message is in write-only mode");
        }

        if (lastBA != null) {
            if (amount == lastBA.length) {
                lastBA = null;
                amount = 0;
                return -1;
            } else {
                int rest = lastBA.length - amount;
                int toRead = Math.min(rest, value.length);
                System.arraycopy(lastBA, amount, value, 0, toRead);
                amount += toRead;
                return toRead;
            }
        } else {
            Object obj = getValue(pos++);

            if (obj == null) {
                return -1;
            }

            if (obj instanceof byte[]) {
                lastBA = (byte[]) obj;
                int len = Math.min(lastBA.length, value.length);
                System.arraycopy(lastBA, 0, value, 0, len);
                amount = len;
                return len;
            }
            pos--;
            throw new MessageFormatException("can't convert message value to byte[]");
        }
    }

    /**
     * Read a Java object from the stream message.
     * 

*

Note that this method can be used to return in objectified format, * an object that had been written to the Stream with the equivalent * writeObject method call, or it's equivalent primitive * write method. * * @return a Java object from the stream message, in objectified * format (ie. if it set as an int, then a Integer is returned). * @throws JMSException if JMS fails to read message due to * some internal JMS error. * @throws MessageEOFException if an end of message stream * @throws MessageNotReadableException if message in write-only mode. */ public Object readObject() throws JMSException { if (mode == WRITE_ONLY) { throw new MessageNotReadableException("message is in write-only mode"); } Object value = getValue(pos++); Object newValue = null; if (value instanceof Character) newValue = new Character(((Character) value).charValue()); else if (value instanceof Boolean) newValue = new Boolean(((Boolean) value).booleanValue()); else if (value instanceof Byte) newValue = new Byte(((Byte) value).byteValue()); else if (value instanceof Short) newValue = new Short(((Short) value).shortValue()); else if (value instanceof Integer) newValue = new Integer(((Integer) value).intValue()); else if (value instanceof Long) newValue = new Long(((Long) value).longValue()); else if (value instanceof Float) newValue = new Float(((Float) value).floatValue()); else if (value instanceof Double) newValue = new Double(((Double) value).doubleValue()); else if (value instanceof String) newValue = new String((String) value); else if (value instanceof byte[]) newValue = ((byte[]) value).clone(); return newValue; } private void checkElements() { if (elements == null) { elements = new Primitive[DEFAULT_SIZE]; nElements = 0; } else { if (nElements == elements.length) { Primitive[] p = new Primitive[elements.length + DEFAULT_SIZE]; System.arraycopy(elements, 0, p, 0, nElements); elements = p; } } } /** * Write a boolean to the stream message. * The value true is written out as the value * (byte)1; the value false is written out as * the value (byte)0. * * @param value the boolean value to be written. * @throws JMSException if JMS fails to read message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeBoolean(boolean value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Boolean(value); } /** * Write out a byte to the stream message. * * @param value the byte value to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeByte(byte value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Byte(value); } /** * Write a short to the stream message. * * @param value the short to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeShort(short value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Short(value); } /** * Write a char to the stream message. * * @param value the char value to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeChar(char value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Char(value); } /** * Write an int to the stream message. * * @param value the int to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeInt(int value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Int(value); } /** * Write a long to the stream message. * * @param value the long to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeLong(long value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Long(value); } /** * Write a float to the stream message. * * @param value the float value to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeFloat(float value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Float(value); } /** * Write a double to the stream message. * * @param value the double value to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeDouble(double value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _Double(value); } /** * Write a string to the stream message. * * @param value the String value to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeString(String value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } checkElements(); elements[nElements++] = new _String(value); } /** * Write a byte array to the stream message. * * @param value the byte array to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeBytes(byte[] value) throws JMSException { writeBytes(value, 0, value.length); } /** * Write a portion of a byte array to the stream message. * * @param value the 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 JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. */ public void writeBytes(byte[] value, int offset, int length) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } byte[] array = new byte[length]; System.arraycopy(value, offset, array, 0, length); checkElements(); elements[nElements++] = new _Bytes(array); } /** * Write a Java object to the stream message. *

*

Note that this method only works for the objectified primitive * object types (Integer, Double, Long ...), String's and byte arrays. * * @param value the Java object to be written. * @throws JMSException if JMS fails to write message due to * some internal JMS error. * @throws MessageNotWriteableException if message in read-only mode. * @throws MessageFormatException if the object is invalid */ public void writeObject(Object value) throws JMSException { if (mode == READ_ONLY) { throw new MessageNotWriteableException("message is in read-only mode"); } Primitive newValue = null; if (value == null) newValue = new _String(null); else if (value instanceof Character) newValue = new _Char(((Character) value).charValue()); else if (value instanceof Boolean) newValue = new _Boolean(((Boolean) value).booleanValue()); else if (value instanceof Byte) newValue = new _Byte(((Byte) value).byteValue()); else if (value instanceof Short) newValue = new _Short(((Short) value).shortValue()); else if (value instanceof Integer) newValue = new _Int(((Integer) value).intValue()); else if (value instanceof Long) newValue = new _Long(((Long) value).longValue()); else if (value instanceof Float) newValue = new _Float(((Float) value).floatValue()); else if (value instanceof Double) newValue = new _Double(((Double) value).doubleValue()); else if (value instanceof String) newValue = new _String((String) value); else if (value instanceof byte[]) newValue = new _Bytes((byte[]) value); if (newValue != null) { checkElements(); elements[nElements++] = newValue; } else { throw new JMSException("writeObject supports only Boolean, Byte, Short, Integer, Long, Float, Double, byte[], or String"); } } /** * Put the message in read-only mode, and reposition the stream * to the beginning. * * @throws JMSException if JMS fails to reset the message due to * some internal JMS error. * @throws MessageFormatException if message has an invalid * format */ public void reset() throws JMSException { pos = 0; mode = READ_ONLY; } /** * Clear out the message body. All other parts of the message are left * untouched. * * @throws JMSException if JMS fails to due to some internal JMS error. */ public void clearBody() throws JMSException { elements = null; nElements = 0; pos = 0; mode = WRITE_ONLY; } public String toString() { StringBuffer b = new StringBuffer("[StreamMessageImpl "); b.append(super.toString()); b.append(" elements="); b.append(elements); b.append(" nElements="); b.append(nElements); b.append("]"); return b.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy