1 7 8 package com.sun.corba.se.impl.presentation.rmi ; 9 10 import java.security.AccessController ; 11 import java.security.PrivilegedAction ; 12 13 import java.lang.reflect.Method ; 14 15 import java.math.BigInteger ; 16 17 import java.util.Map ; 18 import java.util.Set ; 19 import java.util.HashSet ; 20 import java.util.Iterator ; 21 import java.util.HashMap ; 22 import java.util.StringTokenizer ; 23 24 import com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ; 25 26 import com.sun.corba.se.impl.presentation.rmi.IDLType ; 27 import com.sun.corba.se.impl.presentation.rmi.IDLTypeException ; 28 import com.sun.corba.se.impl.presentation.rmi.IDLTypesUtil ; 29 import com.sun.corba.se.impl.orbutil.ObjectUtility ; 30 31 35 public class IDLNameTranslatorImpl implements IDLNameTranslator { 36 37 private static String [] IDL_KEYWORDS = { 42 43 "abstract", "any", "attribute", "boolean", "case", "char", 44 "const", "context", "custom", "default", "double", "enum", 45 "exception", "factory", "FALSE", "fixed", "float", "in", "inout", 46 "interface", "long", "module", "native", "Object", "octet", 47 "oneway", "out", "private", "public", "raises", "readonly", "sequence", 48 "short", "string", "struct", "supports", "switch", "TRUE", "truncatable", 49 "typedef", "unsigned", "union", "ValueBase", "valuetype", "void", 50 "wchar", "wstring" 51 52 }; 53 54 private static char[] HEX_DIGITS = { 55 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 56 'A', 'B', 'C', 'D', 'E', 'F' 57 }; 58 59 private static final String UNDERSCORE = "_"; 60 61 private static final String INNER_CLASS_SEPARATOR = 63 UNDERSCORE + UNDERSCORE; 64 65 private static final String [] BASE_IDL_ARRAY_MODULE_TYPE= 67 new String [] { "org", "omg", "boxedRMI" } ; 68 69 private static final String BASE_IDL_ARRAY_ELEMENT_TYPE = "seq"; 70 71 private static final String LEADING_UNDERSCORE_CHAR = "J"; 73 private static final String ID_CONTAINER_CLASH_CHAR = UNDERSCORE; 74 75 private static final String OVERLOADED_TYPE_SEPARATOR = 77 UNDERSCORE + UNDERSCORE; 78 79 private static final String ATTRIBUTE_METHOD_CLASH_MANGLE_CHARS = 81 UNDERSCORE + UNDERSCORE; 82 83 private static final String GET_ATTRIBUTE_PREFIX = "_get_"; 86 private static final String SET_ATTRIBUTE_PREFIX = "_set_"; 87 private static final String IS_ATTRIBUTE_PREFIX = "_get_"; 88 89 private static Set idlKeywords_; 90 91 static { 92 93 idlKeywords_ = new HashSet (); 94 for(int i = 0; i < IDL_KEYWORDS.length; i++) { 95 String next = (String ) IDL_KEYWORDS[i]; 96 String keywordAllCaps = next.toUpperCase(); 99 idlKeywords_.add(keywordAllCaps); 100 } 101 102 } 103 104 108 private Class [] interf_; 110 111 private Map methodToIDLNameMap_; 115 private Map IDLNameToMethodMap_; 116 private Method [] methods_; 117 118 124 public static IDLNameTranslator get( Class interf ) 125 { 126 127 return new IDLNameTranslatorImpl(new Class [] { interf } ); 128 129 } 130 131 137 public static IDLNameTranslator get( Class [] interfaces ) 138 { 139 140 return new IDLNameTranslatorImpl(interfaces ); 141 142 } 143 144 public static String getExceptionId( Class cls ) 145 { 146 IDLType itype = classToIDLType( cls ) ; 155 return itype.getExceptionName() ; 156 } 157 158 public Class [] getInterfaces() 159 { 160 return interf_; 161 } 162 163 public Method [] getMethods() 164 { 165 return methods_ ; 166 } 167 168 public Method getMethod( String idlName ) 169 { 170 return (Method ) IDLNameToMethodMap_.get(idlName); 171 } 172 173 public String getIDLName( Method method ) 174 { 175 return (String ) methodToIDLNameMap_.get(method); 176 } 177 178 184 private IDLNameTranslatorImpl(Class [] interfaces) 185 { 186 SecurityManager s = System.getSecurityManager(); 187 if (s != null) { 188 s.checkPermission(new DynamicAccessPermission("access")); 189 } 190 try { 191 IDLTypesUtil idlTypesUtil = new IDLTypesUtil(); 192 for (int ctr=0; ctr<interfaces.length; ctr++) 193 idlTypesUtil.validateRemoteInterface(interfaces[ctr]); 194 interf_ = interfaces; 195 buildNameTranslation(); 196 } catch( IDLTypeException ite) { 197 String msg = ite.getMessage(); 198 IllegalStateException ise = new IllegalStateException (msg); 199 ise.initCause(ite); 200 throw ise; 201 } 202 } 203 204 private void buildNameTranslation() 205 { 206 Map allMethodInfo = new HashMap () ; 208 209 for (int ctr=0; ctr<interf_.length; ctr++) { 210 Class interf = interf_[ctr] ; 211 212 IDLTypesUtil idlTypesUtil = new IDLTypesUtil(); 213 final Method [] methods = interf.getMethods(); 214 AccessController.doPrivileged(new PrivilegedAction () { 216 public Object run() { 217 Method.setAccessible( methods, true ) ; 218 return null ; 219 } 220 } ) ; 221 222 for(int i = 0; i < methods.length; i++) { 226 227 Method nextMethod = methods[i]; 228 229 IDLMethodInfo methodInfo = new IDLMethodInfo(); 230 231 methodInfo.method = nextMethod; 232 233 if (idlTypesUtil.isPropertyAccessorMethod(nextMethod, interf)) { 234 methodInfo.isProperty = true; 235 String attributeName = idlTypesUtil. 236 getAttributeNameForProperty(nextMethod.getName()); 237 methodInfo.originalName = attributeName; 238 methodInfo.mangledName = attributeName; 239 } else { 240 methodInfo.isProperty = false; 241 methodInfo.originalName = nextMethod.getName(); 242 methodInfo.mangledName = nextMethod.getName(); 243 } 244 245 allMethodInfo.put(nextMethod, methodInfo); 246 } 247 } 248 249 for(Iterator outerIter=allMethodInfo.values().iterator(); 257 outerIter.hasNext();) { 258 IDLMethodInfo outer = (IDLMethodInfo) outerIter.next(); 259 for(Iterator innerIter = allMethodInfo.values().iterator(); 260 innerIter.hasNext();) { 261 IDLMethodInfo inner = (IDLMethodInfo) innerIter.next(); 262 263 if( (outer != inner) && 264 (!outer.originalName.equals(inner.originalName)) && 265 outer.originalName.equalsIgnoreCase(inner.originalName) ) { 266 outer.mangledName = 267 mangleCaseSensitiveCollision(outer.originalName); 268 break; 269 } 270 271 } 272 } 273 274 for(Iterator iter = allMethodInfo.values().iterator(); 275 iter.hasNext();) { 276 IDLMethodInfo next = (IDLMethodInfo) iter.next(); 277 next.mangledName = 278 mangleIdentifier(next.mangledName, next.isProperty); 279 } 280 281 for(Iterator outerIter=allMethodInfo.values().iterator(); 285 outerIter.hasNext();) { 286 IDLMethodInfo outer = (IDLMethodInfo) outerIter.next(); 287 if( outer.isProperty ) { 288 continue; 289 } 290 for(Iterator innerIter = allMethodInfo.values().iterator(); 291 innerIter.hasNext();) { 292 IDLMethodInfo inner = (IDLMethodInfo) innerIter.next(); 293 294 if( (outer != inner) && 295 !inner.isProperty && 296 outer.originalName.equals(inner.originalName) ) { 297 outer.mangledName = mangleOverloadedMethod 298 (outer.mangledName, outer.method); 299 break; 300 } 301 } 302 } 303 304 for(Iterator outerIter=allMethodInfo.values().iterator(); 308 outerIter.hasNext();) { 309 IDLMethodInfo outer = (IDLMethodInfo) outerIter.next(); 310 if( !outer.isProperty ) { 311 continue; 312 } 313 for(Iterator innerIter = allMethodInfo.values().iterator(); 314 innerIter.hasNext();) { 315 IDLMethodInfo inner = (IDLMethodInfo) innerIter.next(); 316 if( (outer != inner) && 317 !inner.isProperty && 318 outer.mangledName.equals(inner.mangledName) ) { 319 outer.mangledName = outer.mangledName + 320 ATTRIBUTE_METHOD_CLASH_MANGLE_CHARS; 321 break; 322 } 323 } 324 } 325 326 for (int ctr=0; ctr<interf_.length; ctr++ ) { 331 Class interf = interf_[ctr] ; 332 String mappedContainerName = getMappedContainerName(interf); 333 for(Iterator iter = allMethodInfo.values().iterator(); 334 iter.hasNext();) { 335 IDLMethodInfo next = (IDLMethodInfo) iter.next(); 336 if( !next.isProperty && 337 identifierClashesWithContainer(mappedContainerName, 338 next.mangledName)) { 339 next.mangledName = mangleContainerClash(next.mangledName); 340 } 341 } 342 } 343 344 methodToIDLNameMap_ = new HashMap (); 348 IDLNameToMethodMap_ = new HashMap (); 349 methods_ = (Method [])allMethodInfo.keySet().toArray( 350 new Method [0] ) ; 351 352 for(Iterator iter = allMethodInfo.values().iterator(); 353 iter.hasNext();) { 354 IDLMethodInfo next = (IDLMethodInfo) iter.next(); 355 String idlName = next.mangledName; 356 if( next.isProperty ) { 357 String origMethodName = next.method.getName(); 358 String prefix = ""; 359 360 if( origMethodName.startsWith("get") ) { 361 prefix = GET_ATTRIBUTE_PREFIX; 362 } else if( origMethodName.startsWith("set") ) { 363 prefix = SET_ATTRIBUTE_PREFIX; 364 } else { 365 prefix = IS_ATTRIBUTE_PREFIX; 366 } 367 368 idlName = prefix + next.mangledName; 369 } 370 371 methodToIDLNameMap_.put(next.method, idlName); 372 373 if( IDLNameToMethodMap_.containsKey(idlName) ) { 379 Method clash = (Method ) IDLNameToMethodMap_.get(idlName); 381 throw new IllegalStateException ("Error : methods " + 382 clash + " and " + next.method + 383 " both result in IDL name '" + idlName + "'"); 384 } else { 385 IDLNameToMethodMap_.put(idlName, next.method); 386 } 387 } 388 389 return; 390 391 } 392 393 394 402 403 private static String mangleIdentifier(String identifier) { 404 return mangleIdentifier(identifier, false); 405 } 406 407 private static String mangleIdentifier(String identifier, boolean attribute) { 408 409 String mangledName = identifier; 410 411 if( hasLeadingUnderscore(mangledName) ) { 417 mangledName = mangleLeadingUnderscore(mangledName); 418 } 419 420 427 if( !attribute && isIDLKeyword(mangledName) ) { 428 mangledName = mangleIDLKeywordClash(mangledName); 429 } 430 431 if( !isIDLIdentifier(mangledName) ) { 436 mangledName = mangleUnicodeChars(mangledName); 437 } 438 439 return mangledName; 440 } 441 442 455 462 static boolean isIDLKeyword(String identifier) { 463 464 String identifierAllCaps = identifier.toUpperCase(); 465 466 return idlKeywords_.contains(identifierAllCaps); 467 } 468 469 static String mangleIDLKeywordClash(String identifier) { 470 return UNDERSCORE + identifier; 471 } 472 473 private static String mangleLeadingUnderscore(String identifier) { 474 return LEADING_UNDERSCORE_CHAR + identifier; 475 } 476 477 481 private static boolean hasLeadingUnderscore(String identifier) { 482 return identifier.startsWith(UNDERSCORE); 483 } 484 485 490 static String mangleUnicodeChars(String identifier) { 491 StringBuffer mangledIdentifier = new StringBuffer (); 492 493 for(int i = 0; i < identifier.length(); i++) { 494 char nextChar = identifier.charAt(i); 495 if( isIDLIdentifierChar(nextChar) ) { 496 mangledIdentifier.append(nextChar); 497 } else { 498 String unicode = charToUnicodeRepresentation(nextChar); 499 mangledIdentifier.append(unicode); 500 } 501 } 502 503 return mangledIdentifier.toString(); 504 } 505 506 519 String mangleCaseSensitiveCollision(String identifier) { 520 521 StringBuffer mangledIdentifier = new StringBuffer (identifier); 522 523 mangledIdentifier.append(UNDERSCORE); 526 527 boolean needUnderscore = false; 528 for(int i = 0; i < identifier.length(); i++) { 529 char next = identifier.charAt(i); 530 if( Character.isUpperCase(next) ) { 531 if( needUnderscore ) { 537 mangledIdentifier.append(UNDERSCORE); 538 } 539 mangledIdentifier.append(i); 540 needUnderscore = true; 541 } 542 } 543 544 return mangledIdentifier.toString(); 545 } 546 547 private static String mangleContainerClash(String identifier) { 548 return identifier + ID_CONTAINER_CLASH_CHAR; 549 } 550 551 556 private static boolean identifierClashesWithContainer 557 (String mappedContainerName, String identifier) { 558 559 return identifier.equalsIgnoreCase(mappedContainerName); 560 } 561 562 573 public static String charToUnicodeRepresentation(char c) { 574 575 int orig = (int) c; 576 StringBuffer hexString = new StringBuffer (); 577 578 int value = orig; 579 580 while( value > 0 ) { 581 int div = value / 16; 582 int mod = value % 16; 583 hexString.insert(0, HEX_DIGITS[mod]); 584 value = div; 585 } 586 587 int numZerosToAdd = 4 - hexString.length(); 588 for(int i = 0; i < numZerosToAdd; i++) { 589 hexString.insert(0, "0"); 590 } 591 592 hexString.insert(0, "U"); 593 return hexString.toString(); 594 } 595 596 private static boolean isIDLIdentifier(String identifier) { 597 598 boolean isIdentifier = true; 599 600 for(int i = 0; i < identifier.length(); i++) { 601 char nextChar = identifier.charAt(i); 602 isIdentifier = (i == 0) ? 604 isIDLAlphabeticChar(nextChar) : 605 isIDLIdentifierChar(nextChar); 606 if( !isIdentifier ) { 607 break; 608 } 609 } 610 611 return isIdentifier; 612 613 } 614 615 private static boolean isIDLIdentifierChar(char c) { 616 return (isIDLAlphabeticChar(c) || 617 isIDLDecimalDigit(c) || 618 isUnderscore(c)); 619 } 620 621 625 private static boolean isIDLAlphabeticChar(char c) { 626 627 633 boolean alphaChar = 634 ( 635 ((c >= 0x0041) && (c <= 0x005A)) 637 638 || 639 640 ((c >= 0x0061) && (c <= 0x007A)) 642 643 || 644 645 ((c >= 0x00C0) && (c <= 0x00FF) 648 && (c != 0x00D7) && (c != 0x00F7))); 649 650 return alphaChar; 651 } 652 653 657 private static boolean isIDLDecimalDigit(char c) { 658 return ( (c >= 0x0030) && (c <= 0x0039) ); 659 } 660 661 private static boolean isUnderscore(char c) { 662 return ( c == 0x005F ); 663 } 664 665 671 private static String mangleOverloadedMethod(String mangledName, Method m) { 672 673 IDLTypesUtil idlTypesUtil = new IDLTypesUtil(); 674 675 String newMangledName = mangledName + OVERLOADED_TYPE_SEPARATOR; 677 678 Class [] parameterTypes = m.getParameterTypes(); 679 680 for(int i = 0; i < parameterTypes.length; i++) { 681 Class nextParamType = parameterTypes[i]; 682 683 if( i > 0 ) { 684 newMangledName = newMangledName + OVERLOADED_TYPE_SEPARATOR; 685 } 686 IDLType idlType = classToIDLType(nextParamType); 687 688 String moduleName = idlType.getModuleName(); 689 String memberName = idlType.getMemberName(); 690 691 String typeName = (moduleName.length() > 0) ? 692 moduleName + UNDERSCORE + memberName : memberName; 693 694 if( !idlTypesUtil.isPrimitive(nextParamType) && 695 (idlTypesUtil.getSpecialCaseIDLTypeMapping(nextParamType) 696 == null) && 697 isIDLKeyword(typeName) ) { 698 typeName = mangleIDLKeywordClash(typeName); 699 } 700 701 typeName = mangleUnicodeChars(typeName); 702 703 newMangledName = newMangledName + typeName; 704 } 705 706 return newMangledName; 707 } 708 709 710 private static IDLType classToIDLType(Class c) { 711 712 IDLType idlType = null; 713 IDLTypesUtil idlTypesUtil = new IDLTypesUtil(); 714 715 if( idlTypesUtil.isPrimitive(c) ) { 716 717 idlType = idlTypesUtil.getPrimitiveIDLTypeMapping(c); 718 719 } else if( c.isArray() ) { 720 721 Class componentType = c.getComponentType(); 723 int numArrayDimensions = 1; 724 while(componentType.isArray()) { 725 componentType = componentType.getComponentType(); 726 numArrayDimensions++; 727 } 728 IDLType componentIdlType = classToIDLType(componentType); 729 730 String [] modules = BASE_IDL_ARRAY_MODULE_TYPE; 731 if( componentIdlType.hasModule() ) { 732 modules = (String [])ObjectUtility.concatenateArrays( modules, 733 componentIdlType.getModules() ) ; 734 } 735 736 String memberName = BASE_IDL_ARRAY_ELEMENT_TYPE + 737 numArrayDimensions + UNDERSCORE + 738 componentIdlType.getMemberName(); 739 740 idlType = new IDLType(c, modules, memberName); 741 742 } else { 743 idlType = idlTypesUtil.getSpecialCaseIDLTypeMapping(c); 744 745 if (idlType == null) { 746 String memberName = getUnmappedContainerName(c); 749 750 memberName = memberName.replaceAll("\\$", 752 INNER_CLASS_SEPARATOR); 753 754 if( hasLeadingUnderscore(memberName) ) { 755 memberName = mangleLeadingUnderscore(memberName); 756 } 757 758 String packageName = getPackageName(c); 762 763 if (packageName == null) { 764 idlType = new IDLType( c, memberName ) ; 765 } else { 766 if (idlTypesUtil.isEntity(c)) { 769 packageName = "org.omg.boxedIDL." + packageName ; 770 } 771 772 StringTokenizer tokenizer = 780 new StringTokenizer (packageName, "."); 781 782 String [] modules = new String [ tokenizer.countTokens() ] ; 783 int index = 0 ; 784 while (tokenizer.hasMoreElements()) { 785 String next = tokenizer.nextToken(); 786 String moreMangled = hasLeadingUnderscore( next ) ? 787 mangleLeadingUnderscore( next ) : next; 788 789 modules[index++] = moreMangled ; 790 } 791 792 idlType = new IDLType(c, modules, memberName); 793 } 794 } 795 } 796 797 return idlType; 798 } 799 800 803 private static String getPackageName(Class c) { 804 Package thePackage = c.getPackage(); 805 String packageName = null; 806 807 if( thePackage != null ) { 810 packageName = thePackage.getName(); 811 } else { 812 String fullyQualifiedClassName = c.getName(); 814 int lastDot = fullyQualifiedClassName.indexOf('.'); 815 packageName = (lastDot == -1) ? null : 816 fullyQualifiedClassName.substring(0, lastDot); 817 } 818 return packageName; 819 } 820 821 private static String getMappedContainerName(Class c) { 822 String unmappedName = getUnmappedContainerName(c); 823 824 return mangleIdentifier(unmappedName); 825 } 826 827 830 private static String getUnmappedContainerName(Class c) { 831 832 String memberName = null; 833 String packageName = getPackageName(c); 834 835 String fullyQualifiedClassName = c.getName(); 836 837 if( packageName != null ) { 838 int packageLength = packageName.length(); 839 memberName = fullyQualifiedClassName.substring(packageLength + 1); 840 } else { 841 memberName = fullyQualifiedClassName; 842 843 } 844 845 return memberName; 846 } 847 848 852 private static class IDLMethodInfo 853 { 854 public Method method; 855 public boolean isProperty; 856 857 public String originalName; 860 861 public String mangledName; 864 865 } 866 867 public String toString() { 868 869 StringBuffer contents = new StringBuffer (); 870 contents.append("IDLNameTranslator[" ); 871 for( int ctr=0; ctr<interf_.length; ctr++) { 872 if (ctr != 0) 873 contents.append( " " ) ; 874 contents.append( interf_[ctr].getName() ) ; 875 } 876 contents.append("]\n"); 877 for(Iterator iter = methodToIDLNameMap_.keySet().iterator(); 878 iter.hasNext();) { 879 880 Method method = (Method ) iter.next(); 881 String idlName = (String ) methodToIDLNameMap_.get(method); 882 883 contents.append(idlName + ":" + method + "\n"); 884 885 } 886 887 return contents.toString(); 888 } 889 890 public static void main(String [] args) { 891 892 Class remoteInterface = java.rmi.Remote .class; 893 894 if( args.length > 0 ) { 895 String className = args[0]; 896 try { 897 remoteInterface = Class.forName(className); 898 } catch(Exception e) { 899 e.printStackTrace(); 900 System.exit(-1); 901 } 902 } 903 904 System.out.println("Building name translation for " + remoteInterface); 905 try { 906 IDLNameTranslator nameTranslator = 907 IDLNameTranslatorImpl.get(remoteInterface); 908 System.out.println(nameTranslator); 909 } catch(IllegalStateException ise) { 910 ise.printStackTrace(); 911 } 912 } 913 } 914 | Popular Tags |