1 22 package org.jboss.iiop.rmi; 23 24 import java.io.ByteArrayOutputStream ; 25 import java.io.DataOutputStream ; 26 import java.io.Externalizable ; 27 import java.io.IOException ; 28 import java.io.ObjectOutputStream ; 29 import java.io.ObjectStreamClass ; 30 import java.io.Serializable ; 31 import java.lang.reflect.Field ; 32 import java.lang.reflect.Method ; 33 import java.lang.reflect.Modifier ; 34 import java.security.MessageDigest ; 35 import java.security.NoSuchAlgorithmException ; 36 import java.util.Collections ; 37 import java.util.Comparator ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 import java.util.SortedSet ; 41 import java.util.TreeSet ; 42 import java.util.WeakHashMap ; 43 44 import org.omg.CORBA.Any ; 45 46 55 public class Util 56 { 57 59 61 63 private static final org.jboss.logging.Logger logger = 64 org.jboss.logging.Logger.getLogger(Util.class); 65 66 70 public static String getTypeIDLName(Class cls) 71 throws RMIIIOPViolationException 72 { 73 logger.debug("getTypeIDLName " + cls); 74 75 if (cls.isPrimitive()) 76 return PrimitiveAnalysis.getPrimitiveAnalysis(cls).getIDLName(); 77 78 if (cls.isArray()) 79 { 80 Class componentClass = cls; 82 int sequence = 0; 83 while (componentClass.isArray()) 84 { 85 componentClass = componentClass.getComponentType(); 86 ++sequence; 87 } 88 89 String idlName = getTypeIDLName(componentClass); 90 int idx = idlName.lastIndexOf("::"); 91 String idlModule = idlName.substring(0, idx+2); 92 String baseName = idlName.substring(idx+2); 93 return "::org::omg::boxedRMI" + idlModule + "seq" + sequence + "_" + baseName; 94 } 95 96 if (cls == java.lang.String .class) 98 return "::CORBA::WStringValue"; 99 if (cls == java.lang.Object .class) 100 return "::java::lang::_Object"; 101 if (cls == java.lang.Class .class) 102 return "::javax::rmi::CORBA::ClassDesc"; 103 if (cls == java.io.Serializable .class) 104 return "::java::io::Serializable"; 105 if (cls == java.io.Externalizable .class) 106 return "::java::io::Externalizable"; 107 if (cls == java.rmi.Remote .class) 108 return "::java::rmi::Remote"; 109 if (cls == org.omg.CORBA.Object .class) 110 return "::CORBA::Object"; 111 112 113 if (cls.isInterface() && java.rmi.Remote .class.isAssignableFrom(cls)) { 115 InterfaceAnalysis ia = InterfaceAnalysis.getInterfaceAnalysis(cls); 116 117 return ia.getIDLModuleName() + "::" + ia.getIDLName(); 118 } 119 120 if (cls.isInterface() && 122 org.omg.CORBA.Object .class.isAssignableFrom(cls) && 123 org.omg.CORBA.portable.IDLEntity .class.isAssignableFrom(cls)) { 124 InterfaceAnalysis ia = InterfaceAnalysis.getInterfaceAnalysis(cls); 125 126 return ia.getIDLModuleName() + "::" + ia.getIDLName(); 127 } 128 129 if (Throwable .class.isAssignableFrom(cls)) { 131 if (Exception .class.isAssignableFrom(cls) && 132 !RuntimeException .class.isAssignableFrom(cls)) { 133 ExceptionAnalysis ea = ExceptionAnalysis.getExceptionAnalysis(cls); 134 135 return ea.getIDLModuleName() + "::" + ea.getIDLName(); 136 } 137 } 138 139 ValueAnalysis va = ValueAnalysis.getValueAnalysis(cls); 141 142 return va.getIDLModuleName() + "::" + va.getIDLName(); 143 } 144 145 149 public static boolean isValidRMIIIOP(Class cls) 150 throws RMIIIOPViolationException 151 { 152 if (cls.isPrimitive()) 153 return true; 154 155 if (cls.isArray()) 156 return isValidRMIIIOP(cls.getComponentType()); 157 158 if (cls == Serializable .class || cls == Externalizable .class) 160 return true; 161 162 if (cls.isInterface() && java.rmi.Remote .class.isAssignableFrom(cls)) { 164 logger.debug("Util.isValidRMIIIOP(): doing interface analysis on " + 165 cls.getName()); 166 InterfaceAnalysis.getInterfaceAnalysis(cls); 167 return true; 168 } 169 170 if (Throwable .class.isAssignableFrom(cls)) { 172 if (Exception .class.isAssignableFrom(cls) && 173 !RuntimeException .class.isAssignableFrom(cls)) { 174 logger.debug("Util.isValidRMIIIOP(): doing exception analysis on " 175 + cls.getName()); 176 ExceptionAnalysis.getExceptionAnalysis(cls); 177 } 178 return true; 179 } 180 181 if (cls == Object .class || cls == String .class || cls == Class .class) 183 return true; 184 185 logger.debug("Util.isValidRMIIIOP(): doing value analysis on " + 187 cls.getName()); 188 ValueAnalysis.getValueAnalysis(cls); 189 return true; 190 } 191 192 197 public static void insertAnyPrimitive(Any any, Object primitive) 198 { 199 Class type = primitive.getClass(); 200 201 if (type == Boolean .class) 202 any.insert_boolean(((Boolean )primitive).booleanValue()); 203 else if (type == Character .class) 204 any.insert_wchar(((Character )primitive).charValue()); 205 else if (type == Byte .class) 206 any.insert_octet(((Byte )primitive).byteValue()); 207 else if (type == Short .class) 208 any.insert_short(((Short )primitive).shortValue()); 209 else if (type == Integer .class) 210 any.insert_long(((Integer )primitive).intValue()); 211 else if (type == Long .class) 212 any.insert_longlong(((Long )primitive).longValue()); 213 else if (type == Float .class) 214 any.insert_float(((Float )primitive).floatValue()); 215 else if (type == Double .class) 216 any.insert_double(((Double )primitive).doubleValue()); 217 else 218 throw new IllegalArgumentException ("Not a primitive type: " + 219 type.getName()); 220 } 221 222 228 public static String javaToIDLName(String name) 229 { 230 if (name == null) 231 throw new IllegalArgumentException ("Null name."); 232 233 if ("".equals(name)) 234 throw new IllegalArgumentException ("Empty name."); 235 236 if (name.indexOf('.') != -1) 237 throw new IllegalArgumentException ("No qualified name allowed here."); 238 239 StringBuffer res = new StringBuffer (name.length()); 240 241 if (name.charAt(0) == '_') 242 res.append('J'); 244 for (int i = 0; i < name.length(); ++i) { 245 char c = name.charAt(i); 246 247 if (isLegalIDLIdentifierChar(c)) 248 res.append(c); 249 else res.append('U').append(toHexString((int)c)); 251 } 252 253 String s = res.toString(); 254 255 if (isReservedIDLKeyword(s)) 256 return "_" + s; 257 else 258 return s; 259 } 260 261 267 public static String getIRIdentifierOfClass(Class cls) 268 { 269 if (cls.isPrimitive()) 270 throw new IllegalArgumentException ("Primitives have no IR IDs."); 271 272 String result = (String )classIRIdentifierCache.get(cls); 273 if (result != null) 274 return result; 275 276 String name = cls.getName(); 277 StringBuffer b = new StringBuffer ("RMI:"); 278 279 for (int i = 0; i < name.length(); ++i) { 280 char c = name.charAt(i); 281 282 if (c < 256) 283 b.append(c); 284 else 285 b.append("\\U").append(toHexString((int)c)); 286 } 287 288 long clsHash = getClassHashCode(cls); 289 290 b.append(':').append(toHexString(clsHash)); 291 292 ObjectStreamClass osClass = ObjectStreamClass.lookup(cls); 293 if (osClass != null) { 294 long serialVersionUID = osClass.getSerialVersionUID(); 295 296 if (clsHash != serialVersionUID) 297 b.append(':').append(toHexString(serialVersionUID)); 298 } 299 300 result = b.toString(); 301 302 classIRIdentifierCache.put(cls, result); 303 304 return result; 305 } 306 307 308 310 313 private static Map classHashCodeCache = 314 Collections.synchronizedMap(new WeakHashMap ()); 315 316 319 private static Map classIRIdentifierCache = 320 Collections.synchronizedMap(new WeakHashMap ()); 321 322 328 private static final String [] reservedIDLKeywords = new String [] { 329 "abstract", 330 "any", 331 "attribute", 332 "boolean", 333 "case", 334 "char", 335 "const", 336 "context", 337 "custom", 338 "default", 339 "double", 340 "exception", 341 "enum", 342 "factory", 343 "FALSE", 344 "fixed", 345 "float", 346 "in", 347 "inout", 348 "interface", 349 "local", 350 "long", 351 "module", 352 "native", 353 "Object", 354 "octet", 355 "oneway", 356 "out", 357 "private", 358 "public", 359 "raises", 360 "readonly", 361 "sequence", 362 "short", 363 "string", 364 "struct", 365 "supports", 366 "switch", 367 "TRUE", 368 "truncatable", 369 "typedef", 370 "unsigned", 371 "union", 372 "ValueBase", 373 "valuetype", 374 "void", 375 "wchar", 376 "wstring" 377 }; 378 379 static { 380 classHashCodeCache = Collections.synchronizedMap(new WeakHashMap ()); 382 383 classIRIdentifierCache = Collections.synchronizedMap(new WeakHashMap ()); 384 } 385 386 389 private static String toHexString(int i) 390 { 391 String s = Integer.toHexString(i).toUpperCase(); 392 393 if (s.length() < 8) 394 return "00000000".substring(8 - s.length()) + s; 395 else 396 return s; 397 } 398 401 private static String toHexString(long l) 402 { 403 String s = Long.toHexString(l).toUpperCase(); 404 405 if (s.length() < 16) 406 return "0000000000000000".substring(16 - s.length()) + s; 407 else 408 return s; 409 } 410 411 414 private static boolean isReservedIDLKeyword(String s) 415 { 416 for (int i = 0; i < reservedIDLKeywords.length; ++i) 418 if (reservedIDLKeywords[i].equals(s)) 419 return true; 420 return false; 421 } 422 423 426 private static boolean isLegalIDLIdentifierChar(char c) 427 { 428 if (c >= 0x61 && c <= 0x7a) 429 return true; 431 if (c >= 0x30 && c <= 0x39) 432 return true; 434 if (c >= 0x41 && c <= 0x5a) 435 return true; 437 if (c == '_') 438 return true; 440 return false; 441 } 442 443 446 private static boolean isLegalIDLStartIdentifierChar(char c) 447 { 448 if (c >= 0x61 && c <= 0x7a) 449 return true; 451 if (c >= 0x41 && c <= 0x5a) 452 return true; 454 return false; 455 } 456 457 462 static long getClassHashCode(Class cls) 463 { 464 if (cls.isInterface()) 466 return 0; 467 if (!Serializable .class.isAssignableFrom(cls)) 468 return 0; 469 if (Externalizable .class.isAssignableFrom(cls)) 470 return 1; 471 472 Long l = (Long )classHashCodeCache.get(cls); 474 if (l != null) 475 return l.longValue(); 476 477 479 ByteArrayOutputStream baos = new ByteArrayOutputStream (256); 480 DataOutputStream dos = new DataOutputStream (baos); 481 482 Class superClass = cls.getSuperclass(); 484 if (superClass != null && superClass != Object .class) { 485 try { 486 dos.writeLong(getClassHashCode(superClass)); 487 } catch (IOException ex) { 488 throw new RuntimeException ("Unexpected IOException: " + ex); 489 } 490 } 491 492 boolean hasWriteObject = false; 494 try { 495 Method m; 496 int mods; 497 498 m = cls.getDeclaredMethod("writeObject", 499 new Class [] { ObjectOutputStream .class }); 500 mods = m.getModifiers(); 501 502 if (!Modifier.isPrivate(mods) && !Modifier.isStatic(mods)) 503 hasWriteObject = true; 504 } catch (NoSuchMethodException ex) { 505 } 507 try { 508 dos.writeInt(hasWriteObject ? 2 : 1); 509 } catch (IOException ex) { 510 throw new RuntimeException ("Unexpected IOException: " + ex); 511 } 512 513 Field [] fields = cls.getDeclaredFields(); 515 SortedSet set = new TreeSet (new FieldComparator()); 516 517 for (int i = 0; i < fields.length; ++i) { 518 int mods = fields[i].getModifiers(); 519 520 if (!Modifier.isStatic(mods) && !Modifier.isTransient(mods)) 521 set.add(fields[i]); 522 } 523 Iterator iter = set.iterator(); 524 try { 525 while (iter.hasNext()) { 526 Field f = (Field )iter.next(); 527 528 dos.writeUTF(f.getName()); 529 dos.writeUTF(getSignature(f.getType())); 530 } 531 } catch (IOException ex) { 532 throw new RuntimeException ("Unexpected IOException: " + ex); 533 } 534 535 try { 537 dos.flush(); 538 } catch (IOException ex) { 539 throw new RuntimeException ("Unexpected IOException: " + ex); 540 } 541 byte[] bytes = baos.toByteArray(); 542 543 MessageDigest digest; 545 try { 546 digest = MessageDigest.getInstance("SHA"); 547 } catch (NoSuchAlgorithmException ex) { 548 throw new RuntimeException ("No SHA MEssageDigest: " + ex); 549 } 550 digest.update(bytes); 551 byte[] sha = digest.digest(); 552 553 long hash = 0; 555 for (int i = 0; i < Math.min(8, sha.length); i++) { 556 hash += (long)(sha[i] & 255) << (i * 8); 557 } 558 559 classHashCodeCache.put(cls, new Long (hash)); 561 562 return hash; 563 } 564 565 569 private static String getSignature(Class cls) 570 { 571 if (cls.isArray()) 572 return "[" + cls.getComponentType(); 573 574 if (cls.isPrimitive()) { 575 if (cls == Byte.TYPE) 576 return "B"; 577 if (cls == Character.TYPE) 578 return "C"; 579 if (cls == Double.TYPE) 580 return "D"; 581 if (cls == Float.TYPE) 582 return "F"; 583 if (cls == Integer.TYPE) 584 return "I"; 585 if (cls == Long.TYPE) 586 return "J"; 587 if (cls == Short.TYPE) 588 return "S"; 589 if (cls == Boolean.TYPE) 590 return "Z"; 591 throw new RuntimeException ("Unknown primitive class."); 592 } 593 594 return "L" + cls.getName().replace('.', '/') + ";"; 595 } 596 597 601 private static String getSignature(Method method) 602 { 603 StringBuffer b = new StringBuffer ("("); 604 Class [] parameterTypes = method.getParameterTypes(); 605 606 for (int i = 0; i < parameterTypes.length; ++i) 607 b.append(getSignature(parameterTypes[i])); 608 609 b.append(')').append(getSignature(method.getReturnType())); 610 611 return b.toString(); 612 } 613 614 617 static String primitiveTypeIDLName(Class type) 618 { 619 if (type == Void.TYPE) 620 return "void"; 621 if (type == Boolean.TYPE) 622 return "boolean"; 623 if (type == Character.TYPE) 624 return "wchar"; 625 if (type == Byte.TYPE) 626 return "octet"; 627 if (type == Short.TYPE) 628 return "short"; 629 if (type == Integer.TYPE) 630 return "long"; 631 if (type == Long.TYPE) 632 return "long long"; 633 if (type == Float.TYPE) 634 return "float"; 635 if (type == Double.TYPE) 636 return "double"; 637 throw new IllegalArgumentException ("Not a primitive type."); 638 } 639 640 641 643 647 private static class FieldComparator 648 implements Comparator 649 { 650 public int compare(Object o1, Object o2) 651 { 652 if (o1 == o2) 653 return 0; 654 655 String n1 = ((Field )o1).getName(); 656 String n2 = ((Field )o2).getName(); 657 658 return n1.compareTo(n2); 659 } 660 } 661 662 } 663 | Popular Tags |