001    package com.mockrunner.mock.jms;
002    
003    import java.io.UnsupportedEncodingException;
004    import java.util.Enumeration;
005    import java.util.HashMap;
006    import java.util.Map;
007    import java.util.Vector;
008    
009    import javax.jms.DeliveryMode;
010    import javax.jms.Destination;
011    import javax.jms.JMSException;
012    import javax.jms.Message;
013    import javax.jms.MessageFormatException;
014    import javax.jms.MessageNotWriteableException;
015    
016    import com.mockrunner.base.NestedApplicationException;
017    
018    /**
019     * Mock implementation of JMS <code>Message</code>.
020     */
021    public class MockMessage implements Message, Cloneable
022    {
023        private String messageId;
024        private long timestamp;
025        private String correlationId;
026        private Destination replyTo;
027        private Destination destination;
028        private int deliveryMode;
029        private boolean redelivered;
030        private String type;
031        private long expiration;
032        private int priority;
033        private boolean acknowledged;
034        private Map properties;
035        private boolean isInWriteMode;
036        private boolean isInWriteModeProperties;
037        
038        public MockMessage()
039        {
040            messageId = "ID:" + String.valueOf(Math.random());
041            timestamp = System.currentTimeMillis();
042            deliveryMode = DeliveryMode.PERSISTENT;
043            redelivered = false;
044            expiration = 0;
045            priority = 4;
046            acknowledged = false;
047            properties = new HashMap();
048            isInWriteMode = true;
049            isInWriteModeProperties = true;
050        }
051        
052        public boolean isAcknowledged()
053        {
054            return acknowledged;
055        }
056        
057        public String getJMSMessageID() throws JMSException
058        {
059            return messageId;
060        }
061    
062        public void setJMSMessageID(String messageId) throws JMSException
063        {
064            this.messageId = messageId;
065        }
066    
067        public long getJMSTimestamp() throws JMSException
068        {
069            return timestamp;
070        }
071    
072        public void setJMSTimestamp(long timestamp) throws JMSException
073        {
074            this.timestamp = timestamp;
075        }
076    
077        public byte[] getJMSCorrelationIDAsBytes() throws JMSException
078        {
079            if(null == correlationId) return null;
080            try
081            {
082                return correlationId.getBytes("ISO-8859-1");
083            }
084            catch(UnsupportedEncodingException exc)
085            {
086                throw new JMSException(exc.getMessage());
087            }
088        }
089    
090        public void setJMSCorrelationIDAsBytes(byte[] correlationId) throws JMSException
091        {
092            try
093            {
094                if(null == correlationId)
095                {
096                    this.correlationId = null;
097                }
098                else
099                {
100                    this.correlationId = new String(correlationId, "ISO-8859-1");
101                }
102            }
103            catch(UnsupportedEncodingException exc)
104            {
105                throw new JMSException(exc.getMessage());
106            }
107        }
108    
109        public void setJMSCorrelationID(String correlationId) throws JMSException
110        {
111            this.correlationId = correlationId;
112        }
113    
114        public String getJMSCorrelationID() throws JMSException
115        {
116            return correlationId;
117        }
118    
119        public Destination getJMSReplyTo() throws JMSException
120        {
121            return replyTo;
122        }
123    
124        public void setJMSReplyTo(Destination replyTo) throws JMSException
125        {
126            this.replyTo = replyTo;
127        }
128    
129        public Destination getJMSDestination() throws JMSException
130        {
131            return destination;
132        }
133    
134        public void setJMSDestination(Destination destination) throws JMSException
135        {
136            this.destination = destination;
137        }
138    
139        public int getJMSDeliveryMode() throws JMSException
140        {
141            return deliveryMode;
142        }
143    
144        public void setJMSDeliveryMode(int deliveryMode) throws JMSException
145        {
146            this.deliveryMode = deliveryMode;
147        }
148    
149        public boolean getJMSRedelivered() throws JMSException
150        {
151            return redelivered;
152        }
153    
154        public void setJMSRedelivered(boolean redelivered) throws JMSException
155        {
156            this.redelivered = redelivered;
157        }
158    
159        public String getJMSType() throws JMSException
160        {
161            return type;
162        }
163    
164        public void setJMSType(String type) throws JMSException
165        {
166            this.type = type;
167        }
168    
169        public long getJMSExpiration() throws JMSException
170        {
171            return expiration;
172        }
173    
174        public void setJMSExpiration(long expiration) throws JMSException
175        {
176            this.expiration = expiration;
177        }
178    
179        public int getJMSPriority() throws JMSException
180        {
181            return priority;
182        }
183    
184        public void setJMSPriority(int priority) throws JMSException
185        {
186            this.priority = priority;
187        }
188    
189        public void clearProperties() throws JMSException
190        {
191            isInWriteModeProperties = true;
192            properties.clear();
193        }
194    
195        public boolean propertyExists(String name) throws JMSException
196        {
197            return properties.containsKey(name);
198        }
199    
200        public boolean getBooleanProperty(String name) throws JMSException
201        {
202            Object value = getObjectProperty(name);
203            if(value == null)
204            {
205                return Boolean.valueOf(null).booleanValue();
206            }
207            if(value instanceof String)
208            {
209                return Boolean.valueOf((String)value).booleanValue();
210            }
211            if(value instanceof Boolean)
212            {
213                return ((Boolean)value).booleanValue();
214            }
215            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to boolean");
216        }
217    
218        public byte getByteProperty(String name) throws JMSException
219        {
220            Object value = getObjectProperty(name);
221            if(value == null)
222            {
223                return Byte.valueOf(null).byteValue();
224            }
225            if(value instanceof String)
226            {
227                return Byte.valueOf((String)value).byteValue();
228            }
229            if(value instanceof Byte)
230            {
231                return ((Number)value).byteValue();
232            }
233            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to byte");
234        }
235    
236        public short getShortProperty(String name) throws JMSException
237        {
238            Object value = getObjectProperty(name);
239            if(value == null)
240            {
241                return Short.valueOf(null).shortValue();
242            }
243            if(value instanceof String)
244            {
245                return Short.valueOf((String)value).shortValue();
246            }
247            if((value instanceof Short) || (value instanceof Byte))
248            {
249                return ((Number)value).shortValue();
250            }
251            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to short");
252        }
253    
254        public int getIntProperty(String name) throws JMSException
255        {
256            Object value = getObjectProperty(name);
257            if(value == null)
258            {
259                return Integer.valueOf(null).intValue();
260            }
261            if(value instanceof String)
262            {
263                return Integer.valueOf((String)value).intValue();
264            }
265            if((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte))
266            {
267                return ((Number)value).intValue();
268            }
269            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to int");
270        }
271    
272        public long getLongProperty(String name) throws JMSException
273        {
274            Object value = getObjectProperty(name);
275            if(value == null)
276            {
277                return Long.valueOf(null).longValue();
278            }
279            if(value instanceof String)
280            {
281                return Long.valueOf((String)value).longValue();
282            }
283            if((value instanceof Long) || (value instanceof Integer) || (value instanceof Short) || (value instanceof Byte))
284            {
285                return ((Number)value).longValue();
286            }
287            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to long");
288        }
289    
290        public float getFloatProperty(String name) throws JMSException
291        {
292            Object value = getObjectProperty(name);
293            if(value == null)
294            {
295                return Float.valueOf(null).floatValue();
296            }
297            if(value instanceof String)
298            {
299                return Float.valueOf((String)value).floatValue();
300            }
301            if(value instanceof Float)
302            {
303                return ((Number)value).floatValue();
304            }
305            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to float");
306        }
307    
308        public double getDoubleProperty(String name) throws JMSException
309        {
310            Object value = getObjectProperty(name);
311            if(value == null)
312            {
313                return Double.valueOf(null).doubleValue();
314            }
315            if(value instanceof String)
316            {
317               return Double.valueOf((String)value).doubleValue();
318            }
319            if((value instanceof Double) || (value instanceof Float))
320            {
321                return ((Number)value).doubleValue();
322            }
323            throw new MessageFormatException("Cannot convert property " + name + " of type " + value.getClass().getName() + " to double");
324        }
325    
326        public String getStringProperty(String name) throws JMSException
327        {
328            Object value = getObjectProperty(name);
329            if(null == value) return null;
330            return value.toString();
331        }
332    
333        public Object getObjectProperty(String name) throws JMSException
334        {
335            return properties.get(name);
336        }
337    
338        public Enumeration getPropertyNames() throws JMSException
339        {
340            return new Vector(properties.keySet()).elements();
341        }
342    
343        public void setBooleanProperty(String name, boolean value) throws JMSException
344        {
345            setObjectProperty(name, new Boolean(value));
346        }
347    
348        public void setByteProperty(String name, byte value) throws JMSException
349        {
350            setObjectProperty(name, new Byte(value));
351        }
352    
353        public void setShortProperty(String name, short value) throws JMSException
354        {
355            setObjectProperty(name, new Short(value));
356        }
357    
358        public void setIntProperty(String name, int value) throws JMSException
359        {
360            setObjectProperty(name, new Integer(value));
361        }
362    
363        public void setLongProperty(String name, long value) throws JMSException
364        {
365            setObjectProperty(name, new Long(value));
366        }
367    
368        public void setFloatProperty(String name, float value) throws JMSException
369        {
370            setObjectProperty(name, new Float(value));
371        }
372    
373        public void setDoubleProperty(String name, double value) throws JMSException
374        {
375            setObjectProperty(name, new Double(value));
376        }
377    
378        public void setStringProperty(String name, String value) throws JMSException
379        {
380            setObjectProperty(name, value);
381        }
382    
383        public void setObjectProperty(String name, Object object) throws JMSException
384        {
385            if(!isInWriteModeProperties)
386            {
387                throw new MessageNotWriteableException("Message is in read mode");
388            }
389            if(null == name || name.length() <= 0)
390            {
391                throw new IllegalArgumentException("Property names must not be null or empty strings");
392            }
393            if(null == object) return;
394            if((object instanceof String) || (object instanceof Number) || (object instanceof Boolean))
395            {
396                properties.put(name, object);
397                return;
398            }
399            throw new MessageFormatException(object.getClass().getName() + " not a valid type");
400        }
401    
402        public void acknowledge() throws JMSException
403        {
404            acknowledged = true;
405        }
406    
407        public void clearBody() throws JMSException
408        {
409            isInWriteMode = true;
410        }
411        
412        public void setReadOnly(boolean isReadOnly)
413        {
414            isInWriteMode = !isReadOnly;
415        }
416        
417        public void setReadOnlyProperties(boolean isReadOnly)
418        {
419            isInWriteModeProperties = !isReadOnly;
420        }
421        
422        public Object clone()
423        {
424            try
425            {
426                MockMessage clone = (MockMessage)super.clone();
427                clone.properties = new HashMap(properties);
428                return clone;
429            }
430            catch(CloneNotSupportedException exc)
431            {
432                throw new NestedApplicationException(exc);
433            }
434        }
435        
436        protected boolean isInWriteMode()
437        {
438            return isInWriteMode;
439        }
440    }