1 16 package net.sf.cglib.beans; 17 18 import java.beans.PropertyDescriptor ; 19 import java.lang.reflect.Method ; 20 import net.sf.cglib.core.*; 21 import org.objectweb.asm.ClassVisitor; 22 import org.objectweb.asm.Type; 23 24 27 public class ImmutableBean 28 { 29 private static final Type ILLEGAL_STATE_EXCEPTION = 30 TypeUtils.parseType("IllegalStateException"); 31 private static final Signature CSTRUCT_OBJECT = 32 TypeUtils.parseConstructor("Object"); 33 private static final Class [] OBJECT_CLASSES = { Object .class }; 34 private static final String FIELD_NAME = "CGLIB$RWBean"; 35 36 private ImmutableBean() { 37 } 38 39 public static Object create(Object bean) { 40 Generator gen = new Generator(); 41 gen.setBean(bean); 42 return gen.create(); 43 } 44 45 public static class Generator extends AbstractClassGenerator { 46 private static final Source SOURCE = new Source(ImmutableBean.class.getName()); 47 private Object bean; 48 private Class target; 49 50 public Generator() { 51 super(SOURCE); 52 } 53 54 public void setBean(Object bean) { 55 this.bean = bean; 56 target = bean.getClass(); 57 } 58 59 protected ClassLoader getDefaultClassLoader() { 60 return target.getClassLoader(); 61 } 62 63 public Object create() { 64 String name = target.getName(); 65 setNamePrefix(name); 66 return super.create(name); 67 } 68 69 public void generateClass(ClassVisitor v) { 70 Type targetType = Type.getType(target); 71 ClassEmitter ce = new ClassEmitter(v); 72 ce.begin_class(Constants.V1_2, 73 Constants.ACC_PUBLIC, 74 getClassName(), 75 targetType, 76 null, 77 Constants.SOURCE_FILE); 78 79 ce.declare_field(Constants.ACC_FINAL | Constants.ACC_PRIVATE, FIELD_NAME, targetType, null); 80 81 CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null); 82 e.load_this(); 83 e.super_invoke_constructor(); 84 e.load_this(); 85 e.load_arg(0); 86 e.checkcast(targetType); 87 e.putfield(FIELD_NAME); 88 e.return_value(); 89 e.end_method(); 90 91 PropertyDescriptor [] descriptors = ReflectUtils.getBeanProperties(target); 92 Method [] getters = ReflectUtils.getPropertyMethods(descriptors, true, false); 93 Method [] setters = ReflectUtils.getPropertyMethods(descriptors, false, true); 94 95 for (int i = 0; i < getters.length; i++) { 96 MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); 97 e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC); 98 e.load_this(); 99 e.getfield(FIELD_NAME); 100 e.invoke(getter); 101 e.return_value(); 102 e.end_method(); 103 } 104 105 for (int i = 0; i < setters.length; i++) { 106 MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]); 107 e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC); 108 e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable"); 109 e.end_method(); 110 } 111 112 ce.end_class(); 113 } 114 115 protected Object firstInstance(Class type) { 116 return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object []{ bean }); 117 } 118 119 protected Object nextInstance(Object instance) { 121 return firstInstance(instance.getClass()); 122 } 123 } 124 } 125 | Popular Tags |