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