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

This page was automatically generated by Maven