1 /*
2 * @(#)StreamMessageImpl.java
3 *
4 * JFoxMQ the open source JMS MOM.
5 *
6 * Corpyright 2002-2003 Huihoo Power, Inc. All Rights Reserved. This software
7 * is licensed under LGPL license.
8 *
9 * For more information, please visit: http://www.huihoo.org
10 */
11
12 package org.huihoo.jfox.ms.jms.message;
13
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataInputStream;
17 import java.io.DataOutputStream;
18 import java.io.EOFException;
19 import java.io.IOException;
20 import java.io.Serializable;
21
22 import javax.jms.JMSException;
23 import javax.jms.MessageEOFException;
24 import javax.jms.MessageFormatException;
25 import javax.jms.MessageNotReadableException;
26 import javax.jms.MessageNotWriteableException;
27 import javax.jms.StreamMessage;
28
29 /***
30 * <p>
31 * A <CODE>BytesMessage</CODE> object is used to send a message containing a
32 * stream of uninterpreted bytes. It inherits from the <CODE>Message</CODE>
33 * interface and adds a bytes message body. The receiver of the message
34 * supplies the interpretation of the bytes.
35 * </p>
36 *
37 * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter.Cheng</a>
38 * @version Revision: 1.1 Date: 2002-12-08 22:46:11
39 */
40
41 public class StreamMessageImpl
42 extends MessageImpl
43 implements StreamMessage, Serializable {
44
45 public static final byte TYPE_NULL = 0;
46 public static final byte TYPE_BOOLEAN = 1;
47 public static final byte TYPE_BYTE = 2;
48 public static final byte TYPE_BYTE_ARRAY = 3;
49 public static final byte TYPE_SHORT = 4;
50 public static final byte TYPE_CHAR = 5;
51 public static final byte TYPE_INT = 6;
52 public static final byte TYPE_LONG = 7;
53 public static final byte TYPE_FLOAT = 8;
54 public static final byte TYPE_DOUBLE = 9;
55 public static final byte TYPE_STRING = 10;
56
57 private DataOutputStream dos = null;
58 private DataInputStream dis = null;
59 private ByteArrayOutputStream baos = null;
60 private ByteArrayInputStream bais = null;
61 private byte[] buffer = null;
62 private int readBytes = 0;
63 private int byteArrayLength = 0;
64
65 private static final String[] TYPE_NAMES =
66 {
67 "null",
68 "boolean",
69 "byte",
70 "byte[]",
71 "short",
72 "char",
73 "int",
74 "long",
75 "float",
76 "double",
77 "String" };
78
79 /***
80 * Default constructor.
81 */
82 public StreamMessageImpl() {
83 super();
84 buffer = new byte[0];
85 baos = new ByteArrayOutputStream();
86 dos = new DataOutputStream(baos);
87 }
88
89 /***
90 * Reads a <code>boolean</code> from the stream message.
91 *
92 * @return the <code>boolean</code> value read
93 *
94 * @exception JMSException
95 * if the JMS provider fails to read the message due to some
96 * internal error.
97 * @exception MessageEOFException
98 * if unexpected end of message stream has been reached.
99 * @exception MessageFormatException
100 * if this type conversion is invalid.
101 * @exception MessageNotReadableException
102 * if the message is in write-only mode.
103 *
104 * @see javax.jms.StreamMessage#readBoolean()
105 */
106 public boolean readBoolean() throws JMSException {
107 prepareRead();
108 try {
109 return FormatHelper.getBoolean(readNext());
110 } catch (MessageFormatException e) {
111 try {
112 dis.reset();
113 } catch (IOException ex) {
114 throw new JMSException(ex.getMessage());
115 }
116 throw new MessageFormatException(e.getMessage());
117 }
118 }
119
120 /***
121 * Reads a <code>byte</code> value from the stream message.
122 *
123 * @return the next byte from the stream message as a 8-bit <code>byte</code>
124 *
125 * @exception JMSException
126 * if the JMS provider fails to read the message due to some
127 * internal error.
128 * @exception MessageEOFException
129 * if unexpected end of message stream has been reached.
130 * @exception MessageFormatException
131 * if this type conversion is invalid.
132 * @exception MessageNotReadableException
133 * if the message is in write-only mode.
134 *
135 * @see javax.jms.StreamMessage#readByte()
136 */
137 public byte readByte() throws JMSException {
138 prepareRead();
139 try {
140 return FormatHelper.getByte(readNext());
141 } catch (MessageFormatException e) {
142 try {
143 dis.reset();
144 } catch (IOException ex) {
145 throw new JMSException(ex.getMessage());
146 }
147 throw new MessageFormatException(e.getMessage());
148
149 } catch (NumberFormatException e) {
150 try {
151 dis.reset();
152 } catch (IOException ex) {
153 throw new JMSException(ex.getMessage());
154 }
155 throw new JMSException(e.getMessage());
156 }
157 }
158
159 /***
160 * Reads a 16-bit integer from the stream message.
161 *
162 * @return a 16-bit integer from the stream message
163 *
164 * @exception JMSException
165 * if the JMS provider fails to read the message due to some
166 * internal error.
167 * @exception MessageEOFException
168 * if unexpected end of message stream has been reached.
169 * @exception MessageFormatException
170 * if this type conversion is invalid.
171 * @exception MessageNotReadableException
172 * if the message is in write-only mode.
173 *
174 * @see javax.jms.StreamMessage#readShort()
175 */
176 public short readShort() throws JMSException {
177 prepareRead();
178 try {
179 return FormatHelper.getShort(readNext());
180 } catch (MessageFormatException e) {
181 try {
182 dis.reset();
183 } catch (IOException ex) {
184 throw new JMSException(ex.getMessage());
185 }
186 throw new MessageFormatException(e.getMessage());
187 } catch (NumberFormatException e) {
188 try {
189 dis.reset();
190 } catch (IOException ex) {
191 throw new JMSException(ex.getMessage());
192 }
193 throw new JMSException(e.getMessage());
194 }
195 }
196
197 /***
198 * Reads a Unicode character value from the stream message.
199 *
200 * @return a Unicode character from the stream message
201 *
202 * @exception JMSException
203 * if the JMS provider fails to read the message due to some
204 * internal error.
205 * @exception MessageEOFException
206 * if unexpected end of message stream has been reached.
207 * @exception MessageFormatException
208 * if this type conversion is invalid
209 * @exception MessageNotReadableException
210 * if the message is in write-only mode.
211 *
212 * @see javax.jms.StreamMessage#readChar()
213 */
214 public char readChar() throws JMSException {
215 prepareRead();
216 try {
217 return FormatHelper.getChar(readNext());
218 } catch (MessageFormatException e) {
219 try {
220 dis.reset();
221 } catch (IOException ex) {
222 throw new JMSException(ex.getMessage());
223 }
224 throw new MessageFormatException(e.getMessage());
225 } catch (NullPointerException e) {
226 try {
227 dis.reset();
228 } catch (IOException ex) {
229 throw new JMSException(ex.getMessage());
230 }
231 throw new JMSException(e.getMessage());
232 }
233 }
234
235 /***
236 * Reads a 32-bit integer from the stream message.
237 *
238 * @return a 32-bit integer value from the stream message, interpreted as
239 * an <code>int</code>
240 *
241 * @exception JMSException
242 * if the JMS provider fails to read the message due to some
243 * internal error.
244 * @exception MessageEOFException
245 * if unexpected end of message stream has been reached.
246 * @exception MessageFormatException
247 * if this type conversion is invalid.
248 * @exception MessageNotReadableException
249 * if the message is in write-only mode.
250 *
251 * @see javax.jms.StreamMessage#readInt()
252 */
253 public int readInt() throws JMSException {
254 prepareRead();
255 try {
256 return FormatHelper.getInt(readNext());
257 } catch (MessageFormatException e) {
258 try {
259 dis.reset();
260 } catch (IOException ex) {
261 throw new JMSException(ex.getMessage());
262 }
263 throw new MessageFormatException(e.getMessage());
264 } catch (NumberFormatException e) {
265 try {
266 dis.reset();
267 } catch (IOException ex) {
268 throw new JMSException(ex.getMessage());
269 }
270 throw new JMSException(e.getMessage());
271 }
272 }
273
274 /***
275 * Reads a 64-bit integer from the stream message.
276 *
277 * @return a 64-bit integer value from the stream message, interpreted as a
278 * <code>long</code>
279 *
280 * @exception JMSException
281 * if the JMS provider fails to read the message due to some
282 * internal error.
283 * @exception MessageEOFException
284 * if unexpected end of message stream has been reached.
285 * @exception MessageFormatException
286 * if this type conversion is invalid.
287 * @exception MessageNotReadableException
288 * if the message is in write-only mode.
289 *
290 * @see javax.jms.StreamMessage#readLong()
291 */
292 public long readLong() throws JMSException {
293 prepareRead();
294 try {
295 return FormatHelper.getLong(readNext());
296 } catch (MessageFormatException e) {
297 try {
298 dis.reset();
299 } catch (IOException ex) {
300 throw new JMSException(ex.getMessage());
301 }
302 throw new MessageFormatException(e.getMessage());
303 } catch (NumberFormatException e) {
304 try {
305 dis.reset();
306 } catch (IOException ex) {
307 throw new JMSException(ex.getMessage());
308 }
309 throw new JMSException(e.getMessage());
310 }
311 }
312
313 /***
314 * Reads a <code>float</code> from the stream message.
315 *
316 * @return a <code>float</code> value from the stream message
317 *
318 * @exception JMSException
319 * if the JMS provider fails to read the message due to some
320 * internal error.
321 * @exception MessageEOFException
322 * if unexpected end of message stream has been reached.
323 * @exception MessageFormatException
324 * if this type conversion is invalid.
325 * @exception MessageNotReadableException
326 * if the message is in write-only mode.
327 *
328 * @see javax.jms.StreamMessage#readFloat()
329 */
330 public float readFloat() throws JMSException {
331 prepareRead();
332 try {
333 return FormatHelper.getFloat(readNext());
334 } catch (MessageFormatException e) {
335 try {
336 dis.reset();
337 } catch (IOException ex) {
338 throw new JMSException(ex.getMessage());
339 }
340 throw new MessageFormatException(e.getMessage());
341 } catch (NullPointerException e) {
342 try {
343 dis.reset();
344 } catch (IOException ex) {
345 throw new JMSException(ex.getMessage());
346 }
347 throw new JMSException(e.getMessage());
348 } catch (NumberFormatException e) {
349 try {
350 dis.reset();
351 } catch (IOException ex) {
352 throw new JMSException(ex.getMessage());
353 }
354 throw new JMSException(e.getMessage());
355 }
356 }
357
358 /***
359 * Reads a <code>double</code> from the stream message.
360 *
361 * @return a <code>double</code> value from the stream message
362 *
363 * @exception JMSException
364 * if the JMS provider fails to read the message due to some
365 * internal error.
366 * @exception MessageEOFException
367 * if unexpected end of message stream has been reached.
368 * @exception MessageFormatException
369 * if this type conversion is invalid.
370 * @exception MessageNotReadableException
371 * if the message is in write-only mode.
372 *
373 * @see javax.jms.StreamMessage#readDouble()
374 */
375 public double readDouble() throws JMSException {
376 prepareRead();
377 try {
378 return FormatHelper.getDouble(readNext());
379 } catch (MessageFormatException e) {
380 try {
381 dis.reset();
382 } catch (IOException ex) {
383 throw new JMSException(ex.getMessage());
384 }
385 throw new MessageFormatException(e.getMessage());
386 } catch (NullPointerException e) {
387 try {
388 dis.reset();
389 } catch (IOException ex) {
390 throw new JMSException(ex.getMessage());
391 }
392 throw new JMSException(e.getMessage());
393 } catch (NumberFormatException e) {
394 try {
395 dis.reset();
396 } catch (IOException ex) {
397 throw new JMSException(ex.getMessage());
398 }
399 throw new JMSException(e.getMessage());
400 }
401 }
402
403 /***
404 * Reads a <CODE>String</CODE> from the stream message.
405 *
406 * @return a Unicode string from the stream message
407 *
408 * @exception JMSException
409 * if the JMS provider fails to read the message due to some
410 * internal error.
411 * @exception MessageEOFException
412 * if unexpected end of message stream has been reached.
413 * @exception MessageFormatException
414 * if this type conversion is invalid.
415 * @exception MessageNotReadableException
416 * if the message is in write-only mode.
417 *
418 * @see javax.jms.StreamMessage#readString()
419 */
420 public String readString() throws JMSException {
421 prepareRead();
422 try {
423 return FormatHelper.getString(readNext());
424 } catch (MessageFormatException e) {
425 try {
426 dis.reset();
427 } catch (IOException ex) {
428 throw new JMSException(ex.getMessage());
429 }
430 throw new MessageFormatException(e.getMessage());
431 }
432 }
433
434 /***
435 * Reads a byte array field from the stream message into the specified
436 * <CODE>byte[]</CODE> object (the read buffer).
437 *
438 * <P>
439 * To read the field value, <CODE>readBytes</CODE> should be successively
440 * called until it returns a value less than the length of the read buffer.
441 * The value of the bytes in the buffer following the last byte read is
442 * undefined.
443 *
444 * <P>
445 * If <CODE>readBytes</CODE> returns a value equal to the length of the
446 * buffer, a subsequent <CODE>readBytes</CODE> call must be made. If
447 * there are no more bytes to be read, this call returns -1.
448 *
449 * <P>
450 * If the byte array field value is null, <CODE>readBytes</CODE> returns
451 * -1.
452 *
453 * <P>
454 * If the byte array field value is empty, <CODE>readBytes</CODE> returns 0.
455 *
456 * <P>
457 * Once the first <CODE>readBytes</CODE> call on a <CODE>byte[]</CODE>
458 * field value has been made, the full value of the field must be read
459 * before it is valid to read the next field. An attempt to read the next
460 * field before that has been done will throw a <CODE>
461 * MessageFormatException</CODE>.
462 *
463 * <P>
464 * To read the byte field value into a new <CODE>byte[]</CODE> object,
465 * use the <CODE>readObject</CODE> method.
466 *
467 * @param value
468 * the buffer into which the data is read
469 *
470 * @return the total number of bytes read into the buffer, or -1 if there
471 * is no more data because the end of the byte field has been
472 * reached
473 *
474 * @exception JMSException
475 * if the JMS provider fails to read the message due to some
476 * internal error.
477 * @exception MessageEOFException
478 * if unexpected end of message stream has been reached.
479 * @exception MessageFormatException
480 * if this type conversion is invalid.
481 * @exception MessageNotReadableException
482 * if the message is in write-only mode.
483 *
484 * @see #readObject()
485 *
486 * @see javax.jms.StreamMessage#readBytes(byte[])
487 */
488 public int readBytes(byte[] value) throws JMSException {
489 if (isBodyModifiable()) {
490 throw new MessageNotReadableException("StreamMessage write_only");
491 }
492 getInputStream();
493 int read = 0; // the number of bytes read
494 if (readBytes == 0) {
495 try {
496 dis.mark(buffer.length - dis.available());
497 byte type = (byte) (dis.readByte() & 0x0F);
498 if (type == TYPE_NULL) {
499 return -1;
500 } else if (type != TYPE_BYTE_ARRAY) {
501 dis.reset();
502 if (type < TYPE_NAMES.length) {
503 throw new MessageFormatException(
504 "Expected type="
505 + TYPE_NAMES[TYPE_BYTE_ARRAY]
506 + ", but got type="
507 + TYPE_NAMES[type]);
508 } else {
509 throw new MessageFormatException("StreamMessage corrupted");
510 }
511 }
512 } catch (IOException e) {
513 throw new JMSException(e.getMessage());
514 }
515 try {
516 byteArrayLength = dis.readInt();
517 } catch (IOException e) {
518 throw new JMSException(e.getMessage());
519 }
520 }
521 if (byteArrayLength == 0) {
522 if (readBytes != 0) { // not the first invocation
523 read = -1;
524 }
525 readBytes = 0; // finished reading the byte array
526 } else {
527 ++readBytes;
528 try {
529 if (value.length <= byteArrayLength) {
530 read = value.length;
531 dis.readFully(value);
532 byteArrayLength -= value.length;
533 } else {
534 read = byteArrayLength;
535 dis.readFully(value, 0, byteArrayLength);
536 byteArrayLength = 0;
537 }
538 } catch (IOException e) {
539 throw new JMSException(e.getMessage());
540 }
541 }
542 return read;
543 }
544
545 /***
546 * Reads an object from the stream message.
547 *
548 * <P>
549 * This method can be used to return, in objectified format, an object in
550 * the Java programming language ("Java object") that has been written to
551 * the stream with the equivalent <CODE>writeObject</CODE> method call,
552 * or its equivalent primitive <CODE>write <I>type</I></CODE> method.
553 *
554 * <P>
555 * Note that byte values are returned as <CODE>byte[]</CODE>, not <CODE>
556 * Byte[]</CODE>.
557 *
558 * <P>
559 * An attempt to call <CODE>readObject</CODE> to read a byte field value
560 * into a new <CODE>byte[]</CODE> object before the full value of the
561 * byte field has been read will throw a <CODE>MessageFormatException
562 * </CODE>.
563 *
564 * @return a Java object from the stream message, in objectified format
565 * (for example, if the object was written as an <CODE>int</CODE>,
566 * an <CODE>Integer</CODE> is returned)
567 *
568 * @exception JMSException
569 * if the JMS provider fails to read the message due to some
570 * internal error.
571 * @exception MessageEOFException
572 * if unexpected end of message stream has been reached.
573 * @exception MessageFormatException
574 * if this type conversion is invalid.
575 * @exception MessageNotReadableException
576 * if the message is in write-only mode.
577 *
578 * @see #readBytes(byte[] value)
579 *
580 * @see javax.jms.StreamMessage#readObject()
581 */
582 public Object readObject() throws JMSException {
583 prepareRead();
584 try {
585 return readNext();
586 } catch (MessageFormatException e) {
587 try {
588 dis.reset();
589 } catch (IOException ex) {
590 throw new JMSException(ex.getMessage());
591 }
592 throw new MessageFormatException(e.getMessage());
593 }
594 }
595
596 /***
597 * Writes a <code>boolean</code> to the stream message. The value <code>true</code>
598 * is written as the value <code>(byte)1</code>; the value <code>false</code>
599 * is written as the value <code>(byte)0</code>.
600 *
601 * @param value
602 * the <code>boolean</code> value to be written
603 *
604 * @exception JMSException
605 * if the JMS provider fails to write the message due to
606 * some internal error.
607 * @exception MessageNotWriteableException
608 * if the message is in read-only mode.
609 *
610 * @see javax.jms.StreamMessage#writeBoolean(boolean)
611 */
612 public void writeBoolean(boolean value) throws JMSException {
613 if (!isBodyModifiable()) {
614 throw new MessageNotWriteableException("StreamMessage read_only");
615 }
616
617 try {
618 dos.writeByte((int)TYPE_BOOLEAN);
619 dos.writeBoolean(value);
620 } catch (IOException e) {
621 throw new JMSException(e.getMessage());
622 }
623 }
624
625 /***
626 * Writes a <code>byte</code> to the stream message.
627 *
628 * @param value
629 * the <code>byte</code> value to be written
630 *
631 * @exception JMSException
632 * if the JMS provider fails to write the message due to
633 * some internal error.
634 * @exception MessageNotWriteableException
635 * if the message is in read-only mode.
636 *
637 * @see javax.jms.StreamMessage#writeByte(byte)
638 */
639 public void writeByte(byte value) throws JMSException {
640 if (!isBodyModifiable()) {
641 throw new MessageNotWriteableException("StreamMessage read_only");
642 }
643
644 try {
645 dos.writeByte((int)TYPE_BYTE);
646 dos.writeByte((int)value);
647 } catch (IOException e) {
648 throw new JMSException(e.getMessage());
649 }
650 }
651
652 /***
653 * Writes a <code>short</code> to the stream message.
654 *
655 * @param value
656 * the <code>short</code> value to be written
657 *
658 * @exception JMSException
659 * if the JMS provider fails to write the message due to
660 * some internal error.
661 * @exception MessageNotWriteableException
662 * if the message is in read-only mode.
663 *
664 *
665 * @see javax.jms.StreamMessage#writeShort(short)
666 */
667 public void writeShort(short value) throws JMSException {
668 if (!isBodyModifiable()) {
669 throw new MessageNotWriteableException("StreamMessage read_only");
670 }
671
672 try {
673 dos.writeByte((int)TYPE_SHORT);
674 dos.writeShort((int)value);
675 } catch (IOException e) {
676 throw new JMSException(e.getMessage());
677 }
678 }
679
680 /***
681 * Writes a <code>char</code> to the stream message.
682 *
683 * @param value
684 * the <code>char</code> value to be written
685 *
686 * @exception JMSException
687 * if the JMS provider fails to write the message due to
688 * some internal error.
689 * @exception MessageNotWriteableException
690 * if the message is in read-only mode.
691 *
692 * @see javax.jms.StreamMessage#writeChar(char)
693 */
694 public void writeChar(char value) throws JMSException {
695 if (!isBodyModifiable()) {
696 throw new MessageNotWriteableException("StreamMessage read_only");
697 }
698
699 try {
700 dos.writeByte((int)TYPE_CHAR);
701 dos.writeChar((int)value);
702 } catch (IOException e) {
703 throw new JMSException(e.getMessage());
704 }
705 }
706
707 /***
708 * Writes an <code>int</code> to the stream message.
709 *
710 * @param value
711 * the <code>int</code> value to be written
712 *
713 * @exception JMSException
714 * if the JMS provider fails to write the message due to
715 * some internal error.
716 * @exception MessageNotWriteableException
717 * if the message is in read-only mode.
718 *
719 * @see javax.jms.StreamMessage#writeInt(int)
720 */
721 public void writeInt(int value) throws JMSException {
722 if (!isBodyModifiable()) {
723 throw new MessageNotWriteableException("StreamMessage read_only");
724 }
725
726 try {
727 dos.writeByte((int)TYPE_INT);
728 dos.writeInt(value);
729 } catch (IOException e) {
730 throw new JMSException(e.getMessage());
731 }
732 }
733
734 /***
735 * Writes a <code>long</code> to the stream message.
736 *
737 * @param value
738 * the <code>long</code> value to be written
739 *
740 * @exception JMSException
741 * if the JMS provider fails to write the message due to
742 * some internal error.
743 * @exception MessageNotWriteableException
744 * if the message is in read-only mode.
745 *
746 * @see javax.jms.StreamMessage#writeLong(long)
747 */
748 public void writeLong(long value) throws JMSException {
749 if (!isBodyModifiable()) {
750 throw new MessageNotWriteableException("StreamMessage read_only");
751 }
752
753 try {
754 dos.writeByte((int)TYPE_LONG);
755 dos.writeLong(value);
756 } catch (IOException e) {
757 throw new JMSException(e.getMessage());
758 }
759 }
760
761 /***
762 * Writes a <code>float</code> to the stream message.
763 *
764 * @param value
765 * the <code>float</code> value to be written
766 *
767 * @exception JMSException
768 * if the JMS provider fails to write the message due to
769 * some internal error.
770 * @exception MessageNotWriteableException
771 * if the message is in read-only mode.
772 *
773 * @see javax.jms.StreamMessage#writeFloat(float)
774 */
775 public void writeFloat(float value) throws JMSException {
776 if (!isBodyModifiable()) {
777 throw new MessageNotWriteableException("StreamMessage read_only");
778 }
779
780 try {
781 dos.writeByte((int)TYPE_FLOAT);
782 dos.writeFloat(value);
783 } catch (IOException e) {
784 throw new JMSException(e.getMessage());
785 }
786 }
787
788 /***
789 * Writes a <code>double</code> to the stream message.
790 *
791 * @param value
792 * the <code>double</code> value to be written
793 *
794 * @exception JMSException
795 * if the JMS provider fails to write the message due to
796 * some internal error.
797 * @exception MessageNotWriteableException
798 * if the message is in read-only mode.
799 *
800 * @see javax.jms.StreamMessage#writeDouble(double)
801 */
802 public void writeDouble(double value) throws JMSException {
803 if (!isBodyModifiable()) {
804 throw new MessageNotWriteableException("StreamMessage read_only");
805 }
806
807 try {
808 dos.writeByte((int)TYPE_DOUBLE);
809 dos.writeDouble(value);
810 } catch (IOException e) {
811 throw new JMSException(e.getMessage());
812 }
813 }
814
815 /***
816 * Writes a <code>String</code> to the stream message.
817 *
818 * @param value
819 * the <code>String</code> value to be written
820 *
821 * @exception JMSException
822 * if the JMS provider fails to write the message due to
823 * some internal error.
824 * @exception MessageNotWriteableException
825 * if the message is in read-only mode.
826 *
827 * @see javax.jms.StreamMessage#writeString(String)
828 */
829 public void writeString(String value) throws JMSException {
830 if (!isBodyModifiable()) {
831 throw new MessageNotWriteableException("StreamMessage read_only");
832 }
833
834 try {
835 if (value != null) {
836 dos.writeByte((int)TYPE_STRING);
837 dos.writeUTF(value);
838 } else {
839 throw new JMSException("Value is null");
840 }
841 } catch (IOException e) {
842 throw new JMSException(e.getMessage());
843 }
844 }
845
846 /***
847 * Writes a byte array field to the stream message.
848 *
849 * <P>
850 * The byte array <code>value</code> is written to the message as a byte
851 * array field. Consecutively written byte array fields are treated as two
852 * distinct fields when the fields are read.
853 *
854 * @param value
855 * the byte array value to be written
856 *
857 * @exception JMSException
858 * if the JMS provider fails to write the message due to
859 * some internal error.
860 * @exception MessageNotWriteableException
861 * if the message is in read-only mode.
862 *
863 * @see javax.jms.StreamMessage#writeBytes(byte[])
864 */
865 public void writeBytes(byte[] value) throws JMSException {
866 writeBytes(value, 0, value.length);
867 }
868
869 /***
870 * Writes a portion of a byte array as a byte array field to the stream
871 * message.
872 *
873 * <P>
874 * The a portion of the byte array <code>value</code> is written to the
875 * message as a byte array field. Consecutively written byte array fields
876 * are treated as two distinct fields when the fields are read.
877 *
878 * @param value
879 * the byte array value to be written
880 * @param offset
881 * the initial offset within the byte array
882 * @param length
883 * the number of bytes to use
884 *
885 * @exception JMSException
886 * if the JMS provider fails to write the message due to
887 * some internal error.
888 * @exception MessageNotWriteableException
889 * if the message is in read-only mode.
890 *
891 * @see javax.jms.StreamMessage#writeBytes(byte[], int, int)
892 */
893 public void writeBytes(byte[] value, int offset, int length)
894 throws JMSException {
895 if (!isBodyModifiable()) {
896 throw new MessageNotWriteableException("StreamMessage read_only");
897 }
898
899 try {
900 if (value != null) {
901 dos.writeByte((int)TYPE_BYTE_ARRAY);
902 dos.writeInt(length);
903 dos.write(value, offset, length);
904 } else {
905 throw new JMSException("Value is null");
906 }
907 } catch (IOException e) {
908 throw new JMSException(e.getMessage());
909 }
910 }
911
912 /***
913 * Writes an object to the stream message.
914 *
915 * <P>
916 * This method works only for the objectified primitive object types (
917 * <code>Integer</code>,<code>Double</code>,<code>Long</code>
918 * ...), <code>String</code> objects, and byte arrays.
919 *
920 * @param value
921 * the Java object to be written
922 *
923 * @exception JMSException
924 * if the JMS provider fails to write the message due to
925 * some internal error.
926 * @exception MessageFormatException
927 * if the object is invalid.
928 * @exception MessageNotWriteableException
929 * if the message is in read-only mode.
930 *
931 * @see javax.jms.StreamMessage#writeObject(Object)
932 */
933 public void writeObject(Object value) throws JMSException {
934 if (value == null) {
935 try {
936 if (!isBodyModifiable()) {
937 throw new MessageNotWriteableException("StreamMessage read_only");
938 }
939 getOutputStream();
940 dos.writeByte(TYPE_NULL);
941 } catch (IOException e) {
942 throw new JMSException(e.getMessage());
943 }
944 } else if (value instanceof Boolean) {
945 writeBoolean(((Boolean)value).booleanValue());
946 } else if (value instanceof Byte) {
947 writeByte(((Byte)value).byteValue());
948 } else if (value instanceof byte[]) {
949 writeBytes((byte[])value);
950 } else if (value instanceof Short) {
951 writeShort(((Short)value).shortValue());
952 } else if (value instanceof Character) {
953 writeChar(((Character)value).charValue());
954 } else if (value instanceof Integer) {
955 writeInt(((Integer)value).intValue());
956 } else if (value instanceof Long) {
957 writeLong(((Long)value).longValue());
958 } else if (value instanceof Float) {
959 writeFloat(((Float)value).floatValue());
960 } else if (value instanceof Double) {
961 writeDouble(((Double)value).doubleValue());
962 } else if (value instanceof String) {
963 writeString((String)value);
964 } else {
965 throw new MessageFormatException("StreamMessag invalid_type");
966 }
967 }
968
969 /***
970 * @see javax.jms.StreamMessage#reset()
971 */
972 public void reset() throws JMSException {
973 try {
974 if (!isBodyModifiable()) {
975 setBodyModifiable(true);
976 if (dos != null) {
977 dos.flush();
978 buffer = baos.toByteArray();
979 baos = null;
980 dos.close();
981 dos = null;
982 }
983 } else {
984 if (dis != null) {
985 bais = null;
986 dis.close();
987 dis = null;
988 }
989 }
990 readBytes = 0;
991 } catch (IOException e) {
992 if (e instanceof EOFException) {
993 throw new MessageEOFException(e.getMessage());
994 } else {
995 throw new JMSException(e.getMessage());
996 }
997 }
998 }
999
1000 /***
1001 * Sets the object reference in the message to null and sets the message to
1002 * modifiable.
1003 *
1004 * @exception javax.jms.JMSException
1005 */
1006 public void clearBody() throws JMSException {
1007 super.clearBody();
1008 buffer = new byte[0];
1009 baos = new ByteArrayOutputStream();
1010 dos = new DataOutputStream(baos);
1011 bais = null;
1012 dis = null;
1013 }
1014
1015 /***
1016 * Read the next object from the stream and verify that it is one of the
1017 * specified data types.
1018 *
1019 * @return The read object in its original type format
1020 *
1021 * @exception javax.jms.MessageEOFException
1022 * if the end of the stream is reached.
1023 * @exception javax.jms.MessageFormatException
1024 * if the type conversion is invalid or the client is
1025 * currently reading a bytes field (and hasn't completed).
1026 * @exception javax.jms.MessageNotReadableException
1027 * if the message is write-only.
1028 * @exception javax.jms.JMSException
1029 * if an IO error occurs with the underlying message.
1030 * @exception NullPointerException
1031 * if value is null.
1032 */
1033 private Object readNext() throws JMSException {
1034 if (readBytes != 0) {
1035 throw new MessageFormatException("Must finish reading byte array before reading next field");
1036 }
1037
1038 byte type = 0;
1039 try {
1040 type = dis.readByte();
1041 } catch (IOException e) {
1042 throw new JMSException(e.getMessage());
1043 }
1044 if ((type & 0x0F) > TYPE_NAMES.length) {
1045 throw new JMSException("StreamMessage corrupted");
1046 }
1047 Object result = null;
1048
1049 try {
1050 switch (type & 0x0F) {
1051 case TYPE_BOOLEAN :
1052 boolean value = ((type & 0xF0) != 0) ? true : false;
1053 result = new Boolean(value);
1054 break;
1055 case TYPE_BYTE :
1056 result = new Byte(dis.readByte());
1057 break;
1058 case TYPE_BYTE_ARRAY :
1059 int length = dis.readInt();
1060 byte[] bytes = new byte[length];
1061 dis.readFully(bytes);
1062 result = bytes;
1063 break;
1064 case TYPE_SHORT :
1065 result = new Short(dis.readShort());
1066 break;
1067 case TYPE_CHAR :
1068 result = new Character(dis.readChar());
1069 break;
1070 case TYPE_INT :
1071 result = new Integer(dis.readInt());
1072 break;
1073 case TYPE_LONG :
1074 result = new Long(dis.readLong());
1075 break;
1076 case TYPE_FLOAT :
1077 result = new Float(dis.readFloat());
1078 break;
1079 case TYPE_DOUBLE :
1080 result = new Double(dis.readDouble());
1081 break;
1082 case TYPE_STRING :
1083 result = dis.readUTF();
1084 break;
1085 }
1086 } catch (IOException e) {
1087 throw new JMSException(e.getMessage());
1088 }
1089 return result;
1090 }
1091
1092 private void prepareRead() throws JMSException {
1093 if (isBodyModifiable()) {
1094 throw new MessageNotReadableException("StreamMessage write_only");
1095 }
1096 getInputStream();
1097 try {
1098 dis.mark(buffer.length - dis.available());
1099 } catch (IOException e) {
1100 throw new JMSException(e.getMessage());
1101 }
1102 }
1103
1104 /***
1105 * Initialise the input stream if it hasn't been intialised
1106 *
1107 * @return the input stream
1108 */
1109 private DataInputStream getInputStream() {
1110 if (dis == null) {
1111 bais = new ByteArrayInputStream(buffer);
1112 dis = new DataInputStream(bais);
1113 }
1114 return dis;
1115 }
1116
1117 /***
1118 * Initialise the output stream if it hasn't been intialised
1119 *
1120 * @return the output stream
1121 * @throws IOException
1122 * if the output stream can't be created
1123 */
1124 private DataOutputStream getOutputStream() throws IOException {
1125 if (dos == null) {
1126 baos = new ByteArrayOutputStream();
1127 dos = new DataOutputStream(baos);
1128 dos.write(buffer);
1129 }
1130 return dos;
1131 }
1132
1133 }
This page was automatically generated by Maven