1 /*
2 * @(#)MessageProperties.java
3 *
4 * JFoxMQ the open source JMS MOM.
5 *
6 * Corpyright 2002-2003 Huihoo Power, Inc. All Rights Reserved. This software
7 * is licensed under LGPL license.
8 *
9 * For more information, please visit: http://www.huihoo.org
10 */
11
12 package org.huihoo.jfox.ms.jms.message;
13
14 import java.util.Collections;
15 import java.util.Enumeration;
16 import java.util.Hashtable;
17
18 import javax.jms.JMSException;
19 import javax.jms.MessageFormatException;
20
21 /***
22 * <p>
23 * Built-in facility for supporting property values.
24 * </p>
25
26 *
27 *
28 * <P>Message properties support the following conversion table. The marked
29 * cases must be supported. The unmarked cases must throw a
30 * <CODE>JMSException</CODE>. The <CODE>String</CODE>-to-primitive conversions
31 * may throw a runtime exception if the
32 * primitive's <CODE>valueOf</CODE> method does not accept the
33 * <CODE>String</CODE> as a valid representation of the primitive.
34 *
35 * <P>A value written as the row type can be read as the column type.
36 *
37 * <PRE>
38 * | | boolean byte short int long float double String
39 * |----------------------------------------------------------
40 * |boolean | X X
41 * |byte | X X X X X
42 * |short | X X X X
43 * |int | X X X
44 * |long | X X
45 * |float | X X X
46 * |double | X X
47 * |String | X X X X X X X X
48 * |----------------------------------------------------------
49 * </PRE>
50 *
51 * <P>In addition to the type-specific set/get methods for properties, JMS
52 * provides the <CODE>setObjectProperty</CODE> and
53 * <CODE>getObjectProperty</CODE> methods. These support the same set of
54 * property types using the objectified primitive values. Their purpose is
55 * to allow the decision of property type to made at execution time rather
56 * than at compile time. They support the same property value conversions.
57 *
58 * <P>The <CODE>setObjectProperty</CODE> method accepts values of class
59 * <CODE>Boolean</CODE>, <CODE>Byte</CODE>, <CODE>Short</CODE>,
60 * <CODE>Integer</CODE>, <CODE>Long</CODE>, <CODE>Float</CODE>,
61 * <CODE>Double</CODE>, and <CODE>String</CODE>. An attempt
62 * to use any other class must throw a <CODE>JMSException</CODE>.
63 *
64 * <P>The <CODE>getObjectProperty</CODE> method only returns values of class
65 * <CODE>Boolean</CODE>, <CODE>Byte</CODE>, <CODE>Short</CODE>,
66 * <CODE>Integer</CODE>, <CODE>Long</CODE>, <CODE>Float</CODE>,
67 * <CODE>Double</CODE>, and <CODE>String</CODE>.
68 *
69 * <P>The order of property values is not defined. To iterate through a
70 * message's property values, use <CODE>getPropertyNames</CODE> to retrieve
71 * a property name enumeration and then use the various property get methods
72 * to retrieve their values.
73 *
74 * <P>A message's properties are deleted by the <CODE>clearProperties</CODE>
75 * method. This leaves the message with an empty set of properties.
76 *
77 * <P>Getting a property value for a name which has not been set returns a
78 * null value. Only the <CODE>getStringProperty</CODE> and
79 * <CODE>getObjectProperty</CODE> methods can return a null value.
80 * Attempting to read a null value as a primitive type must be treated as
81 * calling the primitive's corresponding <CODE>valueOf(String)</CODE>
82 * conversion method with a null value.
83 *
84 * <P>The JMS API reserves the <CODE>JMSX</CODE> property name prefix for JMS
85 * defined properties.
86 * The full set of these properties is defined in the Java Message Service
87 * specification. New JMS defined properties may be added in later versions
88 * of the JMS API. Support for these properties is optional. The
89 * <CODE>String[] ConnectionMetaData.getJMSXPropertyNames</CODE> method
90 * returns the names of the JMSX properties supported by a connection.
91 *
92 * <P>JMSX properties may be referenced in message selectors whether or not
93 * they are supported by a connection. If they are not present in a
94 * message, they are treated like any other absent property.
95 *
96 * <P>JMSX properties defined in the specification as "set by provider on
97 * send" are available to both the producer and the consumers of the message.
98 * JMSX properties defined in the specification as "set by provider on
99 * receive" are available only to the consumers.
100 *
101 * <P><CODE>JMSXGroupID</CODE> and <CODE>JMSXGroupSeq</CODE> are standard
102 * properties that clients
103 * should use if they want to group messages. All providers must support them.
104 * Unless specifically noted, the values and semantics of the JMSX properties
105 * are undefined.
106 *
107 * <P>The JMS API reserves the <CODE>JMS_<I>vendor_name</I></CODE> property
108 * name prefix for provider-specific properties. Each provider defines its own
109 * value for <CODE><I>vendor_name</I></CODE>. This is the mechanism a JMS
110 * provider uses to make its special per-message services available to a JMS
111 * client.
112 *
113 * <P>The purpose of provider-specific properties is to provide special
114 * features needed to integrate JMS clients with provider-native clients in a
115 * single JMS application. They should not be used for messaging between JMS
116 * clients.
117 *
118 * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter.Cheng</a>
119 * @version Revision: 1.1 Date: 2002-12-01 21:57:33
120 */
121
122 public class MessageProperties {
123
124 // JMS-Standard Tags and Values
125 private static final String JMSX_USERID = "JMSXUserID";
126 private static final String JMSX_APPID = "JMSXAppID";
127 private static final String JMSX_GROUPID = "JMSXGroupID";
128 private static final String JMSX_GROUPSEQ = "JMSXGroupSeq";
129
130 private Hashtable properties = new Hashtable();
131
132
133 /***
134 * Sets a <CODE>boolean</CODE> property value with the specified name into
135 * the message.
136 *
137 * @param name the name of the <CODE>boolean</CODE> property
138 * @param value the <CODE>boolean</CODE> property value to set
139 *
140 * @exception JMSException if the JMS provider fails to set the property
141 * due to some internal error.
142 */
143 public void setBooleanProperty(String name, boolean value) throws JMSException {
144 setProperty(name, new Boolean(value));
145 }
146
147 /***
148 * Returns the value of the <CODE>boolean</CODE> property with the
149 * specified name.
150 *
151 * @param name the name of the <CODE>boolean</CODE> property
152 *
153 * @return the <CODE>boolean</CODE> property value for the specified name
154 *
155 * @exception JMSException if the JMS provider fails to get the property
156 * value due to some internal error.
157 * @exception MessageFormatException if this type conversion is invalid.
158 */
159 public boolean getBooleanProperty(String name) throws JMSException {
160 return getBoolean(properties.get(name));
161 }
162
163 /***
164 * Sets a <CODE>byte</CODE> property value with the specified name into
165 * the message.
166 *
167 * @param name the name of the <CODE>byte</CODE> property
168 * @param value the <CODE>byte</CODE> property value to set
169 *
170 * @exception JMSException if the JMS provider fails to set the property
171 * due to some internal error.
172 */
173 public void setByteProperty(String name, byte value) throws JMSException {
174 setProperty(name, new Byte(value));
175 }
176
177 /***
178 * Returns the value of the <CODE>byte</CODE> property with the specified
179 * name.
180 *
181 * @param name the name of the <CODE>byte</CODE> property
182 *
183 * @return the <CODE>byte</CODE> property value for the specified name
184 *
185 * @exception JMSException if the JMS provider fails to get the property
186 * value due to some internal error.
187 * @exception MessageFormatException if this type conversion is invalid.
188 */
189 public byte getByteProperty(String name) throws JMSException {
190 return getByte(properties.get(name));
191 }
192
193 /***
194 * Sets a <CODE>short</CODE> property value with the specified name into
195 * the message.
196 *
197 * @param name the name of the <CODE>short</CODE> property
198 * @param value the <CODE>short</CODE> property value to set
199 *
200 * @exception JMSException if the JMS provider fails to set the property
201 * due to some internal error.
202 */
203 public void setShortProperty(String name, short value) throws JMSException {
204 setProperty(name, new Short(value));
205 }
206
207 /***
208 * Returns the value of the <CODE>short</CODE> property with the specified
209 * name.
210 *
211 * @param name the name of the <CODE>short</CODE> property
212 *
213 * @return the <CODE>short</CODE> property value for the specified name
214 *
215 * @exception JMSException if the JMS provider fails to get the property
216 * value due to some internal error.
217 * @exception MessageFormatException if this type conversion is invalid.
218 */
219 public short getShortProperty(String name) throws JMSException {
220 return getShort(properties.get(name));
221 }
222
223 /***
224 * Sets an <CODE>int</CODE> property value with the specified name into
225 * the message.
226 *
227 * @param name the name of the <CODE>int</CODE> property
228 * @param value the <CODE>int</CODE> property value to set
229 *
230 * @exception JMSException if the JMS provider fails to set the property
231 * due to some internal error.
232 */
233 public void setIntProperty(String name, int value) throws JMSException {
234 setProperty(name, new Integer(value));
235 }
236
237 /***
238 * Returns the value of the <CODE>int</CODE> property with the specified
239 * name.
240 *
241 * @param name the name of the <CODE>int</CODE> property
242 *
243 * @return the <CODE>int</CODE> property value for the specified name
244 *
245 * @exception JMSException if the JMS provider fails to get the property
246 * value due to some internal error.
247 * @exception MessageFormatException if this type conversion is invalid.
248 */
249 public int getIntProperty(String name) throws JMSException {
250 return getInt(properties.get(name));
251 }
252
253 /***
254 * Sets a <CODE>long</CODE> property value with the specified name into
255 * the message.
256 *
257 * @param name the name of the <CODE>long</CODE> property
258 * @param value the <CODE>long</CODE> property value to set
259 *
260 * @exception JMSException if the JMS provider fails to set the property
261 * due to some internal error.
262 */
263 public void setLongProperty(String name, long value) throws JMSException {
264 setProperty(name, new Long(value));
265 }
266
267 /***
268 * Returns the value of the <CODE>long</CODE> property with the specified
269 * name.
270 *
271 * @param name the name of the <CODE>long</CODE> property
272 *
273 * @return the <CODE>long</CODE> property value for the specified name
274 *
275 * @exception JMSException if the JMS provider fails to get the property
276 * value due to some internal error.
277 * @exception MessageFormatException if this type conversion is invalid.
278 */
279 public long getLongProperty(String name) throws JMSException {
280 return getLong(properties.get(name));
281 }
282
283 /***
284 * Sets a <CODE>float</CODE> property value with the specified name into
285 * the message.
286 *
287 * @param name the name of the <CODE>float</CODE> property
288 * @param value the <CODE>float</CODE> property value to set
289 *
290 * @exception JMSException if the JMS provider fails to set the property
291 * due to some internal error.
292 */
293 public void setFloatProperty(String name, float value) throws JMSException {
294 setProperty(name, new Float(value));
295 }
296
297 /***
298 * Returns the value of the <CODE>float</CODE> property with the specified
299 * name.
300 *
301 * @param name the name of the <CODE>float</CODE> property
302 *
303 * @return the <CODE>float</CODE> property value for the specified name
304 *
305 * @exception JMSException if the JMS provider fails to get the property
306 * value due to some internal error.
307 * @exception MessageFormatException if this type conversion is invalid.
308 */
309 public float getFloatProperty(String name) throws JMSException {
310 return getFloat(properties.get(name));
311 }
312
313 /***
314 * Sets a <CODE>double</CODE> property value with the specified name into
315 * the message.
316 *
317 * @param name the name of the <CODE>double</CODE> property
318 * @param value the <CODE>double</CODE> property value to set
319 *
320 * @exception JMSException if the JMS provider fails to set the property
321 * due to some internal error.
322 */
323 public void setDoubleProperty(String name, double value) throws JMSException {
324 setProperty(name, new Double(value));
325 }
326
327 /***
328 * Returns the value of the <CODE>double</CODE> property with the specified
329 * name.
330 *
331 * @param name the name of the <CODE>double</CODE> property
332 *
333 * @return the <CODE>double</CODE> property value for the specified name
334 *
335 * @exception JMSException if the JMS provider fails to get the property
336 * value due to some internal error.
337 * @exception MessageFormatException if this type conversion is invalid.
338 */
339 public double getDoubleProperty(String name) throws JMSException {
340 return getDouble(properties.get(name));
341 }
342
343 /***
344 * Sets a <CODE>String</CODE> property value with the specified name into
345 * the message.
346 *
347 * @param name the name of the <CODE>String</CODE> property
348 * @param value the <CODE>String</CODE> property value to set
349 *
350 * @exception JMSException if the JMS provider fails to set the property
351 * due to some internal error.
352 */
353 public void setStringProperty(String name, String value) throws JMSException {
354 setProperty(name, new String(value));
355 }
356
357 /***
358 * Returns the value of the <CODE>String</CODE> property with the specified
359 * name.
360 *
361 * @param name the name of the <CODE>String</CODE> property
362 *
363 * @return the <CODE>String</CODE> property value for the specified name;
364 * if there is no property by this name, a null value is returned
365 *
366 * @exception JMSException if the JMS provider fails to get the property
367 * value due to some internal error.
368 * @exception MessageFormatException if this type conversion is invalid.
369 */
370 public String getStringProperty(String name) throws JMSException {
371 return getString(properties.get(name));
372 }
373
374 /***
375 * Sets a Java object property value with the specified name into the
376 * message.
377 *
378 * <P>Note that this method works only for the objectified primitive
379 * object types (<CODE>Integer</CODE>, <CODE>Double</CODE>,
380 * <CODE>Long</CODE> ...) and <CODE>String</CODE> objects.
381 *
382 * @param name the name of the Java object property
383 * @param value the Java object property value to set
384 *
385 * @exception JMSException if the JMS provider fails to set the property
386 * due to some internal error.
387 * @exception MessageFormatException if the object is invalid
388 */
389 public void setObjectProperty(String name, Object value) throws JMSException {
390 if (value instanceof Boolean) {
391 setBooleanProperty(name, ((Boolean)value).booleanValue());
392 } else if (value instanceof Byte) {
393 setByteProperty(name, ((Byte)value).byteValue());
394 } else if (value instanceof Short) {
395 setShortProperty(name, ((Short)value).shortValue());
396 } else if (value instanceof Integer) {
397 setIntProperty(name, ((Integer)value).intValue());
398 } else if (value instanceof Long) {
399 setLongProperty(name, ((Long)value).longValue());
400 } else if (value instanceof Float) {
401 setFloatProperty(name, ((Float)value).floatValue());
402 } else if (value instanceof Double) {
403 setDoubleProperty(name, ((Double)value).doubleValue());
404 } else if (value instanceof String) {
405 setStringProperty(name, (String)value);
406 } else if (value == null) {
407 setProperty(name, null);
408 } else {
409 throw new MessageFormatException(
410 "Does not support objects of " + "type=" + value.getClass().getName());
411 }
412 }
413
414 /***
415 * Returns the value of the Java object property with the specified name.
416 *
417 * <P>This method can be used to return, in objectified format,
418 * an object that has been stored as a property in the message with the
419 * equivalent <CODE>setObjectProperty</CODE> method call, or its equivalent
420 * primitive <CODE>set<I>type</I>Property</CODE> method.
421 *
422 * @param name the name of the Java object property
423 *
424 * @return the Java object property value with the specified name, in
425 * objectified format (for example, if the property was set as an
426 * <CODE>int</CODE>, an <CODE>Integer</CODE> is
427 * returned); if there is no property by this name, a null value
428 * is returned
429 *
430 * @exception JMSException if the JMS provider fails to get the property
431 * value due to some internal error.
432 */
433 public Object getObjectProperty(String name) throws JMSException {
434 Object value = properties.get(name);
435 if (value != null) {
436 if (value instanceof Boolean) {
437 return new Boolean(((Boolean)value).booleanValue());
438 } else if (value instanceof Byte) {
439 return new Byte(((Byte)value).byteValue());
440 } else if (value instanceof Short) {
441 return new Short(((Short)value).shortValue());
442 } else if (value instanceof Integer) {
443 return new Integer(((Integer)value).intValue());
444 } else if (value instanceof Long) {
445 return new Long(((Long)value).longValue());
446 } else if (value instanceof Float) {
447 return new Float(((Float)value).floatValue());
448 } else if (value instanceof Double) {
449 return new Double(((Double)value).doubleValue());
450 } else {
451 return new String((String)value);
452 }
453 } else {
454 return null;
455 }
456 }
457
458
459 /***
460 * Inner common method setProperty
461 *
462 * @param name the name of the Java object property
463 * @param value the Java object property value to set
464 *
465 * @exception JMSException if the JMS provider fails to set the property
466 * due to some internal error.
467 */
468 private void setProperty(String name, Object value) throws JMSException {
469 if (name == null) {
470 throw new JMSException("It's invalid property name");
471 } else {
472 if (name.equalsIgnoreCase("NULL") ||
473 name.equalsIgnoreCase("TRUE") ||
474 name.equalsIgnoreCase("FALSE") ||
475 name.equals("NOT") ||
476 name.equals("AND") ||
477 name.equals("OR") ||
478 name.equals("BETWEEN") ||
479 name.equals("LIKE") ||
480 name.equals("IN") ||
481 name.equals("IS") ) {
482 throw new JMSException("Invalid property name");
483 } else {
484 if (name.startsWith("JMS") && !name.startsWith("JMS_")) {
485 throw new JMSException("Properties cannot begin with JMS");
486 } else {
487 properties.put(name, value);
488 }
489 }
490 }
491 }
492
493 /***
494 * Convert value to boolean
495 *
496 * @param value
497 * @return the converted boolean
498 * @exception MessageFormatException if the conversion is invalid
499 */
500 private boolean getBoolean(Object value) throws MessageFormatException {
501 if (value instanceof Boolean) {
502 return ((Boolean)value).booleanValue();
503 } else if (value instanceof String) {
504 return Boolean.valueOf((String)value).booleanValue();
505 } else if (value == null) {
506 return Boolean.valueOf((String)value).booleanValue();
507 } else {
508 throw new MessageFormatException("Can't convert value of type "
509 + value.getClass().getName() + " to Boolean");
510 }
511 }
512
513 /***
514 * Convert value to byte
515 *
516 * @param value
517 * @return the converted byte
518 * @exception MessageFormatException if the conversion is invalid
519 */
520 private byte getByte(Object value) throws MessageFormatException {
521 if (value instanceof Byte) {
522 return ((Byte)value).byteValue();
523 } else if (value instanceof String) {
524 return Byte.parseByte((String)value);
525 } else if (value == null) {
526 return Byte.valueOf((String)value).byteValue();
527 } else {
528 throw new MessageFormatException("Can't convert value of type "
529 + value.getClass().getName() + " to Byte");
530 }
531 }
532
533 /***
534 * Convert value to short
535 *
536 * @param value
537 * @return the converted short
538 * @exception MessageFormatException if the conversion is invalid
539 */
540 private short getShort(Object value) throws MessageFormatException {
541 if (value instanceof Short) {
542 return ((Short)value).shortValue();
543 } else if (value instanceof Byte) {
544 return ((Byte)value).shortValue();
545 } else if (value instanceof String) {
546 return Short.parseShort((String)value);
547 } else if (value == null) {
548 return Short.valueOf((String)value).shortValue();
549 } else {
550 throw new MessageFormatException("Can't convert value of type "
551 + value.getClass().getName() + " to Short");
552 }
553 }
554
555 /***
556 * Convert value to int
557 *
558 * @param value
559 * @return the converted int
560 * @exception MessageFormatException if the conversion is invalid
561 * @exception NumberFormatException if value is a String and the conversion
562 * is invalid
563 */
564 private int getInt(Object value) throws MessageFormatException {
565 if (value instanceof Integer) {
566 return ((Integer)value).intValue();
567 } else if (value instanceof Byte) {
568 return ((Byte)value).intValue();
569 } else if (value instanceof Short) {
570 return ((Short) value).intValue();
571 } else if (value instanceof String) {
572 return Integer.parseInt((String)value);
573 } else if (value == null) {
574 return Integer.valueOf((String)value).intValue();
575 } else {
576 throw new MessageFormatException("Can't convert value of type "
577 + value.getClass().getName() + " to Int");
578 }
579 }
580
581
582 /***
583 * Convert value to long
584 *
585 * @param value
586 * @return the converted long
587 * @exception MessageFormatException if the conversion is invalid
588 * @exception NumberFormatException if value is a String and the conversion
589 * is invalid
590 */
591 private long getLong(Object value) throws MessageFormatException {
592 if (value instanceof Long) {
593 return ((Long)value).longValue();
594 } else if (value instanceof Byte) {
595 return ((Byte)value).longValue();
596 } else if (value instanceof Short) {
597 return ((Short)value).longValue();
598 } else if (value instanceof Integer) {
599 return ((Integer)value).longValue();
600 } else if (value instanceof String) {
601 return Long.parseLong((String)value);
602 } else if (value == null) {
603 return Long.valueOf((String)value).longValue();
604 } else {
605 throw new MessageFormatException("Can't convert value of type "
606 + value.getClass().getName() + " to Long");
607 }
608 }
609
610 /***
611 * Convert value to float
612 *
613 * @param value
614 * @return the converted float
615 * @exception MessageFormatException if the conversion is invalid
616 * @exception NumberFormatException if value is a String and the conversion
617 * is invalid
618 */
619 private float getFloat(Object value) throws MessageFormatException {
620 if (value instanceof Float) {
621 return ((Float)value).floatValue();
622 } else if (value instanceof String) {
623 return Float.parseFloat((String)value);
624 } else if (value == null) {
625 return Float.valueOf((String)value).floatValue();
626 } else {
627 throw new MessageFormatException("Can't convert value of type "
628 + value.getClass().getName() + " to Float");
629 }
630 }
631
632 /***
633 * Convert value to double
634 *
635 * @param value the object to convert from
636 * @return the converted double
637 * @exception MessageFormatException if the conversion is invalid
638 * @exception NumberFormatException if value is a String and the conversion
639 * is invalid
640 */
641 private double getDouble(Object value) throws MessageFormatException {
642 if (value instanceof Double) {
643 return ((Double) value).doubleValue();
644 } else if (value instanceof Float) {
645 return ((Float) value).doubleValue();
646 } else if (value instanceof String) {
647 return Double.parseDouble((String)value);
648 } else if (value == null) {
649 return Double.valueOf((String)value).doubleValue();
650 } else {
651 throw new MessageFormatException("Can't convert value of type "
652 + value.getClass().getName() + " to Double");
653 }
654 }
655
656 /***
657 * Convert value to String
658 *
659 * @param value the object to convert from
660 * @return the converted String
661 * @exception MessageFormatException if the conversion is invalid
662 */
663 private String getString(Object value) throws MessageFormatException {
664 return (value == null) ? null : String.valueOf(value);
665 }
666
667
668 /***
669 * Clear any values contained in the properties section of the message.
670 *
671 * @see javax.jms.Message
672 */
673 public void clearProperties() {
674 properties.clear();
675 }
676
677 /***
678 * Determine if the specified property exists.
679 *
680 * @see javax.jms.Message
681 */
682 public boolean propertyExists(String name) {
683 return properties.containsKey(name);
684 }
685
686 /***
687 * Returns an <CODE>Enumeration</CODE> of all the property names.
688 *
689 * @return an enumeration of all the names of property values
690 */
691 public Enumeration getPropertyNames() {
692 return Collections.enumeration(properties.keySet());
693 }
694 }
This page was automatically generated by Maven