KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > message > BytesMessageImpl


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "Exolab" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of Exoffice Technologies. For written permission,
18  * please contact info@exolab.org.
19  *
20  * 4. Products derived from this Software may not be called "Exolab"
21  * nor may "Exolab" appear in their names without prior written
22  * permission of Exoffice Technologies. Exolab is a registered
23  * trademark of Exoffice Technologies.
24  *
25  * 5. Due credit should be given to the Exolab Project
26  * (http://www.exolab.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2000-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42  *
43  * $Id: BytesMessageImpl.java,v 1.2 2005/03/18 03:50:12 tanderson Exp $
44  */

45 package org.exolab.jms.message;
46
47 import java.io.ByteArrayInputStream JavaDoc;
48 import java.io.ByteArrayOutputStream JavaDoc;
49 import java.io.DataInputStream JavaDoc;
50 import java.io.DataOutputStream JavaDoc;
51 import java.io.EOFException JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.io.ObjectInput JavaDoc;
54 import java.io.ObjectOutput JavaDoc;
55 import java.io.UTFDataFormatException JavaDoc;
56
57 import javax.jms.BytesMessage JavaDoc;
58 import javax.jms.JMSException JavaDoc;
59 import javax.jms.MessageEOFException JavaDoc;
60 import javax.jms.MessageFormatException JavaDoc;
61 import javax.jms.MessageNotReadableException JavaDoc;
62 import javax.jms.MessageNotWriteableException JavaDoc;
63
64
65 /**
66  * This class implements the {@link BytesMessage} interface.
67  *
68  * @version $Revision: 1.2 $ $Date: 2005/03/18 03:50:12 $
69  * @author <a HREF="mailto:mourikis@intalio.com">Jim Mourikis</a>
70  * @author <a HREF="mailto:tima@netspace.net.au">Tim Anderson</a>
71  * @see BytesMessage
72  */

73 public final class BytesMessageImpl extends MessageImpl
74     implements BytesMessage JavaDoc {
75
76     /**
77      * Object version no. for serialization.
78      */

79     static final long serialVersionUID = 1;
80
81     /**
82      * Empty byte array for initialisation purposes.
83      */

84     private static final byte[] EMPTY = new byte[]{};
85
86     /**
87      * The byte stream to store data.
88      */

89     private byte[] _bytes = EMPTY;
90
91     /**
92      * The stream used for writes.
93      */

94     private DataOutputStream JavaDoc _out = null;
95
96     /**
97      * The byte stream backing the output stream.
98      */

99     private ByteArrayOutputStream JavaDoc _byteOut = null;
100
101     /**
102      * The stream used for reads.
103      */

104     private DataInputStream JavaDoc _in = null;
105
106     /**
107      * The byte stream backing the input stream.
108      */

109     private ByteArrayInputStream JavaDoc _byteIn = null;
110
111     /**
112      * The offset of the byte stream to start reading from. This defaults
113      * to 0, and only applies to messages that are cloned from a
114      * read-only instance where part of the stream had already been read.
115      */

116     private int _offset = 0;
117
118     /**
119      * Construct a new BytesMessage. When first created, the message is in
120      * write-only mode.
121      *
122      * @throws JMSException if the message type can't be set
123      */

124     public BytesMessageImpl() throws JMSException JavaDoc {
125         setJMSType("BytesMessage");
126     }
127
128     /**
129      * Clone an instance of this object.
130      *
131      * @return a copy of this object
132      * @throws CloneNotSupportedException if object or attributes aren't
133      * cloneable
134      */

135     public final Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
136         BytesMessageImpl result = (BytesMessageImpl) super.clone();
137         if (_bodyReadOnly) {
138             result._bytes = new byte[_bytes.length];
139             System.arraycopy(_bytes, 0, result._bytes, 0, _bytes.length);
140             if (_byteIn != null) {
141                 // if a client subsequently reads from the cloned object,
142
// start reading from offset of the original stream
143
_offset = _bytes.length - _byteIn.available();
144             }
145             result._byteIn = null;
146             result._in = null;
147         } else {
148             if (_out != null) {
149                 try {
150                     _out.flush();
151                 } catch (IOException JavaDoc exception) {
152                     throw new CloneNotSupportedException JavaDoc(
153                         exception.getMessage());
154                 }
155                 result._bytes = _byteOut.toByteArray();
156                 result._byteOut = null;
157                 result._out = null;
158             } else {
159                 result._bytes = new byte[_bytes.length];
160                 System.arraycopy(_bytes, 0, result._bytes, 0, _bytes.length);
161             }
162         }
163
164         return result;
165     }
166
167     /**
168      * Serialize out this message's data.
169      *
170      * @param out the stream to serialize out to
171      * @throws IOException if any I/O exceptions occurr
172      */

173     public final void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
174         // If it was in write mode, extract the byte array.
175
if (!_bodyReadOnly && _out != null) {
176             _out.flush();
177             _bytes = _byteOut.toByteArray();
178         }
179
180         super.writeExternal(out);
181         out.writeLong(serialVersionUID);
182         out.writeInt(_bytes.length);
183         out.write(_bytes);
184         out.flush();
185     }
186
187     /**
188      * Serialize in this message's data.
189      *
190      * @param in the stream to serialize in from
191      * @throws ClassNotFoundException if the class for an object being
192      * restored cannot be found.
193      * @throws IOException if any I/O exceptions occur
194      */

