Package net.sf.cglib.reflect

Source Code of net.sf.cglib.reflect.FastClassEmitter$GetIndexCallback

/*     */ package net.sf.cglib.reflect;
/*     */
/*     */ import java.lang.reflect.Method;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.HashMap;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import net.sf.cglib.asm.ClassVisitor;
/*     */ import net.sf.cglib.asm.Label;
/*     */ import net.sf.cglib.asm.Type;
/*     */ import net.sf.cglib.core.Block;
/*     */ import net.sf.cglib.core.ClassEmitter;
/*     */ import net.sf.cglib.core.CodeEmitter;
/*     */ 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.MethodInfo;
/*     */ import net.sf.cglib.core.MethodInfoTransformer;
/*     */ import net.sf.cglib.core.ObjectSwitchCallback;
/*     */ import net.sf.cglib.core.ProcessSwitchCallback;
/*     */ import net.sf.cglib.core.ReflectUtils;
/*     */ import net.sf.cglib.core.Signature;
/*     */ import net.sf.cglib.core.Transformer;
/*     */ import net.sf.cglib.core.TypeUtils;
/*     */ import net.sf.cglib.core.VisibilityPredicate;
/*     */
/*     */ class FastClassEmitter extends ClassEmitter
/*     */ {
/*  26 */   private static final Signature CSTRUCT_CLASS = TypeUtils.parseConstructor("Class");
/*     */
/*  28 */   private static final Signature METHOD_GET_INDEX = TypeUtils.parseSignature("int getIndex(String, Class[])");
/*     */
/*  30 */   private static final Signature SIGNATURE_GET_INDEX = new Signature("getIndex", Type.INT_TYPE, new Type[] { Constants.TYPE_SIGNATURE });
/*     */
/*  32 */   private static final Signature TO_STRING = TypeUtils.parseSignature("String toString()");
/*     */
/*  34 */   private static final Signature CONSTRUCTOR_GET_INDEX = TypeUtils.parseSignature("int getIndex(Class[])");
/*     */
/*  36 */   private static final Signature INVOKE = TypeUtils.parseSignature("Object invoke(int, Object, Object[])");
/*     */
/*  38 */   private static final Signature NEW_INSTANCE = TypeUtils.parseSignature("Object newInstance(int, Object[])");
/*     */
/*  40 */   private static final Signature GET_MAX_INDEX = TypeUtils.parseSignature("int getMaxIndex()");
/*     */
/*  42 */   private static final Signature GET_SIGNATURE_WITHOUT_RETURN_TYPE = TypeUtils.parseSignature("String getSignatureWithoutReturnType(String, Class[])");
/*     */
/*  44 */   private static final Type FAST_CLASS = TypeUtils.parseType("net.sf.cglib.reflect.FastClass");
/*     */
/*  46 */   private static final Type ILLEGAL_ARGUMENT_EXCEPTION = TypeUtils.parseType("IllegalArgumentException");
/*     */
/*  48 */   private static final Type INVOCATION_TARGET_EXCEPTION = TypeUtils.parseType("java.lang.reflect.InvocationTargetException");
/*     */
/*  50 */   private static final Type[] INVOCATION_TARGET_EXCEPTION_ARRAY = { INVOCATION_TARGET_EXCEPTION };
/*     */   private static final int TOO_MANY_METHODS = 100;
/*     */
/*     */   public FastClassEmitter(ClassVisitor v, String className, Class type)
/*     */   {
/*  53 */     super(v);
/*     */
/*  55 */     begin_class(46, 1, className, FAST_CLASS, null, "<generated>");
/*     */
/*  58 */     CodeEmitter e = begin_method(1, CSTRUCT_CLASS, null, null);
/*  59 */     e.load_this();
/*  60 */     e.load_args();
/*  61 */     e.super_invoke_constructor(CSTRUCT_CLASS);
/*  62 */     e.return_value();
/*  63 */     e.end_method();
/*     */
/*  65 */     VisibilityPredicate vp = new VisibilityPredicate(type, false);
/*  66 */     List methods = ReflectUtils.addAllMethods(type, new ArrayList());
/*  67 */     CollectionUtils.filter(methods, vp);
/*  68 */     CollectionUtils.filter(methods, new DuplicatesPredicate());
/*  69 */     List constructors = new ArrayList(Arrays.asList(type.getDeclaredConstructors()));
/*  70 */     CollectionUtils.filter(constructors, vp);
/*     */
/*  73 */     emitIndexBySignature(methods);
/*     */
/*  76 */     emitIndexByClassArray(methods);
/*     */
/*  79 */     e = begin_method(1, CONSTRUCTOR_GET_INDEX, null, null);
/*  80 */     e.load_args();
/*  81 */     List info = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
/*  82 */     EmitUtils.constructor_switch(e, info, new GetIndexCallback(e, info));
/*  83 */     e.end_method();
/*     */
/*  86 */     e = begin_method(1, INVOKE, INVOCATION_TARGET_EXCEPTION_ARRAY, null);
/*  87 */     e.load_arg(1);
/*  88 */     e.checkcast(Type.getType(type));
/*  89 */     e.load_arg(0);
/*  90 */     invokeSwitchHelper(e, methods, 2);
/*  91 */     e.end_method();
/*     */
/*  94 */     e = begin_method(1, NEW_INSTANCE, INVOCATION_TARGET_EXCEPTION_ARRAY, null);
/*  95 */     e.new_instance(Type.getType(type));
/*  96 */     e.dup();
/*  97 */     e.load_arg(0);
/*  98 */     invokeSwitchHelper(e, constructors, 1);
/*  99 */     e.end_method();
/*     */
/* 102 */     e = begin_method(1, GET_MAX_INDEX, null, null);
/* 103 */     e.push(methods.size() - 1);
/* 104 */     e.return_value();
/* 105 */     e.end_method();
/*     */
/* 107 */     end_class();
/*     */   }
/*     */
/*     */   private void emitIndexBySignature(List methods)
/*     */   {
/* 112 */     CodeEmitter e = begin_method(1, SIGNATURE_GET_INDEX, null, null);
/* 113 */     List signatures = CollectionUtils.transform(methods, new Transformer() {
/*     */       public Object transform(Object obj) {
/* 115 */         return ReflectUtils.getSignature((Method)obj).toString();
/*     */       }
/*     */     });
/* 118 */     e.load_arg(0);
/* 119 */     e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING);
/* 120 */     signatureSwitchHelper(e, signatures);
/* 121 */     e.end_method();
/*     */   }
/*     */
/*     */   private void emitIndexByClassArray(List methods)
/*     */   {
/* 126 */     CodeEmitter e = begin_method(1, METHOD_GET_INDEX, null, null);
/* 127 */     if (methods.size() > 100)
/*     */     {
/* 129 */       List signatures = CollectionUtils.transform(methods, new Transformer() {
/*     */         public Object transform(Object obj) {
/* 131 */           String s = ReflectUtils.getSignature((Method)obj).toString();
/* 132 */           return s.substring(0, s.lastIndexOf(')') + 1);
/*     */         }
/*     */       });
/* 135 */       e.load_args();
/* 136 */       e.invoke_static(FAST_CLASS, GET_SIGNATURE_WITHOUT_RETURN_TYPE);
/* 137 */       signatureSwitchHelper(e, signatures);
/*     */     } else {
/* 139 */       e.load_args();
/* 140 */       List info = CollectionUtils.transform(methods, MethodInfoTransformer.getInstance());
/* 141 */       EmitUtils.method_switch(e, info, new GetIndexCallback(e, info));
/*     */     }
/* 143 */     e.end_method();
/*     */   }
/*     */
/*     */   private void signatureSwitchHelper(CodeEmitter e, List signatures) {
/* 147 */     ObjectSwitchCallback callback = new ObjectSwitchCallback(e, signatures)
/*     */     {
/*     */       public void processCase(Object key, Label end) {
/* 150 */         this.val$e.push(this.val$signatures.indexOf(key));
/* 151 */         this.val$e.return_value();
/*     */       }
/*     */       public void processDefault() {
/* 154 */         this.val$e.push(-1);
/* 155 */         this.val$e.return_value();
/*     */       }
/*     */     };
/* 158 */     EmitUtils.string_switch(e, (String[])signatures.toArray(new String[signatures.size()]), 1, callback);
/*     */   }
/*     */
/*     */   private static void invokeSwitchHelper(CodeEmitter e, List members, int arg)
/*     */   {
/* 165 */     List info = CollectionUtils.transform(members, MethodInfoTransformer.getInstance());
/* 166 */     Label illegalArg = e.make_label();
/* 167 */     Block block = e.begin_block();
/* 168 */     e.process_switch(getIntRange(info.size()), new ProcessSwitchCallback(info, e, arg, illegalArg) {
/*     */       public void processCase(int key, Label end) {
/* 170 */         MethodInfo method = (MethodInfo)this.val$info.get(key);
/* 171 */         Type[] types = method.getSignature().getArgumentTypes();
/* 172 */         for (int i = 0; i < types.length; i++) {
/* 173 */           this.val$e.load_arg(this.val$arg);
/* 174 */           this.val$e.aaload(i);
/* 175 */           this.val$e.unbox(types[i]);
/*     */         }
/* 177 */         this.val$e.invoke(method);
/* 178 */         if (!TypeUtils.isConstructor(method)) {
/* 179 */           this.val$e.box(method.getSignature().getReturnType());
/*     */         }
/* 181 */         this.val$e.return_value();
/*     */       }
/*     */       public void processDefault() {
/* 184 */         this.val$e.goTo(this.val$illegalArg);
/*     */       }
/*     */     });
/* 187 */     block.end();
/* 188 */     EmitUtils.wrap_throwable(block, INVOCATION_TARGET_EXCEPTION);
/* 189 */     e.mark(illegalArg);
/* 190 */     e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Cannot find matching method/constructor");
/*     */   }
/*     */
/*     */   private static int[] getIntRange(int length)
/*     */   {
/* 217 */     int[] range = new int[length];
/* 218 */     for (int i = 0; i < length; i++) {
/* 219 */       range[i] = i;
/*     */     }
/* 221 */     return range;
/*     */   }
/*     */
/*     */   private static class GetIndexCallback
/*     */     implements ObjectSwitchCallback
/*     */   {
/*     */     private CodeEmitter e;
/* 195 */     private Map indexes = new HashMap();
/*     */
/*     */     public GetIndexCallback(CodeEmitter e, List methods) {
/* 198 */       this.e = e;
/* 199 */       int index = 0;
/* 200 */       for (Iterator it = methods.iterator(); it.hasNext(); )
/* 201 */         this.indexes.put(it.next(), new Integer(index++));
/*     */     }
/*     */
/*     */     public void processCase(Object key, Label end)
/*     */     {
/* 206 */       this.e.push(((Integer)this.indexes.get(key)).intValue());
/* 207 */       this.e.return_value();
/*     */     }
/*     */
/*     */     public void processDefault() {
/* 211 */       this.e.push(-1);
/* 212 */       this.e.return_value();
/*     */     }
/*     */   }
/*     */ }

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

Related Classes of net.sf.cglib.reflect.FastClassEmitter$GetIndexCallback

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.