KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ubermq > kernel > AbstractDatagram


1 package com.ubermq.kernel;
2
3 import com.ubermq.*;
4 import com.ubermq.util.*;
5
6 import java.nio.*;
7 import java.nio.charset.*;
8
9 /**
10  * A generally useful implementation of common datagram functionality,
11  * such as type serialization/deserialization, datagram flags, and
12  * some static methods used to write typed information in a byte-compact
13  * way.
14  */

15 public abstract class AbstractDatagram
16     implements IDatagram
17 {
18     private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AbstractDatagram.class);
19     
20     private int datagramType;
21     private int datagramFlags;
22
23     /**
24      * Constructs an abstract datagram with the specified
25      * type and flag values.
26      *
27      * @param datagramType the type code of the datagram.
28      * @param datagramFlags a set of flags that are implementation specific.
29      */

30     protected AbstractDatagram(int datagramType,
31                                int datagramFlags)
32     {
33         setDatagramProps(datagramType, datagramFlags);
34     }
35
36     /**
37      * Sets the datagram type and flags.
38      *
39      * @param datagramType the type code of the datagram.
40      * @param datagramFlags a set of flags that are implementation specific.
41      */

42     protected void setDatagramProps(int datagramType,
43                                     int datagramFlags)
44     {
45         this.datagramType = datagramType;
46         this.datagramFlags = datagramFlags;
47     }
48
49     public int getDatagramType() { return datagramType; }
50     public int getDatagramFlags() { return datagramFlags; }
51     public void setDatagramFlagBits(int f) {datagramFlags |= f;}
52     public void unsetDatagramFlagBits(int f) {datagramFlags &= ~f;}
53
54     /**
55      * Returns a bitmask representing fields present in this
56      * datagram. This should be used to enable backward compatibility.
57      *
58      * In this version, should return FIELDS_BASIC.
59      */

60     public int getDatagramFieldMask() { return IDatagram.FIELDS_BASIC; }
61
62     public void incoming(ByteBuffer bb)
63         throws java.io.IOException JavaDoc
64     {
65         this.datagramFlags = bb.getInt();
66     }
67
68     public void outgoing(ByteBuffer bb)
69     {
70         bb.putInt(getDatagramFlags());
71     }
72
73     public String JavaDoc toString()
74     {
75         String JavaDoc type = String.valueOf(getDatagramType());
76         return "\nType:\t\t" + type;
77     }
78
79     /**
80      * Writes a String to a buffer in the default encoding, preceded by a
81      * int length.
82      */

83     protected static void writePascalString(String JavaDoc sz, ByteBuffer bb)
84     {
85         if (sz == null)
86         {
87             bb.putInt(0);
88             return;
89         }
90         else {
91             int pos = bb.position();
92             bb.putInt(0); // reserve space for the length
93

94             Utility.encode(sz, bb);
95             bb.putInt(pos, bb.position() - (pos + 4));
96         }
97     }
98
99     /**
100      * Reads a String from a byte buffer that was written by writePascalString.
101      * It expects the string to be in the default encoding, preceded by a two byte
102      * length.
103      *
104      * @return the decoded string. if the string is zero length, null is returned.
105      * @see com.ubermq.Utility.decode
106      */

107     protected static String JavaDoc readPascalString(ByteBuffer bb)
108     {
109         int n = bb.getInt();
110         if (n == 0) {
111             return null;
112         }
113         else {
114             ByteBuffer szb = bb.slice();
115             szb.limit(n);
116
117             bb.position( bb.position() + n );
118             return Utility.decode(szb).toString();
119         }
120     }
121
122     private static final byte TYPE_INTEGER = 1;
123     private static final byte TYPE_LONG = 2;
124     private static final byte TYPE_STRING = 3;
125     private static final byte TYPE_OBJECT = 4;
126     private static final byte TYPE_DOUBLE = 5;
127     private static final byte TYPE_BYTES = 6;
128     private static final byte TYPE_SHORT = 7;
129     private static final byte TYPE_FLOAT = 8;
130     private static final byte TYPE_BYTE = 9;
131     private static final byte TYPE_BOOLEAN = 10;
132     private static final byte TYPE_NULL = 11;
133
134     /**
135      * Writes an Object to a byte buffer. If the Object is a primitive type,
136      * it is written into the ByteBuffer in a compact
137      * way. This avoids Java serialization overhead and inefficiencies.<P>
138      *
139      * If it is an instance of Serializable, the standard Java serialization
140      * algorithms will be used to write binary data to the buffer.<P>
141      *
142      * @param data a Boolean, Byte, Short, Integer, Long, Float, Double,
143      * String, byte[] for compact representation,
144      * or an Object that implements java.io.Serializable.
145      * @param bb the destination buffer
146      */

