Package net.sf.cglib.proxy

Source Code of net.sf.cglib.proxy.Enhancer$EnhancerKey

/*      */ package net.sf.cglib.proxy;
/*      */
/*      */ import java.lang.reflect.InvocationTargetException;
/*      */ import java.lang.reflect.Method;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Arrays;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Set;
/*      */ import net.sf.cglib.asm.ClassVisitor;
/*      */ import net.sf.cglib.asm.Label;
/*      */ import net.sf.cglib.asm.Type;
/*      */ import net.sf.cglib.core.AbstractClassGenerator;
/*      */ import net.sf.cglib.core.AbstractClassGenerator.Source;
/*      */ import net.sf.cglib.core.ClassEmitter;
/*      */ import net.sf.cglib.core.CodeEmitter;
/*      */ import net.sf.cglib.core.CodeGenerationException;
/*      */ import net.sf.cglib.core.CollectionUtils;
/*      */ import net.sf.cglib.core.Constants;
/*      */ import net.sf.cglib.core.DuplicatesPredicate;
/*      */ import net.sf.cglib.core.EmitUtils;
/*      */ import net.sf.cglib.core.KeyFactory;
/*      */ import net.sf.cglib.core.Local;
/*      */ import net.sf.cglib.core.MethodInfo;
/*      */ import net.sf.cglib.core.MethodInfoTransformer;
/*      */ import net.sf.cglib.core.MethodWrapper;
/*      */ import net.sf.cglib.core.ObjectSwitchCallback;
/*      */ import net.sf.cglib.core.ProcessSwitchCallback;
/*      */ import net.sf.cglib.core.ReflectUtils;
/*      */ import net.sf.cglib.core.RejectModifierPredicate;
/*      */ import net.sf.cglib.core.Signature;
/*      */ import net.sf.cglib.core.Transformer;
/*      */ import net.sf.cglib.core.TypeUtils;
/*      */ import net.sf.cglib.core.VisibilityPredicate;
/*      */
/*      */ public class Enhancer extends AbstractClassGenerator
/*      */ {
/*   62 */   private static final CallbackFilter ALL_ZERO = new CallbackFilter() {
/*      */     public int accept(Method method) {
/*   64 */       return 0;
/*      */     }
/*   62 */   };
/*      */
/*   68 */   private static final AbstractClassGenerator.Source SOURCE = new AbstractClassGenerator.Source(Enhancer.class.getName());
/*   69 */   private static final EnhancerKey KEY_FACTORY = (EnhancerKey)KeyFactory.create(EnhancerKey.class);
/*      */   private static final String BOUND_FIELD = "CGLIB$BOUND";
/*      */   private static final String THREAD_CALLBACKS_FIELD = "CGLIB$THREAD_CALLBACKS";
/*      */   private static final String STATIC_CALLBACKS_FIELD = "CGLIB$STATIC_CALLBACKS";
/*      */   private static final String SET_THREAD_CALLBACKS_NAME = "CGLIB$SET_THREAD_CALLBACKS";
/*      */   private static final String SET_STATIC_CALLBACKS_NAME = "CGLIB$SET_STATIC_CALLBACKS";
/*      */   private static final String CONSTRUCTED_FIELD = "CGLIB$CONSTRUCTED";
/*   79 */   private static final Type FACTORY = TypeUtils.parseType("net.sf.cglib.proxy.Factory");
/*      */
/*   81 */   private static final Type ILLEGAL_STATE_EXCEPTION = TypeUtils.parseType("IllegalStateException");
/*      */
/*   83 */   private static final Type ILLEGAL_ARGUMENT_EXCEPTION = TypeUtils.parseType("IllegalArgumentException");
/*      */
/*   85 */   private static final Type THREAD_LOCAL = TypeUtils.parseType("ThreadLocal");
/*      */
/*   87 */   private static final Type CALLBACK = TypeUtils.parseType("net.sf.cglib.proxy.Callback");
/*      */
/*   89 */   private static final Type CALLBACK_ARRAY = Type.getType("[Lnet/sf/cglib/proxy/Callback;");
/*      */
/*   91 */   private static final Signature CSTRUCT_NULL = TypeUtils.parseConstructor("");
/*      */
/*   93 */   private static final Signature SET_THREAD_CALLBACKS = new Signature("CGLIB$SET_THREAD_CALLBACKS", Type.VOID_TYPE, new Type[] { CALLBACK_ARRAY });
/*      */
/*   95 */   private static final Signature SET_STATIC_CALLBACKS = new Signature("CGLIB$SET_STATIC_CALLBACKS", Type.VOID_TYPE, new Type[] { CALLBACK_ARRAY });
/*      */
/*   97 */   private static final Signature NEW_INSTANCE = new Signature("newInstance", Constants.TYPE_OBJECT, new Type[] { CALLBACK_ARRAY });
/*      */
/*   99 */   private static final Signature MULTIARG_NEW_INSTANCE = new Signature("newInstance", Constants.TYPE_OBJECT, new Type[] { Constants.TYPE_CLASS_ARRAY, Constants.TYPE_OBJECT_ARRAY, CALLBACK_ARRAY });
/*      */
/*  105 */   private static final Signature SINGLE_NEW_INSTANCE = new Signature("newInstance", Constants.TYPE_OBJECT, new Type[] { CALLBACK });
/*      */
/*  107 */   private static final Signature SET_CALLBACK = new Signature("setCallback", Type.VOID_TYPE, new Type[] { Type.INT_TYPE, CALLBACK });
/*      */
/*  109 */   private static final Signature GET_CALLBACK = new Signature("getCallback", CALLBACK, new Type[] { Type.INT_TYPE });
/*      */
/*  111 */   private static final Signature SET_CALLBACKS = new Signature("setCallbacks", Type.VOID_TYPE, new Type[] { CALLBACK_ARRAY });
/*      */
/*  113 */   private static final Signature GET_CALLBACKS = new Signature("getCallbacks", CALLBACK_ARRAY, new Type[0]);
/*      */
/*  115 */   private static final Signature THREAD_LOCAL_GET = TypeUtils.parseSignature("Object get()");
/*      */
/*  117 */   private static final Signature THREAD_LOCAL_SET = TypeUtils.parseSignature("void set(Object)");
/*      */
/*  119 */   private static final Signature BIND_CALLBACKS = TypeUtils.parseSignature("void CGLIB$BIND_CALLBACKS(Object)");
/*      */   private Class[] interfaces;
/*      */   private CallbackFilter filter;
/*      */   private Callback[] callbacks;
/*      */   private Type[] callbackTypes;
/*      */   private boolean classOnly;
/*      */   private Class superclass;
/*      */   private Class[] argumentTypes;
/*      */   private Object[] arguments;
/*  141 */   private boolean useFactory = true;
/*      */   private Long serialVersionUID;
/*  143 */   private boolean interceptDuringConstruction = true;
/*      */
/*      */   public Enhancer()
/*      */   {
/*  153 */     super(SOURCE);
/*      */   }
/*      */
/*      */   public void setSuperclass(Class superclass)
/*      */   {
/*  166 */     if ((superclass != null) && (superclass.isInterface()))
/*  167 */       setInterfaces(new Class[] { superclass });
/*  168 */     else if ((superclass != null) && (superclass.equals(Object.class)))
/*      */     {
/*  170 */       this.superclass = null;
/*      */     }
/*  172 */     else this.superclass = superclass;
/*      */   }
/*      */
/*      */   public void setInterfaces(Class[] interfaces)
/*      */   {
/*  183 */     this.interfaces = interfaces;
/*      */   }
/*      */
/*      */   public void setCallbackFilter(CallbackFilter filter)
/*      */   {
/*  195 */     this.filter = filter;
/*      */   }
/*      */
/*      */   public void setCallback(Callback callback)
/*      */   {
/*  206 */     setCallbacks(new Callback[] { callback });
/*      */   }
/*      */
/*      */   public void setCallbacks(Callback[] callbacks)
/*      */   {
/*  219 */     if ((callbacks != null) && (callbacks.length == 0)) {
/*  220 */       throw new IllegalArgumentException("Array cannot be empty");
/*      */     }
/*  222 */     this.callbacks = callbacks;
/*      */   }
/*      */
/*      */   public void setUseFactory(boolean useFactory)
/*      */   {
/*  235 */     this.useFactory = useFactory;
/*      */   }
/*      */
/*      */   public void setInterceptDuringConstruction(boolean interceptDuringConstruction)
/*      */   {
/*  245 */     this.interceptDuringConstruction = interceptDuringConstruction;
/*      */   }
/*      */
/*      */   public void setCallbackType(Class callbackType)
/*      */   {
/*  257 */     setCallbackTypes(new Class[] { callbackType });
/*      */   }
/*      */
/*      */   public void setCallbackTypes(Class[] callbackTypes)
/*      */   {
/*  270 */     if ((callbackTypes != null) && (callbackTypes.length == 0)) {
/*  271 */       throw new IllegalArgumentException("Array cannot be empty");
/*      */     }
/*  273 */     this.callbackTypes = CallbackInfo.determineTypes(callbackTypes);
/*      */   }
/*      */
/*      */   public Object create()
/*      */   {
/*  283 */     this.classOnly = false;
/*  284 */     this.argumentTypes = null;
/*  285 */     return createHelper();
/*      */   }
/*      */
/*      */   public Object create(Class[] argumentTypes, Object[] arguments)
/*      */   {
/*  298 */     this.classOnly = false;
/*  299 */     if ((argumentTypes == null) || (arguments == null) || (argumentTypes.length != arguments.length)) {
/*  300 */       throw new IllegalArgumentException("Arguments must be non-null and of equal length");
/*      */     }
/*  302 */     this.argumentTypes = argumentTypes;
/*  303 */     this.arguments = arguments;
/*  304 */     return createHelper();
/*      */   }
/*      */
/*      */   public Class createClass()
/*      */   {
/*  316 */     this.classOnly = true;
/*  317 */     return (Class)createHelper();
/*      */   }
/*      */
/*      */   public void setSerialVersionUID(Long sUID)
/*      */   {
/*  325 */     this.serialVersionUID = sUID;
/*      */   }
/*      */
/*      */   private void validate() {
/*  329 */     if ((this.classOnly ^ this.callbacks == null)) {
/*  330 */       if (this.classOnly) {
/*  331 */         throw new IllegalStateException("createClass does not accept callbacks");
/*      */       }
/*  333 */       throw new IllegalStateException("Callbacks are required");
/*      */     }
/*      */
/*  336 */     if ((this.classOnly) && (this.callbackTypes == null)) {
/*  337 */       throw new IllegalStateException("Callback types are required");
/*      */     }
/*  339 */     if ((this.callbacks != null) && (this.callbackTypes != null)) {
/*  340 */       if (this.callbacks.length != this.callbackTypes.length) {
/*  341 */         throw new IllegalStateException("Lengths of callback and callback types array must be the same");
/*      */       }
/*  343 */       Type[] check = CallbackInfo.determineTypes(this.callbacks);
/*  344 */       for (int i = 0; i < check.length; i++) {
/*  345 */         if (!check[i].equals(this.callbackTypes[i]))
/*  346 */           throw new IllegalStateException("Callback " + check[i] + " is not assignable to " + this.callbackTypes[i]);
/*      */       }
/*      */     }
/*  349 */     else if (this.callbacks != null) {
/*  350 */       this.callbackTypes = CallbackInfo.determineTypes(this.callbacks);
/*      */     }
/*  352 */     if (this.filter == null) {
/*  353 */       if (this.callbackTypes.length > 1) {
/*  354 */         throw new IllegalStateException("Multiple callback types possible but no filter specified");
/*      */       }
/*  356 */       this.filter = ALL_ZERO;
/*      */     }
/*  358 */     if (this.interfaces != null)
/*  359 */       for (int i = 0; i < this.interfaces.length; i++) {
/*  360 */         if (this.interfaces[i] == null) {
/*  361 */           throw new IllegalStateException("Interfaces cannot be null");
/*      */         }
/*  363 */         if (!this.interfaces[i].isInterface())
/*  364 */           throw new IllegalStateException(this.interfaces[i] + " is not an interface");
/*      */       }
/*      */   }
/*      */
/*      */   private Object createHelper()
/*      */   {
/*  371 */     validate();
/*  372 */     if (this.superclass != null)
/*  373 */       setNamePrefix(this.superclass.getName());
/*  374 */     else if (this.interfaces != null) {
/*  375 */       setNamePrefix(this.interfaces[ReflectUtils.findPackageProtected(this.interfaces)].getName());
/*      */     }
/*  377 */     return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID));
/*      */   }
/*      */
/*      */   protected ClassLoader getDefaultClassLoader()
/*      */   {
/*  387 */     if (this.superclass != null)
/*  388 */       return this.superclass.getClassLoader();
/*  389 */     if (this.interfaces != null) {
/*  390 */       return this.interfaces[0].getClassLoader();
/*      */     }
/*  392 */     return null;
/*      */   }
/*      */
/*      */   private Signature rename(Signature sig, int index)
/*      */   {
/*  397 */     return new Signature("CGLIB$" + sig.getName() + "$" + index, sig.getDescriptor());
/*      */   }
/*      */
/*      */   public static void getMethods(Class superclass, Class[] interfaces, List methods)
/*      */   {
/*  416 */     getMethods(superclass, interfaces, methods, null, null);
/*      */   }
/*      */
/*      */   private static void getMethods(Class superclass, Class[] interfaces, List methods, List interfaceMethods, Set forcePublic)
/*      */   {
/*  421 */     ReflectUtils.addAllMethods(superclass, methods);
/*  422 */     List target = interfaceMethods != null ? interfaceMethods : methods;
/*  423 */     if (interfaces != null) {
/*  424 */       for (int i = 0; i < interfaces.length; i++) {
/*  425 */         if (interfaces[i] != Factory.class) {
/*  426 */           ReflectUtils.addAllMethods(interfaces[i], target);
/*      */         }
/*      */       }
/*      */     }
/*  430 */     if (interfaceMethods != null) {
/*  431 */       if (forcePublic != null) {
/*  432 */         forcePublic.addAll(MethodWrapper.createSet(interfaceMethods));
/*      */       }
/*  434 */       methods.addAll(interfaceMethods);
/*      */     }
/*  436 */     CollectionUtils.filter(methods, new RejectModifierPredicate(8));
/*  437 */     CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true));
/*  438 */     CollectionUtils.filter(methods, new DuplicatesPredicate());
/*  439 */     CollectionUtils.filter(methods, new RejectModifierPredicate(16));
/*      */   }
/*      */
/*      */   public void generateClass(ClassVisitor v) throws Exception {
/*  443 */     Class sc = this.superclass == null ? Object.class : this.superclass;
/*      */
/*  445 */     if (TypeUtils.isFinal(sc.getModifiers()))
/*  446 */       throw new IllegalArgumentException("Cannot subclass final class " + sc);
/*  447 */     List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
/*  448 */     filterConstructors(sc, constructors);
/*      */
/*  453 */     List actualMethods = new ArrayList();
/*  454 */     List interfaceMethods = new ArrayList();
/*  455 */     Set forcePublic = new HashSet();
/*  456 */     getMethods(sc, this.interfaces, actualMethods, interfaceMethods, forcePublic);
/*      */
/*  458 */     List methods = CollectionUtils.transform(actualMethods, new Transformer(forcePublic) {
/*      */       public Object transform(Object value) {
/*  460 */         Method method = (Method)value;
/*  461 */         int modifiers = 0x10 | method.getModifiers() & 0xFFFFFBFF & 0xFFFFFEFF & 0xFFFFFFDF;
/*      */
/*  466 */         if (this.val$forcePublic.contains(MethodWrapper.create(method))) {
/*  467 */           modifiers = modifiers & 0xFFFFFFFB | 0x1;
/*      */         }
/*  469 */         return ReflectUtils.getMethodInfo(method, modifiers);
/*      */       }
/*      */     });
/*  473 */     ClassEmitter e = new ClassEmitter(v);
/*  474 */     e.begin_class(46, 1, getClassName(), Type.getType(sc), this.useFactory ? TypeUtils.add(TypeUtils.getTypes(this.interfaces), FACTORY) : TypeUtils.getTypes(this.interfaces), "<generated>");
/*      */
/*  482 */     List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
/*      */
/*  484 */     e.declare_field(2, "CGLIB$BOUND", Type.BOOLEAN_TYPE, null, null);
/*  485 */     if (!this.interceptDuringConstruction) {
/*  486 */       e.declare_field(2, "CGLIB$CONSTRUCTED", Type.BOOLEAN_TYPE, null, null);
/*      */     }
/*  488 */     e.declare_field(26, "CGLIB$THREAD_CALLBACKS", THREAD_LOCAL, null, null);
/*  489 */     e.declare_field(26, "CGLIB$STATIC_CALLBACKS", CALLBACK_ARRAY, null, null);
/*  490 */     if (this.serialVersionUID != null) {
/*  491 */       e.declare_field(26, "serialVersionUID", Type.LONG_TYPE, this.serialVersionUID, null);
/*      */     }
/*      */
/*  494 */     for (int i = 0; i < this.callbackTypes.length; i++) {
/*  495 */       e.declare_field(2, getCallbackField(i), this.callbackTypes[i], null, null);
/*      */     }
/*      */
/*  498 */     emitMethods(e, methods, actualMethods);
/*  499 */     emitConstructors(e, constructorInfo);
/*  500 */     emitSetThreadCallbacks(e);
/*  501 */     emitSetStaticCallbacks(e);
/*  502 */     emitBindCallbacks(e);
/*      */
/*  504 */     if (this.useFactory) {
/*  505 */       int[] keys = getCallbackKeys();
/*  506 */       emitNewInstanceCallbacks(e);
/*  507 */       emitNewInstanceCallback(e);
/*  508 */       emitNewInstanceMultiarg(e, constructorInfo);
/*  509 */       emitGetCallback(e, keys);
/*  510 */       emitSetCallback(e, keys);
/*  511 */       emitGetCallbacks(e);
/*  512 */       emitSetCallbacks(e);
/*      */     }
/*      */
/*  515 */     e.end_class();
/*      */   }
/*      */
/*      */   protected void filterConstructors(Class sc, List constructors)
/*      */   {
/*  529 */     CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true));
/*  530 */     if (constructors.size() == 0)
/*  531 */       throw new IllegalArgumentException("No visible constructors in " + sc);
/*      */   }
/*      */
/*      */   protected Object firstInstance(Class type) throws Exception {
/*  535 */     if (this.classOnly) {
/*  536 */       return type;
/*      */     }
/*  538 */     return createUsingReflection(type);
/*      */   }
/*      */
/*      */   protected Object nextInstance(Object instance)
/*      */   {
/*  543 */     Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass();
/*  544 */     if (this.classOnly)
/*  545 */       return protoclass;
/*  546 */     if ((instance instanceof Factory)) {
/*  547 */       if (this.argumentTypes != null) {
/*  548 */         return ((Factory)instance).newInstance(this.argumentTypes, this.arguments, this.callbacks);
/*      */       }
/*  550 */       return ((Factory)instance).newInstance(this.callbacks);
/*      */     }
/*      */
/*  553 */     return createUsingReflection(protoclass);
/*      */   }
/*      */
/*      */   public static void registerCallbacks(Class generatedClass, Callback[] callbacks)
/*      */   {
/*  578 */     setThreadCallbacks(generatedClass, callbacks);
/*      */   }
/*      */
/*      */   public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks)
/*      */   {
/*  591 */     setCallbacksHelper(generatedClass, callbacks, "CGLIB$SET_STATIC_CALLBACKS");
/*      */   }
/*      */
/*      */   public static boolean isEnhanced(Class type)
/*      */   {
/*      */     try
/*      */     {
/*  601 */       getCallbacksSetter(type, "CGLIB$SET_THREAD_CALLBACKS");
/*  602 */       return true; } catch (NoSuchMethodException e) {
/*      */     }
/*  604 */     return false;
/*      */   }
/*      */
/*      */   private static void setThreadCallbacks(Class type, Callback[] callbacks)
/*      */   {
/*  609 */     setCallbacksHelper(type, callbacks, "CGLIB$SET_THREAD_CALLBACKS");
/*      */   }
/*      */
/*      */   private static void setCallbacksHelper(Class type, Callback[] callbacks, String methodName)
/*      */   {
/*      */     try {
/*  615 */       Method setter = getCallbacksSetter(type, methodName);
/*  616 */       setter.invoke(null, new Object[] { callbacks });
/*      */     } catch (NoSuchMethodException e) {
/*  618 */       throw new IllegalArgumentException(type + " is not an enhanced class");
/*      */     } catch (IllegalAccessException e) {
/*  620 */       throw new CodeGenerationException(e);
/*      */     } catch (InvocationTargetException e) {
/*  622 */       throw new CodeGenerationException(e);
/*      */     }
/*      */   }
/*      */
/*      */   private static Method getCallbacksSetter(Class type, String methodName) throws NoSuchMethodException {
/*  627 */     return type.getDeclaredMethod(methodName, new Class[] { new Callback[0].getClass() });
/*      */   }
/*      */
/*      */   private Object createUsingReflection(Class type) {
/*  631 */     setThreadCallbacks(type, this.callbacks);
/*      */     try
/*      */     {
/*  634 */       if (this.argumentTypes != null)
/*      */       {
/*  636 */         localObject1 = ReflectUtils.newInstance(type, this.argumentTypes, this.arguments);
/*      */         return localObject1;
/*      */       }
/*  640 */       Object localObject1 = ReflectUtils.newInstance(type);
/*      */       return localObject1; } finally { setThreadCallbacks(type, null); } throw localObject2;
/*      */   }
/*      */
/*      */   public static Object create(Class type, Callback callback)
/*      */   {
/*  657 */     Enhancer e = new Enhancer();
/*  658 */     e.setSuperclass(type);
/*  659 */     e.setCallback(callback);
/*  660 */     return e.create();
/*      */   }
/*      */
/*      */   public static Object create(Class superclass, Class[] interfaces, Callback callback)
/*      */   {
/*  672 */     Enhancer e = new Enhancer();
/*  673 */     e.setSuperclass(superclass);
/*  674 */     e.setInterfaces(interfaces);
/*  675 */     e.setCallback(callback);
/*  676 */     return e.create();
/*      */   }
/*      */
/*      */   public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks)
/*      */   {
/*  689 */     Enhancer e = new Enhancer();
/*  690 */     e.setSuperclass(superclass);
/*  691 */     e.setInterfaces(interfaces);
/*  692 */     e.setCallbackFilter(filter);
/*  693 */     e.setCallbacks(callbacks);
/*  694 */     return e.create();
/*      */   }
/*      */
/*      */   private void emitConstructors(ClassEmitter ce, List constructors) {
/*  698 */     boolean seenNull = false;
/*  699 */     for (Iterator it = constructors.iterator(); it.hasNext(); ) {
/*  700 */       MethodInfo constructor = (MethodInfo)it.next();
/*  701 */       CodeEmitter e = EmitUtils.begin_method(ce, constructor, 1);
/*  702 */       e.load_this();
/*  703 */       e.dup();
/*  704 */       e.load_args();
/*  705 */       Signature sig = constructor.getSignature();
/*  706 */       seenNull = (seenNull) || (sig.getDescriptor().equals("()V"));
/*  707 */       e.super_invoke_constructor(sig);
/*  708 */       e.invoke_static_this(BIND_CALLBACKS);
/*  709 */       if (!this.interceptDuringConstruction) {
/*  710 */         e.load_this();
/*  711 */         e.push(1);
/*  712 */         e.putfield("CGLIB$CONSTRUCTED");
/*      */       }
/*  714 */       e.return_value();
/*  715 */       e.end_method();
/*      */     }
/*  717 */     if ((!this.classOnly) && (!seenNull) && (this.arguments == null))
/*  718 */       throw new IllegalArgumentException("Superclass has no null constructors but no arguments were given");
/*      */   }
/*      */
/*      */   private int[] getCallbackKeys() {
/*  722 */     int[] keys = new int[this.callbackTypes.length];
/*  723 */     for (int i = 0; i < this.callbackTypes.length; i++) {
/*  724 */       keys[i] = i;
/*      */     }
/*  726 */     return keys;
/*      */   }
/*      */
/*      */   private void emitGetCallback(ClassEmitter ce, int[] keys) {
/*  730 */     CodeEmitter e = ce.begin_method(1, GET_CALLBACK, null, null);
/*  731 */     e.load_this();
/*  732 */     e.invoke_static_this(BIND_CALLBACKS);
/*  733 */     e.load_this();
/*  734 */     e.load_arg(0);
/*  735 */     e.process_switch(keys, new ProcessSwitchCallback(e) {
/*      */       public void processCase(int key, Label end) {
/*  737 */         this.val$e.getfield(Enhancer.access$000(key));
/*  738 */         this.val$e.goTo(end);
/*      */       }
/*      */       public void processDefault() {
/*  741 */         this.val$e.pop();
/*  742 */         this.val$e.aconst_null();
/*      */       }
/*      */     });
/*  745 */     e.return_value();
/*  746 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitSetCallback(ClassEmitter ce, int[] keys) {
/*  750 */     CodeEmitter e = ce.begin_method(1, SET_CALLBACK, null, null);
/*  751 */     e.load_this();
/*  752 */     e.load_arg(1);
/*  753 */     e.load_arg(0);
/*  754 */     e.process_switch(keys, new ProcessSwitchCallback(e) {
/*      */       public void processCase(int key, Label end) {
/*  756 */         this.val$e.checkcast(Enhancer.this.callbackTypes[key]);
/*  757 */         this.val$e.putfield(Enhancer.access$000(key));
/*  758 */         this.val$e.goTo(end);
/*      */       }
/*      */
/*      */       public void processDefault() {
/*  762 */         this.val$e.pop2();
/*      */       }
/*      */     });
/*  765 */     e.return_value();
/*  766 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitSetCallbacks(ClassEmitter ce) {
/*  770 */     CodeEmitter e = ce.begin_method(1, SET_CALLBACKS, null, null);
/*  771 */     e.load_this();
/*  772 */     e.load_arg(0);
/*  773 */     for (int i = 0; i < this.callbackTypes.length; i++) {
/*  774 */       e.dup2();
/*  775 */       e.aaload(i);
/*  776 */       e.checkcast(this.callbackTypes[i]);
/*  777 */       e.putfield(getCallbackField(i));
/*      */     }
/*  779 */     e.return_value();
/*  780 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitGetCallbacks(ClassEmitter ce) {
/*  784 */     CodeEmitter e = ce.begin_method(1, GET_CALLBACKS, null, null);
/*  785 */     e.load_this();
/*  786 */     e.invoke_static_this(BIND_CALLBACKS);
/*  787 */     e.load_this();
/*  788 */     e.push(this.callbackTypes.length);
/*  789 */     e.newarray(CALLBACK);
/*  790 */     for (int i = 0; i < this.callbackTypes.length; i++) {
/*  791 */       e.dup();
/*  792 */       e.push(i);
/*  793 */       e.load_this();
/*  794 */       e.getfield(getCallbackField(i));
/*  795 */       e.aastore();
/*      */     }
/*  797 */     e.return_value();
/*  798 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitNewInstanceCallbacks(ClassEmitter ce) {
/*  802 */     CodeEmitter e = ce.begin_method(1, NEW_INSTANCE, null, null);
/*  803 */     e.load_arg(0);
/*  804 */     e.invoke_static_this(SET_THREAD_CALLBACKS);
/*  805 */     emitCommonNewInstance(e);
/*      */   }
/*      */
/*      */   private void emitCommonNewInstance(CodeEmitter e) {
/*  809 */     e.new_instance_this();
/*  810 */     e.dup();
/*  811 */     e.invoke_constructor_this();
/*  812 */     e.aconst_null();
/*  813 */     e.invoke_static_this(SET_THREAD_CALLBACKS);
/*  814 */     e.return_value();
/*  815 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitNewInstanceCallback(ClassEmitter ce) {
/*  819 */     CodeEmitter e = ce.begin_method(1, SINGLE_NEW_INSTANCE, null, null);
/*  820 */     switch (this.callbackTypes.length)
/*      */     {
/*      */     case 0:
/*  823 */       break;
/*      */     case 1:
/*  826 */       e.push(1);
/*  827 */       e.newarray(CALLBACK);
/*  828 */       e.dup();
/*  829 */       e.push(0);
/*  830 */       e.load_arg(0);
/*  831 */       e.aastore();
/*  832 */       e.invoke_static_this(SET_THREAD_CALLBACKS);
/*  833 */       break;
/*      */     default:
/*  835 */       e.throw_exception(ILLEGAL_STATE_EXCEPTION, "More than one callback object required");
/*      */     }
/*  837 */     emitCommonNewInstance(e);
/*      */   }
/*      */
/*      */   private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
/*  841 */     CodeEmitter e = ce.begin_method(1, MULTIARG_NEW_INSTANCE, null, null);
/*  842 */     e.load_arg(2);
/*  843 */     e.invoke_static_this(SET_THREAD_CALLBACKS);
/*  844 */     e.new_instance_this();
/*  845 */     e.dup();
/*  846 */     e.load_arg(0);
/*  847 */     EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback(e) {
/*      */       public void processCase(Object key, Label end) {
/*  849 */         MethodInfo constructor = (MethodInfo)key;
/*  850 */         Type[] types = constructor.getSignature().getArgumentTypes();
/*  851 */         for (int i = 0; i < types.length; i++) {
/*  852 */           this.val$e.load_arg(1);
/*  853 */           this.val$e.push(i);
/*  854 */           this.val$e.aaload();
/*  855 */           this.val$e.unbox(types[i]);
/*      */         }
/*  857 */         this.val$e.invoke_constructor_this(constructor.getSignature());
/*  858 */         this.val$e.goTo(end);
/*      */       }
/*      */       public void processDefault() {
/*  861 */         this.val$e.throw_exception(Enhancer.ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
/*      */       }
/*      */     });
/*  864 */     e.aconst_null();
/*  865 */     e.invoke_static_this(SET_THREAD_CALLBACKS);
/*  866 */     e.return_value();
/*  867 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitMethods(ClassEmitter ce, List methods, List actualMethods) {
/*  871 */     CallbackGenerator[] generators = CallbackInfo.getGenerators(this.callbackTypes);
/*      */
/*  873 */     Map groups = new HashMap();
/*  874 */     Map indexes = new HashMap();
/*  875 */     Map originalModifiers = new HashMap();
/*  876 */     Map positions = CollectionUtils.getIndexMap(methods);
/*      */
/*  878 */     Iterator it1 = methods.iterator();
/*  879 */     Iterator it2 = actualMethods != null ? actualMethods.iterator() : null;
/*      */
/*  881 */     while (it1.hasNext()) {
/*  882 */       MethodInfo method = (MethodInfo)it1.next();
/*  883 */       Method actualMethod = it2 != null ? (Method)it2.next() : null;
/*  884 */       int index = this.filter.accept(actualMethod);
/*  885 */       if (index >= this.callbackTypes.length) {
/*  886 */         throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
/*      */       }
/*  888 */       originalModifiers.put(method, new Integer(actualMethod != null ? actualMethod.getModifiers() : method.getModifiers()));
/*  889 */       indexes.put(method, new Integer(index));
/*  890 */       List group = (List)groups.get(generators[index]);
/*  891 */       if (group == null) {
/*  892 */         groups.put(generators[index], group = new ArrayList(methods.size()));
/*      */       }
/*  894 */       group.add(method);
/*      */     }
/*      */
/*  897 */     Set seenGen = new HashSet();
/*  898 */     CodeEmitter se = ce.getStaticHook();
/*  899 */     se.new_instance(THREAD_LOCAL);
/*  900 */     se.dup();
/*  901 */     se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
/*  902 */     se.putfield("CGLIB$THREAD_CALLBACKS");
/*      */
/*  904 */     Object[] state = new Object[1];
/*  905 */     CallbackGenerator.Context context = new CallbackGenerator.Context(originalModifiers, indexes, positions) {
/*      */       public int getOriginalModifiers(MethodInfo method) {
/*  907 */         return ((Integer)this.val$originalModifiers.get(method)).intValue();
/*      */       }
/*      */       public int getIndex(MethodInfo method) {
/*  910 */         return ((Integer)this.val$indexes.get(method)).intValue();
/*      */       }
/*      */       public void emitCallback(CodeEmitter e, int index) {
/*  913 */         Enhancer.this.emitCurrentCallback(e, index);
/*      */       }
/*      */       public Signature getImplSignature(MethodInfo method) {
/*  916 */         return Enhancer.this.rename(method.getSignature(), ((Integer)this.val$positions.get(method)).intValue());
/*      */       }
/*      */       public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
/*  919 */         CodeEmitter e = EmitUtils.begin_method(ce, method);
/*  920 */         if ((!Enhancer.this.interceptDuringConstruction) && (!TypeUtils.isAbstract(method.getModifiers())))
/*      */         {
/*  922 */           Label constructed = e.make_label();
/*  923 */           e.load_this();
/*  924 */           e.getfield("CGLIB$CONSTRUCTED");
/*  925 */           e.if_jump(154, constructed);
/*  926 */           e.load_this();
/*  927 */           e.load_args();
/*  928 */           e.super_invoke();
/*  929 */           e.return_value();
/*  930 */           e.mark(constructed);
/*      */         }
/*  932 */         return e;
/*      */       }
/*      */     };
/*  935 */     for (int i = 0; i < this.callbackTypes.length; i++) {
/*  936 */       CallbackGenerator gen = generators[i];
/*  937 */       if (!seenGen.contains(gen)) {
/*  938 */         seenGen.add(gen);
/*  939 */         List fmethods = (List)groups.get(gen);
/*  940 */         if (fmethods == null) continue;
/*      */         try {
/*  942 */           gen.generate(ce, context, fmethods);
/*  943 */           gen.generateStatic(se, context, fmethods);
/*      */         } catch (RuntimeException x) {
/*  945 */           throw x;
/*      */         } catch (Exception x) {
/*  947 */           throw new CodeGenerationException(x);
/*      */         }
/*      */       }
/*      */     }
/*      */
/*  952 */     se.return_value();
/*  953 */     se.end_method();
/*      */   }
/*      */
/*      */   private void emitSetThreadCallbacks(ClassEmitter ce) {
/*  957 */     CodeEmitter e = ce.begin_method(9, SET_THREAD_CALLBACKS, null, null);
/*      */
/*  961 */     e.getfield("CGLIB$THREAD_CALLBACKS");
/*  962 */     e.load_arg(0);
/*  963 */     e.invoke_virtual(THREAD_LOCAL, THREAD_LOCAL_SET);
/*  964 */     e.return_value();
/*  965 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitSetStaticCallbacks(ClassEmitter ce) {
/*  969 */     CodeEmitter e = ce.begin_method(9, SET_STATIC_CALLBACKS, null, null);
/*      */
/*  973 */     e.load_arg(0);
/*  974 */     e.putfield("CGLIB$STATIC_CALLBACKS");
/*  975 */     e.return_value();
/*  976 */     e.end_method();
/*      */   }
/*      */
/*      */   private void emitCurrentCallback(CodeEmitter e, int index) {
/*  980 */     e.load_this();
/*  981 */     e.getfield(getCallbackField(index));
/*  982 */     e.dup();
/*  983 */     Label end = e.make_label();
/*  984 */     e.ifnonnull(end);
/*  985 */     e.pop();
/*  986 */     e.load_this();
/*  987 */     e.invoke_static_this(BIND_CALLBACKS);
/*  988 */     e.load_this();
/*  989 */     e.getfield(getCallbackField(index));
/*  990 */     e.mark(end);
/*      */   }
/*      */
/*      */   private void emitBindCallbacks(ClassEmitter ce) {
/*  994 */     CodeEmitter e = ce.begin_method(26, BIND_CALLBACKS, null, null);
/*      */
/*  998 */     Local me = e.make_local();
/*  999 */     e.load_arg(0);
/* 1000 */     e.checkcast_this();
/* 1001 */     e.store_local(me);
/*      */
/* 1003 */     Label end = e.make_label();
/* 1004 */     e.load_local(me);
/* 1005 */     e.getfield("CGLIB$BOUND");
/* 1006 */     e.if_jump(154, end);
/* 1007 */     e.load_local(me);
/* 1008 */     e.push(1);
/* 1009 */     e.putfield("CGLIB$BOUND");
/*      */
/* 1011 */     e.getfield("CGLIB$THREAD_CALLBACKS");
/* 1012 */     e.invoke_virtual(THREAD_LOCAL, THREAD_LOCAL_GET);
/* 1013 */     e.dup();
/* 1014 */     Label found_callback = e.make_label();
/* 1015 */     e.ifnonnull(found_callback);
/* 1016 */     e.pop();
/*      */
/* 1018 */     e.getfield("CGLIB$STATIC_CALLBACKS");
/* 1019 */     e.dup();
/* 1020 */     e.ifnonnull(found_callback);
/* 1021 */     e.pop();
/* 1022 */     e.goTo(end);
/*      */
/* 1024 */     e.mark(found_callback);
/* 1025 */     e.checkcast(CALLBACK_ARRAY);
/* 1026 */     e.load_local(me);
/* 1027 */     e.swap();
/* 1028 */     for (int i = this.callbackTypes.length - 1; i >= 0; i--) {
/* 1029 */       if (i != 0) {
/* 1030 */         e.dup2();
/*      */       }
/* 1032 */       e.aaload(i);
/* 1033 */       e.checkcast(this.callbackTypes[i]);
/* 1034 */       e.putfield(getCallbackField(i));
/*      */     }
/*      */
/* 1037 */     e.mark(end);
/* 1038 */     e.return_value();
/* 1039 */     e.end_method();
/*      */   }
/*      */
/*      */   private static String getCallbackField(int index) {
/* 1043 */     return "CGLIB$CALLBACK_" + index;
/*      */   }
/*      */
/*      */   public static abstract interface EnhancerKey
/*      */   {
/*      */     public abstract Object newInstance(String paramString, String[] paramArrayOfString, CallbackFilter paramCallbackFilter, Type[] paramArrayOfType, boolean paramBoolean1, boolean paramBoolean2, Long paramLong);
/*      */   }
/*      */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/thirdparty-all.jar
* Qualified Name:     net.sf.cglib.proxy.Enhancer
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of net.sf.cglib.proxy.Enhancer$EnhancerKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.