package org.mockejb.jms;
import java.util.*;
import javax.jms.*;
public class StreamMessageImpl extends MessageImpl implements StreamMessage {
private final List streamData = new ArrayList();
private int position;
private int byteArrayPosition;
public StreamMessageImpl() {
super();
}
public StreamMessageImpl(StreamMessage msg) throws JMSException {
super(msg);
setBody(msg);
}
private void setBody(StreamMessage msg) throws JMSException {
int elementsRemaining = 0;
while (true) {
try {
msg.readObject();
elementsRemaining++;
} catch (MessageEOFException ex) {
extractElements(msg);
msg.reset();
int moveTo = streamData.size() - elementsRemaining;
while (moveTo-- > 0) {
msg.readObject();
}
break;
} catch (MessageNotReadableException ex) {
extractElements(msg);
msg.clearBody();
for (int i = 0; i < streamData.size(); i++) {
msg.writeObject(streamData.get(i));
}
break;
}
}
}
private void extractElements(StreamMessage msg) throws JMSException {
msg.reset();
while (true) {
try {
writeObject(msg.readObject());
} catch (MessageEOFException ex) {
break;
}
}
}
public void clearBody() throws JMSException {
super.clearBody();
streamData.clear();
}
public boolean readBoolean() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
boolean result;
if (value instanceof Boolean) {
result = ((Boolean) value).booleanValue();
} else if (value == null || value instanceof String) {
result = Boolean.valueOf((String) value).booleanValue();
} else {
throw new MessageFormatException("Current position does not contain valid Boolean value!");
}
position++;
return result;
}
public byte readByte() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
byte result;
if (value instanceof Byte) {
result = ((Byte) value).byteValue();
} else if (value == null || value instanceof String) {
result = Byte.valueOf((String) value).byteValue();
} else {
throw new MessageFormatException("Current position does not contain valid Byte value!");
}
position++;
return result;
}
public short readShort() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
short result;
if (value instanceof Byte || value instanceof Short) {
result = ((Number) value).shortValue();
} else if (value == null || value instanceof String) {
result = Short.valueOf((String) value).shortValue();
} else {
throw new MessageFormatException("Current position does not contain valid Short value!");
}
position++;
return result;
}
public char readChar() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
char result;
if (value == null) {
throw new NullPointerException();
} else if (value instanceof Character) {
result = ((Character) value).charValue();
} else {
throw new MessageFormatException("Current position does not contain valid Char value!");
}
position++;
return result;
}
public int readInt() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
int result;
if (value instanceof Byte
|| value instanceof Short
|| value instanceof Integer) {
result = ((Number) value).intValue();
} else if (value == null || value instanceof String) {
result = Integer.valueOf((String) value).intValue();
} else {
throw new MessageFormatException("Current position does not contain valid Integer value!");
}
position++;
return result;
}
public long readLong() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
long result;
if (value instanceof Byte
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long) {
result = ((Number) value).longValue();
} else if (value == null || value instanceof String) {
result = Long.valueOf((String) value).longValue();
} else {
throw new MessageFormatException("Current position does not contain valid Long value!");
}
position++;
return result;
}
public float readFloat() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
float result;
if (value instanceof Float) {
result = ((Float) value).floatValue();
} else if (value == null || value instanceof String) {
result = Float.valueOf((String) value).floatValue();
} else {
throw new MessageFormatException("Current position does not contain valid Float value!");
}
position++;
return result;
}
public double readDouble() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
double result;
if (value instanceof Float || value instanceof Double) {
result = ((Number) value).doubleValue();
} else if (value == null || value instanceof String) {
result = Double.valueOf((String) value).doubleValue();
} else {
throw new MessageFormatException("Current position does not contain valid Double value!");
}
position++;
return result;
}
public String readString() throws JMSException {
checkBodyReadable();
checkEOF();
Object value = streamData.get(position);
if (value instanceof byte[]) {
throw new MessageFormatException("Current position does not contain valid UTF value!");
}
position++;
if (value == null) {
return null;
}
return value.toString();
}
public int readBytes(byte[] bytes) throws JMSException {
checkBodyReadable();
checkEOF();
if (bytes == null) {
throw new NullPointerException();
}
Object value = streamData.get(position);
if (byteArrayPosition == -1 || value == null) {
position++;
byteArrayPosition = 0;
return -1;
}
if (!(value instanceof byte[])) {
throw new MessageFormatException("Current position does not contain valid byte[] value!");
}
byte[] byteArray = (byte[]) value;
if (byteArray.length == 0) {
byteArrayPosition = -1;
return 0;
}
int numOfBytesToCopy;
int remainingBytesToCopy = byteArray.length - byteArrayPosition;
int startOffset = byteArrayPosition;
if (remainingBytesToCopy <= bytes.length) {
numOfBytesToCopy = remainingBytesToCopy;
byteArrayPosition = -1;
} else {
numOfBytesToCopy = bytes.length;
byteArrayPosition += numOfBytesToCopy;
}
int i = 0;
int j = numOfBytesToCopy;
while (j > 0) {
bytes[i++] = byteArray[startOffset++];
j--;
}
return numOfBytesToCopy;
}
public Object readObject() throws JMSException {
checkBodyReadable();
checkEOF();
Object result = streamData.get(position++);
if (result instanceof byte[]) {
result = ((byte[]) result).clone();
}
return result;
}
public void writeBoolean(boolean value) throws JMSException {
checkBodyWriteable();
streamData.add(new Boolean(value));
}
public void writeByte(byte value) throws JMSException {
checkBodyWriteable();
streamData.add(new Byte(value));
}
public void writeShort(short value) throws JMSException {
checkBodyWriteable();
streamData.add(new Short(value));
}
public void writeChar(char value) throws JMSException {
checkBodyWriteable();
streamData.add(new Character(value));
}
public void writeInt(int value) throws JMSException {
checkBodyWriteable();
streamData.add(new Integer(value));
}
public void writeLong(long value) throws JMSException {
checkBodyWriteable();
streamData.add(new Long(value));
}
public void writeFloat(float value) throws JMSException {
checkBodyWriteable();
streamData.add(new Float(value));
}
public void writeDouble(double value) throws JMSException {
checkBodyWriteable();
streamData.add(new Double(value));
}
public void writeString(String value) throws JMSException {
checkBodyWriteable();
streamData.add(value);
}
public void writeBytes(byte[] bytes) throws JMSException {
checkBodyWriteable();
if (bytes == null) {
streamData.add(null);
return;
}
writeBytes(bytes, 0, bytes.length);
}
public void writeBytes(byte[] bytes, int offset, int length)
throws JMSException {
checkBodyWriteable();
if (bytes == null) {
streamData.add(null);
return;
}
if (offset < 0 || length < 0 || (offset + length) > bytes.length) {
throw new IllegalArgumentException();
}
byte[] bytesToAdd = new byte[length];
for (int i = 0; i < length; bytesToAdd[i++] = bytes[offset++]);
streamData.add(bytesToAdd);
}
public void writeObject(Object value) throws JMSException {
checkBodyWriteable();
if (!(value == null
|| value instanceof Boolean
|| value instanceof Byte
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long
|| value instanceof Float
|| value instanceof Double
|| value instanceof String
|| value instanceof Character
|| value instanceof byte[])) {
throw new MessageFormatException("Incorrect object type!");
}
if (value instanceof byte[]) {
value = ((byte[]) value).clone();
}
streamData.add(value);
}
public void reset() throws JMSException {
setBodyReadOnly();
position = 0;
byteArrayPosition = 0;
}
private void checkEOF() throws MessageEOFException {
if (position >= streamData.size()) {
throw new MessageEOFException("EOF reached!");
}
}
Object[] getStreamData() {
return streamData.toArray();
}
void resetBody() throws JMSException {
reset();
}
}