195     public final void readExternal(ObjectInput JavaDoc in)
196         throws ClassNotFoundException JavaDoc, IOException JavaDoc {
197         super.readExternal(in);
198         long version = in.readLong();
199         if (version == serialVersionUID) {
200             int length = in.readInt();
201             _bytes = new byte[length];
202             in.readFully(_bytes);
203         } else {
204             throw new IOException JavaDoc("Incorrect version enountered: " + version +
205                 ". This version = " + serialVersionUID);
206         }
207     }
208
209     /**
210      * Gets the number of bytes of the message body when the message is in
211      * read-only mode. The value returned can be used to allocate a byte array.
212      * The value returned is the entire length of the message body, regardless
213      * of where the pointer for reading the message is currently located.
214      *
215      * @return number of bytes in the message
216      * @throws JMSException if the JMS provider fails to read the
217      * message due to some internal error.
218      * @throws MessageNotReadableException if the message is in write-only
219      * mode.
220      */

221
222     public long getBodyLength() throws JMSException JavaDoc {
223         checkRead();
224         return _bytes.length;
225     }
226
227     /**
228      * Read a <code>boolean</code> from the bytes message stream.
229      *
230      * @return the <code>boolean</code> value read
231      * @throws JMSException if JMS fails to read message due to some internal
232      * JMS error
233      * @throws MessageEOFException if end of bytes stream
234      * @throws MessageNotReadableException if message is in write-only mode
235      */

236     public final boolean readBoolean() throws JMSException JavaDoc {
237         boolean result = false;
238         prepare();
239         try {
240             result = _in.readBoolean();
241         } catch (IOException JavaDoc exception) {
242             revert(exception);
243         }
244         return result;
245     }
246
247     /**
248      * Read a signed 8-bit value from the bytes message stream.
249      *
250      * @return the next byte from the bytes message stream as a signed 8-bit
251      * <code>byte</code>
252      * @throws JMSException if JMS fails to read message due to some internal
253      * JMS error
254      * @throws MessageEOFException if end of message stream
255      * @throws MessageNotReadableException if message is in write-only mode
256      */

257     public final byte readByte() throws JMSException JavaDoc {
258         byte result = 0;
259         prepare();
260         try {
261             result = _in.readByte();
262         } catch (IOException JavaDoc exception) {
263             revert(exception);
264         }
265         return result;
266     }
267
268     /**
269      * Read an unsigned 8-bit number from the bytes message stream.
270      *
271      * @return the next byte from the bytes message stream, interpreted as an
272      * unsigned 8-bit number
273      * @throws JMSException if JMS fails to read message due to some internal
274      * JMS error
275      * @throws MessageNotReadableException if message is in write-only mode
276      * @throws MessageEOFException if end of message stream
277      */

