001: package org.mockejb.jms;
002:
003: import javax.jms.*;
004: import java.io.*;
005:
006: /**
007: * <code>BytesMessage</code> implementation.
008: * @author Dimitar Gospodinov
009: * @see javax.jms.BytesMessage
010: */
011: public class BytesMessageImpl extends MessageImpl implements
012: BytesMessage {
013:
014: private final ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
015: private ByteArrayInputStream bytesIn;
016: private DataInputStream dataIn;
017: private DataOutputStream dataOut;
018:
019: /**
020: * Creates empty <code>BytesMessage</code>
021: */
022: public BytesMessageImpl() throws JMSException {
023: clearBody();
024: }
025:
026: /**
027: * Creates <code>BytesMessage</code> and copies its header, properties and
028: * body from <code>msg<code>
029: * The state of <code>msg</code> is not changed.
030: * @param msg message to copy from
031: * @throws JMSException
032: */
033: public BytesMessageImpl(BytesMessage msg) throws JMSException {
034: super (msg);
035: clearBody();
036: setBody(msg);
037: }
038:
039: /**
040: * Extracts body data from <code>msg</code> and sets it to this message.
041: * The state of <code>msg</code> is not changed.
042: * @param msg
043: * @throws JMSException
044: */
045: private void setBody(BytesMessage msg) throws JMSException {
046: // Number of bytes remaining until the end of the byte stream
047: int bytesRemaining = 0;
048: byte[] sourceBytes = null;
049:
050: while (true) {
051: /*
052: * Try to read from the message. If the read succeeds then read until EOF.
053: * This will give us current position in the byte stream.
054: * We have to restore to this position before the method returns.
055: *
056: * If the read fails with MessageNotReadableException then proceed to extracting
057: * the body.
058: */
059: try {
060: msg.readByte();
061: bytesRemaining++;
062: } catch (MessageEOFException ex) {
063: /*
064: * Reached EOF.
065: * Now <code>bytesRemaining</code> contains number of bytes
066: * remaining in the byte stream of <code>msg</code>
067: * Next - reset <code>msg</code> and "extract" all bytes into
068: * <code>sourceBytes</code>
069: */
070: sourceBytes = extractBytes(msg);
071: /*
072: * Reset the message and move to the original position in the byte stream
073: * by reading the required number of bytes.
074: */
075: msg.reset();
076: msg.readBytes(new byte[sourceBytes.length
077: - bytesRemaining]);
078: break;
079: } catch (MessageNotReadableException ex) {
080: // Message is in Write-Only mode
081: sourceBytes = extractBytes(msg);
082: /*
083: * At this point <code>msg</code> is in Read-Only mode
084: * Switch to Write-Only mode and restore the original byte stream.
085: */
086: msg.clearBody();
087: msg.writeBytes(sourceBytes);
088: break;
089: }
090: }
091: writeBytes(sourceBytes);
092: }
093:
094: /**
095: * Calls <code>msg.reset</code> and counts number of bytes in the message.
096: * The implementation is trivial and efficiency is ignored.
097: * Creates byte array, populates it with all bytes from <code>msg</code> and
098: * returns it.
099: * @param msg
100: * @return <code>byte[]</code> that represents the body of <code>msg</code>
101: * @throws JMSException
102: */
103: private byte[] extractBytes(BytesMessage msg) throws JMSException {
104: msg.reset();
105: int numberOfBytes = 0;
106: while (true) {
107: try {
108: msg.readByte();
109: numberOfBytes++;
110: } catch (MessageEOFException ex) {
111: break;
112: }
113: }
114: byte[] result = new byte[numberOfBytes];
115: msg.reset();
116: msg.readBytes(result);
117: return result;
118: }
119:
120: /**
121: * @see javax.jms.BytesMessage#reset()
122: */
123: public void reset() {
124: setBodyReadOnly();
125: if (dataOut != null) {
126: dataOut = null;
127: }
128: bytesIn = new ByteArrayInputStream(bytesOut.toByteArray());
129: dataIn = new DataInputStream(bytesIn);
130: }
131:
132: /**
133: * @see javax.jms.BytesMessage#clearBody()
134: */
135: public void clearBody() throws JMSException {
136: super .clearBody();
137: if (dataIn != null) {
138: dataIn = null;
139: bytesIn = null;
140: }
141: bytesOut.reset();
142: dataOut = new DataOutputStream(bytesOut);
143: }
144:
145: /**
146: * Returns body length. Method is part of <code>BytesMessage</code>
147: * interface, version 1.1
148: * @return body length.
149: */
150: public long getBodyLength() throws JMSException {
151: checkBodyReadable();
152: return bytesOut.size();
153: }
154:
155: /**
156: * @see javax.jms.BytesMessage#readBoolean()
157: */
158: public boolean readBoolean() throws JMSException {
159: checkBodyReadable();
160: try {
161: return dataIn.readBoolean();
162: } catch (EOFException ex) {
163: throw new MessageEOFException(ex.getMessage());
164: } catch (IOException ex) {
165: throw new JMSException(ex.getMessage());
166: }
167: }
168:
169: /**
170: * @see javax.jms.BytesMessage#readByte()
171: */
172: public byte readByte() throws JMSException {
173: checkBodyReadable();
174: try {
175: return dataIn.readByte();
176: } catch (EOFException ex) {
177: throw new MessageEOFException(ex.getMessage());
178: } catch (IOException ex) {
179: throw new JMSException(ex.getMessage());
180: }
181: }
182:
183: /**
184: * @see javax.jms.BytesMessage#readUnsignedByte()
185: */
186: public int readUnsignedByte() throws JMSException {
187: checkBodyReadable();
188: try {
189: return dataIn.readUnsignedByte();
190: } catch (EOFException ex) {
191: throw new MessageEOFException(ex.getMessage());
192: } catch (IOException ex) {
193: throw new JMSException(ex.getMessage());
194: }
195: }
196:
197: /**
198: * @see javax.jms.BytesMessage#readShort()
199: */
200: public short readShort() throws JMSException {
201: checkBodyReadable();
202: try {
203: return dataIn.readShort();
204: } catch (EOFException ex) {
205: throw new MessageEOFException(ex.getMessage());
206: } catch (IOException ex) {
207: throw new JMSException(ex.getMessage());
208: }
209: }
210:
211: /**
212: * @see javax.jms.BytesMessage#readUnsignedShort()
213: */
214: public int readUnsignedShort() throws JMSException {
215: checkBodyReadable();
216: try {
217: return dataIn.readUnsignedShort();
218: } catch (EOFException ex) {
219: throw new MessageEOFException(ex.getMessage());
220: } catch (IOException ex) {
221: throw new JMSException(ex.getMessage());
222: }
223: }
224:
225: /**
226: * @see javax.jms.BytesMessage#readChar()
227: */
228: public char readChar() throws JMSException {
229: checkBodyReadable();
230: try {
231: return dataIn.readChar();
232: } catch (EOFException ex) {
233: throw new MessageEOFException(ex.getMessage());
234: } catch (IOException ex) {
235: throw new JMSException(ex.getMessage());
236: }
237: }
238:
239: /**
240: * @see javax.jms.BytesMessage#readInt()
241: */
242: public int readInt() throws JMSException {
243: checkBodyReadable();
244: try {
245: return dataIn.readInt();
246: } catch (EOFException ex) {
247: throw new MessageEOFException(ex.getMessage());
248: } catch (IOException ex) {
249: throw new JMSException(ex.getMessage());
250: }
251: }
252:
253: /**
254: * @see javax.jms.BytesMessage#readLong()
255: */
256: public long readLong() throws JMSException {
257: checkBodyReadable();
258: try {
259: return dataIn.readLong();
260: } catch (EOFException ex) {
261: throw new MessageEOFException(ex.getMessage());
262: } catch (IOException ex) {
263: throw new JMSException(ex.getMessage());
264: }
265: }
266:
267: /**
268: * @see javax.jms.BytesMessage#readFloat()
269: */
270: public float readFloat() throws JMSException {
271: checkBodyReadable();
272: try {
273: return dataIn.readFloat();
274: } catch (EOFException ex) {
275: throw new MessageEOFException(ex.getMessage());
276: } catch (IOException ex) {
277: throw new JMSException(ex.getMessage());
278: }
279: }
280:
281: /**
282: * @see javax.jms.BytesMessage#readDouble()
283: */
284: public double readDouble() throws JMSException {
285: checkBodyReadable();
286: try {
287: return dataIn.readDouble();
288: } catch (EOFException ex) {
289: throw new MessageEOFException(ex.getMessage());
290: } catch (IOException ex) {
291: throw new JMSException(ex.getMessage());
292: }
293: }
294:
295: /**
296: * @see javax.jms.BytesMessage#readUTF()
297: */
298: public String readUTF() throws JMSException {
299: checkBodyReadable();
300: String result;
301: try {
302: try {
303: dataIn.mark(dataIn.available());
304: result = dataIn.readUTF();
305: dataIn.mark(0);
306: } catch (UTFDataFormatException ex) {
307: throw new MessageFormatException(ex.getMessage());
308: } catch (EOFException ex) {
309: throw new MessageEOFException(ex.getMessage());
310: } finally {
311: dataIn.reset();
312: dataIn.mark(0);
313: }
314: } catch (IOException ex) {
315: throw new JMSException(ex.getMessage());
316: }
317: return result;
318: }
319:
320: /**
321: * @see javax.jms.BytesMessage#readBytes(byte[])
322: */
323: public int readBytes(byte[] bytes) throws JMSException {
324: checkBodyReadable();
325: try {
326: return dataIn.read(bytes);
327: } catch (IOException ex) {
328: throw new JMSException(ex.getMessage());
329: }
330: }
331:
332: /**
333: * @see javax.jms.BytesMessage#readBytes(byte[], int)
334: */
335: public int readBytes(byte[] bytes, int length) throws JMSException {
336: checkBodyReadable();
337: try {
338: return dataIn.read(bytes, 0, length);
339: } catch (IOException ex) {
340: throw new JMSException(ex.getMessage());
341: }
342: }
343:
344: /**
345: * @see javax.jms.BytesMessage#writeBoolean(boolean)
346: */
347: public void writeBoolean(boolean value) throws JMSException {
348: checkBodyWriteable();
349: try {
350: dataOut.writeBoolean(value);
351: } catch (IOException ex) {
352: throw new JMSException(ex.getMessage());
353: }
354: }
355:
356: /**
357: * @see javax.jms.BytesMessage#writeByte(byte)
358: */
359: public void writeByte(byte value) throws JMSException {
360: checkBodyWriteable();
361: try {
362: dataOut.writeByte(value);
363: } catch (IOException ex) {
364: throw new JMSException(ex.getMessage());
365: }
366: }
367:
368: /**
369: * @see javax.jms.BytesMessage#writeShort(short)
370: */
371: public void writeShort(short value) throws JMSException {
372: checkBodyWriteable();
373: try {
374: dataOut.writeShort(value);
375: } catch (IOException ex) {
376: throw new JMSException(ex.getMessage());
377: }
378: }
379:
380: /**
381: * @see javax.jms.BytesMessage#writeChar(char)
382: */
383: public void writeChar(char value) throws JMSException {
384: checkBodyWriteable();
385: try {
386: dataOut.writeChar(value);
387: } catch (IOException ex) {
388: throw new JMSException(ex.getMessage());
389: }
390: }
391:
392: /**
393: * @see javax.jms.BytesMessage#writeInt(int)
394: */
395: public void writeInt(int value) throws JMSException {
396: checkBodyWriteable();
397: try {
398: dataOut.writeInt(value);
399: } catch (IOException ex) {
400: throw new JMSException(ex.getMessage());
401: }
402: }
403:
404: /**
405: * @see javax.jms.BytesMessage#writeLong(long)
406: */
407: public void writeLong(long value) throws JMSException {
408: checkBodyWriteable();
409: try {
410: dataOut.writeLong(value);
411: } catch (IOException ex) {
412: throw new JMSException(ex.getMessage());
413: }
414: }
415:
416: /**
417: * @see javax.jms.BytesMessage#writeFloat(float)
418: */
419: public void writeFloat(float value) throws JMSException {
420: checkBodyWriteable();
421: try {
422: dataOut.writeFloat(value);
423: } catch (IOException ex) {
424: throw new JMSException(ex.getMessage());
425: }
426: }
427:
428: /**
429: * @see javax.jms.BytesMessage#writeDouble(double)
430: */
431: public void writeDouble(double value) throws JMSException {
432: checkBodyWriteable();
433: try {
434: dataOut.writeDouble(value);
435: } catch (IOException ex) {
436: throw new JMSException(ex.getMessage());
437: }
438: }
439:
440: /**
441: * @see javax.jms.BytesMessage#writeUTF(java.lang.String)
442: */
443: public void writeUTF(String value) throws JMSException {
444: checkBodyWriteable();
445: try {
446: dataOut.writeUTF(value);
447: } catch (IOException ex) {
448: throw new JMSException(ex.getMessage());
449: }
450: }
451:
452: /**
453: * @see javax.jms.BytesMessage#writeBytes(byte[])
454: */
455: public void writeBytes(byte[] bytes) throws JMSException {
456: checkBodyWriteable();
457: try {
458: dataOut.write(bytes);
459: } catch (IOException ex) {
460: throw new JMSException(ex.getMessage());
461: }
462: }
463:
464: /**
465: * @see javax.jms.BytesMessage#writeBytes(byte[], int, int)
466: */
467: public void writeBytes(byte[] bytes, int offset, int length)
468: throws JMSException {
469:
470: checkBodyWriteable();
471: try {
472: dataOut.write(bytes, offset, length);
473: } catch (IOException ex) {
474: throw new JMSException(ex.getMessage());
475: }
476: }
477:
478: /**
479: * @see javax.jms.BytesMessage#writeObject(java.lang.Object)
480: */
481: public void writeObject(Object value) throws JMSException {
482: checkBodyWriteable();
483:
484: if (value == null) {
485: throw new NullPointerException();
486: }
487:
488: if (value instanceof Boolean) {
489: writeBoolean(((Boolean) value).booleanValue());
490: }
491: if (value instanceof Byte) {
492: writeByte(((Byte) value).byteValue());
493: }
494: if (value instanceof Short) {
495: writeShort(((Short) value).shortValue());
496: }
497: if (value instanceof Integer) {
498: writeInt(((Integer) value).intValue());
499: }
500: if (value instanceof Long) {
501: writeLong(((Long) value).longValue());
502: }
503: if (value instanceof Float) {
504: writeFloat(((Float) value).floatValue());
505: }
506: if (value instanceof Double) {
507: writeDouble(((Double) value).doubleValue());
508: }
509: if (value instanceof String) {
510: writeUTF((String) value);
511: }
512: if (value instanceof byte[]) {
513: writeBytes((byte[]) value);
514: }
515:
516: throw new MessageFormatException("Incorrect object type!");
517: }
518:
519: // Non-standard methods
520:
521: /**
522: * Sets message body in read-only mode.
523: * @throws JMSException
524: */
525: void resetBody() throws JMSException {
526: reset();
527: }
528:
529: }
|