147     protected static void writeTypedData(Object JavaDoc data, ByteBuffer bb)
148     {
149         if (data instanceof Integer JavaDoc)
150         {
151             bb.put(TYPE_INTEGER);
152             bb.putInt(((Integer JavaDoc)data).intValue());
153         }
154         else if (data instanceof Long JavaDoc)
155         {
156             bb.put(TYPE_LONG);
157             bb.putLong(((Long JavaDoc)data).longValue());
158         }
159         else if (data instanceof Double JavaDoc)
160         {
161             bb.put(TYPE_DOUBLE);
162             bb.putDouble(((Double JavaDoc)data).doubleValue());
163         }
164         else if (data instanceof String JavaDoc)
165         {
166             bb.put(TYPE_STRING);
167             writePascalString((String JavaDoc)data, bb);
168         }
169         else if (data instanceof byte[])
170         {
171             bb.put(TYPE_BYTES);
172
173             byte[] b = (byte[])data;
174             bb.putInt(b.length);
175             bb.put(b);
176         }
177         else if (data instanceof Short JavaDoc)
178         {
179             bb.put(TYPE_SHORT);
180             bb.putShort(((Short JavaDoc)data).shortValue());
181         }
182         else if (data instanceof Float JavaDoc)
183         {
184             bb.put(TYPE_FLOAT);
185             bb.putFloat(((Float JavaDoc)data).floatValue());
186         }
187         else if (data instanceof Byte JavaDoc)
188         {
189             bb.put(TYPE_BYTE);
190             bb.put(((Byte JavaDoc)data).byteValue());
191         }
192         else if (data instanceof Boolean JavaDoc)
193         {
194             bb.put(TYPE_BOOLEAN);
195             bb.put(((Boolean JavaDoc)data).booleanValue() ? (byte)1 : (byte)0);
196         }
197         else if (data instanceof java.io.Serializable JavaDoc)
198         {
199             try {
200                 java.io.ByteArrayOutputStream JavaDoc baos = new java.io.ByteArrayOutputStream JavaDoc();
201                 java.io.ObjectOutputStream JavaDoc oos = new java.io.ObjectOutputStream JavaDoc(baos);
202                 oos.writeObject(data);
203
204                 byte[] b = baos.toByteArray();
205                 bb.put(TYPE_OBJECT);
206                 bb.putInt(b.length);
207                 bb.put(b);
208             }
209             catch(java.io.IOException JavaDoc iox) {
210                 log.error("", iox);
211             }
212         }
213         else if (data == null)
214         {
215             bb.put(TYPE_NULL);
216         }
217     }
218
219     /**
220      * Reads typed data from a buffer. The data should have been written
221      * by the above <code>writeTypedData</code> method.
222      * @return an Object representing the deserialized version of what was
223      * originally written. Primitive types that are supported are Boolean, Byte,
224      * Short, Integer, Long, Float, Double, byte[] and String.
225      */

226     protected static Object JavaDoc readTypedData(ByteBuffer bb)
227     {
228         Object JavaDoc value = null;
229         if (bb.remaining() == 0)
230             return value;
231
232         switch(bb.get())
233         {
234             case TYPE_INTEGER:
235                 value = new Integer JavaDoc(bb.getInt());
236                 break;
237             case TYPE_BYTES:
238                 {
239                     int len = bb.getInt();
240                     byte[] b = new byte[len];
241                     bb.get(b, 0, len);
242                     value = b;
243                     break;
244                 }
245             case TYPE_DOUBLE:
246                 value = new Double JavaDoc(bb.getDouble());
247                 break;
248             case TYPE_LONG:
249                 value = new Long JavaDoc(bb.getLong());
250                 break;
251             case TYPE_OBJECT:
252                 {
253                     int len = bb.getInt();
254                     byte[] b = new byte[len];
255                     bb.get(b, 0, len);
256
257                     try {
258                         java.io.ObjectInputStream JavaDoc ois = new java.io.ObjectInputStream JavaDoc(new java.io.ByteArrayInputStream JavaDoc(b));
259                         value = ois.readObject();
260                     } catch(Exception JavaDoc x) {
261                         log.error("", x);
262                     }
263                     break;
264                 }
265             case TYPE_STRING:
266                 value = readPascalString(bb);
267                 break;
268             case TYPE_SHORT:
269                 value = new Short JavaDoc(bb.getShort());
270                 break;
271             case TYPE_BYTE:
272                 value = new Byte JavaDoc(bb.get());
273                 break;
274             case TYPE_FLOAT:
275                 value = new Float JavaDoc(bb.getFloat());
276                 break;
277             case TYPE_BOOLEAN:
278                 value = bb.get() != 0 ? Boolean.TRUE : Boolean.FALSE;
279                 break;
280             case TYPE_NULL:
281                 value = null;
282                 break;
283         }
284
285         return value;
286     }
287 }
288
Popular Tags