278     public final int readUnsignedByte() throws JMSException JavaDoc {
279         int result = 0;
280         prepare();
281         try {
282             result = _in.readUnsignedByte();
283         } catch (IOException JavaDoc exception) {
284             revert(exception);
285         }
286         return result;
287     }
288
289     /**
290      * Read a signed 16-bit number from the bytes message stream.
291      *
292      * @return the next two bytes from the bytes message stream, interpreted
293      * as a signed 16-bit number
294      * @throws JMSException if JMS fails to read message due to some internal
295      * JMS error
296      * @throws MessageEOFException if end of message stream
297      * @throws MessageNotReadableException if message is in write-only mode
298      */

299     public final short readShort() throws JMSException JavaDoc {
300         short result = 0;
301         prepare();
302         try {
303             result = _in.readShort();
304         } catch (IOException JavaDoc exception) {
305             revert(exception);
306         }
307         return result;
308     }
309
310     /**
311      * Read an unsigned 16-bit number from the bytes message stream.
312      *
313      * @return the next two bytes from the bytes message stream, interpreted
314      * as an unsigned 16-bit integer
315      *
316      * @throws JMSException if JMS fails to read message due to some internal
317      * JMS error
318      * @throws MessageEOFException if end of message stream
319      * @throws MessageNotReadableException if message is in write-only mode
320      */

321     public final int readUnsignedShort() throws JMSException JavaDoc {
322         int result = 0;
323         prepare();
324         try {
325             result = _in.readUnsignedShort();
326         } catch (IOException JavaDoc exception) {
327             revert(exception);
328         }
329         return result;
330     }
331
332     /**
333      * Read a Unicode character value from the bytes message stream.
334      *
335      * @return the next two bytes from the bytes message stream as a Unicode
336      * character
337      * @throws JMSException if JMS fails to read message due to some internal
338      * JMS error
339      * @throws MessageEOFException if end of message stream
340      * @throws MessageNotReadableException if message is in write-only mode
341      */

342     public final char readChar() throws JMSException JavaDoc {
343         char result = 0;
344         prepare();
345         try {
346             result = _in.readChar();
347         } catch (IOException JavaDoc exception) {
348             revert(exception);
349         }
350         return result;
351     }
352
353     /**
354      * Read a signed 32-bit integer from the bytes message stream.
355      *
356      * @return the next four bytes from the bytes message stream, interpreted
357      * as an <code>int</code>
358      * @throws JMSException if JMS fails to read message due to some internal
359      * JMS error
360      * @throws MessageEOFException if end of message stream
361      * @throws MessageNotReadableException if message is in write-only mode
362      */

363     public final int readInt() throws JMSException JavaDoc {
364         int result = 0;
365         prepare();
366         try {
367             result = _in.readInt();
368         } catch (IOException JavaDoc exception) {
369             revert(exception);
370         }
371         return result;
372     }
373
374     /**
375      * Read a signed 64-bit integer from the bytes message stream.
376      *
377      * @return the next eight bytes from the bytes message stream, interpreted
378      * as a <code>long</code>.
379      * @throws JMSException if JMS fails to read message due to some internal
380      * JMS error
381      * @throws MessageEOFException if end of message stream
382      * @throws MessageNotReadableException if message is in write-only mode
383      */

384     public final long readLong() throws JMSException JavaDoc {
385         long result = 0;
386         prepare();
387         try {
388             result = _in.readLong();
389         } catch (IOException JavaDoc exception) {
390             revert(exception);
391         }
392         return result;
393     }
394
395     /**
396      * Read a <code>float</code> from the bytes message stream.
397      *
398      * @return the next four bytes from the bytes message stream, interpreted
399      * as a <code>float</code>
400      * @throws JMSException if JMS fails to read message due to some internal
401      * JMS error
402      * @throws MessageEOFException if end of message stream
403      * @throws MessageNotReadableException if message is in write-only mode
404      */

