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 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: BasicStreamMessage.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.util.ArrayList; 49 import java.util.List; 50 51 import javax.jms.JMSException; 52 import javax.jms.MessageEOFException; 53 import javax.jms.MessageFormatException; 54 import javax.jms.MessageNotWriteableException; 55 import javax.jms.StreamMessage; 56 57 58 /*** 59 * This class provides a basic implementation of the javax.jms.ObjectMessage 60 * interface. 61 * 62 * @version $Revision: 1.2 $ $Date: 2004/02/02 03:49:55 $ 63 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 64 * @see javax.jms.StreamMessage 65 */ 66 public class BasicStreamMessage extends BasicMessage implements StreamMessage { 67 68 /*** 69 * The message body 70 */ 71 private List _body = new ArrayList(); 72 73 /*** 74 * Index into the body array 75 */ 76 private int _index = 0; 77 78 79 /*** 80 * Current byte array field being processed 81 */ 82 private byte[] _bytes; 83 84 /*** 85 * Non-zero if incrementally reading a byte array using 86 * {@link #readBytes(byte[])} 87 */ 88 private int _bytesRead = 0; 89 90 91 /*** 92 * Construct a new <code>BasicStreamMessage</code>. 93 * When first created, the message is in write-only mode. 94 */ 95 public BasicStreamMessage() { 96 } 97 98 /*** 99 * Read a <code>boolean</code> from the bytes message stream 100 * 101 * @return the <code>boolean</code> value read 102 * @throws JMSException if JMS fails to read message due to some internal 103 * JMS error 104 * @throws MessageEOFException if end of message stream 105 * @throws MessageFormatException if this type conversion is invalid 106 */ 107 public boolean readBoolean() throws JMSException { 108 boolean result = FormatConverter.getBoolean(readNext()); 109 _index++; 110 return result; 111 } 112 113 /*** 114 * Read a byte value from the stream message 115 * 116 * @return the next byte from the stream message as an 8-bit 117 * <code>byte</code> 118 * @throws JMSException if JMS fails to read message due to some internal 119 * JMS error 120 * @throws MessageEOFException if end of message stream 121 * @throws MessageFormatException if this type conversion is invalid 122 * @throws NumberFormatException if numeric conversion is invalid 123 */ 124 public byte readByte() throws JMSException { 125 byte result = FormatConverter.getByte(readNext()); 126 _index++; 127 return result; 128 } 129 130 /*** 131 * Read a 16-bit number from the stream message. 132 * 133 * @return a 16-bit number from the stream message 134 * @throws JMSException if JMS fails to read message due to some internal 135 * JMS error 136 * @throws MessageEOFException if end of message stream 137 * @throws MessageFormatException if this type conversion is invalid 138 * @throws NumberFormatException if numeric conversion is invalid 139 */ 140 public short readShort() throws JMSException { 141 short result = FormatConverter.getShort(readNext()); 142 _index++; 143 return result; 144 } 145 146 /*** 147 * Read a Unicode character value from the stream message 148 * 149 * @return a Unicode character from the stream message 150 * @throws JMSException if JMS fails to read message due to some internal 151 * JMS error 152 * @throws MessageEOFException if end of message stream 153 * @throws MessageFormatException if this type conversion is invalid 154 */ 155 public char readChar() throws JMSException { 156 char result = FormatConverter.getChar(readNext()); 157 _index++; 158 return result; 159 } 160 161 /*** 162 * Read a 32-bit integer from the stream message 163 * 164 * @return a 32-bit integer value from the stream message, interpreted 165 * as an <code>int</code> 166 * @throws JMSException if JMS fails to read message due to some internal 167 * JMS error 168 * @throws MessageEOFException if end of message stream 169 * @throws MessageFormatException if this type conversion is invalid 170 * @throws NumberFormatException if numeric conversion is invalid 171 */ 172 public int readInt() throws JMSException { 173 int result = FormatConverter.getInt(readNext()); 174 _index++; 175 return result; 176 } 177 178 /*** 179 * Read a 64-bit integer from the stream message 180 * 181 * @return a 64-bit integer value from the stream message, interpreted as 182 * a <code>long</code> 183 * @throws JMSException if JMS fails to read message due to some internal 184 * JMS error 185 * @throws MessageEOFException if end of message stream 186 * @throws MessageFormatException if this type conversion is invalid 187 * @throws NumberFormatException if numeric conversion is invalid 188 */ 189 public long readLong() throws JMSException { 190 long result = FormatConverter.getLong(readNext()); 191 _index++; 192 return result; 193 } 194 195 /*** 196 * Read a <code>float</code> from the stream message 197 * 198 * @return a <code>float</code> value from the stream message 199 * @throws JMSException if JMS fails to read message due to some internal 200 * JMS error 201 * @throws MessageEOFException if end of message stream 202 * @throws MessageFormatException if this type conversion is invalid 203 * @throws NullPointerException if the value is null 204 * @throws NumberFormatException if numeric conversion is invalid 205 */ 206 public float readFloat() throws JMSException { 207 float result = FormatConverter.getFloat(readNext()); 208 _index++; 209 return result; 210 } 211 212 /*** 213 * Read a <code>double</code> from the stream message 214 * 215 * @return a <code>double</code> value from the stream message 216 * @throws JMSException if JMS fails to read message due to some internal 217 * JMS error 218 * @throws MessageEOFException if end of message stream 219 * @throws MessageFormatException if this type conversion is invalid 220 * @throws NullPointerException if the value is null 221 * @throws NumberFormatException if numeric conversion is invalid 222 */ 223 public double readDouble() throws JMSException { 224 double result = FormatConverter.getDouble(readNext()); 225 _index++; 226 return result; 227 } 228 229 /*** 230 * Read in a string from the stream message 231 * 232 * @return a Unicode string from the stream message 233 * @throws JMSException if JMS fails to read message due to some internal 234 * JMS error 235 * @throws MessageEOFException if end of message stream 236 * @throws MessageFormatException if this type conversion is invalid 237 */ 238 public String readString() throws JMSException { 239 String result = FormatConverter.getString(readNext()); 240 _index++; 241 return result; 242 } 243 244 /*** 245 * Read a byte array field from the stream message into the 246 * specified byte[] object (the read buffer). 247 * <p> 248 * To read the field value, readBytes should be successively called 249 * until it returns a value less than the length of the read buffer. 250 * The value of the bytes in the buffer following the last byte 251 * read are undefined. 252 * <p> 253 * If readBytes returns a value equal to the length of the buffer, a 254 * subsequent readBytes call must be made. If there are no more bytes 255 * to be read this call will return -1. 256 * <p> 257 * If the bytes array field value is null, readBytes returns -1. 258 * <p> 259 * If the bytes array field value is empty, readBytes returns 0. 260 * <p> 261 * Once the first readBytes call on a byte[] field value has been done, 262 * the full value of the field must be read before it is valid to read 263 * the next field. An attempt to read the next field before that has 264 * been done will throw a MessageFormatException. 265 * <p> 266 * To read the byte field value into a new byte[] object, use the 267 * {@link #readObject} method. 268 * 269 * @param value the buffer into which the data is read. 270 * @return the total number of bytes read into the buffer, or -1 if 271 * there is no more data because the end of the byte field has been 272 * reached. 273 * @throws JMSException if JMS fails to read message due to some internal 274 * JMS error 275 * @throws MessageEOFException if an end of message stream 276 * @throws MessageFormatException if this type conversion is invalid 277 */ 278 public int readBytes(byte[] value) throws JMSException { 279 int read = 0; // the number of bytes read 280 if (_bytes == null) { 281 Object next = readNext(); 282 if (!(next instanceof byte[])) { 283 throw new MessageFormatException("Field is not a byte array"); 284 } 285 _bytes = (byte[]) next; 286 _bytesRead = 0; 287 _index++; 288 } 289 int available = _bytes.length - _bytesRead; 290 291 if (available == 0) { 292 if (_bytesRead != 0) { // not the first invocation 293 read = -1; 294 } 295 } else { 296 if (value.length <= available) { 297 read = value.length; 298 } else { 299 read = available; 300 } 301 System.arraycopy(_bytes, _bytesRead, value, 0, value.length); 302 _bytesRead += read; 303 } 304 return read; 305 } 306 307 /*** 308 * Read a Java object from the stream message 309 * <p> 310 * Note that this method can be used to return in objectified format, 311 * an object that had been written to the stream with the equivalent 312 * <code>writeObject</code> method call, or it's equivalent primitive 313 * write<type> method. 314 * <p> 315 * Note that byte values are returned as byte[], not Byte[]. 316 * 317 * @return a Java object from the stream message, in objectified 318 * format (eg. if it set as an int, then a Integer is returned). 319 * @throws JMSException if JMS fails to read message due to some internal 320 * JMS error 321 * @throws MessageEOFException if end of message stream 322 */ 323 public Object readObject() throws JMSException { 324 Object result = readNext(); 325 _index++; 326 return result; 327 } 328 329 /*** 330 * Write a <code>boolean</code> to the stream message. 331 * The value <code>true</code> is written out as the value 332 * <code>(byte)1</code>; the value <code>false</code> is written out as 333 * the value <code>(byte)0</code>. 334 * 335 * @param value the <code>boolean</code> value to be written. 336 * @throws MessageNotWriteableException if message in read-only mode 337 */ 338 public void writeBoolean(boolean value) 339 throws MessageNotWriteableException { 340 checkWrite(); 341 _body.add(new Boolean(value)); 342 } 343 344 /*** 345 * Write out a <code>byte</code> to the stream message 346 * 347 * @param value the <code>byte</code> value to be written 348 * @throws MessageNotWriteableException if message in read-only mode 349 */ 350 public void writeByte(byte value) throws MessageNotWriteableException { 351 checkWrite(); 352 _body.add(new Byte(value)); 353 } 354 355 /*** 356 * Write a <code>short</code> to the stream message 357 * 358 * @param value the <code>short</code> to be written 359 * @throws MessageNotWriteableException if message in read-only mode 360 */ 361 public void writeShort(short value) throws MessageNotWriteableException { 362 checkWrite(); 363 _body.add(new Short(value)); 364 } 365 366 /*** 367 * Write a <code>char</code> to the stream message 368 * 369 * @param value the <code>char</code> value to be written 370 * @throws MessageNotWriteableException if message in read-only mode 371 */ 372 public void writeChar(char value) throws MessageNotWriteableException { 373 checkWrite(); 374 _body.add(new Character(value)); 375 } 376 377 /*** 378 * Write an <code>int</code> to the stream message 379 * 380 * @param value the <code>int</code> to be written 381 * @throws MessageNotWriteableException if message in read-only mode 382 */ 383 public void writeInt(int value) throws MessageNotWriteableException { 384 checkWrite(); 385 _body.add(new Integer(value)); 386 } 387 388 /*** 389 * Write a <code>long</code> to the stream message 390 * 391 * @param value the <code>long</code> to be written 392 * @throws MessageNotWriteableException if message in read-only mode 393 */ 394 public void writeLong(long value) throws MessageNotWriteableException { 395 checkWrite(); 396 _body.add(new Long(value)); 397 } 398 399 /*** 400 * Write a <code>float</code> to the stream message 401 * 402 * @param value the <code>float</code> value to be written 403 * @throws MessageNotWriteableException if message in read-only mode 404 */ 405 public void writeFloat(float value) throws MessageNotWriteableException { 406 checkWrite(); 407 _body.add(new Float(value)); 408 } 409 410 /*** 411 * Write a <code>double</code> to the stream message 412 * 413 * @param value the <code>double</code> value to be written 414 * @throws MessageNotWriteableException if message in read-only mode 415 */ 416 public void writeDouble(double value) throws MessageNotWriteableException { 417 checkWrite(); 418 _body.add(new Double(value)); 419 } 420 421 /*** 422 * Write a string to the stream message 423 * 424 * @param value the <code>String</code> value to be written 425 * @throws MessageNotWriteableException if message in read-only mode 426 */ 427 public void writeString(String value) throws MessageNotWriteableException { 428 checkWrite(); 429 _body.add(value); 430 } 431 432 /*** 433 * Write a byte array field to the stream message 434 * <p> 435 * The byte array <code>value</code> is written as a byte array field 436 * into the StreamMessage. Consecutively written byte array fields are 437 * treated as two distinct fields when reading byte array fields. 438 * 439 * @param value the byte array to be written 440 * @throws MessageNotWriteableException if message in read-only mode 441 */ 442 public void writeBytes(byte[] value) throws MessageNotWriteableException { 443 writeBytes(value, 0, value.length); 444 } 445 446 /*** 447 * Write a portion of a byte array as a byte array field to the stream 448 * message 449 * <p> 450 * The a portion of the byte array <code>value</code> is written as a 451 * byte array field into the StreamMessage. Consecutively written byte 452 * array fields are treated as two distinct fields when reading byte 453 * array fields. 454 * 455 * @param value the byte array value to be written 456 * @param offset the initial offset within the byte array 457 * @param length the number of bytes to write 458 * @throws MessageNotWriteableException if message in read-only mode 459 */ 460 public void writeBytes(byte[] value, int offset, int length) 461 throws MessageNotWriteableException { 462 checkWrite(); 463 byte[] buffer = new byte[length]; 464 System.arraycopy(value, offset, buffer, 0, length); 465 _body.add(buffer); 466 } 467 468 /*** 469 * Write a Java object to the stream message 470 * <p> 471 * Note that this method only works for the objectified primitive 472 * object types (Integer, Double, Long ...), String's and byte arrays. 473 * 474 * @param value the Java object to be written 475 * @throws JMSException if JMS fails to write message due to 476 * some internal JMS error 477 * @throws MessageFormatException if the object is invalid 478 * @throws MessageNotWriteableException if message in read-only mode 479 */ 480 public void writeObject(Object value) throws JMSException { 481 if (value == null) { 482 checkWrite(); 483 _body.add(null); 484 } else if (value instanceof Boolean) { 485 writeBoolean(((Boolean) value).booleanValue()); 486 } else if (value instanceof Byte) { 487 writeByte(((Byte) value).byteValue()); 488 } else if (value instanceof byte[]) { 489 writeBytes((byte[]) value); 490 } else if (value instanceof Short) { 491 writeShort(((Short) value).shortValue()); 492 } else if (value instanceof Character) { 493 writeChar(((Character) value).charValue()); 494 } else if (value instanceof Integer) { 495 writeInt(((Integer) value).intValue()); 496 } else if (value instanceof Long) { 497 writeLong(((Long) value).longValue()); 498 } else if (value instanceof Float) { 499 writeFloat(((Float) value).floatValue()); 500 } else if (value instanceof Double) { 501 writeDouble(((Double) value).doubleValue()); 502 } else if (value instanceof String) { 503 writeString((String) value); 504 } else { 505 throw new MessageFormatException( 506 "Objects of type " + value.getClass().getName() 507 + " are not supported by StreamMessage"); 508 } 509 } 510 511 /*** 512 * Put the message body in read-only mode, and reposition the stream 513 * to the beginning 514 */ 515 public void reset() { 516 setBodyReadOnly(true); 517 _index = 0; 518 _bytes = null; 519 _bytesRead = 0; 520 } 521 522 /*** 523 * Clear the message body 524 * 525 * @throws JMSException if JMS fails to reset the message due to 526 * some internal JMS error. 527 */ 528 public void clearBody() throws JMSException { 529 super.clearBody(); 530 _body.clear(); 531 _index = 0; 532 _bytes = null; 533 _bytesRead = 0; 534 } 535 536 /*** 537 * Set the read-only mode of the message. 538 * 539 * @param readOnly if true, make the message body and properties read-only, 540 * and invoke {@link #reset} 541 * @throws JMSException if the read-only mode cannot be changed 542 */ 543 public void setReadOnly(boolean readOnly) throws JMSException { 544 super.setReadOnly(readOnly); 545 if (readOnly) { 546 reset(); 547 } 548 } 549 550 /*** 551 * Read the next object from the stream message 552 * 553 * @return a Java object from the stream message, in objectified 554 * format (eg. if it set as an int, then a Integer is returned). 555 * @throws JMSException if JMS fails to read message due to some internal 556 * JMS error 557 * @throws MessageEOFException if end of message stream 558 * @throws MessageFormatException if a byte array has not been fully read 559 * by {@link #readBytes(byte[])} 560 */ 561 private Object readNext() throws JMSException { 562 checkRead(); 563 564 if (_bytesRead != 0) { 565 throw new MessageFormatException( 566 "Cannot read the next field until the byte array is read"); 567 } 568 569 if (_index == _body.size()) { 570 throw new MessageEOFException("End of stream"); 571 } 572 return _body.get(_index); 573 } 574 575 }

This page was automatically generated by Maven