KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtworks > xstream > converters > reflection > SerializationMethodInvoker


1 package com.thoughtworks.xstream.converters.reflection;
2
3 import com.thoughtworks.xstream.converters.ConversionException;
4
5 import java.lang.reflect.InvocationTargetException JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Collections JavaDoc;
10 import java.io.ObjectInputStream JavaDoc;
11 import java.io.ObjectOutputStream JavaDoc;
12
13 /**
14  * Convenience wrapper to invoke special serialization methods on objects (and perform reflection caching).
15  *
16  * @author Joe Walnes
17  */

18 public class SerializationMethodInvoker {
19
20     private Map JavaDoc cache = Collections.synchronizedMap(new HashMap JavaDoc());
21     private static final Object JavaDoc NO_METHOD = new Object JavaDoc();
22
23     /**
24      * Resolves an object as native serialization does by calling readResolve(), if available.
25      */

26     public Object JavaDoc callReadResolve(Object JavaDoc result) {
27         if (result == null) {
28             return null;
29         } else {
30             Method JavaDoc readResolveMethod = getMethod(result.getClass(), "readResolve", null, true);
31             if (readResolveMethod != null) {
32                 try {
33                     return readResolveMethod.invoke(result, null);
34                 } catch (IllegalAccessException JavaDoc e) {
35                     throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", e);
36                 } catch (InvocationTargetException JavaDoc e) {
37                     throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", e);
38                 }
39             } else {
40                 return result;
41             }
42         }
43     }
44
45     public Object JavaDoc callWriteReplace(Object JavaDoc object) {
46         if (object == null) {
47             return null;
48         } else {
49             Method JavaDoc writeReplaceMethod = getMethod(object.getClass(), "writeReplace", null, true);
50             if (writeReplaceMethod != null) {
51                 try {
52                     return writeReplaceMethod.invoke(object, null);
53                 } catch (IllegalAccessException JavaDoc e) {
54                     throw new ObjectAccessException("Could not call " + object.getClass().getName() + ".writeReplace()", e);
55                 } catch (InvocationTargetException JavaDoc e) {
56                     throw new ObjectAccessException("Could not call " + object.getClass().getName() + ".writeReplace()", e);
57                 }
58             } else {
59                 return object;
60             }
61         }
62     }
63
64     public boolean supportsReadObject(Class JavaDoc type, boolean includeBaseClasses) {
65         return getMethod(type, "readObject", new Class JavaDoc[]{ObjectInputStream JavaDoc.class}, includeBaseClasses) != null;
66     }
67
68     public void callReadObject(Class JavaDoc type, Object JavaDoc object, ObjectInputStream JavaDoc stream) {
69         try {
70             Method JavaDoc readObjectMethod = getMethod(type, "readObject", new Class JavaDoc[]{ObjectInputStream JavaDoc.class}, false);
71             readObjectMethod.invoke(object, new Object JavaDoc[]{stream});
72         } catch (IllegalAccessException JavaDoc e) {
73             throw new ConversionException("Could not call " + object.getClass().getName() + ".readObject()", e);
74         } catch (InvocationTargetException JavaDoc e) {
75             throw new ConversionException("Could not call " + object.getClass().getName() + ".readObject()", e);
76         }
77     }
78
79     public boolean supportsWriteObject(Class JavaDoc type, boolean includeBaseClasses) {
80         return getMethod(type, "writeObject", new Class JavaDoc[]{ObjectOutputStream JavaDoc.class}, includeBaseClasses) != null;
81     }
82
83     public void callWriteObject(Class JavaDoc type, Object JavaDoc instance, ObjectOutputStream JavaDoc stream) {
84         try {
85             Method JavaDoc readObjectMethod = getMethod(type, "writeObject", new Class JavaDoc[]{ObjectOutputStream JavaDoc.class}, false);
86             readObjectMethod.invoke(instance, new Object JavaDoc[]{stream});
87         } catch (IllegalAccessException JavaDoc e) {
88             throw new ConversionException("Could not call " + instance.getClass().getName() + ".writeObject()", e);
89         } catch (InvocationTargetException JavaDoc e) {
90             throw new ConversionException("Could not call " + instance.getClass().getName() + ".writeObject()", e);
91         }
92     }
93
94     private Method JavaDoc getMethod(Class JavaDoc type, String JavaDoc name, Class JavaDoc[] parameterTypes, boolean includeBaseclasses) {
95         Object JavaDoc key = type.getName() + "." + name + "." + includeBaseclasses;
96         if (cache.containsKey(key)) {
97             Object JavaDoc result = cache.get(key);
98             return (Method JavaDoc) (result == NO_METHOD ? null : result);
99         }
100         if (includeBaseclasses) {
101             while (type != null) {
102                 try {
103                     Method JavaDoc result = type.getDeclaredMethod(name, parameterTypes);
104                     result.setAccessible(true);
105                     cache.put(key, result);
106                     return result;
107                 } catch (NoSuchMethodException JavaDoc e) {
108                     type = type.getSuperclass();
109                 }
110             }
111             cache.put(key, NO_METHOD);
112             return null;
113         } else {
114             try {
115                 Method JavaDoc result = type.getDeclaredMethod(name, parameterTypes);
116                 result.setAccessible(true);
117                 cache.put(key, result);
118                 return result;
119             } catch (NoSuchMethodException JavaDoc e) {
120                 cache.put(key, NO_METHOD);
121                 return null;
122             }
123         }
124     }
125
126 }
127
Popular Tags