1 /***
2 * Copyright 2003, 2004, 2005. CodeStreet LLC.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15 package com.codestreet.selector.jms;
16
17 import java.util.StringTokenizer;
18
19 import javax.jms.JMSException;
20 import javax.jms.MapMessage;
21 import javax.jms.Message;
22
23 import com.codestreet.selector.parser.IValueProvider;
24 import com.codestreet.selector.parser.Identifier;
25 import com.codestreet.selector.parser.NumericValue;
26
27 /***
28 * Value provider for JMS. As an extension to the JMS specification, this
29 * implementation allows values to be extracted from <tt>JMS</tt> message
30 * <tt>body</tt> using a <tt>dot</tt> notation.
31 * <p>
32 * The <tt>dot</tt> notation provides reference to message body fields. For
33 * example, <tt>.order.quantity</tt> would access the <tt>quantity</tt>
34 * field of the nested sub-message field <tt>order</tt>, if it exists. If the
35 * field does not exist, it returns <tt>null</tt>.
36 *
37 * @author Jawaid Hakim.
38 */
39 public class ValueProvider implements IValueProvider
40 {
41 /***
42 * Factory.
43 *
44 * @param msg
45 * Message to extract values from.
46 * @return Instance.
47 */
48 public static IValueProvider valueOf(final Message msg)
49 {
50 return new ValueProvider(msg);
51 }
52
53 /***
54 * Ctor.
55 *
56 * @param msg
57 * <tt>Message</tt> from which to extract values.
58 * <p>
59 * For example, <tt>order.quantity</tt> would select the
60 * <tt>quantity</tt> field of the nested sub-message field
61 * <tt>order</tt> if it exists. If the field does not exist, it
62 * returns <tt>null</tt>.
63 * @see #getValue(com.codestreet.selector.parser.Identifier, Object)
64 */
65 private ValueProvider(final Message msg)
66 {
67 msg_ = msg;
68 }
69
70 /***
71 * Get the value of the specified identifier.
72 *
73 * @param identifier
74 * Field identifier.
75 * @param correlation
76 * Application correlation data. May be <tt>null</tt>.
77 * @return Value of the specified identifier. Returns <tt>null</tt> if
78 * value of the specified identifier is not found.
79 */
80 public Object getValue(final Object identifier, final Object correlation)
81 {
82 try
83 {
84 /***
85 * Wrap numeric values in NumericValue instance
86 */
87 Object value = (getValue(msg_, (Identifier) identifier));
88 if ((value instanceof Integer))
89 return new NumericValue((Integer) value);
90
91 if ((value instanceof Float))
92 return new NumericValue((Float) value);
93
94 if ((value instanceof Double))
95 return new NumericValue((Double) value);
96
97 if ((value instanceof Long))
98 return new NumericValue((Long) value);
99
100 if ((value instanceof Short))
101 return new NumericValue((Short) value);
102
103 if ((value instanceof Byte))
104 return new NumericValue((Byte) value);
105
106 return value;
107 }
108 catch (JMSException ex)
109 {
110 throw new IllegalArgumentException(ex.toString());
111 }
112 }
113
114 private static Object getValue(final Message msg,
115 final Identifier identifier) throws JMSException
116 {
117 Message workMsg = msg;
118 if (identifier.isJMSHeader())
119 return getHeaderValue(workMsg, identifier);
120
121 String fldName = identifier.getIdentifier();
122
123 // Leading '.' is there to indicate that this identifier references a
124 // nested
125 // message field (not a property)
126 int ind = fldName.indexOf('.');
127 if (ind >= 0)
128 {
129 // Skip over leading '.' if any
130 if (ind == 0)
131 fldName = fldName.substring(1);
132
133 for (StringTokenizer strTok = new StringTokenizer(identifier
134 .getIdentifier(), ".", false); strTok.hasMoreTokens();)
135 {
136 if (!(workMsg instanceof MapMessage))
137 return null;
138
139 MapMessage mapMsg = (MapMessage) workMsg;
140
141 fldName = strTok.nextToken();
142 Object nestedMsg = mapMsg.getObject(fldName);
143 if (strTok.hasMoreTokens())
144 {
145 if (!(nestedMsg instanceof MapMessage))
146 return null;
147
148 workMsg = (Message) nestedMsg;
149 }
150 else
151 return nestedMsg;
152 }
153 }
154
155 // Must be a property
156 if (workMsg.propertyExists(fldName))
157 {
158 return workMsg.getObjectProperty(fldName);
159 }
160 return null;
161 }
162
163 private static Object getHeaderValue(final Message msg,
164 final Identifier identifier) throws JMSException
165 {
166 String prop = identifier.getIdentifier();
167 if (prop.equals("JMSMessageID"))
168 return msg.getJMSMessageID();
169 else if (prop.equals("JMSPriority"))
170 return new Integer(msg.getJMSPriority());
171 else if (prop.equals("JMSTimestamp"))
172 return new Long(msg.getJMSTimestamp());
173 else if (prop.equals("JMSCorrelationID"))
174 return msg.getJMSCorrelationID();
175 else if (prop.equals("JMSDeliveryMode"))
176 return new Integer(msg.getJMSDeliveryMode());
177 else if (prop.equals("JMSRedelivered"))
178 return new Boolean(msg.getJMSRedelivered());
179 else if (prop.equals("JMSType"))
180 return msg.getJMSType();
181 else if (prop.equals("JMSExpiration"))
182 return new Long(msg.getJMSExpiration());
183
184 throw new java.lang.IllegalStateException(
185 "Invalid JMS property referenced: " + prop);
186 }
187
188 private final Message msg_;
189 }
This page was automatically generated by Maven