001    package com.mockrunner.mock.jms;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.ByteArrayOutputStream;
005    import java.io.DataInputStream;
006    import java.io.DataOutputStream;
007    import java.io.EOFException;
008    import java.io.IOException;
009    import java.util.Arrays;
010    
011    import javax.jms.BytesMessage;
012    import javax.jms.JMSException;
013    import javax.jms.MessageEOFException;
014    import javax.jms.MessageFormatException;
015    import javax.jms.MessageNotReadableException;
016    import javax.jms.MessageNotWriteableException;
017    
018    import com.mockrunner.base.NestedApplicationException;
019    
020    /**
021     * Mock implementation of JMS <code>BytesMessage</code>.
022     */
023    public class MockBytesMessage extends MockMessage implements BytesMessage
024    {
025        private DataOutputStream outStream;
026        private ByteArrayOutputStream byteOutStream;
027        private DataInputStream inStream;
028        
029        public MockBytesMessage()
030        {
031            try
032            {
033                clearBody();
034            }
035            catch(JMSException exc)
036            {
037                throw new NestedApplicationException(exc);
038            }
039        }
040        
041        public long getBodyLength() throws JMSException
042        {
043            if(isInWriteMode())
044            {
045                throw new MessageNotReadableException("Message is in write mode");
046            }
047            return outStream.size();
048        }
049    
050        public boolean readBoolean() throws JMSException
051        {
052            if(isInWriteMode())
053            {
054                throw new MessageNotReadableException("Message is in write mode");
055            }
056            try
057            {
058                return inStream.readBoolean();
059            }
060            catch(EOFException exc)
061            {
062                throw new MessageEOFException(exc.getMessage());
063            }
064            catch(IOException exc)
065            {
066                throw new JMSException(exc.getMessage());
067            }
068        }
069    
070        public byte readByte() throws JMSException
071        {
072            if(isInWriteMode())
073            {
074                throw new MessageNotReadableException("Message is in write mode");
075            }
076            try
077            {
078                return inStream.readByte();
079            }
080            catch(EOFException exc)
081            {
082                throw new MessageEOFException(exc.getMessage());
083            }
084            catch(IOException exc)
085            {
086                throw new JMSException(exc.getMessage());
087            }
088        }
089    
090        public int readUnsignedByte() throws JMSException
091        {
092            if(isInWriteMode())
093            {
094                throw new MessageNotReadableException("Message is in write mode");
095            }
096            try
097            {
098                return inStream.readByte();
099            }
100            catch(EOFException exc)
101            {
102                throw new MessageEOFException(exc.getMessage());
103            }
104            catch(IOException exc)
105            {
106                throw new JMSException(exc.getMessage());
107            }
108        }
109    
110        public short readShort() throws JMSException
111        {
112            if(isInWriteMode())
113            {
114                throw new MessageNotReadableException("Message is in write mode");
115            }
116            try
117            {
118                return inStream.readShort();
119            }
120            catch(EOFException exc)
121            {
122                throw new MessageEOFException(exc.getMessage());
123            }
124            catch(IOException exc)
125            {
126                throw new JMSException(exc.getMessage());
127            }
128        }
129    
130        public int readUnsignedShort() throws JMSException
131        {
132            if(isInWriteMode())
133            {
134                throw new MessageNotReadableException("Message is in write mode");
135            }
136            try
137            {
138                return inStream.readShort();
139            }
140            catch(EOFException exc)
141            {
142                throw new MessageEOFException(exc.getMessage());
143            }
144            catch(IOException exc)
145            {
146                throw new JMSException(exc.getMessage());
147            }
148        }
149    
150        public char readChar() throws JMSException
151        {
152            if(isInWriteMode())
153            {
154                throw new MessageNotReadableException("Message is in write mode");
155            }
156            try
157            {
158                return inStream.readChar();
159            }
160            catch(EOFException exc)
161            {
162                throw new MessageEOFException(exc.getMessage());
163            }
164            catch(IOException exc)
165            {
166                throw new JMSException(exc.getMessage());
167            }
168        }
169    
170        public int readInt() throws JMSException
171        {
172            if(isInWriteMode())
173            {
174                throw new MessageNotReadableException("Message is in write mode");
175            }
176            try
177            {
178                return inStream.readInt();
179            }
180            catch(EOFException exc)
181            {
182                throw new MessageEOFException(exc.getMessage());
183            }
184            catch(IOException exc)
185            {
186                throw new JMSException(exc.getMessage());
187            }
188        }
189    
190        public long readLong() throws JMSException
191        {
192            if(isInWriteMode())
193            {
194                throw new MessageNotReadableException("Message is in write mode");
195            }
196            try
197            {
198                return inStream.readLong();
199            }
200            catch(EOFException exc)
201            {
202                throw new MessageEOFException(exc.getMessage());
203            }
204            catch(IOException exc)
205            {
206                throw new JMSException(exc.getMessage());
207            }
208        }
209    
210        public float readFloat() throws JMSException
211        {
212            if(isInWriteMode())
213            {
214                throw new MessageNotReadableException("Message is in write mode");
215            }
216            try
217            {
218                return inStream.readFloat();
219            }
220            catch(EOFException exc)
221            {
222                throw new MessageEOFException(exc.getMessage());
223            }
224            catch(IOException exc)
225            {
226                throw new JMSException(exc.getMessage());
227            }
228        }
229    
230        public double readDouble() throws JMSException
231        {
232            if(isInWriteMode())
233            {
234                throw new MessageNotReadableException("Message is in write mode");
235            }
236            try
237            {
238                return inStream.readDouble();
239            }
240            catch(EOFException exc)
241            {
242                throw new MessageEOFException(exc.getMessage());
243            }
244            catch(IOException exc)
245            {
246                throw new JMSException(exc.getMessage());
247            }
248        }
249    
250        public String readUTF() throws JMSException
251        {
252            if(isInWriteMode())
253            {
254                throw new MessageNotReadableException("Message is in write mode");
255            }
256            try
257            {
258                return inStream.readUTF();
259            }
260            catch(EOFException exc)
261            {
262                throw new MessageEOFException(exc.getMessage());
263            }
264            catch(IOException exc)
265            {
266                throw new JMSException(exc.getMessage());
267            }
268        }
269    
270        public int readBytes(byte[] data) throws JMSException
271        {
272            if(isInWriteMode())
273            {
274                throw new MessageNotReadableException("Message is in write mode");
275            }
276            try
277            {
278                return inStream.read(data);
279            }
280            catch(EOFException exc)
281            {
282                throw new MessageEOFException(exc.getMessage());
283            }
284            catch(IOException exc)
285            {
286                throw new JMSException(exc.getMessage());
287            }
288        }
289    
290        public int readBytes(byte[] data, int length) throws JMSException
291        {
292            if(isInWriteMode())
293            {
294                throw new MessageNotReadableException("Message is in write mode");
295            }
296            try
297            {
298                return inStream.read(data, 0, length);
299            }
300            catch(EOFException exc)
301            {
302                throw new MessageEOFException(exc.getMessage());
303            }
304            catch(IOException exc)
305            {
306                throw new JMSException(exc.getMessage());
307            }
308        }
309    
310        public void writeBoolean(boolean value) throws JMSException
311        {
312            if(!isInWriteMode())
313            {
314                throw new MessageNotWriteableException("Message is in read mode");
315            }
316            try
317            {
318                outStream.writeBoolean(value);
319            }
320            catch(IOException exc)
321            {
322                throw new JMSException(exc.getMessage());
323            }
324        }
325    
326        public void writeByte(byte value) throws JMSException
327        {
328            if(!isInWriteMode())
329            {
330                throw new MessageNotWriteableException("Message is in read mode");
331            }
332            try
333            {
334                outStream.writeByte(value);
335            }
336            catch(IOException exc)
337            {
338                throw new JMSException(exc.getMessage());
339            }
340        }
341    
342        public void writeShort(short value) throws JMSException
343        {
344            if(!isInWriteMode())
345            {
346                throw new MessageNotWriteableException("Message is in read mode");
347            }
348            try
349            {
350                outStream.writeShort(value);
351            }
352            catch(IOException exc)
353            {
354                throw new JMSException(exc.getMessage());
355            }
356        }
357    
358        public void writeChar(char value) throws JMSException
359        {
360            if(!isInWriteMode())
361            {
362                throw new MessageNotWriteableException("Message is in read mode");
363            }
364            try
365            {
366                outStream.writeChar(value);
367            }
368            catch(IOException exc)
369            {
370                throw new JMSException(exc.getMessage());
371            }
372        }
373    
374        public void writeInt(int value) throws JMSException
375        {
376            if(!isInWriteMode())
377            {
378                throw new MessageNotWriteableException("Message is in read mode");
379            }
380            try
381            {
382                outStream.writeInt(value);
383            }
384            catch(IOException exc)
385            {
386                throw new JMSException(exc.getMessage());
387            }
388        }
389    
390        public void writeLong(long value) throws JMSException
391        {
392            if(!isInWriteMode())
393            {
394                throw new MessageNotWriteableException("Message is in read mode");
395            }
396            try
397            {
398                outStream.writeLong(value);
399            }
400            catch(IOException exc)
401            {
402                throw new JMSException(exc.getMessage());
403            }
404        }
405    
406        public void writeFloat(float value) throws JMSException
407        {
408            if(!isInWriteMode())
409            {
410                throw new MessageNotWriteableException("Message is in read mode");
411            }
412            try
413            {
414                outStream.writeFloat(value);
415            }
416            catch(IOException exc)
417            {
418                throw new JMSException(exc.getMessage());
419            }
420        }
421    
422        public void writeDouble(double value) throws JMSException
423        {
424            if(!isInWriteMode())
425            {
426                throw new MessageNotWriteableException("Message is in read mode");
427            }
428            try
429            {
430                outStream.writeDouble(value);
431            }
432            catch(IOException exc)
433            {
434                throw new JMSException(exc.getMessage());
435            }
436        }
437    
438        public void writeUTF(String value) throws JMSException
439        {
440            if(!isInWriteMode())
441            {
442                throw new MessageNotWriteableException("Message is in read mode");
443            }
444            try
445            {
446                outStream.writeUTF(value);
447            }
448            catch(IOException exc)
449            {
450                throw new JMSException(exc.getMessage());
451            }
452        }
453    
454        public void writeBytes(byte[] data) throws JMSException
455        {
456            if(!isInWriteMode())
457            {
458                throw new MessageNotWriteableException("Message is in read mode");
459            }
460            try
461            {
462                outStream.write(data);
463            }
464            catch(IOException exc)
465            {
466                throw new JMSException(exc.getMessage());
467            }
468        }
469    
470        public void writeBytes(byte[] data, int offset, int length) throws JMSException
471        {
472            if(!isInWriteMode())
473            {
474                throw new MessageNotWriteableException("Message is in read mode");
475            }
476            try
477            {
478                outStream.write(data, offset, length);
479            }
480            catch(IOException exc)
481            {
482                throw new JMSException(exc.getMessage());
483            }
484        }
485    
486        public void writeObject(Object object) throws JMSException
487        {
488            if(!isInWriteMode())
489            {
490                throw new MessageNotWriteableException("Message is in read mode");
491            }
492            if(object instanceof Byte) 
493            {
494                writeByte(((Byte)object).byteValue());
495                return;
496            }
497            if(object instanceof Short) 
498            {
499                writeShort(((Short)object).shortValue());
500                return;
501            }
502            if(object instanceof Integer) 
503            {
504                writeInt(((Integer)object).intValue());
505                return;
506            }
507            if(object instanceof Long) 
508            {
509                writeLong(((Long)object).longValue());
510                return;
511            }
512            if(object instanceof Float) 
513            {
514                writeFloat(((Float)object).floatValue());
515                return;
516            }
517            if(object instanceof Double) 
518            {
519                writeDouble(((Double)object).doubleValue());
520                return;
521            }
522            if(object instanceof Character) 
523            {
524                writeChar(((Character)object).charValue());
525                return;
526            }
527            if(object instanceof Boolean) 
528            {
529                writeBoolean(((Boolean)object).booleanValue());
530                return;
531            }
532            if(object instanceof String) 
533            {
534                writeUTF((String)object);
535                return;
536            }
537            if(object instanceof byte[])
538            {
539                writeBytes((byte[])object);
540                return;
541            }
542            throw new MessageFormatException(object.getClass().getName() + " is an invalid type");
543        }
544    
545        public void reset() throws JMSException
546        {
547            setReadOnly(true);
548            try
549            {
550                outStream.flush();
551            }
552            catch(IOException exc)
553            {
554                throw new JMSException(exc.getMessage());
555            }
556            inStream = new DataInputStream(new ByteArrayInputStream(byteOutStream.toByteArray()));
557        }
558        
559        public void clearBody() throws JMSException
560        {
561            super.clearBody();
562            byteOutStream = new ByteArrayOutputStream();
563            outStream = new DataOutputStream(byteOutStream);
564        }
565        
566        /**
567         * Returns a copy of the underlying byte data regardless if the message
568         * is in read or write mode.
569         * @return the byte data
570         */
571        public byte[] getBytes()
572        {
573            try
574            {
575                outStream.flush();
576            }
577            catch(IOException exc)
578            {
579                throw new RuntimeException(exc.getMessage());
580            }
581            return byteOutStream.toByteArray();
582        }
583        
584        /**
585         * Compares the underlying byte data.
586         */
587        public boolean equals(Object otherObject)
588        {
589            if(null == otherObject) return false;
590            if(!(otherObject instanceof MockBytesMessage)) return false;
591            MockBytesMessage otherMessage = (MockBytesMessage)otherObject;
592            byte[] firstData = getBytes();
593            byte[] secondData = otherMessage.getBytes();
594            return Arrays.equals(firstData, secondData);
595        }
596    
597        public int hashCode()
598        {
599            int value = 17;
600            byte[] data = getBytes();
601            for(int ii = 0; ii < data.length; ii++)
602            {
603                value = (31 * value) + data[ii];
604            }
605            return value;
606        }
607        
608        public Object clone()
609        {
610            MockBytesMessage message = (MockBytesMessage)super.clone();
611            try
612            {
613                message.clearBody();
614                message.outStream.write(getBytes());
615                return message;
616            }
617            catch(Exception exc)
618            {
619                throw new NestedApplicationException(exc);
620            }
621        }
622    
623        public String toString()
624        {
625            StringBuffer buffer = new StringBuffer();
626            buffer.append(this.getClass().getName() + ": [");
627            byte[] data = getBytes();
628            for(int ii = 0; ii < data.length; ii++)
629            {
630                buffer.append(data[ii]);
631                if(ii < data.length - 1)
632                {
633                    buffer.append(", ");
634                }
635            }
636            buffer.append("]");
637            return buffer.toString();
638        }
639    }