1 22 package org.jboss.util; 23 24 import java.io.ByteArrayOutputStream ; 25 import java.io.DataOutputStream ; 26 import java.lang.reflect.Method ; 27 import java.lang.reflect.Constructor ; 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 = clazz.getDeclaredMethods(); 50 for (int i = 0; i < methods.length; i++) 51 { 52 if (methodHash(methods[i]) == hash) return methods[i]; 53 } 54 if (clazz.getSuperclass() != null) 55 { 56 return findMethodByHash(clazz.getSuperclass(), hash); 57 } 58 return null; 59 } 60 61 public static Constructor findConstructorByHash(Class clazz, long hash) throws Exception 62 { 63 Constructor [] cons = clazz.getDeclaredConstructors(); 64 for (int i = 0; i < cons.length; i++) 65 { 66 if (constructorHash(cons[i]) == hash) return cons[i]; 67 } 68 if (clazz.getSuperclass() != null) 69 { 70 return findConstructorByHash(clazz.getSuperclass(), hash); 71 } 72 return null; 73 } 74 75 public static long methodHash(Method method) 76 throws Exception 77 { 78 Class [] parameterTypes = method.getParameterTypes(); 79 String methodDesc = method.getName()+"("; 80 for(int j = 0; j < parameterTypes.length; j++) 81 { 82 methodDesc += getTypeString(parameterTypes[j]); 83 } 84 methodDesc += ")"+getTypeString(method.getReturnType()); 85 86 long hash = 0; 87 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 88 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 89 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 90 dataoutputstream.writeUTF(methodDesc); 91 dataoutputstream.flush(); 92 byte abyte0[] = messagedigest.digest(); 93 for(int j = 0; j < Math.min(8, abyte0.length); j++) 94 hash += (long)(abyte0[j] & 0xff) << j * 8; 95 return hash; 96 } 97 98 public static long constructorHash(Constructor method) 99 throws Exception 100 { 101 Class [] parameterTypes = method.getParameterTypes(); 102 String methodDesc = method.getName()+"("; 103 for(int j = 0; j < parameterTypes.length; j++) 104 { 105 methodDesc += getTypeString(parameterTypes[j]); 106 } 107 methodDesc += ")"; 108 109 long hash = 0; 110 ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream (512); 111 MessageDigest messagedigest = MessageDigest.getInstance("SHA"); 112 DataOutputStream dataoutputstream = new DataOutputStream (new DigestOutputStream (bytearrayoutputstream, messagedigest)); 113 dataoutputstream.writeUTF(methodDesc); 114 dataoutputstream.flush(); 115 byte abyte0[] = messagedigest.digest(); 116 for(int j = 0; j < Math.min(8, abyte0.length); j++) 117 hash += (long)(abyte0[j] & 0xff) << j * 8; 118 return hash; 119 } 120 121 127 public static Map getInterfaceHashes(Class intf) 128 { 129 Method [] methods = intf.getDeclaredMethods(); 131 HashMap map = new HashMap (); 132 for (int i = 0; i < methods.length; i++) 133 { 134 Method method = methods[i]; 135 try 136 { 137 long hash = methodHash(method); 138 map.put(method.toString(), new Long (hash)); 139 } 140 catch (Exception e) 141 { 142 } 143 } 144 145 return map; 146 } 147 148 static String getTypeString(Class cl) 149 { 150 if (cl == Byte.TYPE) 151 { 152 return "B"; 153 } else if (cl == Character.TYPE) 154 { 155 return "C"; 156 } else if (cl == Double.TYPE) 157 { 158 return "D"; 159 } else if (cl == Float.TYPE) 160 { 161 return "F"; 162 } else if (cl == Integer.TYPE) 163 { 164 return "I"; 165 } else if (cl == Long.TYPE) 166 { 167 return "J"; 168 } else if (cl == Short.TYPE) 169 { 170 return "S"; 171 } else if (cl == Boolean.TYPE) 172 { 173 return "Z"; 174 } else if (cl == Void.TYPE) 175 { 176 return "V"; 177 } else if (cl.isArray()) 178 { 179 return "["+getTypeString(cl.getComponentType()); 180 } else 181 { 182 return "L"+cl.getName().replace('.','/')+";"; 183 } 184 } 185 186 193 public static long calculateHash(Method method) 194 { 195 Map methodHashes = (Map )hashMap.get(method.getDeclaringClass()); 196 197 if (methodHashes == null) 198 { 199 methodHashes = getInterfaceHashes(method.getDeclaringClass()); 200 201 WeakHashMap newHashMap = new WeakHashMap (); 203 newHashMap.putAll(hashMap); 204 newHashMap.put(method.getDeclaringClass(), methodHashes); 205 hashMap = newHashMap; 206 } 207 208 return ((Long )methodHashes.get(method.toString())).longValue(); 209 } 210 211 } 212 | Popular Tags |