001: package com.mockrunner.mock.jms;
002:
003: import java.util.Arrays;
004: import java.util.Enumeration;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.Map;
008: import java.util.Vector;
009:
010: import javax.jms.JMSException;
011: import javax.jms.MapMessage;
012: import javax.jms.MessageFormatException;
013: import javax.jms.MessageNotWriteableException;
014:
015: import com.mockrunner.util.common.ArrayUtil;
016:
017: /**
018: * Mock implementation of JMS <code>MapMessage</code>.
019: */
020: public class MockMapMessage extends MockMessage implements MapMessage {
021: private Map data;
022:
023: public MockMapMessage() {
024: data = new HashMap();
025: }
026:
027: public boolean getBoolean(String name) throws JMSException {
028: Object value = getObject(name);
029: if (null == value) {
030: return Boolean.valueOf(null).booleanValue();
031: }
032: if (value instanceof Boolean) {
033: return ((Boolean) value).booleanValue();
034: }
035: if (value instanceof String) {
036: return Boolean.valueOf((String) value).booleanValue();
037: }
038: throw new MessageFormatException(value.getClass().getName()
039: + " cannot be converted to boolean");
040: }
041:
042: public byte getByte(String name) throws JMSException {
043: Object value = getObject(name);
044: if (null == value) {
045: return Byte.valueOf(null).byteValue();
046: }
047: if (value instanceof Byte) {
048: return ((Byte) value).byteValue();
049: }
050: if (value instanceof String) {
051: return Byte.valueOf((String) value).byteValue();
052: }
053: throw new MessageFormatException(value.getClass().getName()
054: + " cannot be converted to byte");
055: }
056:
057: public short getShort(String name) throws JMSException {
058: Object value = getObject(name);
059: if (null == value) {
060: return Short.valueOf(null).shortValue();
061: }
062: if ((value instanceof Byte) || (value instanceof Short)) {
063: return ((Number) value).shortValue();
064: }
065: if (value instanceof String) {
066: return Short.valueOf((String) value).shortValue();
067: }
068: throw new MessageFormatException(value.getClass().getName()
069: + " cannot be converted to short");
070: }
071:
072: public char getChar(String name) throws JMSException {
073: Object value = getObject(name);
074: if (null == value) {
075: throw new NullPointerException();
076: }
077: if (!(value instanceof Character)) {
078: throw new MessageFormatException(value.getClass().getName()
079: + " cannot be converted to char");
080: }
081: return ((Character) value).charValue();
082: }
083:
084: public int getInt(String name) throws JMSException {
085: Object value = getObject(name);
086: if (null == value) {
087: return Integer.valueOf(null).intValue();
088: }
089: if ((value instanceof Byte) || (value instanceof Short)
090: || (value instanceof Integer)) {
091: return ((Number) value).intValue();
092: }
093: if (value instanceof String) {
094: return Integer.valueOf((String) value).intValue();
095: }
096: throw new MessageFormatException(value.getClass().getName()
097: + " cannot be converted to int");
098: }
099:
100: public long getLong(String name) throws JMSException {
101: Object value = getObject(name);
102: if (null == value) {
103: return Long.valueOf(null).longValue();
104: }
105: if ((value instanceof Byte) || (value instanceof Short)
106: || (value instanceof Integer)
107: || (value instanceof Long)) {
108: return ((Number) value).longValue();
109: }
110: if (value instanceof String) {
111: return Long.valueOf((String) value).longValue();
112: }
113: throw new MessageFormatException(value.getClass().getName()
114: + " cannot be converted to long");
115: }
116:
117: public float getFloat(String name) throws JMSException {
118: Object value = getObject(name);
119: if (null == value) {
120: return Float.valueOf(null).floatValue();
121: }
122: if (value instanceof Float) {
123: return ((Float) value).floatValue();
124: }
125: if (value instanceof String) {
126: return Float.valueOf((String) value).floatValue();
127: }
128: throw new MessageFormatException(value.getClass().getName()
129: + " cannot be converted to float");
130: }
131:
132: public double getDouble(String name) throws JMSException {
133: Object value = getObject(name);
134: if (null == value) {
135: return Double.valueOf(null).doubleValue();
136: }
137: if ((value instanceof Double) || (value instanceof Float)) {
138: return ((Number) value).doubleValue();
139: }
140: if (value instanceof String) {
141: return Double.valueOf((String) value).doubleValue();
142: }
143: throw new MessageFormatException(value.getClass().getName()
144: + " cannot be converted to double");
145: }
146:
147: public String getString(String name) throws JMSException {
148: Object value = getObject(name);
149: if (null == value) {
150: return null;
151: }
152: if (value instanceof byte[]) {
153: throw new MessageFormatException(value.getClass().getName()
154: + " cannot be converted to String");
155: }
156: return value.toString();
157: }
158:
159: public byte[] getBytes(String name) throws JMSException {
160: Object value = getObject(name);
161: if (null == value) {
162: throw new NullPointerException();
163: }
164: if (!(value instanceof byte[])) {
165: throw new MessageFormatException(value.getClass().getName()
166: + " cannot be converted to byte[]");
167: }
168: return (byte[]) value;
169: }
170:
171: public Object getObject(String name) throws JMSException {
172: return data.get(name);
173: }
174:
175: public Enumeration getMapNames() throws JMSException {
176: return new Vector(data.keySet()).elements();
177: }
178:
179: public void setBoolean(String name, boolean value)
180: throws JMSException {
181: setObject(name, new Boolean(value));
182: }
183:
184: public void setByte(String name, byte value) throws JMSException {
185: setObject(name, new Byte(value));
186: }
187:
188: public void setShort(String name, short value) throws JMSException {
189: setObject(name, new Short(value));
190: }
191:
192: public void setChar(String name, char value) throws JMSException {
193: setObject(name, new Character(value));
194: }
195:
196: public void setInt(String name, int value) throws JMSException {
197: setObject(name, new Integer(value));
198: }
199:
200: public void setLong(String name, long value) throws JMSException {
201: setObject(name, new Long(value));
202: }
203:
204: public void setFloat(String name, float value) throws JMSException {
205: setObject(name, new Float(value));
206: }
207:
208: public void setDouble(String name, double value)
209: throws JMSException {
210: setObject(name, new Double(value));
211: }
212:
213: public void setString(String name, String value)
214: throws JMSException {
215: setObject(name, value);
216: }
217:
218: public void setBytes(String name, byte[] byteData)
219: throws JMSException {
220: byte[] copy = (byte[]) byteData.clone();
221: setObject(name, copy);
222: }
223:
224: public void setBytes(String name, byte[] byteData, int offset,
225: int length) throws JMSException {
226: if (null == byteData) {
227: setObject(name, null);
228: return;
229: }
230: setBytes(name, (byte[]) ArrayUtil.truncateArray(byteData,
231: offset, length));
232: }
233:
234: public void setObject(String name, Object object)
235: throws JMSException {
236: if (!isInWriteMode()) {
237: throw new MessageNotWriteableException(
238: "Message is in read mode");
239: }
240: if (null == name || name.length() <= 0) {
241: throw new IllegalArgumentException(
242: "Property names must not be null or empty strings");
243: }
244: if (null == object)
245: return;
246: if ((object instanceof Number) || (object instanceof Boolean)
247: || (object instanceof Character)
248: || (object instanceof String)
249: || (object instanceof byte[])) {
250: data.put(name, object);
251: return;
252: }
253: throw new MessageFormatException(object.getClass().getName()
254: + " not a valid type");
255: }
256:
257: public boolean itemExists(String name) throws JMSException {
258: return data.containsKey(name);
259: }
260:
261: public void clearBody() throws JMSException {
262: super .clearBody();
263: data.clear();
264: }
265:
266: /**
267: * Returns a copy of the underlying data as a <code>Map</code>
268: * regardless if the message is in read or write mode. Primitives
269: * are wrapped into their corresponding type.
270: * @return the <code>Map</code> data
271: */
272: public Map getMap() {
273: Map map = new HashMap();
274: copyDataToMap(map);
275: return map;
276: }
277:
278: /**
279: * Compares the underlying map data.
280: */
281: public boolean equals(Object otherObject) {
282: if (null == otherObject)
283: return false;
284: if (!(otherObject instanceof MockMapMessage))
285: return false;
286: MockMapMessage otherMessage = (MockMapMessage) otherObject;
287: if (data.size() != otherMessage.data.size())
288: return false;
289: Iterator keys = data.keySet().iterator();
290: while (keys.hasNext()) {
291: Object nextKey = keys.next();
292: Object nextValue = data.get(nextKey);
293: Object otherValue = otherMessage.data.get(nextKey);
294: if (null == nextValue) {
295: if (null != otherValue)
296: return false;
297: } else if (nextValue instanceof byte[]) {
298: if (null == otherValue)
299: return false;
300: if (!(otherValue instanceof byte[]))
301: return false;
302: if (!Arrays.equals((byte[]) nextValue,
303: (byte[]) otherValue))
304: return false;
305: } else {
306: if (!nextValue.equals(otherValue))
307: return false;
308: }
309: }
310: return true;
311: }
312:
313: public int hashCode() {
314: int value = 17;
315: Iterator values = data.values().iterator();
316: while (values.hasNext()) {
317: Object nextValue = values.next();
318: if (nextValue instanceof byte[]) {
319: for (int ii = 0; ii < ((byte[]) nextValue).length; ii++) {
320: value = (31 * value) + ((byte[]) nextValue)[ii];
321: }
322: } else if (nextValue != null) {
323: value = (31 * value) + nextValue.hashCode();
324: }
325: }
326: return value;
327: }
328:
329: public Object clone() {
330: MockMapMessage message = (MockMapMessage) super .clone();
331: message.data = new HashMap(data.size());
332: copyDataToMap(message.data);
333: return message;
334: }
335:
336: private void copyDataToMap(Map target) {
337: Iterator keys = data.keySet().iterator();
338: while (keys.hasNext()) {
339: Object nextKey = keys.next();
340: Object nextValue = data.get(nextKey);
341: if (nextValue instanceof byte[]) {
342: target.put(nextKey, ((byte[]) nextValue).clone());
343: } else {
344: target.put(nextKey, nextValue);
345: }
346: }
347: }
348:
349: public String toString() {
350: return this .getClass().getName() + ": " + data.toString();
351: }
352: }
|