1 45 package org.exolab.jms.message; 46 47 import java.io.ByteArrayInputStream ; 48 import java.io.ByteArrayOutputStream ; 49 import java.io.DataInputStream ; 50 import java.io.DataOutputStream ; 51 import java.io.EOFException ; 52 import java.io.IOException ; 53 import java.io.ObjectInput ; 54 import java.io.ObjectOutput ; 55 56 import javax.jms.JMSException ; 57 import javax.jms.MessageEOFException ; 58 import javax.jms.MessageFormatException ; 59 import javax.jms.MessageNotReadableException ; 60 import javax.jms.MessageNotWriteableException ; 61 import javax.jms.StreamMessage ; 62 63 64 134 public final class StreamMessageImpl extends MessageImpl 135 implements StreamMessage { 136 137 140 static final long serialVersionUID = 2; 141 142 145 private static final byte NULL = 0; 146 private static final byte BOOLEAN = 1; 147 private static final byte BYTE = 2; 148 private static final byte BYTE_ARRAY = 3; 149 private static final byte SHORT = 4; 150 private static final byte CHAR = 5; 151 private static final byte INT = 6; 152 private static final byte LONG = 7; 153 private static final byte FLOAT = 8; 154 private static final byte DOUBLE = 9; 155 private static final byte STRING = 10; 156 157 161 private static final String [] TYPE_NAMES = { 162 "null", "boolean", "byte", "byte[]", "short", "char", "int", "long", 163 "float", "double", "String"}; 164 165 168 private static final byte[] EMPTY = new byte[]{}; 169 170 173 private byte[] _bytes = EMPTY; 174 175 178 private DataOutputStream _out = null; 179 180 183 private ByteArrayOutputStream _byteOut = null; 184 185 188 private DataInputStream _in = null; 189 190 193 private ByteArrayInputStream _byteIn = null; 194 195 199 private int _readBytes = 0; 200 201 204 private int _byteArrayLength = 0; 205 206 211 private int _offset = 0; 212 213 214 221 public StreamMessageImpl() throws JMSException { 222 setJMSType("StreamMessage"); 223 } 224 225 232 public final Object clone() throws CloneNotSupportedException { 233 StreamMessageImpl result = (StreamMessageImpl) super.clone(); 234 if (_bodyReadOnly) { 235 result._bytes = new byte[_bytes.length]; 236 System.arraycopy(_bytes, 0, result._bytes, 0, _bytes.length); 237 if (_byteIn != null) { 238 _offset = _bytes.length - _byteIn.available(); 241 } 242 result._byteIn = null; 243 result._in = null; 244 } else { 245 if (_out != null) { 246 try { 247 _out.flush(); 248 } catch (IOException exception) { 249 throw new CloneNotSupportedException ( 250 exception.getMessage()); 251 } 252 result._bytes = _byteOut.toByteArray(); 253 result._byteOut = null; 254 result._out = null; 255 } else { 256 result._bytes = new byte[_bytes.length]; 257 System.arraycopy(_bytes, 0, result._bytes, 0, _bytes.length); 258 } 259 } 260 261 return result; 262 } 263 264 270 public final void writeExternal(ObjectOutput out) throws IOException { 271 if (!_bodyReadOnly && _out != null) { 273 _out.flush(); 274 _bytes = _byteOut.toByteArray(); 275 } 276 277 super.writeExternal(out); 278 out.writeLong(serialVersionUID); 279 out.writeInt(_bytes.length); 280 out.write(_bytes); 281 out.flush(); 282 } 283 284 292 public final void readExternal(ObjectInput in) 293 throws ClassNotFoundException , IOException { 294 super.readExternal(in); 295 long version = in.readLong(); 296 if (version == serialVersionUID) { 297 int length = in.readInt(); 298 _bytes = new byte[length]; 299 in.readFully(_bytes); 300 } else { 301 throw new IOException ("Incorrect version enountered: " + version 302 + ". This version = " + serialVersionUID); 303 } 304 } 305 306 316 public final boolean readBoolean() throws JMSException { 317 boolean result = false; 318 prepare(); 319 try { 320 result = FormatConverter.getBoolean(readNext()); 321 } catch (MessageFormatException exception) { 322 revert(exception); 323 } 324 return result; 325 } 326 327 339 public final byte readByte() throws JMSException { 340 byte result = 0; 341 prepare(); 342 try { 343 result = FormatConverter.getByte(readNext()); 344 } catch (MessageFormatException exception) { 345 revert(exception); 346 } catch (NumberFormatException exception) { 347 revert(exception); 348 } 349 return result; 350 } 351 352 363 public final short readShort() throws JMSException { 364 short result = 0; 365 prepare(); 366 try { 367 result = FormatConverter.getShort(readNext()); 368 } catch (MessageFormatException exception) { 369 revert(exception); 370 } catch (NumberFormatException exception) { 371 revert(exception); 372 } 373 return result; 374 } 375 376 386 public final char readChar() throws JMSException { 387 char result = 0; 388 prepare(); 389 try { 390 result = FormatConverter.getChar(readNext()); 391 } catch (MessageFormatException exception) { 392 revert(exception); 393 } catch (NullPointerException exception) { 394 revert(exception); 395 } 396 return result; 397 } 398 399 411 public final int readInt() throws JMSException { 412 int result = 0; 413 prepare(); 414 try { 415 result = FormatConverter.getInt(readNext()); 416 } catch (MessageFormatException exception) { 417 revert(exception); 418 } catch (NumberFormatException exception) { 419 revert(exception); 420 } 421 return result; 422 } 423 424 436 public final long readLong() throws JMSException { 437 long result = 0; 438 prepare(); 439 try { 440 result = FormatConverter.getLong(readNext()); 441 } catch (MessageFormatException exception) { 442 revert(exception); 443 } catch (NumberFormatException exception) { 444 revert(exception); 445 } 446 return result; 447 } 448 449 461 public final float readFloat() throws JMSException { 462 float result = 0; 463 prepare(); 464 try { 465 result = FormatConverter.getFloat(readNext()); 466 } catch (MessageFormatException exception) { 467 revert(exception); 468 } catch (NullPointerException exception) { 469 revert(exception); 470 } catch (NumberFormatException exception) { 471 revert(exception); 472 } 473 return result; 474 } 475 476 488 public final double readDouble() throws JMSException { 489 double result = 0; 490 prepare(); 491 try { 492 result = FormatConverter.getDouble(readNext()); 493 } catch (MessageFormatException exception) { 494 revert(exception); 495 } catch (NullPointerException exception) { 496 revert(exception); 497 } catch (NumberFormatException exception) { 498 revert(exception); 499 } 500 return result; 501 } 502 503 513 public final String readString() throws JMSException { 514 String result = null; 515 prepare(); 516 try { 517 result = FormatConverter.getString(readNext()); 518 } catch (MessageFormatException exception) { 519 revert(exception); 520 } 521 return result; 522 } 523 524 559 public final int readBytes(byte[] value) throws JMSException { 560 checkRead(); 561 getInputStream(); 562 int read = 0; if (_readBytes == 0) { 564 try { 566 _in.mark(_bytes.length - _in.available()); 567 byte type = (byte) (_in.readByte() & 0x0F); 568 if (type == NULL) { 569 return -1; 570 } else if (type != BYTE_ARRAY) { 571 _in.reset(); 572 if (type < TYPE_NAMES.length) { 573 throw new MessageFormatException ( 574 "Expected type=" + TYPE_NAMES[BYTE_ARRAY] 575 + ", but got type=" + TYPE_NAMES[type]); 576 } else { 577 throw new MessageFormatException ( 578 "StreamMessage corrupted"); 579 } 580 } 581 } catch (IOException exception) { 582 raise(exception); 583 } 584 try { 585 _byteArrayLength = _in.readInt(); 586 } catch (IOException exception) { 587 raise(exception); 588 } 589 } 590 591 if (_byteArrayLength == 0) { 592 if (_readBytes != 0) { 595 read = -1; 597 } 598 _readBytes = 0; } else if (value.length <= _byteArrayLength) { 600 read = value.length; 602 try { 603 _in.readFully(value); 604 } catch (IOException exception) { 605 raise(exception); 606 } 607 _byteArrayLength -= value.length; 608 ++_readBytes; 609 } else { 610 read = _byteArrayLength; 612 try { 613 _in.readFully(value, 0, _byteArrayLength); 614 } catch (IOException exception) { 615 raise(exception); 616 } 617 _readBytes = 0; 618 } 619 return read; 620 } 621 622 639 public final Object readObject() throws JMSException { 640 Object result = null; 641 prepare(); 642 try { 643 result = readNext(); 644 } catch (MessageFormatException exception) { 645 revert(exception); 646 } 647 return result; 648 } 649 650 661 public final void writeBoolean(boolean value) throws JMSException { 662 checkWrite(); 663 try { 664 getOutputStream(); 665 _out.writeByte(BOOLEAN | ((value) ? 1 << 4 : 0)); 667 } catch (IOException exception) { 668 raise(exception); 669 } 670 } 671 672 680 public final void writeByte(byte value) throws JMSException { 681 checkWrite(); 682 try { 683 getOutputStream(); 684 _out.writeByte(BYTE); 685 _out.writeByte(value); 686 } catch (IOException exception) { 687 raise(exception); 688 } 689 } 690 691 699 public final void writeShort(short value) throws JMSException { 700 checkWrite(); 701 try { 702 getOutputStream(); 703 _out.writeByte(SHORT); 704 _out.writeShort(value); 705 } catch (IOException exception) { 706 raise(exception); 707 } 708 } 709 710 718 public final void writeChar(char value) throws JMSException { 719 checkWrite(); 720 try { 721 getOutputStream(); 722 _out.writeByte(CHAR); 723 _out.writeChar(value); 724 } catch (IOException exception) { 725 raise(exception); 726 } 727 } 728 729 737 public final void writeInt(int value) throws JMSException { 738 checkWrite(); 739 try { 740 getOutputStream(); 741 _out.writeByte(INT); 742 _out.writeInt(value); 743 } catch (IOException exception) { 744 raise(exception); 745 } 746 } 747 748 756 public final void writeLong(long value) throws JMSException { 757 checkWrite(); 758 try { 759 getOutputStream(); 760 _out.writeByte(LONG); 761 _out.writeLong(value); 762 } catch (IOException exception) { 763 raise(exception); 764 } 765 } 766 767 775 public final void writeFloat(float value) throws JMSException { 776 checkWrite(); 777 try { 778 getOutputStream(); 779 _out.writeByte(FLOAT); 780 _out.writeFloat(value); 781 } catch (IOException exception) { 782 raise(exception); 783 } 784 } 785 786 794 public final void writeDouble(double value) throws JMSException { 795 checkWrite(); 796 try { 797 getOutputStream(); 798 _out.writeByte(DOUBLE); 799 _out.writeDouble(value); 800 } catch (IOException exception) { 801 raise(exception); 802 } 803 } 804 805 814 public final void writeString(String value) throws JMSException { 815 checkWrite(); 816 if (value == null) { 817 throw new NullPointerException ("Argument value is null"); 820 } 821 try { 822 getOutputStream(); 823 _out.writeByte(STRING); 824 _out.writeUTF(value); 825 } catch (IOException exception) { 826 raise(exception); 827 } 828 } 829 830 843 public final void writeBytes(byte[] value) throws JMSException { 844 checkWrite(); 845 if (value == null) { 846 throw new NullPointerException ("Argument value is null"); 849 } 850 try { 851 getOutputStream(); 852 _out.writeByte(BYTE_ARRAY); 853 _out.writeInt(value.length); 854 _out.write(value); 855 } catch (IOException exception) { 856 raise(exception); 857 } 858 } 859 860 877 public void writeBytes(byte[] value, int offset, int length) 878 throws JMSException { 879 checkWrite(); 880 if (value == null) { 881 throw new NullPointerException ("Argument value is null"); 884 } 885 try { 886 getOutputStream(); 887 _out.writeByte(BYTE_ARRAY); 888 _out.writeInt(length); 889 _out.write(value, offset, length); 890 } catch (IOException exception) { 891 raise(exception); 892 } 893 } 894 895 907 public void writeObject(Object value) throws JMSException { 908 if (value == null) { 909 try { 910 checkWrite(); 911 getOutputStream(); 912 _out.writeByte(NULL); 913 } catch (IOException exception) { 914 raise(exception); 915 } 916 } else if (value instanceof Boolean ) { 917 writeBoolean(((Boolean ) value).booleanValue()); 918 } else if (value instanceof Byte ) { 919 writeByte(((Byte ) value).byteValue()); 920 } else if (value instanceof byte[]) { 921 writeBytes((byte[]) value); 922 } else if (value instanceof Short ) { 923 writeShort(((Short ) value).shortValue()); 924 } else if (value instanceof Character ) { 925 writeChar(((Character ) value).charValue()); 926 } else if (value instanceof Integer ) { 927 writeInt(((Integer ) value).intValue()); 928 } else if (value instanceof Long ) { 929 writeLong(((Long ) value).longValue()); 930 } else if (value instanceof Float ) { 931 writeFloat(((Float ) value).floatValue()); 932 } else if (value instanceof Double ) { 933 writeDouble(((Double ) value).doubleValue()); 934 } else if (value instanceof String ) { 935 writeString((String ) value); 936 } else { 937 throw new MessageFormatException ( 938 "Objects of type " + value.getClass().getName() 939 + " are not supported by StreamMessage"); 940 } 941 } 942 943 950 public void reset() throws JMSException { 951 try { 952 if (!_bodyReadOnly) { 953 _bodyReadOnly = true; 954 if (_out != null) { 955 _out.flush(); 956 _bytes = _byteOut.toByteArray(); 957 _byteOut = null; 958 _out.close(); 959 _out = null; 960 } 961 } else { 962 if (_in != null) { 963 _byteIn = null; 964 _in.close(); 965 _in = null; 966 } 967 } 968 _readBytes = 0; 969 } catch (IOException exception) { 970 raise(exception); 971 } 972 } 973 974 981 public void clearBody() throws JMSException { 982 try { 983 if (_bodyReadOnly) { 984 _bodyReadOnly = false; 986 if (_in != null) { 987 _byteIn = null; 988 _in.close(); 989 _in = null; 990 _offset = 0; 991 } 992 } else if (_out != null) { 993 _byteOut = null; 995 _out.close(); 996 _out = null; 997 } 998 _bytes = EMPTY; 999 _readBytes = 0; 1000 } catch (IOException exception) { 1001 raise(exception); 1002 } 1003 } 1004 1005 1012 public final void setReadOnly(boolean readOnly) throws JMSException { 1013 if (readOnly) { 1014 reset(); 1015 } 1016 super.setReadOnly(readOnly); 1017 } 1018 1019 1026 private final void prepare() throws JMSException { 1027 checkRead(); 1028 getInputStream(); 1029 try { 1030 _in.mark(_bytes.length - _in.available()); 1031 } catch (IOException exception) { 1032 raise(exception); 1033 } 1034 } 1035 1036 1043 private void revert(MessageFormatException exception) 1044 throws MessageFormatException { 1045 try { 1046 _in.reset(); 1047 } catch (IOException ignore) { 1048 } 1051 throw exception; 1052 } 1053 1054 1062 private void revert(RuntimeException exception) { 1063 try { 1064 _in.reset(); 1065 } catch (IOException ignore) { 1066 } 1069 throw exception; 1070 } 1071 1072 1084 private Object readNext() throws JMSException { 1085 if (_readBytes != 0) { 1086 throw new MessageFormatException ( 1087 "Cannot read the next field until the byte array is read"); 1088 } 1089 1090 byte type = 0; 1091 try { 1092 type = _in.readByte(); 1093 } catch (IOException exception) { 1094 raise(exception); 1095 } 1096 if ((type & 0x0F) > TYPE_NAMES.length) { 1097 throw new JMSException ("StreamMessage corrupted"); 1098 } 1099 Object result = null; 1100 1101 try { 1102 switch (type & 0x0F) { 1103 case BOOLEAN: 1104 boolean value = ((type & 0xF0) != 0) ? true : false; 1105 result = new Boolean (value); 1106 break; 1107 case BYTE: 1108 result = new Byte (_in.readByte()); 1109 break; 1110 case BYTE_ARRAY: 1111 int length = _in.readInt(); 1112 byte[] bytes = new byte[length]; 1113 _in.readFully(bytes); 1114 result = bytes; 1115 break; 1116 case SHORT: 1117 result = new Short (_in.readShort()); 1118 break; 1119 case CHAR: 1120 result = new Character (_in.readChar()); 1121 break; 1122 case INT: 1123 result = new Integer (_in.readInt()); 1124 break; 1125 case LONG: 1126 result = new Long (_in.readLong()); 1127 break; 1128 case FLOAT: 1129 result = new Float (_in.readFloat()); 1130 break; 1131 case DOUBLE: 1132 result = new Double (_in.readDouble()); 1133 break; 1134 case STRING: 1135 result = _in.readUTF(); 1136 break; 1137 } 1138 } catch (IOException exception) { 1139 raise(exception); 1140 } 1141 1142 return result; 1143 } 1144 1145 1150 private DataInputStream getInputStream() { 1151 if (_in == null) { 1152 _byteIn = new ByteArrayInputStream (_bytes, _offset, 1153 _bytes.length - _offset); 1154 _in = new DataInputStream (_byteIn); 1155 } 1156 return _in; 1157 } 1158 1159 1165 private final DataOutputStream getOutputStream() throws IOException { 1166 if (_out == null) { 1167 _byteOut = new ByteArrayOutputStream (); 1168 _out = new DataOutputStream (_byteOut); 1169 _out.write(_bytes); 1170 } 1171 return _out; 1172 } 1173 1174 1180 private final void raise(IOException exception) throws JMSException { 1181 JMSException error = null; 1182 if (exception instanceof EOFException ) { 1183 error = new MessageEOFException (exception.getMessage()); 1184 } else { 1185 error = new JMSException (exception.getMessage()); 1186 } 1187 error.setLinkedException(exception); 1188 throw error; 1189 } 1190 1191} 1192 | Popular Tags |