405     public final float readFloat() throws JMSException JavaDoc {
406         float result = 0;
407         prepare();
408         try {
409             result = _in.readFloat();
410         } catch (IOException JavaDoc exception) {
411             revert(exception);
412         }
413         return result;
414     }
415
416     /**
417      * Read a <code>double</code> from the bytes message stream.
418      *
419      * @return the next eight bytes from the bytes message stream,
420      * interpreted as a <code>double</code>
421      * @throws JMSException if JMS fails to read message due to some internal
422      * JMS error
423      * @throws MessageEOFException if end of message stream
424      * @throws MessageNotReadableException if message is in write-only mode
425      */

426     public final double readDouble() throws JMSException JavaDoc {
427         double result = 0;
428         prepare();
429         try {
430             result = _in.readDouble();
431         } catch (IOException JavaDoc exception) {
432             revert(exception);
433         }
434         return result;
435     }
436
437     /**
438      * Read in a string that has been encoded using a modified UTF-8 format
439      * from the bytes message stream.
440      *
441      * <p>For more information on the UTF-8 format, see "File System Safe
442      * UCS Transformation Format (FSS_UFT)", X/Open Preliminary Specification,
443      * X/Open Company Ltd., Document Number: P316. This information also
444      * appears in ISO/IEC 10646, Annex P.
445      *
446      * @return a Unicode string from the bytes message stream
447      * @throws JMSException if JMS fails to read message due to some internal
448      * JMS error
449      * @throws MessageEOFException if end of message stream
450      * @throws MessageFormatException if string has an invalid format
451      * @throws MessageNotReadableException if message is in write-only mode
452      */

453     public final String JavaDoc readUTF() throws JMSException JavaDoc {
454         String JavaDoc result = null;
455         prepare();
456         try {
457             result = _in.readUTF();
458         } catch (IOException JavaDoc exception) {
459             revert(exception);
460         }
461         return result;
462     }
463
464     /**
465      * Read a byte array from the bytes message stream.
466      *
467      * <p>If the length of array <code>value</code> is less than
468      * the bytes remaining to be read from the stream, the array should
469      * be filled. A subsequent call reads the next increment, etc.
470      *
471      * <p>If the bytes remaining in the stream is less than the length of
472      * array <code>value</code>, the bytes should be read into the array.
473      * The return value of the total number of bytes read will be less than
474      * the length of the array, indicating that there are no more bytes left
475      * to be read from the stream. The next read of the stream returns -1.
476      *
477      * @param value the buffer into which the data is read
478      * @return the total number of bytes read into the buffer, or -1 if
479      * there is no more data because the end of the stream has been reached
480      * @throws JMSException if JMS fails to read message due to some internal
481      * JMS error
482      * @throws MessageNotReadableException if message is in write-only mode
483      */

484     public final int readBytes(byte[] value) throws JMSException JavaDoc {
485         return readBytes(value, value.length);
486     }
487
488     /**
489      * Read a portion of the bytes message stream.
490      *
491      * <p>If the length of array <code>value</code> is less than
492      * the bytes remaining to be read from the stream, the array should
493      * be filled. A subsequent call reads the next increment, etc.
494      *
495      * <p>If the bytes remaining in the stream is less than the length of
496      * array <code>value</code>, the bytes should be read into the array.
497      * The return value of the total number of bytes read will be less than
498      * the length of the array, indicating that there are no more bytes left
499      * to be read from the stream. The next read of the stream returns -1.
500      *
501      * <p> If <code>length</code> is negative, or
502      * <code>length</code> is greater than the length of the array
503      * <code>value</code>, then an <code>IndexOutOfBoundsException</code> is
504      * thrown. No bytes will be read from the stream for this exception case.
505      *
506      * @param value the buffer into which the data is read.
507      * @param length the number of bytes to read. Must be less than or equal
508      * to value.length.
509      * @return the total number of bytes read into the buffer, or -1 if
510      * there is no more data because the end of the stream has been reached.
511      * @throws IndexOutOfBoundsException if <code>length</code> is invalid
512      * @throws JMSException if JMS fails to read message due to some internal
513      * JMS error
514      * @throws MessageNotReadableException if message is in write-only mode
515      */

