KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mq > SpyBytesMessage


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mq;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.DataInputStream JavaDoc;
27 import java.io.DataOutputStream JavaDoc;
28 import java.io.EOFException JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.Externalizable JavaDoc;
31 import java.io.ObjectInput JavaDoc;
32 import java.io.ObjectOutput JavaDoc;
33 import java.security.PrivilegedAction JavaDoc;
34 import java.security.AccessController JavaDoc;
35 import java.util.ArrayList JavaDoc;
36
37 import javax.jms.BytesMessage JavaDoc;
38 import javax.jms.JMSException JavaDoc;
39 import javax.jms.MessageEOFException JavaDoc;
40 import javax.jms.MessageFormatException JavaDoc;
41 import javax.jms.MessageNotReadableException JavaDoc;
42 import javax.jms.MessageNotWriteableException JavaDoc;
43
44 /**
45  * This class implements javax.jms.BytesMessage
46  *
47  * @author Norbert Lataille (Norbert.Lataille@m4x.org)
48  * @author <a HREF="mailto:adrian@jboss.org">Adrian Brock</a>
49  * @version $Revision: 41445 $
50  */

51 public class SpyBytesMessage extends SpyMessage
52    implements Cloneable JavaDoc, BytesMessage JavaDoc, Externalizable JavaDoc
53 {
54    /** The org.jboss.mq.useWriteUTF boolean system property defines whether the
55     * writeObject(String) call encodes the string using the pre-4.0.3 format
56     * of a series of writeChar calls(=false), or as a writeUTF call(=true).
57     * This defaults to true.
58     */

59    private final static String JavaDoc USE_WRITE_UTF = "org.jboss.mq.useWriteUTF";
60
61    private static boolean useWriteUTF = true;
62
63    /**
64     * The org.jboss.mq.chunkUTF boolean system property defines whether
65     * UTF strings greater than 64K are chunked.
66     * The default is true.
67     */

68    private final static String JavaDoc CHUNK_UTF = "org.jboss.mq.chunkUTF";
69
70    private static boolean chunkUTF = true;
71
72    /** The chunkSize */
73    private final static int chunkSize = 16384;
74
75    /** The serialVersionUID */
76    private final static long serialVersionUID = -6572727147964701014L;
77
78    static
79    {
80       PrivilegedAction JavaDoc action = new PrivilegedAction JavaDoc()
81       {
82          public Object JavaDoc run()
83          {
84             return System.getProperty(USE_WRITE_UTF, "true");
85          }
86       };
87       try
88       {
89          String JavaDoc flag = (String JavaDoc) AccessController.doPrivileged(action);
90          useWriteUTF = Boolean.valueOf(flag).booleanValue();
91       }
92       catch(Throwable JavaDoc ignore)
93       {
94       }
95       action = new PrivilegedAction JavaDoc()
96       {
97          public Object JavaDoc run()
98          {
99             return System.getProperty(CHUNK_UTF, "true");
100          }
101       };
102       try
103       {
104          String JavaDoc flag = (String JavaDoc) AccessController.doPrivileged(action);
105          chunkUTF = Boolean.valueOf(flag).booleanValue();
106       }
107       catch(Throwable JavaDoc ignore)
108       {
109       }
110    }
111
112    /** The internal representation */
113    byte[] InternalArray = null;
114    
115    private transient ByteArrayOutputStream JavaDoc ostream = null;
116    private transient DataOutputStream JavaDoc p = null;
117    private transient ByteArrayInputStream JavaDoc istream = null;
118    private transient DataInputStream JavaDoc m = null;
119
120    /**
121     * Create a new SpyBytesMessage
122     */

123    public SpyBytesMessage()
124    {
125       header.msgReadOnly = false;
126       ostream = new ByteArrayOutputStream JavaDoc();
127       p = new DataOutputStream JavaDoc(ostream);
128    }
129    
130    public boolean readBoolean() throws JMSException JavaDoc
131    {
132       checkRead();
133       try
134       {
135          return m.readBoolean();
136       }
137       catch (EOFException JavaDoc e)
138       {
139          throw new MessageEOFException JavaDoc("");
140       }
141       catch (IOException JavaDoc e)
142       {
143          throw new JMSException JavaDoc("IOException");
144       }
145    }
146
147    public byte readByte() throws JMSException JavaDoc
148    {
149       checkRead();
150       try
151       {
152          return m.readByte();
153       }
154       catch (EOFException JavaDoc e)
155       {
156          throw new MessageEOFException JavaDoc("");
157       }
158       catch (IOException JavaDoc e)
159       {
160          throw new JMSException JavaDoc("IOException");
161       }
162    }
163
164    public int readUnsignedByte() throws JMSException JavaDoc
165    {
166       checkRead();
167       try
168       {
169          return m.readUnsignedByte();
170       }
171       catch (EOFException JavaDoc e)
172       {
173          throw new MessageEOFException JavaDoc("");
174       }
175       catch (IOException JavaDoc e)
176       {
177          throw new JMSException JavaDoc("IOException");
178       }
179    }
180
181    public short readShort() throws JMSException JavaDoc
182    {
183       checkRead();
184       try
185       {
186          return m.readShort();
187       }
188       catch (EOFException JavaDoc e)
189       {
190          throw new MessageEOFException JavaDoc("");
191       }
192       catch (IOException JavaDoc e)
193       {
194          throw new JMSException JavaDoc("IOException");
195       }
196    }
197
198    public int readUnsignedShort() throws JMSException JavaDoc
199    {
200       checkRead();
201       try
202       {
203          return m.readUnsignedShort();
204       }
205       catch (EOFException JavaDoc e)
206       {
207          throw new MessageEOFException JavaDoc("");
208       }
209       catch (IOException JavaDoc e)
210       {
211          throw new JMSException JavaDoc("IOException");
212       }
213    }
214
215    public char readChar() throws JMSException JavaDoc
216    {
217       checkRead();
218       try
219       {
220          return m.readChar();
221       }
222       catch (EOFException JavaDoc e)
223       {
224          throw new MessageEOFException JavaDoc("");
225       }
226       catch (IOException JavaDoc e)
227       {
228          throw new JMSException JavaDoc("IOException");
229       }
230    }
231
232    public int readInt() throws JMSException JavaDoc
233    {
234       checkRead();
235       try
236       {
237          return m.readInt();
238       }
239       catch (EOFException JavaDoc e)
240       {
241          throw new MessageEOFException JavaDoc("");
242       }
243       catch (IOException JavaDoc e)
244       {
245          throw new JMSException JavaDoc("IOException");
246       }
247    }
248
249    public long readLong() throws JMSException JavaDoc
250    {
251       checkRead();
252       try
253       {
254          return m.readLong();
255       }
256       catch (EOFException JavaDoc e)
257       {
258          throw new MessageEOFException JavaDoc("");
259       }
260       catch (IOException JavaDoc e)
261       {
262          throw new JMSException JavaDoc("IOException");
263       }
264    }
265
266    public float readFloat() throws JMSException JavaDoc
267    {
268       checkRead();
269       try
270       {
271          return m.readFloat();
272       }
273       catch (EOFException JavaDoc e)
274       {
275          throw new MessageEOFException JavaDoc("");
276       }
277       catch (IOException JavaDoc e)
278       {
279          throw new JMSException JavaDoc("IOException");
280       }
281    }
282
283    public double readDouble() throws JMSException JavaDoc
284    {
285       checkRead();
286       try
287       {
288          return m.readDouble();
289       }
290       catch (EOFException JavaDoc e)
291       {
292          throw new MessageEOFException JavaDoc("");
293       }
294       catch (IOException JavaDoc e)
295       {
296          throw new JMSException JavaDoc("IOException");
297       }
298    }
299
300    public String JavaDoc readUTF() throws JMSException JavaDoc
301    {
302       checkRead();
303       try
304       {
305          if (chunkUTF == false)
306             return m.readUTF();
307          
308          byte type = m.readByte();
309          if (type == NULL)
310             return null;
311
312          // apply workaround for string > 64K bug in jdk's 1.3.*
313

314          // Read the no. of chunks this message is split into, allocate
315
// a StringBuffer that can hold all chunks, read the chunks
316
// into the buffer and set 'content' accordingly
317
int chunksToRead = m.readInt();
318          int bufferSize = chunkSize * chunksToRead;
319
320          // special handling for single chunk
321
if (chunksToRead == 1)
322          {
323             // The text size is likely to be much smaller than the chunkSize
324
// so set bufferSize to the min of the input stream available
325
// and the maximum buffer size. Since the input stream
326
// available() can be <= 0 we check for that and default to
327
// a small msg size of 256 bytes.
328

329             int inSize = m.available();
330             if (inSize <= 0)
331             {
332                inSize = 256;
333             }
334
335             bufferSize = Math.min(inSize, bufferSize);
336          }
337
338          // read off all of the chunks
339
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(bufferSize);
340
341          for (int i = 0; i < chunksToRead; i++)
342          {
343             sb.append(m.readUTF());
344          }
345
346          return sb.toString();
347       }
348       catch (EOFException JavaDoc e)
349       {
350          throw new MessageEOFException JavaDoc("");
351       }
352       catch (IOException JavaDoc e)
353       {
354          throw new JMSException JavaDoc("IOException");
355       }
356    }
357
358    public int readBytes(byte[] value) throws JMSException JavaDoc
359    {
360       checkRead();
361       try
362       {
363          return m.read(value);
364       }
365       catch (IOException JavaDoc e)
366       {
367          throw new JMSException JavaDoc("IOException");
368       }
369    }
370
371    public int readBytes(byte[] value, int length) throws JMSException JavaDoc
372    {
373       checkRead();
374       try
375       {
376          return m.read(value, 0, length);
377       }
378       catch (IOException JavaDoc e)
379       {
380          throw new JMSException JavaDoc("IOException");
381       }
382    }
383
384    public void writeBoolean(boolean value) throws JMSException JavaDoc
385    {
386       if (header.msgReadOnly)
387       {
388          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
389       }
390       try
391       {
392          p.writeBoolean(value);
393       }
394       catch (IOException JavaDoc e)
395       {
396          throw new JMSException JavaDoc("IOException");
397       }
398    }
399
400    public void writeByte(byte value) throws JMSException JavaDoc
401    {
402       if (header.msgReadOnly)
403       {
404          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
405       }
406       try
407       {
408          p.writeByte(value);
409       }
410       catch (IOException JavaDoc e)
411       {
412          throw new JMSException JavaDoc("IOException");
413       }
414    }
415
416    public void writeShort(short value) throws JMSException JavaDoc
417    {
418       if (header.msgReadOnly)
419       {
420          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
421       }
422       try
423       {
424          p.writeShort(value);
425       }
426       catch (IOException JavaDoc e)
427       {
428          throw new JMSException JavaDoc("IOException");
429       }
430    }
431
432    public void writeChar(char value) throws JMSException JavaDoc
433    {
434       if (header.msgReadOnly)
435       {
436          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
437       }
438       try
439       {
440          p.writeChar(value);
441       }
442       catch (IOException JavaDoc e)
443       {
444          throw new JMSException JavaDoc("IOException");
445       }
446    }
447
448    public void writeInt(int value) throws JMSException JavaDoc
449    {
450       if (header.msgReadOnly)
451       {
452          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
453       }
454       try
455       {
456          p.writeInt(value);
457       }
458       catch (IOException JavaDoc e)
459       {
460          throw new JMSException JavaDoc("IOException");
461       }
462    }
463
464    public void writeLong(long value) throws JMSException JavaDoc
465    {
466       if (header.msgReadOnly)
467       {
468          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
469       }
470       try
471       {
472          p.writeLong(value);
473       }
474       catch (IOException JavaDoc e)
475       {
476          throw new JMSException JavaDoc("IOException");
477       }
478    }
479
480    public void writeFloat(float value) throws JMSException JavaDoc
481    {
482       if (header.msgReadOnly)
483       {
484          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
485       }
486       try
487       {
488          p.writeFloat(value);
489       }
490       catch (IOException JavaDoc e)
491       {
492          throw new JMSException JavaDoc("IOException");
493       }
494    }
495
496    public void writeDouble(double value) throws JMSException JavaDoc
497    {
498       if (header.msgReadOnly)
499       {
500          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
501       }
502       try
503       {
504          p.writeDouble(value);
505       }
506       catch (IOException JavaDoc e)
507       {
508          throw new JMSException JavaDoc("IOException");
509       }
510    }
511
512    public void writeUTF(String JavaDoc value) throws JMSException JavaDoc
513    {
514       if (header.msgReadOnly)
515       {
516          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
517       }
518       try
519       {
520          if (chunkUTF == false)
521             p.writeUTF(value);
522          else
523          {
524             if (value == null)
525                p.writeByte(NULL);
526             else
527             {
528                // apply workaround for string > 64K bug in jdk's 1.3.*
529

530                // Split content into chunks of size 'chunkSize' and assemble
531
// the pieces into a List ...
532

533                // FIXME: could calculate the number of chunks first, then
534
// write as we chunk for efficiency
535

536                ArrayList JavaDoc v = new ArrayList JavaDoc();
537                int contentLength = value.length();
538
539                while (contentLength > 0)
540                  {
541                   int beginCopy = (v.size()) * chunkSize;
542                   int endCopy = contentLength <= chunkSize ? beginCopy + contentLength : beginCopy + chunkSize;
543
544                   String JavaDoc theChunk = value.substring(beginCopy, endCopy);
545                   v.add(theChunk);
546
547                   contentLength -= chunkSize;
548                }
549
550                // Write out the type (OBJECT), the no. of chunks and finally
551
// all chunks that have been assembled previously
552
p.writeByte(OBJECT);
553                p.writeInt(v.size());
554
555                for (int i = 0; i < v.size(); i++)
556                {
557                   p.writeUTF((String JavaDoc) v.get(i));
558                }
559             }
560          }
561       }
562       catch (IOException JavaDoc e)
563       {
564          throw new JMSException JavaDoc("IOException");
565       }
566    }
567
568    public void writeBytes(byte[] value) throws JMSException JavaDoc
569    {
570       if (header.msgReadOnly)
571       {
572          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
573       }
574       try
575       {
576          p.write(value, 0, value.length);
577       }
578       catch (IOException JavaDoc e)
579       {
580          throw new JMSException JavaDoc("IOException");
581       }
582    }
583
584    public void writeBytes(byte[] value, int offset, int length) throws JMSException JavaDoc
585    {
586       if (header.msgReadOnly)
587       {
588          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
589       }
590       try
591       {
592          p.write(value, offset, length);
593       }
594       catch (IOException JavaDoc e)
595       {
596          throw new JMSException JavaDoc("IOException");
597       }
598    }
599
600    public void writeObject(Object JavaDoc value) throws JMSException JavaDoc
601    {
602       if (header.msgReadOnly)
603       {
604          throw new MessageNotWriteableException JavaDoc("the message body is read-only");
605       }
606       try
607       {
608          if (value == null)
609          {
610             throw new NullPointerException JavaDoc("Attempt to write a new value");
611          }
612          if (value instanceof String JavaDoc)
613          {
614             String JavaDoc s = (String JavaDoc) value;
615             if( useWriteUTF == true )
616                writeUTF(s);
617             else
618                p.writeChars(s);
619          }
620          else if (value instanceof Boolean JavaDoc)
621          {
622             p.writeBoolean(((Boolean JavaDoc) value).booleanValue());
623          }
624          else if (value instanceof Byte JavaDoc)
625          {
626             p.writeByte(((Byte JavaDoc) value).byteValue());
627          }
628          else if (value instanceof Short JavaDoc)
629          {
630             p.writeShort(((Short JavaDoc) value).shortValue());
631          }
632          else if (value instanceof Integer JavaDoc)
633          {
634             p.writeInt(((Integer JavaDoc) value).intValue());
635          }
636          else if (value instanceof Long JavaDoc)
637          {
638             p.writeLong(((Long JavaDoc) value).longValue());
639          }
640          else if (value instanceof Float JavaDoc)
641          {
642             p.writeFloat(((Float JavaDoc) value).floatValue());
643          }
644          else if (value instanceof Double JavaDoc)
645          {
646             p.writeDouble(((Double JavaDoc) value).doubleValue());
647          }
648          else if (value instanceof byte[])
649          {
650             p.write((byte[]) value, 0, ((byte[]) value).length);
651          }
652          else
653          {
654             throw new MessageFormatException JavaDoc("Invalid object for properties");
655          }
656       }
657       catch (IOException JavaDoc e)
658       {
659          throw new JMSException JavaDoc("IOException");
660       }
661
662    }
663
664    public void reset() throws JMSException JavaDoc
665    {
666       try
667       {
668          if (!header.msgReadOnly)
669          {
670             p.flush();
671             InternalArray = ostream.toByteArray();
672             ostream.close();
673          }
674          ostream = null;
675          istream = null;
676          m = null;
677          p = null;
678          header.msgReadOnly = true;
679       }
680       catch (IOException JavaDoc e)
681       {
682          throw new JMSException JavaDoc("IOException");
683       }
684    }
685    
686    public void clearBody() throws JMSException JavaDoc
687    {
688       try
689       {
690          if (!header.msgReadOnly)
691          {
692             ostream.close();
693          }
694          else
695          {
696             // REVIEW: istream is only initialised on a read.
697
// It looks like it is possible to acknowledge
698
// a message without reading it? Guard against
699
// an NPE in this case.
700
if (istream != null)
701                istream.close();
702          }
703       }
704       catch (IOException JavaDoc e)
705       {
706          //don't throw an exception
707
}
708
709       ostream = new ByteArrayOutputStream JavaDoc();
710       p = new DataOutputStream JavaDoc(ostream);
711       InternalArray = null;
712       istream = null;
713       m = null;
714
715       super.clearBody();
716    }
717
718    public SpyMessage myClone() throws JMSException JavaDoc
719    {
720       SpyBytesMessage result = MessagePool.getBytesMessage();
721       this.reset();
722       result.copyProps(this);
723       if (this.InternalArray != null)
724         {
725          result.InternalArray = new byte[this.InternalArray.length];
726          System.arraycopy(this.InternalArray, 0, result.InternalArray, 0, this.InternalArray.length);
727       }
728       return result;
729    }
730    
731    public long getBodyLength() throws JMSException JavaDoc
732    {
733       checkRead();
734       return InternalArray.length;
735    }
736    
737    public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
738    {
739       byte[] arrayToSend = null;
740       if (!header.msgReadOnly)
741         {
742          p.flush();
743          arrayToSend = ostream.toByteArray();
744       }
745       else
746         {
747          arrayToSend = InternalArray;
748       }
749       super.writeExternal(out);
750       if (arrayToSend == null)
751         {
752          out.writeInt(0); //pretend to be empty array
753
}
754       else
755         {
756          out.writeInt(arrayToSend.length);
757          out.write(arrayToSend);
758       }
759    }
760
761    public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc, ClassNotFoundException JavaDoc
762    {
763       super.readExternal(in);
764       int length = in.readInt();
765       if (length < 0)
766         {
767          InternalArray = null;
768       }
769       else
770         {
771          InternalArray = new byte[length];
772          in.readFully(InternalArray);
773       }
774    }
775    
776    /**
777     * Check the message is readable
778     *
779     * @throws JMSException when not readable
780     */

781    private void checkRead() throws JMSException JavaDoc
782    {
783       if (!header.msgReadOnly)
784       {
785          throw new MessageNotReadableException JavaDoc("readByte while the buffer is writeonly");
786       }
787
788       //We have just received/reset() the message, and the client is trying to
789
// read it
790
if (istream == null || m == null)
791         {
792          istream = new ByteArrayInputStream JavaDoc(InternalArray);
793          m = new DataInputStream JavaDoc(istream);
794       }
795    }
796 }
797
Popular Tags