1 7 8 package com.sun.corba.se.impl.orbutil; 9 10 import java.security.MessageDigest ; 12 import java.security.NoSuchAlgorithmException ; 13 import java.security.DigestOutputStream ; 14 import java.security.AccessController ; 15 import java.security.PrivilegedExceptionAction ; 16 import java.security.PrivilegedActionException ; 17 import java.security.PrivilegedAction ; 18 import java.io.DataOutputStream ; 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 22 import java.util.Arrays ; 23 import java.util.Comparator ; 24 import java.lang.reflect.Field ; 25 import java.lang.reflect.Modifier ; 26 import java.lang.reflect.Array ; 27 import java.lang.reflect.Member ; 28 import java.lang.reflect.Method ; 29 import java.lang.reflect.Constructor ; 30 31 32 import com.sun.corba.se.impl.io.ObjectStreamClass; 33 34 public final class ObjectStreamClassUtil_1_3 { 35 36 40 public static long computeSerialVersionUID(final Class cl) { 41 42 long csuid = ObjectStreamClass.getSerialVersionUID(cl); 43 if (csuid == 0) 44 return csuid; 46 csuid = (ObjectStreamClassUtil_1_3.getSerialVersion(csuid, cl).longValue()); 47 return csuid; 48 } 49 50 51 55 private static Long getSerialVersion(final long csuid, final Class cl) 56 { 57 return (Long ) AccessController.doPrivileged(new PrivilegedAction () { 58 public Object run() { 59 long suid; 60 try { 61 final Field f = cl.getDeclaredField("serialVersionUID"); 62 int mods = f.getModifiers(); 63 if (Modifier.isStatic(mods) && 64 Modifier.isFinal(mods) && Modifier.isPrivate(mods)) { 65 suid = csuid; 66 } else { 67 suid = _computeSerialVersionUID(cl); 68 } 69 } catch (NoSuchFieldException ex) { 70 suid = _computeSerialVersionUID(cl); 71 } 74 return new Long (suid); 75 } 76 }); 77 } 78 79 public static long computeStructuralUID(boolean hasWriteObject, Class cl) { 80 ByteArrayOutputStream devnull = new ByteArrayOutputStream (512); 81 82 long h = 0; 83 try { 84 85 if ((!java.io.Serializable .class.isAssignableFrom(cl)) || 86 (cl.isInterface())){ 87 return 0; 88 } 89 90 if (java.io.Externalizable .class.isAssignableFrom(cl)) { 91 return 1; 92 } 93 94 MessageDigest md = MessageDigest.getInstance("SHA"); 95 DigestOutputStream mdo = new DigestOutputStream (devnull, md); 96 DataOutputStream data = new DataOutputStream (mdo); 97 98 103 Class parent = cl.getSuperclass(); 105 if ((parent != null) && (parent != java.lang.Object .class)) { 106 boolean hasWriteObjectFlag = false; 107 Class [] args = {java.io.ObjectOutputStream .class}; 108 Method hasWriteObjectMethod = ObjectStreamClassUtil_1_3.getDeclaredMethod(parent, "writeObject", args, 109 Modifier.PRIVATE, Modifier.STATIC); 110 if (hasWriteObjectMethod != null) 111 hasWriteObjectFlag = true; 112 data.writeLong(ObjectStreamClassUtil_1_3.computeStructuralUID(hasWriteObjectFlag, parent)); 113 } 114 115 if (hasWriteObject) 116 data.writeInt(2); 117 else 118 data.writeInt(1); 119 120 121 Field [] field = ObjectStreamClassUtil_1_3.getDeclaredFields(cl); 122 Arrays.sort(field, compareMemberByName); 123 124 for (int i = 0; i < field.length; i++) { 125 Field f = field[i]; 126 127 130 int m = f.getModifiers(); 131 if (Modifier.isTransient(m) || Modifier.isStatic(m)) 132 continue; 133 134 data.writeUTF(f.getName()); 135 data.writeUTF(getSignature(f.getType())); 136 } 137 138 141 data.flush(); 142 byte hasharray[] = md.digest(); 143 int minimum = Math.min(8, hasharray.length); 144 for (int i = minimum; i > 0; i--) { 145 h += (long)(hasharray[i] & 255) << (i * 8); 146 } 147 } catch (IOException ignore) { 148 149 h = -1; 150 } catch (NoSuchAlgorithmException complain) { 151 throw new SecurityException (complain.getMessage()); 152 } 153 return h; 154 } 155 156 161 private static long _computeSerialVersionUID(Class cl) { 162 ByteArrayOutputStream devnull = new ByteArrayOutputStream (512); 163 164 long h = 0; 165 try { 166 MessageDigest md = MessageDigest.getInstance("SHA"); 167 DigestOutputStream mdo = new DigestOutputStream (devnull, md); 168 DataOutputStream data = new DataOutputStream (mdo); 169 170 171 data.writeUTF(cl.getName()); 172 173 int classaccess = cl.getModifiers(); 174 classaccess &= (Modifier.PUBLIC | Modifier.FINAL | 175 Modifier.INTERFACE | Modifier.ABSTRACT); 176 177 184 Method [] method = cl.getDeclaredMethods(); 185 if ((classaccess & Modifier.INTERFACE) != 0) { 186 classaccess &= (~Modifier.ABSTRACT); 187 if (method.length > 0) { 188 classaccess |= Modifier.ABSTRACT; 189 } 190 } 191 192 data.writeInt(classaccess); 193 194 199 if (!cl.isArray()) { 200 206 207 Class interfaces[] = cl.getInterfaces(); 208 Arrays.sort(interfaces, compareClassByName); 209 210 for (int i = 0; i < interfaces.length; i++) { 211 data.writeUTF(interfaces[i].getName()); 212 } 213 } 214 215 216 Field [] field = cl.getDeclaredFields(); 217 Arrays.sort(field, compareMemberByName); 218 219 for (int i = 0; i < field.length; i++) { 220 Field f = field[i]; 221 222 225 int m = f.getModifiers(); 226 if (Modifier.isPrivate(m) && 227 (Modifier.isTransient(m) || Modifier.isStatic(m))) 228 continue; 229 230 data.writeUTF(f.getName()); 231 data.writeInt(m); 232 data.writeUTF(getSignature(f.getType())); 233 } 234 235 if (hasStaticInitializer(cl)) { 237 data.writeUTF("<clinit>"); 238 data.writeInt(Modifier.STATIC); data.writeUTF("()V"); 240 } 241 242 247 248 MethodSignature[] constructors = 249 MethodSignature.removePrivateAndSort(cl.getDeclaredConstructors()); 250 for (int i = 0; i < constructors.length; i++) { 251 MethodSignature c = constructors[i]; 252 String mname = "<init>"; 253 String desc = c.signature; 254 desc = desc.replace('/', '.'); 255 data.writeUTF(mname); 256 data.writeInt(c.member.getModifiers()); 257 data.writeUTF(desc); 258 } 259 260 263 MethodSignature[] methods = 264 MethodSignature.removePrivateAndSort(method); 265 for (int i = 0; i < methods.length; i++ ) { 266 MethodSignature m = methods[i]; 267 String desc = m.signature; 268 desc = desc.replace('/', '.'); 269 data.writeUTF(m.member.getName()); 270 data.writeInt(m.member.getModifiers()); 271 data.writeUTF(desc); 272 } 273 274 277 data.flush(); 278 byte hasharray[] = md.digest(); 279 for (int i = 0; i < Math.min(8, hasharray.length); i++) { 280 h += (long)(hasharray[i] & 255) << (i * 8); 281 } 282 } catch (IOException ignore) { 283 284 h = -1; 285 } catch (NoSuchAlgorithmException complain) { 286 throw new SecurityException (complain.getMessage()); 287 } 288 return h; 289 } 290 291 294 private static Comparator compareClassByName = 295 new CompareClassByName(); 296 297 private static class CompareClassByName implements Comparator { 298 public int compare(Object o1, Object o2) { 299 Class c1 = (Class )o1; 300 Class c2 = (Class )o2; 301 return (c1.getName()).compareTo(c2.getName()); 302 } 303 } 304 305 308 private static Comparator compareMemberByName = 309 new CompareMemberByName(); 310 311 private static class CompareMemberByName implements Comparator { 312 public int compare(Object o1, Object o2) { 313 String s1 = ((Member )o1).getName(); 314 String s2 = ((Member )o2).getName(); 315 316 if (o1 instanceof Method ) { 317 s1 += getSignature((Method )o1); 318 s2 += getSignature((Method )o2); 319 } else if (o1 instanceof Constructor ) { 320 s1 += getSignature((Constructor )o1); 321 s2 += getSignature((Constructor )o2); 322 } 323 return s1.compareTo(s2); 324 } 325 } 326 327 330 private static String getSignature(Class clazz) { 331 String type = null; 332 if (clazz.isArray()) { 333 Class cl = clazz; 334 int dimensions = 0; 335 while (cl.isArray()) { 336 dimensions++; 337 cl = cl.getComponentType(); 338 } 339 StringBuffer sb = new StringBuffer (); 340 for (int i = 0; i < dimensions; i++) { 341 sb.append("["); 342 } 343 sb.append(getSignature(cl)); 344 type = sb.toString(); 345 } else if (clazz.isPrimitive()) { 346 if (clazz == Integer.TYPE) { 347 type = "I"; 348 } else if (clazz == Byte.TYPE) { 349 type = "B"; 350 } else if (clazz == Long.TYPE) { 351 type = "J"; 352 } else if (clazz == Float.TYPE) { 353 type = "F"; 354 } else if (clazz == Double.TYPE) { 355 type = "D"; 356 } else if (clazz == Short.TYPE) { 357 type = "S"; 358 } else if (clazz == Character.TYPE) { 359 type = "C"; 360 } else if (clazz == Boolean.TYPE) { 361 type = "Z"; 362 } else if (clazz == Void.TYPE) { 363 type = "V"; 364 } 365 } else { 366 type = "L" + clazz.getName().replace('.', '/') + ";"; 367 } 368 return type; 369 } 370 371 374 private static String getSignature(Method meth) { 375 StringBuffer sb = new StringBuffer (); 376 377 sb.append("("); 378 379 Class [] params = meth.getParameterTypes(); for (int j = 0; j < params.length; j++) { 381 sb.append(getSignature(params[j])); 382 } 383 sb.append(")"); 384 sb.append(getSignature(meth.getReturnType())); 385 return sb.toString(); 386 } 387 388 391 private static String getSignature(Constructor cons) { 392 StringBuffer sb = new StringBuffer (); 393 394 sb.append("("); 395 396 Class [] params = cons.getParameterTypes(); for (int j = 0; j < params.length; j++) { 398 sb.append(getSignature(params[j])); 399 } 400 sb.append(")V"); 401 return sb.toString(); 402 } 403 404 private static Field [] getDeclaredFields(final Class clz) { 405 return (Field []) AccessController.doPrivileged(new PrivilegedAction () { 406 public Object run() { 407 return clz.getDeclaredFields(); 408 } 409 }); 410 } 411 412 private static class MethodSignature implements Comparator { 413 Member member; 414 String signature; 416 418 420 static MethodSignature[] removePrivateAndSort(Member [] m) { 421 int numNonPrivate = 0; 422 for (int i = 0; i < m.length; i++) { 423 if (! Modifier.isPrivate(m[i].getModifiers())) { 424 numNonPrivate++; 425 } 426 } 427 MethodSignature[] cm = new MethodSignature[numNonPrivate]; 428 int cmi = 0; 429 for (int i = 0; i < m.length; i++) { 430 if (! Modifier.isPrivate(m[i].getModifiers())) { 431 cm[cmi] = new MethodSignature(m[i]); 432 cmi++; 433 } 434 } 435 if (cmi > 0) 436 Arrays.sort(cm, cm[0]); 437 return cm; 438 } 439 440 442 public int compare(Object o1, Object o2) { 443 444 if (o1 == o2) 445 return 0; 446 447 MethodSignature c1 = (MethodSignature)o1; 448 MethodSignature c2 = (MethodSignature)o2; 449 450 int result; 451 if (isConstructor()) { 452 result = c1.signature.compareTo(c2.signature); 453 } else { result = c1.member.getName().compareTo(c2.member.getName()); 455 if (result == 0) 456 result = c1.signature.compareTo(c2.signature); 457 } 458 return result; 459 } 460 461 final private boolean isConstructor() { 462 return member instanceof Constructor ; 463 } 464 private MethodSignature(Member m) { 465 member = m; 466 if (isConstructor()) { 467 signature = ObjectStreamClassUtil_1_3.getSignature((Constructor )m); 468 } else { 469 signature = ObjectStreamClassUtil_1_3.getSignature((Method )m); 470 } 471 } 472 } 473 474 475 478 private static Method hasStaticInitializerMethod = null; 479 483 private static boolean hasStaticInitializer(Class cl) { 484 if (hasStaticInitializerMethod == null) { 485 Class classWithThisMethod = null; 486 487 try { 488 try { 489 classWithThisMethod = Class.forName("sun.misc.ClassReflector"); 496 } catch (ClassNotFoundException cnfe) { 497 } 501 if (classWithThisMethod == null) 502 classWithThisMethod = java.io.ObjectStreamClass .class; 503 504 hasStaticInitializerMethod = 505 classWithThisMethod.getDeclaredMethod("hasStaticInitializer", 506 new Class [] { Class .class }); 507 } catch (NoSuchMethodException ex) { 508 } 509 510 if (hasStaticInitializerMethod == null) { 511 throw new InternalError ("Can't find hasStaticInitializer method on " 512 + classWithThisMethod.getName()); 513 } 514 hasStaticInitializerMethod.setAccessible(true); 515 } 516 try { 517 Boolean retval = (Boolean ) 518 hasStaticInitializerMethod.invoke(null, new Object [] { cl }); 519 return retval.booleanValue(); 520 } catch (Exception ex) { 521 throw new InternalError ("Error invoking hasStaticInitializer: " 522 + ex); 523 } 524 } 525 526 private static Method getDeclaredMethod(final Class cl, final String methodName, final Class [] args, 527 final int requiredModifierMask, 528 final int disallowedModifierMask) { 529 return (Method ) AccessController.doPrivileged(new PrivilegedAction () { 530 public Object run() { 531 Method method = null; 532 try { 533 method = 534 cl.getDeclaredMethod(methodName, args); 535 int mods = method.getModifiers(); 536 if ((mods & disallowedModifierMask) != 0 || 537 (mods & requiredModifierMask) != requiredModifierMask) { 538 method = null; 539 } 540 } catch (NoSuchMethodException e) { 545 } 548 return method; 549 } 550 }); 551 } 552 553 } 554 | Popular Tags |