516     public final int readBytes(byte[] value, int length) throws JMSException JavaDoc {
517         int read = -1;
518         prepare();
519
520         if (length < 0 || length > value.length) {
521             throw new IndexOutOfBoundsException JavaDoc(
522                 "Length must be > 0 and less than array size");
523         }
524         try {
525             _in.mark(length);
526             int remain = _in.available();
527             if (remain == 0) {
528                 read = -1;
529             } else if (length <= remain) {
530                 read = length;
531                 _in.read(value, 0, length);
532             } else {
533                 _in.readFully(value, 0, remain);
534                 read = remain;
535             }
536         } catch (EOFException JavaDoc ignore) {
537         } catch (IOException JavaDoc exception) {
538             revert(exception);
539         }
540         return read;
541     }
542
543     /**
544      * Write a <code>boolean</code> to the bytes message stream as a 1-byte
545      * value.
546      * The value <code>true</code> is written out as the value
547      * <code>(byte)1</code>; the value <code>false</code> is written out as
548      * the value <code>(byte)0</code>.
549      *
550      * @param value the <code>boolean</code> value to be written
551      * @throws JMSException if JMS fails to write message due to some internal
552      * JMS error
553      * @throws MessageNotWriteableException if message is in read-only mode
554      */

555     public final void writeBoolean(boolean value) throws JMSException JavaDoc {
556         checkWrite();
557         try {
558             getOutputStream().writeBoolean(value);
559         } catch (IOException JavaDoc exception) {
560             raise(exception);
561         }
562     }
563
564     /**
565      * Write out a <code>byte</code> to the bytes message stream as a 1-byte
566      * value.
567      *
568      * @param value the <code>byte</code> value to be written
569      * @throws JMSException if JMS fails to write message due to some internal
570      * JMS error
571      * @throws MessageNotWriteableException if message is in read-only mode
572      */

573     public final void writeByte(byte value) throws JMSException JavaDoc {
574         checkWrite();
575         try {
576             getOutputStream().writeByte(value);
577         } catch (IOException JavaDoc exception) {
578             raise(exception);
579         }
580     }
581
582     /**
583      * Write a <code>short</code> to the bytes message stream as two bytes,
584      * high byte first.
585      *
586      * @param value the <code>short</code> to be written
587      * @throws JMSException if JMS fails to write message due to some internal
588      * JMS error
589      * @throws MessageNotWriteableException if message is in read-only mode
590      */

591     public final void writeShort(short value) throws JMSException JavaDoc {
592         checkWrite();
593         try {
594             getOutputStream().writeShort(value);
595         } catch (IOException JavaDoc exception) {
596             raise(exception);
597         }
598     }
599
600     /**
601      * Write a <code>char</code> to the bytes message stream as a 2-byte
602      * value, high byte first.
603      *
604      * @param value the <code>char</code> value to be written
605      * @throws MessageNotWriteableException if message is in read-only mode
606      * @throws JMSException if JMS fails to write message due to some internal
607      * JMS error
608      */

609     public final void writeChar(char value) throws JMSException JavaDoc {
610         checkWrite();
611         try {
612             getOutputStream().writeChar(value);
613         } catch (IOException JavaDoc exception) {
614             raise(exception);
615         }
616     }
617
618     /**
619      * Write an <code>int</code> to the bytes message stream as four bytes,
620      * high byte first.
621      *
622      * @param value the <code>int</code> to be written
623      * @throws JMSException if JMS fails to write message due to some internal
624      * JMS error
625      * @throws MessageNotWriteableException if message is in read-only mode
626      */

