1 22 package org.jboss.aop.util; 23 24 import java.io.ByteArrayOutputStream ; 25 import java.io.DataOutputStream ; 26 import java.lang.reflect.Constructor ; 27 import java.lang.reflect.Method ; 28 import java.security.DigestOutputStream ; 29 import java.security.MessageDigest ; 30 import java.util.HashMap ; 31 import java.util.Map ; 32 import java.util.WeakHashMap ; 33 34 40 public class MethodHashing 41 { 42 44 static Map hashMap = new WeakHashMap (); 46 47 public static Method findMethodByHash(Class clazz, long hash) throws Exception 48 { 49 Method [] methods = SecurityActions.getDeclaredMethods(clazz); 50 for (int i = 0; i < methods.length; i++) 51 { 52 if (methodHash(methods[i]) == hash) return methods[i]; 53 } 54 55 if (clazz.isInterface()) 56 { 57 final Class [] interfaces = clazz.getInterfaces() ; 58 final int numInterfaces = interfaces.length ; 59 for(int count = 0 ; count < numInterfaces ; count++) 60 { 61 final Method method = findMethodByHash(interfaces[count], hash) ; 62 if (method != null) 63 { 64 return method ; 65 } 66 } 67 } 68 else if (clazz.getSuperclass() != null) 69 { 70 return findMethodByHash(clazz.getSuperclass(), hash); 71 } 72 return null; 73 } 74 75 public static Constructor findConstructorByHash(Class clazz, long hash) throws Exception 76 { 77 Constructor [] cons = SecurityActions.getDeclaredConstructors(clazz); 78 for (int i = 0; i < cons.length; i++) 79 { 80 if (constructorHash(cons[i]) == hash) return cons[i]; 81 } 82 if (clazz.getSuperclass() != null) 83 { 84 return findConstructorByHash(clazz.getSuperclass(), hash); 85 } 86 return null; 87 } 88 89 public static long methodHash(Method method) 90 throws Exception 91 { 92 Class [] parameterTypes = method.getParameterTypes(); 93 String methodDesc = method.getName()+"("; 94 for(int j = 0; j < parameterTypes.length; j++) 95 { 96 methodDesc += getTypeString(parameterTypes[j]); 97 } 98 methodDesc += ")"+getTypeString(method.getReturnType()); 99 return createHash(methodDesc); 100 } 101 102 public static long createHash(String methodDesc) 103 throws Exception 104 { 105 long hash = 0; 106 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 107 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 108 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 109 dataoutputstream.writeUTF(methodDesc); 110 dataoutputstream.flush(); 111 byte abyte0[] = messagedigest.digest(); 112 for(int j = 0; j < Math.min(8, abyte0.length); j++) 113 hash += (long)(abyte0[j] & 0xff) << j * 8; 114 return hash; 115 116 } 117 118 public static long constructorHash(Constructor method) 119 throws Exception 120 { 121 Class [] parameterTypes = method.getParameterTypes(); 122 String methodDesc = method.getName()+"("; 123 for(int j = 0; j < parameterTypes.length; j++) 124 { 125 methodDesc += getTypeString(parameterTypes[j]); 126 } 127 methodDesc += ")"; 128 129 long hash = 0; 130 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 131 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 132 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 133 dataoutputstream.writeUTF(methodDesc); 134 dataoutputstream.flush(); 135 byte abyte0[] = messagedigest.digest(); 136 for(int j = 0; j < Math.min(8, abyte0.length); j++) 137 hash += (long)(abyte0[j] & 0xff) << j * 8; 138 return hash; 139 } 140 141 147 public static Map getInterfaceHashes(Class intf) 148 { 149 Method [] methods = SecurityActions.getDeclaredMethods(intf); 151 HashMap map = new HashMap (); 152 for (int i = 0; i < methods.length; i++) 153 { 154 Method method = methods[i]; 155 try 156 { 157 long hash = methodHash(method); 158 map.put(method.toString(), new Long (hash)); 159 } 160 catch (Exception e) 161 { 162 } 163 } 164 165 return map; 166 } 167 168 static String getTypeString(Class cl) 169 { 170 if (cl == Byte.TYPE) 171 { 172 return "B"; 173 } else if (cl == Character.TYPE) 174 { 175 return "C"; 176 } else if (cl == Double.TYPE) 177 { 178 return "D"; 179 } else if (cl == Float.TYPE) 180 { 181 return "F"; 182 } else if (cl == Integer.TYPE) 183 { 184 return "I"; 185 } else if (cl == Long.TYPE) 186 { 187 return "J"; 188 } else if (cl == Short.TYPE) 189 { 190 return "S"; 191 } else if (cl == Boolean.TYPE) 192 { 193 return "Z"; 194 } else if (cl == Void.TYPE) 195 { 196 return "V"; 197 } else if (cl.isArray()) 198 { 199 return "["+getTypeString(cl.getComponentType()); 200 } else 201 { 202 return "L"+cl.getName().replace('.','/')+";"; 203 } 204 } 205 206 213 public static long calculateHash(Method method) 214 { 215 Map methodHashes = (Map )hashMap.get(method.getDeclaringClass()); 216 217 if (methodHashes == null) 218 { 219 methodHashes = getInterfaceHashes(method.getDeclaringClass()); 220 221 WeakHashMap newHashMap = new WeakHashMap (); 223 newHashMap.putAll(hashMap); 224 newHashMap.put(method.getDeclaringClass(), methodHashes); 225 hashMap = newHashMap; 226 } 227 228 return ((Long )methodHashes.get(method.toString())).longValue(); 229 } 230 231 } 232 | Popular Tags |