KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.thoughtworks.xstream.converters.reflection;
2
3 import sun.misc.Unsafe;
4 import sun.reflect.ReflectionFactory;
5
6 import java.lang.reflect.Constructor JavaDoc;
7 import java.lang.reflect.Field JavaDoc;
8 import java.lang.reflect.InvocationTargetException JavaDoc;
9 import java.util.HashMap JavaDoc;
10 import java.util.Map JavaDoc;
11
12 /**
13  * Instantiates a new object on the Sun JVM by bypassing the constructor (meaning code in the constructor
14  * will never be executed and parameters do not have to be known). This is the same method used by the internals of
15  * standard Java serialization, but relies on internal Sun code that may not be present on all JVMs.
16  *
17  * @author Joe Walnes
18  * @author Brian Slesinsky
19  */

20 public class Sun14ReflectionProvider extends PureJavaReflectionProvider {
21
22     private static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
23     private static final Map JavaDoc constructorCache = new HashMap JavaDoc();
24     private static Unsafe cachedUnsafe;
25
26     private Unsafe getUnsafe() throws ClassNotFoundException JavaDoc, NoSuchFieldException JavaDoc, IllegalAccessException JavaDoc {
27         if (cachedUnsafe != null) {
28             return cachedUnsafe;
29         }
30         Class JavaDoc objectStreamClass = Class.forName("java.io.ObjectStreamClass$FieldReflector");
31         Field JavaDoc unsafeField = objectStreamClass.getDeclaredField("unsafe");
32         unsafeField.setAccessible(true);
33         cachedUnsafe = (Unsafe) unsafeField.get(null);
34         return cachedUnsafe;
35     }
36
37     public Object JavaDoc newInstance(Class JavaDoc type) {
38         try {
39             Constructor JavaDoc customConstructor = getMungedConstructor(type);
40             Object JavaDoc newValue = customConstructor.newInstance(new Object JavaDoc[0]);
41             return newValue;
42         } catch (NoSuchMethodException JavaDoc e) {
43             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
44         } catch (SecurityException JavaDoc e) {
45             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
46         } catch (InstantiationException JavaDoc e) {
47             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
48         } catch (IllegalAccessException JavaDoc e) {
49             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
50         } catch (IllegalArgumentException JavaDoc e) {
51             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
52         } catch (InvocationTargetException JavaDoc e) {
53             throw new ObjectAccessException("Cannot construct " + type.getName(), e);
54         }
55     }
56
57     private Constructor JavaDoc getMungedConstructor(Class JavaDoc type) throws NoSuchMethodException JavaDoc {
58         if (!constructorCache.containsKey(type)) {
59             Constructor JavaDoc javaLangObjectConstructor = Object JavaDoc.class.getDeclaredConstructor(new Class JavaDoc[0]);
60             Constructor JavaDoc customConstructor = reflectionFactory.newConstructorForSerialization(type, javaLangObjectConstructor);
61             constructorCache.put(type, customConstructor);
62         }
63         return (Constructor JavaDoc) constructorCache.get(type);
64     }
65
66     public void writeField(Object JavaDoc object, String JavaDoc fieldName, Object JavaDoc value, Class JavaDoc definedIn) {
67         write(fieldDictionary.field(object.getClass(), fieldName, definedIn), object, value);
68     }
69
70     private void write(Field JavaDoc field, Object JavaDoc object, Object JavaDoc value) {
71         try {
72             Unsafe unsafe = getUnsafe();
73             long offset = unsafe.objectFieldOffset(field);
74             Class JavaDoc type = field.getType();
75             if (type.isPrimitive()) {
76                 if (type.equals(Integer.TYPE)) {
77                     unsafe.putInt(object, offset, ((Integer JavaDoc) value).intValue());
78                 } else if (type.equals(Long.TYPE)) {
79                     unsafe.putLong(object, offset, ((Long JavaDoc) value).longValue());
80                 } else if (type.equals(Short.TYPE)) {
81                     unsafe.putShort(object, offset, ((Short JavaDoc) value).shortValue());
82                 } else if (type.equals(Character.TYPE)) {
83                     unsafe.putChar(object, offset, ((Character JavaDoc) value).charValue());
84                 } else if (type.equals(Byte.TYPE)) {
85                     unsafe.putByte(object, offset, ((Byte JavaDoc) value).byteValue());
86                 } else if (type.equals(Float.TYPE)) {
87                     unsafe.putFloat(object, offset, ((Float JavaDoc) value).floatValue());
88                 } else if (type.equals(Double.TYPE)) {
89                     unsafe.putDouble(object, offset, ((Double JavaDoc) value).doubleValue());
90                 } else if (type.equals(Boolean.TYPE)) {
91                     unsafe.putBoolean(object, offset, ((Boolean JavaDoc) value).booleanValue());
92                 } else {
93                     throw new ObjectAccessException("Could not set field " +
94                             object.getClass() + "." + field.getName() +
95                             ": Unknown type " + type);
96                 }
97             } else {
98                 unsafe.putObject(object, offset, value);
99             }
100
101         } catch (IllegalArgumentException JavaDoc e) {
102             throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
103         } catch (IllegalAccessException JavaDoc e) {
104             throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
105         } catch (NoSuchFieldException JavaDoc e) {
106             throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
107         } catch (ClassNotFoundException JavaDoc e) {
108             throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
109         }
110     }
111
112     protected void validateFieldAccess(Field JavaDoc field) {
113         // (overriden) don't mind final fields.
114
}
115 }
116
Popular Tags