627     public final void writeInt(int value) throws JMSException JavaDoc {
628         checkWrite();
629         try {
630             getOutputStream().writeInt(value);
631         } catch (IOException JavaDoc exception) {
632             raise(exception);
633         }
634     }
635
636     /**
637      * Write a <code>long</code> to the bytes message stream as eight bytes,
638      * high byte first
639      *
640      * @param value the <code>long</code> to be written
641      * @throws JMSException if JMS fails to write message due to some internal
642      * JMS error
643      * @throws MessageNotWriteableException if message is in read-only mode
644      */

645     public final void writeLong(long value) throws JMSException JavaDoc {
646         checkWrite();
647         try {
648             getOutputStream().writeLong(value);
649         } catch (IOException JavaDoc exception) {
650             raise(exception);
651         }
652     }
653
654     /**
655      * Convert the float argument to an <code>int</code> using the
656      * <code>floatToIntBits</code> method in class <code>Float</code>,
657      * and then writes that <code>int</code> value to the bytes message
658      * stream as a 4-byte quantity, high byte first.
659      *
660      * @param value the <code>float</code> value to be written.
661      * @throws JMSException if JMS fails to write message due to some internal
662      * JMS error
663      * @throws MessageNotWriteableException if message is in read-only mode
664      */

665     public final void writeFloat(float value) throws JMSException JavaDoc {
666         checkWrite();
667         try {
668             getOutputStream().writeFloat(value);
669         } catch (IOException JavaDoc exception) {
670             raise(exception);
671         }
672     }
673
674
675     /**
676      * Convert the double argument to a <code>long</code> using the
677      * <code>doubleToLongBits</code> method in class <code>Double</code>,
678      * and then writes that <code>long</code> value to the bytes message
679      * stream as an 8-byte quantity, high byte first.
680      *
681      * @param value the <code>double</code> value to be written.
682      * @throws JMSException if JMS fails to write message due to some internal
683      * JMS error
684      * @throws MessageNotWriteableException if message is in read-only mode
685      */

686     public final void writeDouble(double value) throws JMSException JavaDoc {
687         checkWrite();
688         try {
689             getOutputStream().writeDouble(value);
690         } catch (IOException JavaDoc exception) {
691             raise(exception);
692         }
693     }
694
695     /**
696      * Write a string to the bytes message stream using UTF-8 encoding in a
697      * machine-independent manner.
698      *
699      * <p>For more information on the UTF-8 format, see "File System Safe
700      * UCS Transformation Format (FSS_UFT)", X/Open Preliminary Specification,
701      * X/Open Company Ltd., Document Number: P316. This information also
702      * appears in ISO/IEC 10646, Annex P.
703      *
704      * @param value the <code>String</code> value to be written
705      * @throws MessageNotWriteableException if message is in read-only mode
706      * @throws JMSException if JMS fails to write message due to some internal
707      * JMS error
708      */

709     public final void writeUTF(String JavaDoc value) throws JMSException JavaDoc {
710         checkWrite();
711         try {
712             getOutputStream().writeUTF(value);
713         } catch (IOException JavaDoc exception) {
714             raise(exception);
715         }
716     }
717
718     /**
719      * Write a byte array to the bytes message stream.
720      *
721      * @param value the byte array to be written.
722      * @throws JMSException if JMS fails to write message due to some internal
723      * JMS error
724      * @throws MessageNotWriteableException if message is in read-only mode
725      */

726     public final void writeBytes(byte[] value) throws JMSException JavaDoc {
727         checkWrite();
728         try {
729             getOutputStream().write(value);
730         } catch (IOException JavaDoc exception) {
731             raise(exception);
732         }
733     }
734
735     /**
736      * Write a portion of a byte array to the bytes message stream
737      *
738      * @param value the byte array value to be written.
739      * @param offset the initial offset within the byte array.
740      * @param length the number of bytes to use.
741      * @throws JMSException if JMS fails to write message due to some internal
742      * JMS error
743      * @throws MessageNotWriteableException if message is in read-only mode
744      */

