1 19 package gcc.rmi.iiop; 20 21 import gcc.*; 22 import gcc.rmi.*; 23 import gcc.util.*; 24 import java.io.*; 25 import java.lang.reflect.*; 26 import java.security.*; 27 import java.util.*; 28 import org.omg.CORBA.TCKind; 29 30 35 public class ValueType 36 { 37 public static ValueType getInstance(Class forClass) 38 { 39 ValueType vt = (ValueType)_valueTypeMap.get(forClass); 40 if (vt == null) 41 { 42 synchronized (_valueTypeMap) 43 { 44 vt = (ValueType)_valueTypeMap.get(forClass); 45 if (vt == null) 46 { 47 vt = new ValueType(); 48 vt.init(forClass); 49 _valueTypeMap.put(forClass, vt); 50 } 51 } 52 } 53 return vt; 54 } 55 56 public static ValueType getInstanceByID(String id) 57 { 58 ValueType vt = (ValueType)_idTypeMap.get(id); 60 if (vt == null) 61 { 62 synchronized (_idTypeMap) 63 { 64 vt = (ValueType)_idTypeMap.get(id); 65 if (vt == null) 66 { 67 Class theClass = getClass(id); 68 vt = getInstance(theClass); 69 _idTypeMap.put(id, vt); 70 } 71 } 72 } 73 return vt; 74 } 75 76 80 public Class _class; 81 82 public gcc.rmi.iiop.ObjectHelper helper; 83 84 88 private static HashMap _valueTypeMap = new HashMap(); 89 90 private static HashMap _initMap = new HashMap(); 91 92 private static HashMap _idTypeMap = new HashMap(); 93 94 private static final boolean JDK14 = SystemUtil.isJDK14(); 95 96 private static Method _allocateNewObject; 97 98 private static Object[] _allocateNewObjectArgs; 99 100 private static Method _newInstance; 101 102 private ObjectStreamClass _objectStreamClass; 103 104 private Method _readExternal; 105 private Method _readObject; 106 private Method _readResolve; 107 private Method _writeExternal; 108 private Method _writeObject; 109 private Method _writeReplace; 110 111 115 static final int NULL_VALUE_TAG = 0; 116 static final int NO_TYPE_VALUE_TAG = 0x7fffff00; 117 static final int SINGLE_TYPE_VALUE_TAG = 0x7fffff02; 118 static final int TRUNCATABLE_NO_TYPE_VALUE_TAG = 0x7fffff08; 119 static final int TRUNCATABLE_SINGLE_TYPE_VALUE_TAG = 0x7fffff0a; 120 static final int TYPE_LIST_VALUE_TAG = 0x7fffff06; 121 static final int INDIRECTION_TAG = 0xffffffff; 122 123 static final int CASE_ARRAY = 1; 124 static final int CASE_CLASS = 2; 125 static final int CASE_IDL_ENTITY = 3; 126 static final int CASE_IDL_OBJECT = 4; 127 static final int CASE_STRING = 5; 128 129 static final ValueType OBJECT_VALUE_TYPE = getInstance(Object.class); 130 131 static final ValueType STRING_VALUE_TYPE = getInstance(String.class); 132 133 static final org.omg.CORBA.TypeCode TC_NULL = new TypeCode(TCKind.tk_null); 134 135 static TypeCode TC_ABSTRACT_BASE; 136 137 String id; 139 TypeCode tc; 140 141 ValueType parent; 142 143 ValueTypeField[] fields; 145 ValueType element; 147 boolean hasParentState; 148 boolean hasReadObject; 149 boolean hasReadOrWriteObject; 150 boolean hasWriteObject; 151 boolean hasReadResolve; 152 boolean hasWriteReplace; 153 154 boolean isAbstractInterface; 155 boolean isAny; 156 boolean isAnyOrObjectRefOrAbstractInterface; 157 boolean isArray; 158 boolean isExternalizable; 159 boolean isIDLEntity; 160 boolean isObjectRef; 161 162 int primitiveArray; 163 164 int readWriteCase; 165 166 boolean requiresCustomSerialization; 167 168 boolean skipCustomFlags; 170 174 static 175 { 176 TC_ABSTRACT_BASE = new TypeCode(TCKind.tk_abstract_interface); 177 TC_ABSTRACT_BASE.id("IDL:omg.org/CORBA/AbstractBase:1.0"); 178 TC_ABSTRACT_BASE.name(""); 179 180 try 181 { 182 if (JDK14) 183 { 184 _newInstance = java.io.ObjectStreamClass.class.getDeclaredMethod("newInstance", new Class[] {}); 185 _newInstance.setAccessible(true); 186 } 187 else 188 { 189 _allocateNewObject = java.io.ObjectInputStream.class.getDeclaredMethod("allocateNewObject", new Class[] { Class.class, Class.class }); 190 _allocateNewObject.setAccessible(true); 191 } 192 } 193 catch (Exception ex) 194 { 195 throw ExceptionUtil.getRuntimeException(ex); 196 } 197 } 198 199 203 public Object newInstance() 204 { 205 try 206 { 207 if (JDK14) 208 { 209 if (_class == Object.class) 210 { 211 return new Object(); 212 } 213 else 214 { 215 return _newInstance.invoke(_objectStreamClass, ArrayUtil.EMPTY_OBJECT_ARRAY); 216 } 217 } 218 else 219 { 220 return _allocateNewObject.invoke(null, _allocateNewObjectArgs); 221 } 222 } 223 catch (Exception ex) 224 { 225 throw ExceptionUtil.getRuntimeException(ex); 226 } 227 } 228 229 public String toString() 230 { 231 return "ValueType:" + JavaType.getName(_class); 232 } 233 234 public void readObject(Object _this, gcc.rmi.iiop.ObjectInputStream input) 235 { 236 try 237 { 238 _readObject.invoke(_this, input.thisAsObjectArray); 239 } 240 catch (Exception ex) 241 { 242 throw ExceptionUtil.getRuntimeException(ex); 243 } 244 } 245 246 public void writeObject(Object _this, gcc.rmi.iiop.ObjectOutputStream output) 247 { 248 try 249 { 250 _writeObject.invoke(_this, output.thisAsObjectArray); 251 } 252 catch (Exception ex) 253 { 254 throw ExceptionUtil.getRuntimeException(ex); 255 } 256 } 257 258 public Object readResolve(Object _this) 259 { 260 try 261 { 262 return _readResolve.invoke(_this, ArrayUtil.EMPTY_OBJECT_ARRAY); 263 } 264 catch (Exception ex) 265 { 266 throw ExceptionUtil.getRuntimeException(ex); 267 } 268 } 269 270 public Object writeReplace(Object _this) 271 { 272 try 273 { 274 return _writeReplace.invoke(_this, ArrayUtil.EMPTY_OBJECT_ARRAY); 275 } 276 catch (Exception ex) 277 { 278 throw ExceptionUtil.getRuntimeException(ex); 279 } 280 } 281 282 public void readExternal(Object _this, gcc.rmi.iiop.ObjectInputStream input) 283 { 284 try 285 { 286 _readExternal.invoke(_this, input.thisAsObjectArray); 287 } 288 catch (Exception ex) 289 { 290 throw ExceptionUtil.getRuntimeException(ex); 291 } 292 } 293 294 public void writeExternal(Object _this, gcc.rmi.iiop.ObjectOutputStream output) 295 { 296 try 297 { 298 _writeExternal.invoke(_this, output.thisAsObjectArray); 299 } 300 catch (Exception ex) 301 { 302 throw ExceptionUtil.getRuntimeException(ex); 303 } 304 } 305 306 310 protected void init(Class theClass) 311 { 312 boolean recursive = false; 313 if (_initMap.get(theClass) != null) 314 { 315 return; } 318 _initMap.put(theClass, Boolean.TRUE); 319 try 320 { 321 _class = theClass; 322 _objectStreamClass = ObjectStreamClass.lookup(_class); 323 if (org.omg.CORBA.Object.class.isAssignableFrom(theClass) 324 || javax.ejb.EJBHome.class.isAssignableFrom(theClass) 325 || javax.ejb.EJBObject.class.isAssignableFrom(theClass) 326 || java.rmi.Remote.class.isAssignableFrom(theClass)) 327 { 328 helper = ObjectRefHelper.getInstance(theClass); 329 isObjectRef = true; 330 readWriteCase = CASE_IDL_OBJECT; 331 } 332 else if (org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(theClass)) 333 { 334 helper = IDLEntityHelper.getInstance(theClass); 335 isIDLEntity = true; 336 readWriteCase = CASE_IDL_ENTITY; 337 } 338 else if (theClass == String.class) 339 { 340 helper = StringHelper.SINGLETON; 341 readWriteCase = CASE_STRING; 342 } 343 else if (theClass.isArray()) 344 { 345 Class elementClass = theClass.getComponentType(); 346 element = getInstance(elementClass); 347 isArray = true; 348 if (elementClass.isPrimitive()) 349 { 350 primitiveArray = PrimitiveType.get(elementClass); 351 helper = PrimitiveType.getArrayHelper(elementClass); 352 } 353 else 354 { 355 helper = new ArrayHelper(elementClass); 356 } 357 readWriteCase = CASE_ARRAY; 358 } 359 else if (theClass == Class.class) 360 { 361 readWriteCase = CASE_CLASS; 362 } 363 if (_allocateNewObject != null) 364 { 365 Class bc = _class; 366 while (Serializable.class.isAssignableFrom(bc) && (bc.getSuperclass() != null)) 367 { 368 bc = bc.getSuperclass(); 369 } 370 _allocateNewObjectArgs = new Object[] { _class, bc }; 371 } 372 373 isAny = _class == java.lang.Object.class 374 || _class == java.io.Externalizable.class 375 || _class == java.io.Serializable.class; 376 377 isExternalizable = java.io.Externalizable.class.isAssignableFrom(_class); 378 if (isExternalizable) 379 { 380 _readExternal = _class.getDeclaredMethod("readExternal", new Class[] { ObjectInput.class } ); 381 _writeExternal = _class.getDeclaredMethod("writeExternal", new Class[] { ObjectOutput.class } ); 382 } 383 384 if(recursive) 386 { 387 return; 388 } 389 390 391 java.lang.Class tmpClass = _class; 392 ArrayList fieldList = new ArrayList(); 393 Field[] javaFields = tmpClass.getDeclaredFields(); 394 395 Arrays.sort(javaFields, FieldComparator.SINGLETON); 397 398 int nf = javaFields.length; 401 for (int f = 0; f < nf; f++) 402 { 403 Field javaField = javaFields[f]; 404 int modifiers = javaField.getModifiers(); 405 if ((modifiers & (Modifier.STATIC | Modifier.TRANSIENT)) != 0) 406 { 407 continue; 408 } 409 if (! javaField.isAccessible()) 410 { 411 javaField.setAccessible(true); 412 } 413 ValueTypeField field = new ValueTypeField(javaField); 414 fieldList.add(field); 415 } 416 417 fields = (ValueTypeField[])fieldList.toArray(new ValueTypeField[fieldList.size()]); 418 419 Method[] methods = _class.getDeclaredMethods(); 422 int countThrowsRemoteException = 0; 423 int nm = methods.length; 424 for (int m = 0; m < nm; m++) 425 { 426 Method method = methods[m]; 427 Class[] types = method.getParameterTypes(); 428 if (types.length == 1 429 && types[0] == java.io.ObjectInputStream.class 430 && (method.getModifiers() & Modifier.PRIVATE) != 0 431 && method.getName().equals("readObject")) 432 { 433 _readObject = method; 434 if (! _readObject.isAccessible()) 435 { 436 _readObject.setAccessible(true); 437 } 438 } 439 if (types.length == 1 440 && types[0] == java.io.ObjectOutputStream.class 441 && (method.getModifiers() & Modifier.PRIVATE) != 0 442 && method.getName().equals("writeObject")) 443 { 444 _writeObject = method; 445 if (! _writeObject.isAccessible()) 446 { 447 _writeObject.setAccessible(true); 448 } 449 } 450 451 if (types.length == 0 452 && method.getReturnType() == java.lang.Object.class 453 && method.getName().equals("writeReplace")) 454 { 455 _writeReplace = method; 456 if (! _writeReplace.isAccessible()) 457 { 458 _writeReplace.setAccessible(true); 459 } 460 } 461 if (types.length == 0 462 && method.getReturnType() == java.lang.Object.class 463 && method.getName().equals("readResolve")) 464 { 465 _readResolve = method; 466 if (! _readResolve.isAccessible()) 467 { 468 _readResolve.setAccessible(true); 469 } 470 } 471 Class[] exceptions = method.getExceptionTypes(); 472 for (int i = 0; i < exceptions.length; i++) 473 { 474 Class exception = exceptions[i]; 475 if (exception.isAssignableFrom(java.rmi.RemoteException.class)) 476 { 477 countThrowsRemoteException++; 479 break; 480 } 481 } 482 } 483 484 hasReadOrWriteObject = _readObject != null || _writeObject != null; 485 hasReadObject = _readObject != null; 486 hasWriteObject = _writeObject != null; 487 hasWriteReplace = _writeReplace != null; 488 hasReadResolve = _readResolve != null; 489 490 isAbstractInterface = ! isObjectRef 491 && _class.isInterface() 492 && countThrowsRemoteException == methods.length; 493 494 Class superclass = _class.getSuperclass(); 495 if((superclass != null) && (superclass != java.lang.Object.class) && (!isIDLEntity )) 496 { 497 parent = getInstance(superclass); 498 } 499 500 hasParentState = parent != null 501 && (parent.fields.length > 0 502 || parent.isExternalizable 503 || parent.hasReadOrWriteObject 504 || parent.hasParentState); 505 506 requiresCustomSerialization = hasWriteObject || isExternalizable; 507 508 initRepositoryID(); 509 initTypeCode(); 510 511 isAnyOrObjectRefOrAbstractInterface = isAny || isObjectRef || isAbstractInterface; 512 } 513 catch (Exception ex) 514 { 515 throw ExceptionUtil.getRuntimeException(ex); 516 } 517 finally 518 { 519 if(!recursive) 520 { 521 _initMap.remove(theClass); 522 } 523 } 524 } 525 526 protected void initRepositoryID() 527 { 528 final String sixteenZeros = "0000000000000000"; 529 final int requiredLength = 16; 530 if (isAny) 531 { 532 id = "#ANY-TODO#"; 533 return; 534 } 535 if (isArray && primitiveArray != 0) 536 { 537 id = "#ARRAY-TODO#"; 538 return; 539 } 540 if (_class == String.class) 541 { 542 id = "IDL:omg.org/CORBA/WStringValue:1.0"; 543 return; 544 } 545 if (isObjectRef) 546 { 547 id = "RMI:" + _class.getName() + ":" + sixteenZeros; 548 return; 549 } 550 if (_class == java.lang.Class.class) 551 { 552 id = "RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B"; 553 return; 554 } 555 if (_class == java.math.BigInteger.class) 556 { 557 id = "RMI:java.math.BigInteger:8CAD1A3C6C0A9DF0:8CFC9F1FA93BFB1D"; 558 skipCustomFlags = true; return; 560 } 561 if (_objectStreamClass == null) 562 { 563 id = "???"; 564 return; 565 } 566 long structuralUID = computeStructuralUID(this); 567 long serialVersionUID = _objectStreamClass.getSerialVersionUID(); 568 String structuralUIDString = Long.toHexString(structuralUID).toUpperCase(); 569 String serialVersionUIDString = Long.toHexString(serialVersionUID).toUpperCase(); 570 int currentLength; 571 int lengthNeeded; 572 currentLength = structuralUIDString.length(); 573 if (currentLength < requiredLength) 574 { 575 lengthNeeded = requiredLength - currentLength; 576 structuralUIDString = sixteenZeros.substring(0, lengthNeeded) + structuralUIDString; 577 } 578 currentLength = serialVersionUIDString.length(); 579 if (currentLength < requiredLength) 580 { 581 lengthNeeded = requiredLength - currentLength; 582 serialVersionUIDString = sixteenZeros.substring(0, lengthNeeded) + serialVersionUIDString; 583 } 584 id = "RMI:" + _class.getName() + ":" + structuralUIDString + ":" + serialVersionUIDString; 585 } 586 587 protected void initTypeCode() 588 { 589 if (isObjectRef) 590 { 591 tc = new TypeCode(TCKind.tk_objref); 592 tc.id(id); 593 tc.name(""); 594 } 595 else if (isArray || isIDLEntity || _class == String.class) 596 { 597 tc = new TypeCode(TCKind.tk_value_box); 598 tc.id(id); 599 tc.name(""); 600 if (_class == String.class) 601 { 602 tc.content_type(new TypeCode(TCKind.tk_wstring)); 603 } 604 else if (isArray) 605 { 606 TypeCode seqTC = new TypeCode(TCKind.tk_sequence); 607 if (primitiveArray != 0) 608 { 609 seqTC.content_type(PrimitiveType.getTypeCode(primitiveArray)); 610 } 611 else 612 { 613 seqTC.content_type(element.tc); 614 } 615 tc.content_type(seqTC); 616 } 617 else if (isIDLEntity) 618 { 619 } 621 } 622 else 623 { 624 tc = new TypeCode(TCKind.tk_value); 625 tc.id(id); 626 tc.name(""); 627 628 if (requiresCustomSerialization) 630 { 631 tc.type_modifier((short)1); 632 } 633 else if (isAbstractInterface) 634 { 635 tc.type_modifier((short)2); 636 } 637 else 638 { 639 tc.type_modifier((short)0); 640 } 641 if (parent == null) 642 { 643 tc.concrete_base_type(TC_NULL); 644 } 645 else 646 { 647 tc.concrete_base_type(TC_NULL); 649 } 651 tc.member_count(0); 653 } 654 } 655 656 static long computeStructuralUID(ValueType vt) 657 { 658 Class c = vt._class; 659 ObjectStreamClass osc = vt._objectStreamClass; 660 ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); 661 long h = 0; 662 try 663 { 664 if (! java.io.Serializable.class.isAssignableFrom(c) 665 || c.isInterface()) 666 { 667 return 0; 668 } 669 if (java.io.Externalizable.class.isAssignableFrom(c)) 670 { 671 return 1; 672 } 673 MessageDigest md = MessageDigest.getInstance("SHA"); 674 DigestOutputStream mdo = new DigestOutputStream(devnull, md); 675 DataOutputStream data = new DataOutputStream(mdo); 676 if (vt.parent != null) 677 { 678 data.writeLong(computeStructuralUID(vt.parent)); 679 } 680 if (vt.hasWriteObject) 681 { 682 data.writeInt(2); 683 } 684 else 685 { 686 data.writeInt(1); 687 } 688 List fieldList = new ArrayList(vt.fields.length); 689 for (int i = 0; i < vt.fields.length; i++) 690 { 691 fieldList.add(vt.fields[i].javaField); 692 } 693 Field[] fields = (Field[])fieldList.toArray(new Field[fieldList.size()]); 694 Arrays.sort(fields, FieldByNameComparator.SINGLETON); 695 for (int i = 0; i < vt.fields.length; i++) 696 { 697 Field f = fields[i]; 698 data.writeUTF(f.getName()); 699 data.writeUTF(JavaClass.getSignature(f.getType())); 700 } 701 data.flush(); 702 byte[] hasharray = md.digest(); 703 for (int i = 0; i < Math.min(8, hasharray.length); i++) 704 { 705 h += (long)(hasharray[i] & 255) << (i * 8); 706 } 707 return h; 708 } 709 catch (Exception ex) 710 { 711 throw new SystemException(ex); 712 } 713 } 714 715 718 static Class getClass(String id) 719 { 720 if (id.startsWith("RMI:")) 721 { 722 int endClass = id.indexOf(':', 4); 723 if (endClass == -1) 724 { 725 throw new org.omg.CORBA.INV_IDENT(id); 726 } 727 String className = id.substring(4, endClass); 728 if (className.equals("javax.rmi.CORBA.ClassDesc")) 729 { 730 return Class.class; 731 } 732 else 733 { 734 return loadClass(className); 735 } 736 } 737 else if (id.equals("IDL:omg.org/CORBA/WStringValue:1.0")) 738 { 739 return java.lang.String.class; 740 } 741 else if (id.startsWith("IDL:omg.org/")) 742 { 743 int endClass = id.indexOf(':', 12); 744 if (endClass == -1) 745 { 746 throw new org.omg.CORBA.INV_IDENT(id); 747 } 748 String className = "org.omg" + id.substring( "IDL:omg.org".length(), endClass).replace('/', '.'); 749 return loadClass(className); 750 } 751 else if (id.startsWith("IDL:")) 752 { 753 int endClass = id.indexOf(':', 4); 754 if (endClass == -1) 755 { 756 throw new org.omg.CORBA.INV_IDENT(id); 757 } 758 String className = id.substring(4, endClass).replace('/', '.'); 759 return loadClass(className); 760 } 761 else 762 { 763 throw new org.omg.CORBA.INV_IDENT(id); 764 } 765 } 766 767 static Class loadClass(String className) 768 { 769 Class c = null; 770 771 System.out.println( "loadClass(): " + className ); 772 773 try 774 { 775 c = ClassLoader.getSystemClassLoader().loadClass ( className ); 777 } 778 catch( Exception e ) 779 { 780 e.printStackTrace(); 781 } 782 783 return c; 785 } 786 787 public static void main( String args[] ) 788 throws Exception 789 { 790 Class c = Class.forName( args[0] ); 791 ValueType vt = ValueType.getInstance( c ); 792 System.out.println( "vt = " + vt.toString() ); 793 System.out.println( "vt.id = " + vt.id ); 794 System.out.println( "vt.tc = " + vt.tc.id() ); 795 796 c = Class.forName( "org.omg.CosNaming.NameComponent"); 797 vt = ValueType.getInstance( c ); 798 System.out.println( "vt = " + vt.toString() ); 799 System.out.println( "vt.id = " + vt.id ); 800 System.out.println( "vt.tc = " + vt.tc.id() ); 801 802 c = ValueType.getClass( "RMI:mark.comps.Add:0000000000000000" ); 803 System.out.println( "c.getName() = " + c.getName() ); 804 805 c = ValueType.getClass( "RMI:org.omg.CosNaming.NameComponent:7FD3FB2290230F5E:F164A2194A66282A" ); 806 System.out.println( "c.getName() = " + c.getName() ); 807 808 c = ValueType.getClass( "IDL:omg.org/CosNaming/NameComponent:1.0"); 809 System.out.println( "c.getName() = " + c.getName() ); 810 811 c = ValueType.getClass( "RMI:mark.AddData:4165959D0B2418DD:747FE23938318E95"); 812 System.out.println( "c.getName() = " + c.getName() ); 813 } 814 } 815 | Popular Tags |