1 4 package com.tc.object.bytecode; 5 6 import com.tc.asm.MethodVisitor; 7 import com.tc.asm.Opcodes; 8 import com.tc.asm.Type; 9 10 import java.lang.reflect.Method ; 11 import java.util.Collections ; 12 import java.util.HashMap ; 13 import java.util.Map ; 14 15 20 public class ManagerHelperFactory { 21 private final Class managerUtilClass; 22 private final Map methods; 23 24 public ManagerHelperFactory() { 25 this.managerUtilClass = ManagerUtil.class; 26 this.methods = findMethods(); 27 } 28 29 private Map findMethods() { 30 Map map = new HashMap (); 31 32 Method [] mgrUtilMethods = this.managerUtilClass.getDeclaredMethods(); 33 34 for (int i = 0; i < mgrUtilMethods.length; i++) { 35 Method m = mgrUtilMethods[i]; 36 String name = m.getName(); 37 MethodDetail md = new MethodDetail(m); 38 39 if (map.containsKey(name)) { 40 throw new RuntimeException ("Duplicated method name [" + name + "] on interface " + managerUtilClass.getName()); 41 } else { 42 map.put(name, md); 43 } 44 } 45 46 return Collections.unmodifiableMap(map); 47 } 48 49 public ManagerHelper createHelper() { 50 return new ManagerHelperImpl(); 51 } 52 53 private static class MethodDetail implements Opcodes { 54 final String name; 55 final String desc; 56 final boolean takesManagerAsAnArg; 57 58 MethodDetail(Method m) { 59 desc = Type.getMethodDescriptor(m); 60 name = m.getName(); 61 takesManagerAsAnArg = hasManagerClass(m.getParameterTypes()); 62 } 63 64 private boolean hasManagerClass(Class [] parameterTypes) { 65 if (parameterTypes == null) return false; 66 for (int i = 0; i < parameterTypes.length; i++) { 67 if (parameterTypes[i].getName().equals(Manager.class.getName())) { return true; } 68 } 69 return false; 70 } 71 72 } 73 74 private class ManagerHelperImpl implements ManagerHelper, Opcodes { 75 public ManagerHelperImpl() { 76 } 78 79 public void callManagerMethod(String name, MethodVisitor mv) { 80 MethodDetail md = findMethodDetail(name); 81 callMethod(md, mv); 82 } 83 84 private MethodDetail findMethodDetail(String name) { 85 MethodDetail md = (MethodDetail) methods.get(name); 86 if (md == null) { 87 throw new RuntimeException ("No such method [" + name + "] on manager class: " + managerUtilClass.getName()); 89 } 90 return md; 91 } 92 93 private void callMethod(MethodDetail md, MethodVisitor mv) { 94 mv.visitMethodInsn(INVOKESTATIC, ManagerUtil.CLASS, md.name, md.desc); 97 } 98 99 } 100 101 } | Popular Tags |