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 tma@netspace.net.au.
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 2003-2004 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: BasicBytesMessage.java,v 1.2 2004/02/02 03:49:55 tanderson Exp $
44   */
45  
46  package org.exolab.jmscts.jms.message;
47  
48  import java.io.ByteArrayInputStream;
49  import java.io.ByteArrayOutputStream;
50  import java.io.DataInputStream;
51  import java.io.DataOutputStream;
52  import java.io.EOFException;
53  import java.io.IOException;
54  import java.io.UTFDataFormatException;
55  
56  import javax.jms.BytesMessage;
57  import javax.jms.JMSException;
58  import javax.jms.MessageEOFException;
59  import javax.jms.MessageFormatException;
60  
61  
62  /***
63   * This class provides a basic implementation of the javax.jms.BytesMessage
64   * interface.
65   *
66   * @version     $Revision: 1.2 $ $Date: 2004/02/02 03:49:55 $
67   * @author      <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
68   * @see         javax.jms.BytesMessage
69   */
70  public class BasicBytesMessage extends BasicMessage implements BytesMessage {
71  
72      /***
73       * Empty byte array for initialisation purposes
74       */
75      private static final byte[] EMPTY = new byte[]{};
76  
77      /***
78       * The byte stream to store data
79       */
80      private byte[] _bytes = EMPTY;
81  
82      /***
83       * The stream used for writes
84       */
85      private DataOutputStream _out = null;
86  
87      /***
88       * The byte stream backing the output stream
89       */
90      private ByteArrayOutputStream _byteOut = null;
91  
92      /***
93       * The stream used for reads
94       */
95      private DataInputStream _in = null;
96  
97      /***
98       * The byte stream backing the input stream
99       */
100     private ByteArrayInputStream _byteIn = null;
101 
102     /***
103      * The offset of the byte stream to start reading from. This defaults
104      * to 0, and only applies to messages that are cloned from a
105      * read-only instance where part of the stream had already been read.
106      */
107     private int _offset = 0;
108 
109     /***
110      * Construct a new <code>BasicBytesMessage</code>.
111      * When first created, the message is in write-only mode.
112      */
113     public BasicBytesMessage() {
114     }
115 
116     /***
117      * Read a <code>boolean</code> from the bytes message stream
118      *
119      * @return the <code>boolean</code> value read
120      * @throws JMSException if JMS fails to read message due to some internal
121      * JMS error
122      * @throws MessageEOFException if end of bytes stream
123      */
124     public boolean readBoolean() throws JMSException {
125         boolean result = false;
126         prepare();
127         try {
128             result = _in.readBoolean();
129         } catch (IOException exception) {
130             revert(exception);
131         }
132         return result;
133     }
134 
135     /***
136      * Read a signed 8-bit value from the bytes message stream
137      *
138      * @return the next byte from the bytes message stream as a signed 8-bit
139      * <code>byte</code>
140      * @throws JMSException if JMS fails to read message due to some internal
141      * JMS error
142      * @throws MessageEOFException if end of message stream
143      */
144     public byte readByte() throws JMSException {
145         byte result = 0;
146         prepare();
147         try {
148             result = _in.readByte();
149         } catch (IOException exception) {
150             revert(exception);
151         }
152         return result;
153     }
154 
155     /***
156      * Read an unsigned 8-bit number from the bytes message stream
157      *
158      * @return the next byte from the bytes message stream, interpreted as an
159      * unsigned 8-bit number
160      * @throws JMSException if JMS fails to read message due to some internal
161      * JMS error
162      * @throws MessageEOFException if end of message stream
163      */
164     public int readUnsignedByte() throws JMSException {
165         int result = 0;
166         prepare();
167         try {
168             result = _in.readUnsignedByte();
169         } catch (IOException exception) {
170             revert(exception);
171         }
172         return result;
173     }
174 
175     /***
176      * Read a signed 16-bit number from the bytes message stream
177      *
178      * @return the next two bytes from the bytes message stream, interpreted
179      * as a signed 16-bit number
180      * @throws JMSException if JMS fails to read message due to some internal
181      * JMS error
182      * @throws MessageEOFException if end of message stream
183      */
184     public short readShort() throws JMSException {
185         short result = 0;
186         prepare();
187         try {
188             result = _in.readShort();
189         } catch (IOException exception) {
190             revert(exception);
191         }
192         return result;
193     }
194 
195     /***
196      * Read an unsigned 16-bit number from the bytes message stream
197      *
198      * @return the next two bytes from the bytes message stream, interpreted
199      * as an unsigned 16-bit integer
200      *
201      * @throws JMSException if JMS fails to read message due to some internal
202      * JMS error
203      * @throws MessageEOFException if end of message stream
204      */
205     public int readUnsignedShort() throws JMSException {
206         int result = 0;
207         prepare();
208         try {
209             result = _in.readUnsignedShort();
210         } catch (IOException exception) {
211             revert(exception);
212         }
213         return result;
214     }
215 
216     /***
217      * Read a Unicode character value from the bytes message stream
218      *
219      * @return the next two bytes from the bytes message stream as a Unicode
220      * character
221      * @throws JMSException if JMS fails to read message due to some internal
222      * JMS error
223      * @throws MessageEOFException if end of message stream
224      */
225     public char readChar() throws JMSException {
226         char result = 0;
227         prepare();
228         try {
229             result = _in.readChar();
230         } catch (IOException exception) {
231             revert(exception);
232         }
233         return result;
234     }
235 
236     /***
237      * Read a signed 32-bit integer from the bytes message stream
238      *
239      * @return the next four bytes from the bytes message stream, interpreted
240      * as an <code>int</code>
241      * @throws JMSException if JMS fails to read message due to some internal
242      * JMS error
243      * @throws MessageEOFException if end of message stream
244      */
245     public int readInt() throws JMSException {
246         int result = 0;
247         prepare();
248         try {
249             result = _in.readInt();
250         } catch (IOException exception) {
251             revert(exception);
252         }
253         return result;
254     }
255 
256     /***
257      * Read a signed 64-bit integer from the bytes message stream
258      *
259      * @return the next eight bytes from the bytes message stream, interpreted
260      * as a <code>long</code>.
261      * @throws JMSException if JMS fails to read message due to some internal
262      * JMS error
263      * @throws MessageEOFException if end of message stream
264      */
265     public long readLong() throws JMSException {
266         long result = 0;
267         prepare();
268         try {
269             result = _in.readLong();
270         } catch (IOException exception) {
271             revert(exception);
272         }
273         return result;
274     }
275 
276     /***
277      * Read a <code>float</code> from the bytes message stream
278      *
279      * @return the next four bytes from the bytes message stream, interpreted
280      * as a <code>float</code>
281      * @throws JMSException if JMS fails to read message due to some internal
282      * JMS error
283      * @throws MessageEOFException if end of message stream
284      */
285     public float readFloat() throws JMSException {
286         float result = 0;
287         prepare();
288         try {
289             result = _in.readFloat();
290         } catch (IOException exception) {
291             revert(exception);
292         }
293         return result;
294     }
295 
296     /***
297      * Read a <code>double</code> from the bytes message stream
298      *
299      * @return the next eight bytes from the bytes message stream,
300      * interpreted as a <code>double</code>
301      * @throws JMSException if JMS fails to read message due to some internal
302      * JMS error
303      * @throws MessageEOFException if end of message stream
304      */
305     public double readDouble() throws JMSException {
306         double result = 0;
307         prepare();
308         try {
309             result = _in.readDouble();
310         } catch (IOException exception) {
311             revert(exception);
312         }
313         return result;
314     }
315 
316     /***
317      * Read in a string that has been encoded using a modified UTF-8 format
318      * from the bytes message stream
319      *
320      * <p>For more information on the UTF-8 format, see "File System Safe
321      * UCS Transformation Format (FSS_UFT)", X/Open Preliminary Specification,
322      * X/Open Company Ltd., Document Number: P316. This information also
323      * appears in ISO/IEC 10646, Annex P.
324      *
325      * @return a Unicode string from the bytes message stream
326      * @throws JMSException if JMS fails to read message due to some internal
327      * JMS error
328      * @throws MessageEOFException if end of message stream
329      * @throws MessageFormatException if string has an invalid format
330      */
331     public String readUTF() throws JMSException {
332         String result = null;
333         prepare();
334         try {
335             result = _in.readUTF();
336         } catch (IOException exception) {
337             revert(exception);
338         }
339         return result;
340     }
341 
342     /***
343      * Read a byte array from the bytes message stream
344      *
345      * <p>If the length of array <code>value</code> is less than
346      * the bytes remaining to be read from the stream, the array should
347      * be filled. A subsequent call reads the next increment, etc.
348      *
349      * <p>If the bytes remaining in the stream is less than the length of
350      * array <code>value</code>, the bytes should be read into the array.
351      * The return value of the total number of bytes read will be less than
352      * the length of the array, indicating that there are no more bytes left
353      * to be read from the stream. The next read of the stream returns -1.
354      *
355      * @param value the buffer into which the data is read
356      * @return the total number of bytes read into the buffer, or -1 if
357      * there is no more data because the end of the stream has been reached
358      * @throws JMSException if JMS fails to read message due to some internal
359      * JMS error
360      */
361     public int readBytes(byte[] value) throws JMSException {
362         return readBytes(value, value.length);
363     }
364 
365     /***
366      * Read a portion of the bytes message stream.
367      *
368      * <p>If the length of array <code>value</code> is less than
369      * the bytes remaining to be read from the stream, the array should
370      * be filled. A subsequent call reads the next increment, etc.
371      *
372      * <p>If the bytes remaining in the stream is less than the length of
373      * array <code>value</code>, the bytes should be read into the array.
374      * The return value of the total number of bytes read will be less than
375      * the length of the array, indicating that there are no more bytes left
376      * to be read from the stream. The next read of the stream returns -1.
377      *
378      * <p> If <code>length</code> is negative, or
379      * <code>length</code> is greater than the length of the array
380      * <code>value</code>, then an <code>IndexOutOfBoundsException</code> is
381      * thrown. No bytes will be read from the stream for this exception case.
382      *
383      * @param value the buffer into which the data is read.
384      * @param length the number of bytes to read. Must be less than or equal
385      * to value.length.
386      * @return the total number of bytes read into the buffer, or -1 if
387      * there is no more data because the end of the stream has been reached.
388      * @throws IndexOutOfBoundsException if <code>length</code> is invalid
389      * @throws JMSException if JMS fails to read message due to some internal
390      * JMS error
391      */
392     public int readBytes(byte[] value, int length) throws JMSException {
393         int read = -1;
394         prepare();
395 
396         if (length < 0 || length > value.length) {
397             throw new IndexOutOfBoundsException(
398                 "Length must be > 0 and less than array size");
399         }
400         try {
401             _in.mark(length);
402             int remain = _in.available();
403             if (remain == 0) {
404                 read = -1;
405             } else if (length <= remain) {
406                 read = length;
407                 _in.read(value, 0, length);
408             } else {
409                 _in.readFully(value, 0, remain);
410                 read = remain;
411             }
412         } catch (EOFException ignore) {
413             // no-op
414         } catch (IOException exception) {
415             revert(exception);
416         }
417         return read;
418     }
419 
420     /***
421      * Write a <code>boolean</code> to the bytes message stream as a 1-byte
422      * value.
423      * The value <code>true</code> is written out as the value
424      * <code>(byte)1</code>; the value <code>false</code> is written out as
425      * the value <code>(byte)0</code>.
426      *
427      * @param value the <code>boolean</code> value to be written
428      * @throws JMSException if JMS fails to write message due to some internal
429      * JMS error
430      */
431     public void writeBoolean(boolean value) throws JMSException {
432         checkWrite();
433         try {
434             getOutputStream().writeBoolean(value);
435         } catch (IOException exception) {
436             raise(exception);
437         }
438     }
439 
440     /***
441      * Write out a <code>byte</code> to the bytes message stream as a 1-byte
442      * value
443      *
444      * @param value the <code>byte</code> value to be written
445      * @throws JMSException if JMS fails to write message due to some internal
446      * JMS error
447      */
448     public void writeByte(byte value) throws JMSException {
449         checkWrite();
450         try {
451             getOutputStream().writeByte(value);
452         } catch (IOException exception) {
453             raise(exception);
454         }
455     }
456 
457     /***
458      * Write a <code>short</code> to the bytes message stream as two bytes,
459      * high byte first
460      *
461      * @param value the <code>short</code> to be written
462      * @throws JMSException if JMS fails to write message due to some internal
463      * JMS error
464      */
465     public void writeShort(short value) throws JMSException {
466         checkWrite();
467         try {
468             getOutputStream().writeShort(value);
469         } catch (IOException exception) {
470             raise(exception);
471         }
472     }
473 
474     /***
475      * Write a <code>char</code> to the bytes message stream as a 2-byte
476      * value, high byte first.
477      *
478      * @param value the <code>char</code> value to be written
479      * @throws JMSException if JMS fails to write message due to some internal
480      * JMS error
481      */
482     public void writeChar(char value) throws JMSException {
483         checkWrite();
484         try {
485             getOutputStream().writeChar(value);
486         } catch (IOException exception) {
487             raise(exception);
488         }
489     }
490 
491     /***
492      * Write an <code>int</code> to the bytes message stream as four bytes,
493      * high byte first.
494      *
495      * @param value the <code>int</code> to be written
496      * @throws JMSException if JMS fails to write message due to some internal
497      * JMS error
498      */
499     public void writeInt(int value) throws JMSException {
500         checkWrite();
501         try {
502             getOutputStream().writeInt(value);
503         } catch (IOException exception) {
504             raise(exception);
505         }
506     }
507 
508     /***
509      * Write a <code>long</code> to the bytes message stream as eight bytes,
510      * high byte first
511      *
512      * @param value the <code>long</code> to be written
513      * @throws JMSException if JMS fails to write message due to some internal
514      * JMS error
515      */
516     public void writeLong(long value) throws JMSException {
517         checkWrite();
518         try {
519             getOutputStream().writeLong(value);
520         } catch (IOException exception) {
521             raise(exception);
522         }
523     }
524 
525     /***
526      * Convert the float argument to an <code>int</code> using the
527      * <code>floatToIntBits</code> method in class <code>Float</code>,
528      * and then writes that <code>int</code> value to the bytes message
529      * stream as a 4-byte quantity, high byte first.
530      *
531      * @param value the <code>float</code> value to be written.
532      * @throws JMSException if JMS fails to write message due to some internal
533      * JMS error
534      */
535     public void writeFloat(float value) throws JMSException {
536         checkWrite();
537         try {
538             getOutputStream().writeFloat(value);
539         } catch (IOException exception) {
540             raise(exception);
541         }
542     }
543 
544 
545     /***
546      * Convert the double argument to a <code>long</code> using the
547      * <code>doubleToLongBits</code> method in class <code>Double</code>,
548      * and then writes that <code>long</code> value to the bytes message
549      * stream as an 8-byte quantity, high byte first.
550      *
551      * @param value the <code>double</code> value to be written.
552      * @throws JMSException if JMS fails to write message due to some internal
553      * JMS error
554      */
555     public void writeDouble(double value) throws JMSException {
556         checkWrite();
557         try {
558             getOutputStream().writeDouble(value);
559         } catch (IOException exception) {
560             raise(exception);
561         }
562     }
563 
564     /***
565      * Write a string to the bytes message stream using UTF-8 encoding in a
566      * machine-independent manner.
567      *
568      * <p>For more information on the UTF-8 format, see "File System Safe
569      * UCS Transformation Format (FSS_UFT)", X/Open Preliminary Specification,
570      * X/Open Company Ltd., Document Number: P316. This information also
571      * appears in ISO/IEC 10646, Annex P.
572      *
573      * @param value the <code>String</code> value to be written
574      * @throws JMSException if JMS fails to write message due to some internal
575      * JMS error
576      */
577     public void writeUTF(String value) throws JMSException {
578         checkWrite();
579         try {
580             getOutputStream().writeUTF(value);
581         } catch (IOException exception) {
582             raise(exception);
583         }
584     }
585 
586     /***
587      * Write a byte array to the bytes message stream
588      *
589      * @param value the byte array to be written.
590      * @throws JMSException if JMS fails to write message due to some internal
591      * JMS error
592      */
593     public void writeBytes(byte[] value) throws JMSException {
594         checkWrite();
595         try {
596             getOutputStream().write(value);
597         } catch (IOException exception) {
598             raise(exception);
599         }
600     }
601 
602     /***
603      * Write a portion of a byte array to the bytes message stream
604      *
605      * @param value the byte array value to be written.
606      * @param offset the initial offset within the byte array.
607      * @param length the number of bytes to use.
608      * @throws JMSException if JMS fails to write message due to some internal
609      * JMS error
610      */
611     public void writeBytes(byte[] value, int offset, int length)
612         throws JMSException {
613         checkWrite();
614         try {
615             getOutputStream().write(value, offset, length);
616         } catch (IOException exception) {
617             raise(exception);
618         }
619     }
620 
621     /***
622      * Write a Java object to the bytes message stream.
623      *
624      * <p>Note that this method only works for the objectified primitive
625      * object types (Integer, Double, Long ...), String's and byte arrays.
626      *
627      * @param value the Java object to be written. Must not be null.
628      *
629      * @throws JMSException if JMS fails to write message due to some internal
630      * JMS error
631      * @throws MessageFormatException if object is invalid type
632      */
633     public void writeObject(Object value) throws JMSException {
634         if (value instanceof Boolean) {
635             writeBoolean(((Boolean) value).booleanValue());
636         } else if (value instanceof Byte) {
637             writeByte(((Byte) value).byteValue());
638         } else if (value instanceof Short) {
639             writeShort(((Short) value).shortValue());
640         } else if (value instanceof Character) {
641             writeChar(((Character) value).charValue());
642         } else if (value instanceof Integer) {
643             writeInt(((Integer) value).intValue());
644         } else if (value instanceof Long) {
645             writeLong(((Long) value).longValue());
646         } else if (value instanceof Float) {
647             writeFloat(((Float) value).floatValue());
648         } else if (value instanceof Double) {
649             writeDouble(((Double) value).doubleValue());
650         } else if (value instanceof String) {
651             writeUTF((String) value);
652         } else if (value instanceof byte[]) {
653             writeBytes((byte[]) value);
654         } else if (value == null) {
655             throw new NullPointerException(
656                 "BytesMessage does not support null");
657         } else {
658             throw new MessageFormatException("Cannot write objects of type="
659                                              + value.getClass().getName());
660         }
661     }
662 
663     /***
664      * Put the message body in read-only mode, and reposition the stream of
665      * bytes to the beginning
666      *
667      * @throws JMSException if JMS fails to reset the message due to some
668      * internal JMS error
669      */
670     public void reset() throws JMSException {
671         try {
672             if (!getBodyReadOnly()) {
673                 setBodyReadOnly(true);
674                 if (_out != null) {
675                     _out.flush();
676                     _bytes = _byteOut.toByteArray();
677                     _byteOut = null;
678                     _out.close();
679                     _out = null;
680                 }
681             } else {
682                 if (_in != null) {
683                     _byteIn = null;
684                     _in.close();
685                     _in = null;
686                 }
687             }
688         } catch (IOException exception) {
689             raise(exception);
690         }
691     }
692 
693     /***
694      * Overide the super class method to reset the streams, and put the
695      * message body in write only mode.
696      *
697      * <p>If <code>clearBody</code> is called on a message in read-only mode,
698      * the message body is cleared and the message is in write-only mode.
699      * bytes to the beginning.
700      *
701      * <p>If <code>clearBody</code> is called on a message already in
702      * write-only mode, the spec does not define the outcome, so do nothing.
703      * Client must then call <code>reset</code>, followed by
704      * <code>clearBody</code> to reset the stream at the beginning for a
705      * new write.
706      *
707      * @throws JMSException if JMS fails to reset the message due to some
708      * internal JMS error
709      */
710     public void clearBody() throws JMSException {
711         try {
712             if (getBodyReadOnly()) {
713                 // in read-only mode
714                 setBodyReadOnly(false);
715                 if (_in != null) {
716                     _byteIn = null;
717                     _in.close();
718                     _in = null;
719                     _offset = 0;
720                 }
721             } else if (_out != null) {
722                 // already in write-only mode
723                 _byteOut = null;
724                 _out.close();
725                 _out = null;
726             }
727             _bytes = EMPTY;
728             _byteOut = null;
729             _out = null;
730         } catch (IOException exception) {
731             raise(exception);
732         }
733     }
734 
735     /***
736      * Set the read-only mode of the message.
737      *
738      * @param readOnly if true, make the message body and properties read-only,
739      * and invoke {@link #reset}
740      * @throws JMSException if the read-only mode cannot be changed
741      */
742     public void setReadOnly(boolean readOnly) throws JMSException {
743         super.setReadOnly(readOnly);
744         if (readOnly) {
745             reset();
746         }
747     }
748 
749     /***
750      * Prepare to do a read
751      *
752      * @throws JMSException if the current position in the stream can't be
753      * marked
754      */
755     private void prepare() throws JMSException {
756         checkRead();
757         getInputStream();
758         try {
759             _in.mark(_bytes.length - _in.available());
760         } catch (IOException exception) {
761             raise(exception);
762         }
763     }
764 
765     /***
766      * Reverts the stream to its prior position if an I/O exception is
767      * thrown, and propagates the exception as a JMSException
768      *
769      * @param exception the exception that caused the reset
770      * @throws JMSException for general IOException errors
771      * @throws MessageEOFException if end-of-file was reached
772      */
773     private void revert(IOException exception) throws JMSException {
774         try {
775             _in.reset();
776         } catch (IOException ignore) {
777             // no-op
778         }
779         JMSException error = null;
780         if (exception instanceof EOFException) {
781             error = new MessageEOFException(exception.getMessage());
782         } else if (exception instanceof UTFDataFormatException) {
783             error = new MessageFormatException(exception.getMessage());
784         } else {
785             error = new JMSException(exception.getMessage());
786         }
787         error.setLinkedException(exception);
788         throw error;
789     }
790 
791     /***
792      * Initialise the input stream if it hasn't been intialised
793      *
794      * @return the input stream
795      */
796     private DataInputStream getInputStream() {
797         if (_in == null) {
798             _byteIn = new ByteArrayInputStream(_bytes, _offset,
799                 _bytes.length - _offset);
800             _in = new DataInputStream(_byteIn);
801         }
802         return _in;
803     }
804 
805     /***
806      * Initialise the output stream if it hasn't been intialised
807      *
808      * @return the output stream
809      * @throws IOException if the output stream can't be created
810      */
811     private DataOutputStream getOutputStream() throws IOException {
812         if (_out == null) {
813             _byteOut = new ByteArrayOutputStream();
814             _out = new DataOutputStream(_byteOut);
815             _out.write(_bytes);
816         }
817         return _out;
818     }
819 
820     /***
821      * Helper to raise a JMSException when an I/O error occurs
822      *
823      * @param exception the exception that caused the failure
824      * @throws JMSException contains the IOException message
825      */
826     private void raise(IOException exception) throws JMSException {
827         JMSException error = new JMSException(exception.getMessage());
828         error.setLinkedException(exception);
829         throw error;
830     }
831 
832 }
This page was automatically generated by Maven