745     public final void writeBytes(byte[] value, int offset, int length)
746         throws JMSException JavaDoc {
747         checkWrite();
748         try {
749             getOutputStream().write(value, offset, length);
750         } catch (IOException JavaDoc exception) {
751             raise(exception);
752         }
753     }
754
755     /**
756      * Write a Java object to the bytes message stream.
757      *
758      * <p>Note that this method only works for the objectified primitive
759      * object types (Integer, Double, Long ...), String's and byte arrays.
760      *
761      * @param value the Java object to be written. Must not be null.
762      *
763      * @throws JMSException if JMS fails to write message due to some internal
764      * JMS error
765      * @throws MessageFormatException if object is invalid type
766      * @throws MessageNotWriteableException if message in read-only mode
767      * @throws NullPointerException if parameter <code>value</code> is null
768      */

769     public final void writeObject(Object JavaDoc value) throws JMSException JavaDoc {
770         if (value instanceof Boolean JavaDoc) {
771             writeBoolean(((Boolean JavaDoc) value).booleanValue());
772         } else if (value instanceof Byte JavaDoc) {
773             writeByte(((Byte JavaDoc) value).byteValue());
774         } else if (value instanceof Short JavaDoc) {
775             writeShort(((Short JavaDoc) value).shortValue());
776         } else if (value instanceof Character JavaDoc) {
777             writeChar(((Character JavaDoc) value).charValue());
778         } else if (value instanceof Integer JavaDoc) {
779             writeInt(((Integer JavaDoc) value).intValue());
780         } else if (value instanceof Long JavaDoc) {
781             writeLong(((Long JavaDoc) value).longValue());
782         } else if (value instanceof Float JavaDoc) {
783             writeFloat(((Float JavaDoc) value).floatValue());
784         } else if (value instanceof Double JavaDoc) {
785             writeDouble(((Double JavaDoc) value).doubleValue());
786         } else if (value instanceof String JavaDoc) {
787             writeUTF((String JavaDoc) value);
788         } else if (value instanceof byte[]) {
789             writeBytes((byte[]) value);
790         } else if (value == null) {
791             throw new NullPointerException JavaDoc(
792                 "BytesMessage does not support null");
793         } else {
794             throw new MessageFormatException JavaDoc("Cannot write objects of type=" +
795                 value.getClass().getName());
796         }
797     }
798
799     /**
800      * Put the message body in read-only mode, and reposition the stream of
801      * bytes to the beginning.
802      *
803      * @throws JMSException if JMS fails to reset the message due to some
804      * internal JMS error
805      */

806     public final void reset() throws JMSException JavaDoc {
807         try {
808             if (!_bodyReadOnly) {
809                 _bodyReadOnly = true;
810                 if (_out != null) {
811                     _out.flush();
812                     _bytes = _byteOut.toByteArray();
813                     _byteOut = null;
814                     _out.close();
815                     _out = null;
816                 }
817             } else {
818                 if (_in != null) {
819                     _byteIn = null;
820                     _in.close();
821                     _in = null;
822                 }
823             }
824         } catch (IOException JavaDoc exception) {
825             raise(exception);
826         }
827     }
828
829     /**
830      * Overide the super class method to reset the streams, and put the
831      * message body in write only mode.
832      *
833      * <p>If <code>clearBody</code> is called on a message in read-only mode,
834      * the message body is cleared and the message is in write-only mode.
835      * bytes to the beginning.
836      *
837      * <p>If <code>clearBody</code> is called on a message already in
838      * write-only mode, the spec does not define the outcome, so do nothing.
839      * Client must then call <code>reset</code>, followed by
840      * <code>clearBody</code> to reset the stream at the beginning for a
841      * new write.
842      * @throws JMSException if JMS fails to reset the message due to some
843      * internal JMS error
844      */

