KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > hessian > io > JavaSerializer


1 /*
2  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
3  *
4  * The Apache Software License, Version 1.1
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Scott Ferguson
47  */

48
49 package com.caucho.hessian.io;
50
51 import java.io.IOException JavaDoc;
52 import java.io.Serializable JavaDoc;
53 import java.lang.reflect.Field JavaDoc;
54 import java.lang.reflect.Method JavaDoc;
55 import java.lang.reflect.Modifier JavaDoc;
56 import java.util.ArrayList JavaDoc;
57 import java.util.logging.Level JavaDoc;
58 import java.util.logging.Logger JavaDoc;
59
60 /**
61  * Serializing an object for known object types.
62  */

63 public class JavaSerializer extends AbstractSerializer
64 {
65   private static final Logger JavaDoc log
66     = Logger.getLogger(JavaSerializer.class.getName());
67   
68   private Field JavaDoc []_fields;
69   private FieldSerializer []_fieldSerializers;
70   private Method JavaDoc _writeReplace;
71   
72   public JavaSerializer(Class JavaDoc cl)
73   {
74     if (! Serializable JavaDoc.class.isAssignableFrom(cl)) {
75       log.fine("hessian - class " + cl.getName() + " must implement java.io.Serializable");
76       
77       throw new IllegalStateException JavaDoc("Serialized class " + cl.getName() + " does not implement java.io.Serializable");
78     }
79     
80     _writeReplace = getWriteReplace(cl);
81     if (_writeReplace != null)
82       _writeReplace.setAccessible(true);
83
84     ArrayList JavaDoc primitiveFields = new ArrayList JavaDoc();
85     ArrayList JavaDoc compoundFields = new ArrayList JavaDoc();
86     
87     for (; cl != null; cl = cl.getSuperclass()) {
88       Field JavaDoc []fields = cl.getDeclaredFields();
89       for (int i = 0; i < fields.length; i++) {
90     Field JavaDoc field = fields[i];
91
92     if (Modifier.isTransient(field.getModifiers()) ||
93         Modifier.isStatic(field.getModifiers()))
94       continue;
95
96     // XXX: could parameterize the handler to only deal with public
97
field.setAccessible(true);
98
99     if (field.getType().isPrimitive() ||
100         field.getType().getName().startsWith("java.lang.") &&
101         ! field.getType().equals(Object JavaDoc.class))
102       primitiveFields.add(field);
103     else
104       compoundFields.add(field);
105       }
106     }
107
108     ArrayList JavaDoc fields = new ArrayList JavaDoc();
109     fields.addAll(primitiveFields);
110     fields.addAll(compoundFields);
111
112     _fields = new Field JavaDoc[fields.size()];
113     fields.toArray(_fields);
114
115     _fieldSerializers = new FieldSerializer[_fields.length];
116
117     for (int i = 0; i < _fields.length; i++) {
118       _fieldSerializers[i] = getFieldSerializer(_fields[i].getType());
119     }
120   }
121
122   /**
123    * Returns the writeReplace method
124    */

125   protected Method JavaDoc getWriteReplace(Class JavaDoc cl)
126   {
127     for (; cl != null; cl = cl.getSuperclass()) {
128       Method JavaDoc []methods = cl.getDeclaredMethods();
129       
130       for (int i = 0; i < methods.length; i++) {
131     Method JavaDoc method = methods[i];
132
133     if (method.getName().equals("writeReplace") &&
134         method.getParameterTypes().length == 0)
135       return method;
136       }
137     }
138
139     return null;
140   }
141   
142   public void writeObject(Object JavaDoc obj, AbstractHessianOutput out)
143     throws IOException JavaDoc
144   {
145     if (out.addRef(obj)) {
146       return;
147     }
148     
149     Class JavaDoc cl = obj.getClass();
150     
151     try {
152       if (_writeReplace != null) {
153     Object JavaDoc repl = _writeReplace.invoke(obj, new Object JavaDoc[0]);
154
155     out.removeRef(obj);
156
157     out.writeObject(repl);
158
159     out.replaceRef(repl, obj);
160
161     return;
162       }
163     } catch (Exception JavaDoc e) {
164       log.log(Level.FINE, e.toString(), e);
165     }
166
167     int ref = out.writeObjectBegin(cl.getName());
168
169     if (ref < 0) {
170       writeObject10(obj, out);
171     }
172     else {
173       if (ref == 0)
174     writeDefinition20(out);
175
176       writeInstance(obj, out);
177     }
178   }
179   
180   private void writeObject10(Object JavaDoc obj, AbstractHessianOutput out)
181     throws IOException JavaDoc
182   {
183     for (int i = 0; i < _fields.length; i++) {
184       Field JavaDoc field = _fields[i];
185
186       out.writeString(field.getName());
187     
188       _fieldSerializers[i].serialize(out, obj, field);
189     }
190       
191     out.writeMapEnd();
192   }
193   
194   private void writeDefinition20(AbstractHessianOutput out)
195     throws IOException JavaDoc
196   {
197     out.writeClassFieldLength(_fields.length);
198     
199     for (int i = 0; i < _fields.length; i++) {
200       Field JavaDoc field = _fields[i];
201       
202       out.writeString(field.getName());
203     }
204   }
205   
206   public void writeInstance(Object JavaDoc obj, AbstractHessianOutput out)
207     throws IOException JavaDoc
208   {
209     for (int i = 0; i < _fields.length; i++) {
210       Field JavaDoc field = _fields[i];
211
212       _fieldSerializers[i].serialize(out, obj, field);
213     }
214   }
215
216   private static FieldSerializer getFieldSerializer(Class JavaDoc type)
217   {
218     if (int.class.equals(type) ||
219     byte.class.equals(type) ||
220     short.class.equals(type) ||
221     int.class.equals(type)) {
222       return IntFieldSerializer.SER;
223     }
224     else if (long.class.equals(type)) {
225       return LongFieldSerializer.SER;
226     }
227     else if (double.class.equals(type) ||
228          float.class.equals(type)) {
229       return DoubleFieldSerializer.SER;
230     }
231     else if (boolean.class.equals(type)) {
232       return BooleanFieldSerializer.SER;
233     }
234     else if (String JavaDoc.class.equals(type)) {
235       return StringFieldSerializer.SER;
236     }
237     else
238       return FieldSerializer.SER;
239   }
240
241   static class FieldSerializer {
242     static final FieldSerializer SER = new FieldSerializer();
243     
244     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
245       throws IOException JavaDoc
246     {
247       Object JavaDoc value = null;
248     
249       try {
250     value = field.get(obj);
251       } catch (IllegalAccessException JavaDoc e) {
252     log.log(Level.FINE, e.toString(), e);
253       }
254
255       out.writeObject(value);
256     }
257   }
258
259   static class BooleanFieldSerializer extends FieldSerializer {
260     static final FieldSerializer SER = new BooleanFieldSerializer();
261     
262     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
263       throws IOException JavaDoc
264     {
265       boolean value = false;
266     
267       try {
268     value = field.getBoolean(obj);
269       } catch (IllegalAccessException JavaDoc e) {
270     log.log(Level.FINE, e.toString(), e);
271       }
272
273       out.writeBoolean(value);
274     }
275   }
276
277   static class IntFieldSerializer extends FieldSerializer {
278     static final FieldSerializer SER = new IntFieldSerializer();
279     
280     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
281       throws IOException JavaDoc
282     {
283       int value = 0;
284     
285       try {
286     value = field.getInt(obj);
287       } catch (IllegalAccessException JavaDoc e) {
288     log.log(Level.FINE, e.toString(), e);
289       }
290
291       out.writeInt(value);
292     }
293   }
294
295   static class LongFieldSerializer extends FieldSerializer {
296     static final FieldSerializer SER = new LongFieldSerializer();
297     
298     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
299       throws IOException JavaDoc
300     {
301       long value = 0;
302     
303       try {
304     value = field.getLong(obj);
305       } catch (IllegalAccessException JavaDoc e) {
306     log.log(Level.FINE, e.toString(), e);
307       }
308
309       out.writeLong(value);
310     }
311   }
312
313   static class DoubleFieldSerializer extends FieldSerializer {
314     static final FieldSerializer SER = new DoubleFieldSerializer();
315     
316     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
317       throws IOException JavaDoc
318     {
319       double value = 0;
320     
321       try {
322     value = field.getDouble(obj);
323       } catch (IllegalAccessException JavaDoc e) {
324     log.log(Level.FINE, e.toString(), e);
325       }
326
327       out.writeDouble(value);
328     }
329   }
330
331   static class StringFieldSerializer extends FieldSerializer {
332     static final FieldSerializer SER = new StringFieldSerializer();
333     
334     void serialize(AbstractHessianOutput out, Object JavaDoc obj, Field JavaDoc field)
335       throws IOException JavaDoc
336     {
337       String JavaDoc value = null;
338     
339       try {
340     value = (String JavaDoc) field.get(obj);
341       } catch (IllegalAccessException JavaDoc e) {
342     log.log(Level.FINE, e.toString(), e);
343       }
344
345       out.writeString(value);
346     }
347   }
348 }
349
Popular Tags