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-2003 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: MapMessageImpl.java,v 1.8 2003/08/17 01:32:24 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.IOException; 52 import java.io.ObjectInput; 53 import java.io.ObjectOutput; 54 import java.util.Collections; 55 import java.util.Enumeration; 56 import java.util.HashMap; 57 58 import javax.jms.JMSException; 59 import javax.jms.MapMessage; 60 import javax.jms.MessageFormatException; 61 import javax.jms.MessageNotWriteableException; 62 63 64 /*** 65 * This class implements the {@link javax.jms.MapMessage} interface. 66 * <p> 67 * A MapMessage is used to send a set of name-value pairs where names are 68 * Strings and values are Java primitive types. The entries can be accessed 69 * sequentially or randomly by name. The order of the entries is undefined. 70 * It inherits from <code>Message</code> and adds a map message body. 71 * <p> 72 * The primitive types can be read or written explicitly using methods 73 * for each type. They may also be read or written generically as objects. 74 * For instance, a call to <code>MapMessage.setInt("foo", 6)</code> is 75 * equivalent to <code>MapMessage.setObject("foo", new Integer(6))</code>. 76 * Both forms are provided because the explicit form is convenient for 77 * static programming and the object form is needed when types are not known 78 * at compile time. 79 * <p> 80 * When a client receives a MapMessage, it is in read-only mode. If a 81 * client attempts to write to the message at this point, a 82 * MessageNotWriteableException is thrown. If {@link #clearBody} is 83 * called, the message can now be both read from and written to. 84 * <p> 85 * Map messages support the following conversion table. The marked cases 86 * must be supported. The unmarked cases must throw a JMSException. The 87 * String to primitive conversions may throw a runtime exception if the 88 * primitives <code>valueOf()</code> method does not accept it as a valid 89 * String representation of the primitive. 90 * <p> 91 * A value written as the row type can be read as the column type. 92 * 93 * <pre> 94 * | | boolean byte short char int long float double String byte[] 95 * |---------------------------------------------------------------------- 96 * |boolean | X X 97 * |byte | X X X X X 98 * |short | X X X X 99 * |char | X X 100 * |int | X X X 101 * |long | X X 102 * |float | X X X 103 * |double | X X 104 * |String | X X X X X X X X 105 * |byte[] | X 106 * |---------------------------------------------------------------------- 107 * </pre> 108 * 109 * <p> 110 * Attempting to read a null value as a Java primitive type must be treated 111 * as calling the primitive's corresponding <code>valueOf(String)</code> 112 * conversion method with a null value. Since char does not support a 113 * String conversion, attempting to read a null value as a char must 114 * throw NullPointerException. 115 * 116 * @version $Revision: 1.8 $ $Date: 2003/08/17 01:32:24 $ 117 * @author <a href="mailto:mourikis@exolab.org">Jim Mourikis</a> 118 * @see javax.jms.MapMessage 119 */ 120 public class MapMessageImpl extends MessageImpl implements MapMessage { 121 122 /*** 123 * Object version no. for serialization 124 */ 125 static final long serialVersionUID = 2; 126 127 /*** 128 * The initial size of the map 129 */ 130 private static final int INITIAL_SIZE = 20; 131 132 /*** 133 * The container for all message data 134 */ 135 private HashMap _map = new HashMap(INITIAL_SIZE); 136 137 /*** 138 * Construct a new MapMessage 139 * 140 * @throws JMSException if the message type can't be set 141 */ 142 public MapMessageImpl() throws JMSException { 143 setJMSType("MapMessage"); 144 } 145 146 /*** 147 * Clone an instance of this object 148 * 149 * @return a copy of this object 150 * @throws CloneNotSupportedException if object or attributes aren't 151 * cloneable 152 */ 153 public final Object clone() throws CloneNotSupportedException { 154 MapMessageImpl result = (MapMessageImpl) super.clone(); 155 result._map = (HashMap) _map.clone(); 156 return result; 157 } 158 159 /*** 160 * Serialize out this message's data 161 * 162 * @param out the stream to serialize out to 163 * @throws IOException if any I/O exceptions occurr 164 */ 165 public final void writeExternal(ObjectOutput out) throws IOException { 166 super.writeExternal(out); 167 out.writeLong(serialVersionUID); 168 out.writeObject(_map); 169 } 170 171 /*** 172 * Serialize in this message's data 173 * 174 * @param in the stream to serialize in from 175 * @throws ClassNotFoundException if the class for an object being 176 * restored cannot be found. 177 * @throws IOException if any I/O exceptions occur 178 */ 179 public final void readExternal(ObjectInput in) 180 throws ClassNotFoundException, IOException { 181 super.readExternal(in); 182 long version = in.readLong(); 183 if (version == serialVersionUID) { 184 _map = (HashMap) in.readObject(); 185 } else { 186 throw new IOException("Incorrect version enountered: " + version + 187 ". This version = " + serialVersionUID); 188 } 189 } 190 191 /*** 192 * Return the boolean value with the given name 193 * 194 * @param name the name of the boolean 195 * @return the boolean value with the given name 196 * @throws JMSException if JMS fails to read the message due to some 197 * internal JMS error 198 * @throws MessageFormatException if this type conversion is invalid 199 */ 200 public final boolean getBoolean(String name) 201 throws JMSException, MessageFormatException { 202 return FormatConverter.getBoolean(_map.get(name)); 203 } 204 205 /*** 206 * Return the byte value with the given name 207 * 208 * @param name the name of the byte 209 * @return the byte value with the given name 210 * @throws JMSException if JMS fails to read the message due to some 211 * internal JMS error 212 * @throws MessageFormatException if this type conversion is invalid 213 */ 214 public final byte getByte(String name) 215 throws JMSException, MessageFormatException { 216 return FormatConverter.getByte(_map.get(name)); 217 } 218 219 /*** 220 * Return the short value with the given name 221 * 222 * @param name the name of the short 223 * @return the short value with the given name 224 * @throws JMSException if JMS fails to read the message due to some 225 * internal JMS error 226 * @throws MessageFormatException if this type conversion is invalid 227 */ 228 public final short getShort(String name) 229 throws JMSException, MessageFormatException { 230 return FormatConverter.getShort(_map.get(name)); 231 } 232 233 /*** 234 * Return the Unicode character value with the given name 235 * 236 * @param name the name of the Unicode character 237 * @return the Unicode character value with the given name 238 * @throws JMSException if JMS fails to read the message due to some 239 * internal JMS error 240 * @throws MessageFormatException if this type conversion is invalid 241 */ 242 public final char getChar(String name) 243 throws JMSException, MessageFormatException { 244 return FormatConverter.getChar(_map.get(name)); 245 } 246 247 /*** 248 * Return the integer value with the given name 249 * 250 * @param name the name of the integer 251 * @return the integer value with the given name 252 * @throws JMSException if JMS fails to read the message due to some 253 * internal JMS error 254 * @throws MessageFormatException if this type conversion is invalid 255 */ 256 public final int getInt(String name) 257 throws JMSException, MessageFormatException { 258 return FormatConverter.getInt(_map.get(name)); 259 } 260 261 /*** 262 * Return the long value with the given name 263 * 264 * @param name the name of the long 265 * @return the long value with the given name 266 * @throws JMSException if JMS fails to read the message due to some 267 * internal JMS error 268 * @throws MessageFormatException if this type conversion is invalid 269 */ 270 public final long getLong(String name) 271 throws JMSException, MessageFormatException { 272 return FormatConverter.getLong(_map.get(name)); 273 } 274 275 /*** 276 * Return the float value with the given name 277 * 278 * @param name the name of the float 279 * @return the float value with the given name 280 * @throws JMSException if JMS fails to read the message due to some 281 * internal JMS error 282 * @throws MessageFormatException if this type conversion is invalid 283 */ 284 public final float getFloat(String name) 285 throws JMSException, MessageFormatException { 286 return FormatConverter.getFloat(_map.get(name)); 287 } 288 289 /*** 290 * Return the double value with the given name 291 * 292 * @param name the name of the double 293 * @return the double value with the given name 294 * @throws JMSException if JMS fails to read the message due to some 295 * internal JMS error 296 * @throws MessageFormatException if this type conversion is invalid 297 */ 298 public final double getDouble(String name) 299 throws JMSException, MessageFormatException { 300 return FormatConverter.getDouble(_map.get(name)); 301 } 302 303 /*** 304 * Return the String value with the given name 305 * 306 * @param name the name of the String 307 * @return the String value with the given name. If there is no item 308 * by this name, a null value is returned. 309 * @throws JMSException if JMS fails to read the message due to some 310 * internal JMS error 311 * @throws MessageFormatException if this type conversion is invalid 312 */ 313 public final String getString(String name) 314 throws JMSException, MessageFormatException { 315 return FormatConverter.getString(_map.get(name)); 316 } 317 318 /*** 319 * Return the byte array value with the given name 320 * 321 * @param name the name of the byte array 322 * @return a copy of the byte array value with the given name. 323 * If there is no item by this name, a null value is returned. 324 * @throws JMSException if JMS fails to read the message due to some 325 * internal JMS error 326 * @throws MessageFormatException if this type conversion is invalid 327 */ 328 public final byte[] getBytes(String name) 329 throws JMSException, MessageFormatException { 330 return FormatConverter.getBytes(_map.get(name)); 331 } 332 333 /*** 334 * Return the Java object value with the given name 335 * <p> 336 * Note that this method can be used to return in objectified format, 337 * an object that had been stored in the Map with the equivalent 338 * <code>setObject</code> method call, or it's equivalent primitive 339 * set<type> method. 340 * 341 * @param name the name of the Java object 342 * @return a copy of the Java object value with the given name, in 343 * objectified format (eg. if it set as an int, then an Integer is 344 * returned). 345 * Note that byte values are returned as byte[], not Byte[]. 346 * If there is no item by this name, a null value is returned. 347 * @throws JMSException if JMS fails to read the message due to some 348 * internal JMS error 349 */ 350 public final Object getObject(String name) throws JMSException { 351 Object result = null; 352 Object value = _map.get(name); 353 if (value != null) { 354 if (value instanceof Boolean) { 355 result = new Boolean(((Boolean) value).booleanValue()); 356 } else if (value instanceof Byte) { 357 result = new Byte(((Byte) value).byteValue()); 358 } else if (value instanceof Short) { 359 result = new Short(((Short) value).shortValue()); 360 } else if (value instanceof Character) { 361 result = new Character(((Character) value).charValue()); 362 } else if (value instanceof Integer) { 363 result = new Integer(((Integer) value).intValue()); 364 } else if (value instanceof Long) { 365 result = new Long(((Long) value).longValue()); 366 } else if (value instanceof Float) { 367 result = new Float(((Float) value).floatValue()); 368 } else if (value instanceof Double) { 369 result = new Double(((Double) value).doubleValue()); 370 } else if (value instanceof String) { 371 result = (String) value; 372 } else if (value instanceof byte[]) { 373 result = getBytes(name); 374 } else { 375 throw new MessageFormatException( 376 "MapMessage contains an unsupported object of type=" + 377 value.getClass().getName()); 378 } 379 } 380 return result; 381 } 382 383 /*** 384 * Return an Enumeration of all the Map message's names. 385 * 386 * @return an enumeration of all the names in this Map message. 387 */ 388 public final Enumeration getMapNames() { 389 return Collections.enumeration(_map.keySet()); 390 } 391 392 /*** 393 * Set a boolean value with the given name, into the Map 394 * 395 * @param name the name of the boolean 396 * @param value the boolean value to set in the Map 397 * @throws MessageNotWriteableException if the message is in read-only mode 398 */ 399 public final void setBoolean(String name, boolean value) 400 throws MessageNotWriteableException { 401 checkWrite(); 402 _map.put(name, new Boolean(value)); 403 } 404 405 /*** 406 * Set a byte value with the given name, into the Map 407 * 408 * @param name the name of the byte 409 * @param value the byte value to set in the Map 410 * @throws MessageNotWriteableException if the message is in read-only mode 411 */ 412 public final void setByte(String name, byte value) 413 throws MessageNotWriteableException { 414 checkWrite(); 415 _map.put(name, new Byte(value)); 416 } 417 418 /*** 419 * Set a short value with the given name, into the Map 420 * 421 * @param name the name of the short 422 * @param value the short value to set in the Map 423 * @throws MessageNotWriteableException if the message is in read-only mode 424 */ 425 public final void setShort(String name, short value) 426 throws MessageNotWriteableException { 427 checkWrite(); 428 _map.put(name, new Short(value)); 429 } 430 431 /*** 432 * Set a Unicode character value with the given name, into the Map 433 * 434 * @param name the name of the Unicode character 435 * @param value the Unicode character value to set in the Map 436 * @throws MessageNotWriteableException if the message is in read-only mode 437 */ 438 public final void setChar(String name, char value) 439 throws MessageNotWriteableException { 440 checkWrite(); 441 _map.put(name, new Character(value)); 442 } 443 444 /*** 445 * Set an integer value with the given name, into the Map 446 * 447 * @param name the name of the integer 448 * @param value the integer value to set in the Map 449 * @throws MessageNotWriteableException if the message is in read-only mode 450 */ 451 public final void setInt(String name, int value) 452 throws MessageNotWriteableException { 453 checkWrite(); 454 _map.put(name, new Integer(value)); 455 } 456 457 /*** 458 * Set a long value with the given name, into the Map 459 * 460 * @param name the name of the long 461 * @param value the long value to set in the Map 462 * @throws MessageNotWriteableException if the message is in read-only mode 463 */ 464 public final void setLong(String name, long value) 465 throws MessageNotWriteableException { 466 checkWrite(); 467 _map.put(name, new Long(value)); 468 } 469 470 /*** 471 * Set a float value with the given name, into the Map 472 * 473 * @param name the name of the float 474 * @param value the float value to set in the Map 475 * @throws MessageNotWriteableException if the message is in read-only mode 476 */ 477 public final void setFloat(String name, float value) 478 throws MessageNotWriteableException { 479 checkWrite(); 480 _map.put(name, new Float(value)); 481 } 482 483 /*** 484 * Set a double value with the given name, into the Map 485 * 486 * @param name the name of the double 487 * @param value the double value to set in the Map 488 * @throws MessageNotWriteableException if the message is in read-only mode 489 */ 490 public final void setDouble(String name, double value) 491 throws MessageNotWriteableException { 492 checkWrite(); 493 _map.put(name, new Double(value)); 494 } 495 496 /*** 497 * Set a String value with the given name, into the Map 498 * 499 * @param name the name of the String 500 * @param value the String value to set in the Map 501 * @throws MessageNotWriteableException if the message is in read-only mode 502 */ 503 public final void setString(String name, String value) 504 throws MessageNotWriteableException { 505 checkWrite(); 506 _map.put(name, value); 507 } 508 509 /*** 510 * Set a byte array value with the given name, into the Map 511 * 512 * @param name the name of the byte array 513 * @param value the byte array value to set in the Map. The array is 514 * copied so the value for name will not be altered by future 515 * modifications. 516 * @throws MessageNotWriteableException if the message is in read-only mode 517 */ 518 public final void setBytes(String name, byte[] value) 519 throws MessageNotWriteableException { 520 checkWrite(); 521 byte[] bytes = null; 522 if (value != null) { 523 bytes = new byte[value.length]; 524 System.arraycopy(value, 0, bytes, 0, bytes.length); 525 } 526 _map.put(name, bytes); 527 } 528 529 /*** 530 * Set a portion of the byte array value with the given name, into the Map 531 * 532 * @param name the name of the byte array 533 * @param value the byte array value to set in the Map. 534 * @param offset the initial offset within the byte array. 535 * @param length the number of bytes to use. 536 * @throws MessageNotWriteableException if the message is in read-only mode 537 */ 538 public final void setBytes(String name, byte[] value, 539 int offset, int length) 540 throws MessageNotWriteableException { 541 checkWrite(); 542 byte[] bytes = null; 543 if (value != null) { 544 bytes = new byte[length]; 545 System.arraycopy(value, offset, bytes, 0, length); 546 } 547 _map.put(name, bytes); 548 } 549 550 /*** 551 * Set a Java object value with the given name, into the Map 552 * <p> 553 * Note that this method only works for the objectified primitive 554 * object types (Integer, Double, Long ...), String's and byte arrays. 555 * 556 * @param name the name of the Java object 557 * @param value the Java object value to set in the Map 558 * @throws MessageFormatException if object is invalid 559 * @throws MessageNotWriteableException if message in read-only mode. 560 */ 561 public final void setObject(String name, Object value) 562 throws MessageFormatException, MessageNotWriteableException { 563 checkWrite(); 564 if (value == null) { 565 _map.put(name, null); 566 } else if (value instanceof Boolean) { 567 setBoolean(name, ((Boolean) value).booleanValue()); 568 } else if (value instanceof Byte) { 569 setByte(name, ((Byte) value).byteValue()); 570 } else if (value instanceof Short) { 571 setShort(name, ((Short) value).shortValue()); 572 } else if (value instanceof Character) { 573 setChar(name, ((Character) value).charValue()); 574 } else if (value instanceof Integer) { 575 setInt(name, ((Integer) value).intValue()); 576 } else if (value instanceof Long) { 577 setLong(name, ((Long) value).longValue()); 578 } else if (value instanceof Float) { 579 setFloat(name, ((Float) value).floatValue()); 580 } else if (value instanceof Double) { 581 setDouble(name, ((Double) value).doubleValue()); 582 } else if (value instanceof String) { 583 setString(name, (String) value); 584 } else if (value instanceof byte[]) { 585 setBytes(name, (byte[]) value); 586 } else { 587 throw new MessageFormatException( 588 "MapMessage does not support objects of type=" + 589 value.getClass().getName()); 590 } 591 } 592 593 /*** 594 * Check if an item exists in this MapMessage 595 * 596 * @param name the name of the item to test 597 * @return true if the item exists 598 */ 599 public final boolean itemExists(String name) { 600 return _map.containsKey(name); 601 } 602 603 /*** 604 * Clear out the message body. Clearing a message's body does not clear 605 * its header values or property entries. 606 * If this message body was read-only, calling this method leaves the 607 * message body is in the same state as an empty body in a newly created 608 * message 609 */ 610 public final void clearBody() throws JMSException { 611 super.clearBody(); 612 _map = new HashMap(INITIAL_SIZE); 613 } 614 615 } // End MapMessageImpl

This page was automatically generated by Maven