org.apache.qpid.jms.message.JmsStreamMessage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qpid-jms-client Show documentation
Show all versions of qpid-jms-client Show documentation
The core JMS Client implementation
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.qpid.jms.message;
import jakarta.jms.JMSException;
import jakarta.jms.MessageFormatException;
import jakarta.jms.StreamMessage;
import org.apache.qpid.jms.message.facade.JmsStreamMessageFacade;
/**
* JMS Stream message implementation.
*/
public class JmsStreamMessage extends JmsMessage implements StreamMessage {
private static final int NO_BYTES_IN_FLIGHT = -1;
private final JmsStreamMessageFacade facade;
private byte[] bytes;
private int remainingBytes = NO_BYTES_IN_FLIGHT;
public JmsStreamMessage(JmsStreamMessageFacade facade) {
super(facade);
this.facade = facade;
}
@Override
public JmsStreamMessage copy() throws JMSException {
JmsStreamMessage other = new JmsStreamMessage(facade.copy());
other.copy(this);
return other;
}
@Override
public void onSend(long producerTtl) throws JMSException {
reset();
super.onSend(producerTtl);
}
@Override
public void clearBody() throws JMSException {
super.clearBody();
bytes = null;
remainingBytes = -1;
}
@Override
public boolean readBoolean() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Boolean result = null;
Object value;
value = facade.peek();
if (value instanceof Boolean) {
result = (Boolean) value;
} else if (value instanceof String || value == null) {
result = Boolean.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public byte readByte() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Byte result = null;
Object value = facade.peek();
if (value instanceof Byte) {
result = (Byte) value;
} else if (value instanceof String || value == null) {
result = Byte.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public short readShort() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Short result = null;
Object value = facade.peek();
if (value instanceof Short) {
result = (Short) value;
} else if (value instanceof Byte) {
result = ((Byte) value).shortValue();
} else if (value instanceof String || value == null) {
result = Short.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public char readChar() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Character result = null;
Object value = facade.peek();
if (value instanceof Character) {
result = (Character) value;
} else if (value == null) {
throw new NullPointerException("Cannot convert NULL value to char.");
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public int readInt() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Integer result = null;
Object value = facade.peek();
if (value instanceof Integer) {
result = (Integer) value;
} else if (value instanceof Short) {
result = ((Short) value).intValue();
} else if (value instanceof Byte) {
result = ((Byte) value).intValue();
} else if (value instanceof String || value == null) {
result = Integer.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public long readLong() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Long result = null;
Object value = facade.peek();
if (value instanceof Long) {
result = (Long) value;
} else if (value instanceof Integer) {
result = ((Integer) value).longValue();
} else if (value instanceof Short) {
result = ((Short) value).longValue();
} else if (value instanceof Byte) {
result = ((Byte) value).longValue();
} else if (value instanceof String || value == null) {
result = Long.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public float readFloat() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Float result = null;
Object value = facade.peek();
if (value instanceof Float) {
result = (Float) value;
} else if (value instanceof String || value == null) {
result = Float.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public double readDouble() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Double result = null;
Object value = facade.peek();
if (value instanceof Double) {
result = (Double) value;
} else if (value instanceof Float) {
result = ((Float) value).doubleValue();
} else if (value instanceof String || value == null) {
result = Double.valueOf((String) value);
} else {
throw new MessageFormatException(
"stream value: " + value.getClass().getSimpleName() + " cannot be converted to a boolean.");
}
facade.pop();
return result;
}
@Override
public String readString() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
String result = null;
Object value = facade.peek();
if (value == null) {
result = null;
} else if (value instanceof String) {
result = (String) value;
} else if (value instanceof Float) {
result = value.toString();
} else if (value instanceof Double) {
result = value.toString();
} else if (value instanceof Long) {
result = value.toString();
} else if (value instanceof Integer) {
result = value.toString();
} else if (value instanceof Short) {
result = value.toString();
} else if (value instanceof Byte) {
result = value.toString();
} else if (value instanceof Boolean) {
result = value.toString();
} else if (value instanceof Character) {
result = value.toString();
} else {
throw new MessageFormatException("stream cannot convert byte array to String");
}
facade.pop();
return result;
}
@Override
public int readBytes(byte[] target) throws JMSException {
checkWriteOnlyBody();
if (target == null) {
throw new NullPointerException("target byte array was null");
}
if (remainingBytes == NO_BYTES_IN_FLIGHT) {
Object data = facade.peek();
if (data == null) {
facade.pop();
return -1;
} else if (!(data instanceof byte[])) {
throw new MessageFormatException("Next stream value is not a byte array");
}
bytes = (byte[]) data;
remainingBytes = bytes.length;
} else if (remainingBytes == 0) {
// We previously read all the bytes, but must have filled the destination array.
remainingBytes = NO_BYTES_IN_FLIGHT;
bytes = null;
facade.pop();
return -1;
}
int previouslyRead = bytes.length - remainingBytes;
int lengthToCopy = Math.min(target.length, remainingBytes);
if (lengthToCopy > 0) {
System.arraycopy(bytes, previouslyRead, target, 0, lengthToCopy);
}
remainingBytes -= lengthToCopy;
if (remainingBytes == 0 && lengthToCopy < target.length) {
// All bytes have been read and the destination array was not filled on this
// call, so the return will enable the caller to determine completion immediately.
remainingBytes = NO_BYTES_IN_FLIGHT;
bytes = null;
facade.pop();
}
return lengthToCopy;
}
@Override
public Object readObject() throws JMSException {
checkWriteOnlyBody();
checkBytesInFlight();
Object result = null;
Object value = facade.peek();
if (value == null) {
result = null;
} else if (value instanceof String) {
result = value;
} else if (value instanceof Float) {
result = value;
} else if (value instanceof Double) {
result = value;
} else if (value instanceof Long) {
result = value;
} else if (value instanceof Integer) {
result = value;
} else if (value instanceof Short) {
result = value;
} else if (value instanceof Byte) {
result = value;
} else if (value instanceof Boolean) {
result = value;
} else if (value instanceof Character) {
result = value;
} else if (value instanceof byte[]) {
byte[] original = (byte[]) value;
result = new byte[original.length];
System.arraycopy(original, 0, result, 0, original.length);
} else {
throw new MessageFormatException("Unknown type found in stream");
}
facade.pop();
return result;
}
@Override
public void writeBoolean(boolean value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeByte(byte value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeShort(short value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeChar(char value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeInt(int value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeLong(long value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeFloat(float value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeDouble(double value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeString(String value) throws JMSException {
checkReadOnlyBody();
facade.put(value);
}
@Override
public void writeBytes(byte[] value) throws JMSException {
writeBytes(value, 0, value.length);
}
@Override
public void writeBytes(byte[] value, int offset, int length) throws JMSException {
checkReadOnlyBody();
byte[] copy = new byte[length];
System.arraycopy(value, offset, copy, 0, length);
facade.put(copy);
}
@Override
public void writeObject(Object value) throws JMSException {
checkReadOnlyBody();
if (value == null) {
facade.put(null);
} else if (value instanceof String) {
facade.put(value);
} else if (value instanceof Character) {
facade.put(value);
} else if (value instanceof Boolean) {
facade.put(value);
} else if (value instanceof Byte) {
facade.put(value);
} else if (value instanceof Short) {
facade.put(value);
} else if (value instanceof Integer) {
facade.put(value);
} else if (value instanceof Long) {
facade.put(value);
} else if (value instanceof Float) {
facade.put(value);
} else if (value instanceof Double) {
facade.put(value);
} else if (value instanceof byte[]) {
writeBytes((byte[]) value);
} else {
throw new MessageFormatException("Unsupported Object type: " + value.getClass().getSimpleName());
}
}
@Override
public void reset() throws JMSException {
checkReadOnly();
bytes = null;
remainingBytes = NO_BYTES_IN_FLIGHT;
setReadOnlyBody(true);
facade.reset();
}
@Override
public String toString() {
return "JmsStreamMessage { " + facade.toString() + " }";
}
@Override
public boolean isBodyAssignableTo(@SuppressWarnings("rawtypes") Class target) throws JMSException {
return false;
}
private void checkBytesInFlight() throws MessageFormatException {
if (remainingBytes != NO_BYTES_IN_FLIGHT) {
throw new MessageFormatException(
"Partially read byte[] entry still being retrieved using readBytes(byte[] dest)");
}
}
}