845     public final void clearBody() throws JMSException JavaDoc {
846         try {
847             if (_bodyReadOnly) {
848                 // in read-only mode
849
_bodyReadOnly = false;
850                 if (_in != null) {
851                     _byteIn = null;
852                     _in.close();
853                     _in = null;
854                     _offset = 0;
855                 }
856             } else if (_out != null) {
857                 // already in write-only mode
858
_byteOut = null;
859                 _out.close();
860                 _out = null;
861             }
862             _bytes = EMPTY;
863             _byteOut = null;
864             _out = null;
865         } catch (IOException JavaDoc exception) {
866             raise(exception);
867         }
868     }
869
870     /**
871      * Set the read-only mode of the message.
872      *
873      * @param readOnly if true, make the message body and properties read-only,
874      * and invoke {@link #reset}
875      * @throws JMSException if the read-only mode cannot be changed
876      */

877     public final void setReadOnly(boolean readOnly) throws JMSException JavaDoc {
878         if (readOnly) {
879             reset();
880         }
881         super.setReadOnly(readOnly);
882     }
883
884     /**
885      * Prepare to do a read.
886      *
887      * @throws JMSException if the current position in the stream can't be
888      * marked
889      * @throws MessageNotReadableException if the message is in write-only mode
890      */

891     private final void prepare() throws JMSException JavaDoc {
892         checkRead();
893         getInputStream();
894         try {
895             _in.mark(_bytes.length - _in.available());
896         } catch (IOException JavaDoc exception) {
897             raise(exception);
898         }
899     }
900
901     /**
902      * Reverts the stream to its prior position if an I/O exception is
903      * thrown, and propagates the exception as a JMSException.
904      *
905      * @param exception the exception that caused the reset
906      * @throws JMSException for general IOException errors
907      * @throws MessageEOFException if end-of-file was reached
908      */

909     private final void revert(IOException JavaDoc exception) throws JMSException JavaDoc {
910         try {
911             _in.reset();
912         } catch (IOException JavaDoc ignore) {
913         }
914         JMSException JavaDoc error = null;
915         if (exception instanceof EOFException JavaDoc) {
916             error = new MessageEOFException JavaDoc(exception.getMessage());
917         } else if (exception instanceof UTFDataFormatException JavaDoc) {
918             error = new MessageFormatException JavaDoc(exception.getMessage());
919         } else {
920             error = new JMSException JavaDoc(exception.getMessage());
921         }
922         error.setLinkedException(exception);
923         throw error;
924     }
925
926     /**
927      * Initialise the input stream if it hasn't been intialised.
928      *
929      * @return the input stream
930      */

931     private DataInputStream JavaDoc getInputStream() {
932         if (_in == null) {
933             _byteIn = new ByteArrayInputStream JavaDoc(_bytes, _offset,
934                 _bytes.length - _offset);
935             _in = new DataInputStream JavaDoc(_byteIn);
936         }
937         return _in;
938     }
939
940     /**
941      * Initialise the output stream if it hasn't been intialised.
942      *
943      * @return the output stream
944      * @throws IOException if the output stream can't be created
945      */

946     private final DataOutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
947         if (_out == null) {
948             _byteOut = new ByteArrayOutputStream JavaDoc();
949             _out = new DataOutputStream JavaDoc(_byteOut);
950             _out.write(_bytes);
951         }
952         return _out;
953     }
954
955     /**
956      * Helper to raise a JMSException when an I/O error occurs.
957      *
958      * @param exception the exception that caused the failure
959      * @throws JMSException
960      */

961     private final void raise(IOException JavaDoc exception) throws JMSException JavaDoc {
962         JMSException JavaDoc error = new JMSException JavaDoc(exception.getMessage());
963         error.setLinkedException(exception);
964         throw error;
965     }
966
967 }
968
Popular Tags