KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > message > MapMessageImpl


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.1 2004/11/26 01:50:43 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 JavaDoc;
52 import java.io.ObjectInput JavaDoc;
53 import java.io.ObjectOutput JavaDoc;
54 import java.util.Collections JavaDoc;
55 import java.util.Enumeration JavaDoc;
56 import java.util.HashMap JavaDoc;
57
58 import javax.jms.JMSException JavaDoc;
59 import javax.jms.MapMessage JavaDoc;
60 import javax.jms.MessageFormatException JavaDoc;
61 import javax.jms.MessageNotWriteableException JavaDoc;
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.1 $ $Date: 2004/11/26 01:50:43 $
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 JavaDoc {
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 JavaDoc _map = new HashMap JavaDoc(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 JavaDoc {
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 JavaDoc clone() throws CloneNotSupportedException JavaDoc {
154         MapMessageImpl result = (MapMessageImpl) super.clone();
155         result._map = (HashMap JavaDoc) _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 JavaDoc out) throws IOException JavaDoc {
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 JavaDoc in)
180         throws ClassNotFoundException JavaDoc, IOException JavaDoc {
181         super.readExternal(in);
182         long version = in.readLong();
183         if (version == serialVersionUID) {
184             _map = (HashMap JavaDoc) in.readObject();
185         } else {
186             throw new IOException JavaDoc("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 JavaDoc name)
201         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
215         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
229         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
243         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
257         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
271         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
285         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
299         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc getString(String JavaDoc name)
314         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc name)
329         throws JMSException JavaDoc, MessageFormatException JavaDoc {
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 JavaDoc getObject(String JavaDoc name) throws JMSException JavaDoc {
351         Object JavaDoc result = null;
352         Object JavaDoc value = _map.get(name);
353         if (value != null) {
354             if (value instanceof Boolean JavaDoc) {
355                 result = new Boolean JavaDoc(((Boolean JavaDoc) value).booleanValue());
356             } else if (value instanceof Byte JavaDoc) {
357                 result = new Byte JavaDoc(((Byte JavaDoc) value).byteValue());
358             } else if (value instanceof Short JavaDoc) {
359                 result = new Short JavaDoc(((Short JavaDoc) value).shortValue());
360             } else if (value instanceof Character JavaDoc) {
361                 result = new Character JavaDoc(((Character JavaDoc) value).charValue());
362             } else if (value instanceof Integer JavaDoc) {
363                 result = new Integer JavaDoc(((Integer JavaDoc) value).intValue());
364             } else if (value instanceof Long JavaDoc) {
365                 result = new Long JavaDoc(((Long JavaDoc) value).longValue());
366             } else if (value instanceof Float JavaDoc) {
367                 result = new Float JavaDoc(((Float JavaDoc) value).floatValue());
368             } else if (value instanceof Double JavaDoc) {
369                 result = new Double JavaDoc(((Double JavaDoc) value).doubleValue());
370             } else if (value instanceof String JavaDoc) {
371                 result = (String JavaDoc) value;
372             } else if (value instanceof byte[]) {
373                 result = getBytes(name);
374             } else {
375                 throw new MessageFormatException JavaDoc(
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 JavaDoc 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 JavaDoc name, boolean value)
400         throws MessageNotWriteableException JavaDoc {
401         checkWrite();
402         _map.put(name, new Boolean JavaDoc(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 JavaDoc name, byte value)
413         throws MessageNotWriteableException JavaDoc {
414         checkWrite();
415         _map.put(name, new Byte JavaDoc(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 JavaDoc name, short value)
426         throws MessageNotWriteableException JavaDoc {
427         checkWrite();
428         _map.put(name, new Short JavaDoc(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 JavaDoc name, char value)
439         throws MessageNotWriteableException JavaDoc {
440         checkWrite();
441         _map.put(name, new Character JavaDoc(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 JavaDoc name, int value)
452         throws MessageNotWriteableException JavaDoc {
453         checkWrite();
454         _map.put(name, new Integer JavaDoc(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 JavaDoc name, long value)
465         throws MessageNotWriteableException JavaDoc {
466         checkWrite();
467         _map.put(name, new Long JavaDoc(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 JavaDoc name, float value)
478         throws MessageNotWriteableException JavaDoc {
479         checkWrite();
480         _map.put(name, new Float JavaDoc(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 JavaDoc name, double value)
491         throws MessageNotWriteableException JavaDoc {
492         checkWrite();
493         _map.put(name, new Double JavaDoc(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 JavaDoc name, String JavaDoc value)
504         throws MessageNotWriteableException JavaDoc {
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 JavaDoc name, byte[] value)
519         throws MessageNotWriteableException JavaDoc {
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 JavaDoc name, byte[] value,
539                                int offset, int length)
540         throws MessageNotWriteableException JavaDoc {
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 JavaDoc name, Object JavaDoc value)
562         throws MessageFormatException JavaDoc, MessageNotWriteableException JavaDoc {
563         checkWrite();
564         if (value == null) {
565             _map.put(name, null);
566         } else if (value instanceof Boolean JavaDoc) {
567             setBoolean(name, ((Boolean JavaDoc) value).booleanValue());
568         } else if (value instanceof Byte JavaDoc) {
569             setByte(name, ((Byte JavaDoc) value).byteValue());
570         } else if (value instanceof Short JavaDoc) {
571             setShort(name, ((Short JavaDoc) value).shortValue());
572         } else if (value instanceof Character JavaDoc) {
573             setChar(name, ((Character JavaDoc) value).charValue());
574         } else if (value instanceof Integer JavaDoc) {
575             setInt(name, ((Integer JavaDoc) value).intValue());
576         } else if (value instanceof Long JavaDoc) {
577             setLong(name, ((Long JavaDoc) value).longValue());
578         } else if (value instanceof Float JavaDoc) {
579             setFloat(name, ((Float JavaDoc) value).floatValue());
580         } else if (value instanceof Double JavaDoc) {
581             setDouble(name, ((Double JavaDoc) value).doubleValue());
582         } else if (value instanceof String JavaDoc) {
583             setString(name, (String JavaDoc) value);
584         } else if (value instanceof byte[]) {
585             setBytes(name, (byte[]) value);
586         } else {
587             throw new MessageFormatException JavaDoc(
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 JavaDoc 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 JavaDoc {
611         super.clearBody();
612         _map = new HashMap JavaDoc(INITIAL_SIZE);
613     }
614
615 } // End MapMessageImpl
616
Popular Tags