1 15 16 package javassist; 17 18 import java.io.*; 19 import javassist.bytecode.*; 20 import java.util.*; 21 import java.security.*; 22 23 29 public class SerialVersionUID { 30 31 35 public static void setSerialVersionUID(CtClass clazz) 36 throws CannotCompileException, NotFoundException 37 { 38 try { 40 clazz.getDeclaredField("serialVersionUID"); 41 return; 42 } 43 catch (NotFoundException e) {} 44 45 if (!isSerializable(clazz)) 47 return; 48 49 CtField field = new CtField(CtClass.longType, "serialVersionUID", 51 clazz); 52 field.setModifiers(Modifier.PRIVATE | Modifier.STATIC | 53 Modifier.FINAL); 54 clazz.addField(field, calculateDefault(clazz) + "L"); 55 } 56 57 60 private static boolean isSerializable(CtClass clazz) 61 throws NotFoundException 62 { 63 ClassPool pool = clazz.getClassPool(); 64 return clazz.subtypeOf(pool.get("java.io.Serializable")); 65 } 66 67 71 static long calculateDefault(CtClass clazz) 72 throws CannotCompileException 73 { 74 try { 75 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 76 DataOutputStream out = new DataOutputStream(bout); 77 ClassFile classFile = clazz.getClassFile(); 78 79 String javaName = javaName(clazz); 81 out.writeUTF(javaName); 82 83 out.writeInt(clazz.getModifiers() & (Modifier.PUBLIC | 85 Modifier.FINAL | Modifier.INTERFACE | Modifier.ABSTRACT)); 86 87 String [] interfaces = classFile.getInterfaces(); 89 for (int i = 0; i < interfaces.length; i++) 90 interfaces[i] = javaName(interfaces[i]); 91 92 Arrays.sort(interfaces); 93 for (int i = 0; i < interfaces.length; i++) 94 out.writeUTF(interfaces[i]); 95 96 CtField[] fields = clazz.getDeclaredFields(); 98 Arrays.sort(fields, new Comparator() { 99 public int compare(Object o1, Object o2) { 100 CtField field1 = (CtField)o1; 101 CtField field2 = (CtField)o2; 102 return field1.getName().compareTo(field2.getName()); 103 } 104 }); 105 106 for (int i = 0; i < fields.length; i++) { 107 CtField field = (CtField) fields[i]; 108 int mods = field.getModifiers(); 109 if (((mods & Modifier.PRIVATE) == 0) || 110 ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0)) { 111 out.writeUTF(field.getName()); 112 out.writeInt(mods); 113 out.writeUTF(field.getFieldInfo2().getDescriptor()); 114 } 115 } 116 117 if (classFile.getStaticInitializer() != null) { 119 out.writeUTF("<clinit>"); 120 out.writeInt(Modifier.STATIC); 121 out.writeUTF("()V"); 122 } 123 124 CtConstructor[] constructors = clazz.getDeclaredConstructors(); 126 Arrays.sort(constructors, new Comparator() { 127 public int compare(Object o1, Object o2) { 128 CtConstructor c1 = (CtConstructor)o1; 129 CtConstructor c2 = (CtConstructor)o2; 130 return c1.getMethodInfo2().getDescriptor().compareTo( 131 c2.getMethodInfo2().getDescriptor()); 132 } 133 }); 134 135 for (int i = 0; i < constructors.length; i++) { 136 CtConstructor constructor = constructors[i]; 137 int mods = constructor.getModifiers(); 138 if ((mods & Modifier.PRIVATE) == 0) { 139 out.writeUTF("<init>"); 140 out.writeInt(mods); 141 out.writeUTF(constructor.getMethodInfo2() 142 .getDescriptor().replace('/', '.')); 143 } 144 } 145 146 CtMethod[] methods = clazz.getDeclaredMethods(); 148 Arrays.sort(methods, new Comparator() { 149 public int compare(Object o1, Object o2) { 150 CtMethod m1 = (CtMethod)o1; 151 CtMethod m2 = (CtMethod)o2; 152 int value = m1.getName().compareTo(m2.getName()); 153 if (value == 0) 154 value = m1.getMethodInfo2().getDescriptor() 155 .compareTo(m2.getMethodInfo2().getDescriptor()); 156 157 return value; 158 } 159 }); 160 161 for (int i = 0; i < methods.length; i++) { 162 CtMethod method = methods[i]; 163 int mods = method.getModifiers(); 164 if ((mods & Modifier.PRIVATE) == 0) { 165 out.writeUTF(method.getName()); 166 out.writeInt(mods); 167 out.writeUTF(method.getMethodInfo2() 168 .getDescriptor().replace('/', '.')); 169 } 170 } 171 172 out.flush(); 174 MessageDigest digest = MessageDigest.getInstance("SHA"); 175 byte[] digested = digest.digest(bout.toByteArray()); 176 long hash = 0; 177 for (int i = Math.min(digested.length, 8) - 1; i >= 0; i--) 178 hash = (hash << 8) | (digested[i] & 0xFF); 179 180 return hash; 181 } 182 catch (IOException e) { 183 throw new CannotCompileException(e); 184 } 185 catch (NoSuchAlgorithmException e) { 186 throw new CannotCompileException(e); 187 } 188 } 189 190 private static String javaName(CtClass clazz) { 191 return Descriptor.toJavaName(Descriptor.toJvmName(clazz)); 192 } 193 194 private static String javaName(String name) { 195 return Descriptor.toJavaName(Descriptor.toJvmName(name)); 196 } 197 } 198 | Popular Tags |