RepositoryId.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25/* 26 * Licensed Materials - Property of IBM 27 * RMI-IIOP v1.0 28 * Copyright IBM Corp. 1998 1999 All Rights Reserved 29 * 30 */ 31 32package com.sun.corba.se.impl.util; 33 34import java.util.StringTokenizer; 35import java.util.Hashtable; 36import java.io.IOException; 37import java.lang.reflect.Method; 38 39// Imports for using codebase URL to load class 40import java.net.MalformedURLException; 41import org.omg.CORBA.portable.ValueBase; 42import org.omg.CORBA.portable.IDLEntity; 43 44//d11638 files in the same package, therefore remove their reference 45//import com.sun.corba.se.impl.util.JDKBridge; 46//import com.sun.corba.se.impl.util.IdentityHashtable; 47import com.sun.corba.se.impl.io.ObjectStreamClass; 48 49import javax.rmi.CORBA.Util; 50 51public class RepositoryId { 52 53 // Legal IDL Identifier characters (1 = legal). Note 54 // that '.' (2E) is marked as legal even though it is 55 // not legal in IDL. This allows us to treat a fully 56 // qualified Java name with '.' package separators 57 // uniformly, and is safe because that is the only 58 // legal use of '.' in a Java name. 59 60 private static final byte[] IDL_IDENTIFIER_CHARS = { 61 62 // 0 1 2 3 4 5 6 7 8 9 a b c d e f 63 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f 64 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f 65 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f 66 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f 67 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f 68 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f 69 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f 70 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f 71 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f 72 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f 73 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af 74 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf 75 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf 76 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df 77 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef 78 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff 79 }; 80 81 82 private static final long serialVersionUID = 123456789L; 83 84 private static String defaultServerURL = null; 85 private static boolean useCodebaseOnly = false; 86 87 static { 88 if (defaultServerURL == null) 89 defaultServerURL = (String)JDKBridge.getLocalCodebase(); 90 useCodebaseOnly = JDKBridge.useCodebaseOnly(); 91 92 } 93 94 private static IdentityHashtable classToRepStr = new IdentityHashtable(); 95 private static IdentityHashtable classIDLToRepStr = new IdentityHashtable(); 96 private static IdentityHashtable classSeqToRepStr = new IdentityHashtable(); 97 98 private static final IdentityHashtable repStrToByteArray = new IdentityHashtable(); 99 private static Hashtable repStrToClass = new Hashtable(); 100 101 private String repId = null; 102 private boolean isSupportedFormat = true; 103 private String typeString = null; 104 private String versionString = null; 105 private boolean isSequence = false; 106 private boolean isRMIValueType = false; 107 private boolean isIDLType = false; 108 private String completeClassName = null; 109 private String unqualifiedName = null; 110 private String definedInId = null; 111 private Class clazz = null; 112 private String suid = null, actualSuid = null; 113 private long suidLong = ObjectStreamClass.kDefaultUID, actualSuidLong = ObjectStreamClass.kDefaultUID; 114 115 // Repository ID fragments 116 private static final String kSequenceKeyword = "seq"; 117 private static final String kValuePrefix = "RMI:"; 118 private static final String kIDLPrefix = "IDL:"; 119 private static final String kIDLNamePrefix = "omg.org/"; 120 private static final String kIDLClassnamePrefix = "org.omg."; 121 private static final String kSequencePrefix = "["; 122 private static final String kCORBAPrefix = "CORBA/"; 123 private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix; 124 private static final int kValuePrefixLength = kValuePrefix.length(); 125 private static final int kIDLPrefixLength = kIDLPrefix.length(); 126 private static final int kSequencePrefixLength = kSequencePrefix.length(); 127 private static final String kInterfaceHashCode = ":0000000000000000"; 128 private static final String kInterfaceOnlyHashStr = "0000000000000000"; 129 private static final String kExternalizableHashStr = "0000000000000001"; 130 131 // Value tag utility methods and constants 132 public static final int kInitialValueTag= 0x7fffff00; 133 public static final int kNoTypeInfo = 0; 134 public static final int kSingleRepTypeInfo = 0x02; 135 public static final int kPartialListTypeInfo = 0x06; 136 public static final int kChunkedMask = 0x08; 137 public static final int kPreComputed_StandardRMIUnchunked = RepositoryId.computeValueTag(false, RepositoryId.kSingleRepTypeInfo, false); 138 public static final int kPreComputed_CodeBaseRMIUnchunked = RepositoryId.computeValueTag(true, RepositoryId.kSingleRepTypeInfo, false); 139 public static final int kPreComputed_StandardRMIChunked = RepositoryId.computeValueTag(false, RepositoryId.kSingleRepTypeInfo, true); 140 public static final int kPreComputed_CodeBaseRMIChunked = RepositoryId.computeValueTag(true, RepositoryId.kSingleRepTypeInfo, true); 141 142 public static final int kPreComputed_StandardRMIUnchunked_NoRep = RepositoryId.computeValueTag(false, RepositoryId.kNoTypeInfo, false); 143 public static final int kPreComputed_CodeBaseRMIUnchunked_NoRep = RepositoryId.computeValueTag(true, RepositoryId.kNoTypeInfo, false); 144 public static final int kPreComputed_StandardRMIChunked_NoRep = RepositoryId.computeValueTag(false, RepositoryId.kNoTypeInfo, true); 145 public static final int kPreComputed_CodeBaseRMIChunked_NoRep = RepositoryId.computeValueTag(true, RepositoryId.kNoTypeInfo, true); 146 147 // Public, well known repository IDs 148 149 // _REVISIT_ : A table structure with a good search routine for all of this 150 // would be more efficient and easier to maintain... 151 152 // String 153 public static final String kWStringValueVersion = "1.0"; 154 public static final String kWStringValueHash = ":"+kWStringValueVersion; 155 public static final String kWStringStubValue = "WStringValue"; 156 public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue; 157 public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash; 158 159 // Any 160 public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any"; 161 162 // Class 163 // Anita4: convert to uppercase 164 public static final String kClassDescValueHash = ":" + 165 Long.toHexString( 166 ObjectStreamClass.getActualSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase() + ":" + 167 Long.toHexString( 168 ObjectStreamClass.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase(); 169 public static final String kClassDescStubValue = "ClassDesc"; 170 public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue; 171 public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash; 172 173 // Object 174 public static final String kObjectValueHash = ":1.0"; 175 public static final String kObjectStubValue = "Object"; 176 177 // Sequence 178 public static final String kSequenceValueHash = ":1.0"; 179 public static final String kPrimitiveSequenceValueHash = ":0000000000000000"; 180 181 // Serializable 182 public static final String kSerializableValueHash = ":1.0"; 183 public static final String kSerializableStubValue = "Serializable"; 184 185 // Externalizable 186 public static final String kExternalizableValueHash = ":1.0"; 187 public static final String kExternalizableStubValue = "Externalizable"; 188 189 // Remote (The empty string is used for java.rmi.Remote) 190 public static final String kRemoteValueHash = ""; 191 public static final String kRemoteStubValue = ""; 192 public static final String kRemoteTypeStr = ""; 193 public static final String kRemoteValueRepID = ""; 194 195 private static final Hashtable kSpecialArrayTypeStrings = new Hashtable(); 196 197 static { 198 kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName())); 199 kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName())); 200 kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName())); 201 202 } 203 204 private static final Hashtable kSpecialCasesRepIDs = new Hashtable(); 205 206 static { 207 kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID); 208 kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID); 209 kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID); 210 } 211 212 private static final Hashtable kSpecialCasesStubValues = new Hashtable(); 213 214 static { 215 kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue); 216 kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue); 217 kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue); 218 kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue); 219 kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue); 220 kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue); 221 } 222 223 224 private static final Hashtable kSpecialCasesVersions = new Hashtable(); 225 226 static { 227 kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash); 228 kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash); 229 kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash); 230 kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash); 231 kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash); 232 kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash); 233 } 234 235 private static final Hashtable kSpecialCasesClasses = new Hashtable(); 236 237 static { 238 kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class); 239 kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class); 240 kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); 241 242 kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class); 243 kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class); 244 //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class); 245 } 246 247 private static final Hashtable kSpecialCasesArrayPrefix = new Hashtable(); 248 249 static { 250 kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); 251 kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/"); 252 kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/"); 253 kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/"); 254 kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/"); 255 kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix); 256 } 257 258 private static final Hashtable kSpecialPrimitives = new Hashtable(); 259 260 static { 261 kSpecialPrimitives.put("int","long"); 262 kSpecialPrimitives.put("long","longlong"); 263 kSpecialPrimitives.put("byte","octet"); 264 } 265 266 /** 267 * Used to convert ascii to hex. 268 */ 269 private static final byte ASCII_HEX[] = { 270 (byte)'0', 271 (byte)'1', 272 (byte)'2', 273 (byte)'3', 274 (byte)'4', 275 (byte)'5', 276 (byte)'6', 277 (byte)'7', 278 (byte)'8', 279 (byte)'9', 280 (byte)'A', 281 (byte)'B', 282 (byte)'C', 283 (byte)'D', 284 (byte)'E', 285 (byte)'F', 286 }; 287 288 289 // bug fix for 4328952; to eliminate possibility of overriding this 290 // in a subclass. 291 public static final RepositoryIdCache cache = new RepositoryIdCache(); 292 293 // Interface Rep ID Strings 294 public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class); 295 public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class); 296 297 // Dummy arguments for getIdFromHelper method 298 public static final Class kNoParamTypes[] ={}; 299 public static final Object kNoArgs[] = {}; 300 301 302 // To create a RepositoryID, use code similar to the following: 303 // RepositoryId.cache.getId( id ); 304 305 RepositoryId(){} 306 307 RepositoryId(String aRepId){ 308 init(aRepId); 309 } 310 311 RepositoryId init(String aRepId) 312 { 313 this.repId = aRepId; 314 315 // Special case for remote 316 if (aRepId.length() == 0) { 317 clazz = java.rmi.Remote.class; 318 typeString = ""; 319 isRMIValueType = true; 320 suid = kInterfaceOnlyHashStr; 321 return this; 322 } else if (aRepId.equals(kWStringValueRepID)) { 323 clazz = java.lang.String.class; 324 typeString = kWStringTypeStr; 325 isIDLType = true; 326 // fix where Attempting to obtain a FullValueDescription 327 // for an RMI value type with a String field causes an exception. 328 completeClassName = "java.lang.String"; 329 versionString = kWStringValueVersion; 330 return this; 331 } else { 332 String repId = convertFromISOLatin1(aRepId); 333 334 int firstIndex = repId.indexOf(':') ; 335 if (firstIndex == -1) 336 throw new IllegalArgumentException( "RepsitoryId must have the form <type>:<body>" ) ; 337 int secondIndex = repId.indexOf( ':', firstIndex + 1 ) ; 338 339 if (secondIndex == -1) 340 versionString = "" ; 341 else 342 versionString = repId.substring(secondIndex) ; 343 344 if (repId.startsWith(kIDLPrefix)) { 345 typeString = 346 repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength)); 347 isIDLType = true; 348 349 if (typeString.startsWith(kIDLNamePrefix)) 350 completeClassName = kIDLClassnamePrefix + 351 typeString.substring(kIDLNamePrefix.length()).replace('/','.'); 352 else 353 completeClassName = typeString.replace('/','.'); 354 355 } else if (repId.startsWith(kValuePrefix)) { 356 typeString = 357 repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength)); 358 isRMIValueType = true; 359 360 if (versionString.indexOf('.') == -1) { 361 actualSuid = versionString.substring(1); 362 suid = actualSuid; // default if not explicitly specified 363 364 if (actualSuid.indexOf(':') != -1){ 365 // we have a declared hash also 366 int pos = actualSuid.indexOf(':')+1; 367 // actualSuid = suid.substring(pos); 368 // suid = suid.substring(0, pos-1); 369 suid = actualSuid.substring(pos); 370 actualSuid = actualSuid.substring(0, pos-1); 371 } 372 } else { 373 // _REVISIT_ : Special case version failure ? 374 } 375 } else { 376 isSupportedFormat = false; 377 typeString = "" ; 378 } 379 380 if (typeString.startsWith(kSequencePrefix)) { 381 isSequence = true; 382 } 383 384 return this; 385 } 386 } 387 388 public final String getUnqualifiedName() { 389 if (unqualifiedName == null){ 390 String className = getClassName(); 391 int index = className.lastIndexOf('.'); 392 if (index == -1){ 393 unqualifiedName = className; 394 definedInId = "IDL::1.0"; 395 } 396 else { 397 unqualifiedName = className.substring(index); 398 definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0"; 399 } 400 } 401 402 return unqualifiedName; 403 } 404 405 public final String getDefinedInId() { 406 if (definedInId == null){ 407 getUnqualifiedName(); 408 } 409 410 return definedInId; 411 } 412 413 public final String getTypeString() { 414 return typeString; 415 } 416 417 public final String getVersionString() { 418 return versionString; 419 } 420 421 public final String getSerialVersionUID() { 422 return suid; 423 } 424 425 public final String getActualSerialVersionUID() { 426 return actualSuid; 427 } 428 public final long getSerialVersionUIDAsLong() { 429 return suidLong; 430 } 431 432 public final long getActualSerialVersionUIDAsLong() { 433 return actualSuidLong; 434 } 435 436 public final boolean isRMIValueType() { 437 return isRMIValueType; 438 } 439 440 public final boolean isIDLType() { 441 return isIDLType; 442 } 443 444 public final String getRepositoryId() { 445 return repId; 446 } 447 448 public static byte[] getByteArray(String repStr) { 449 synchronized (repStrToByteArray){ 450 return (byte[]) repStrToByteArray.get(repStr); 451 } 452 } 453 454 public static void setByteArray(String repStr, byte[] repStrBytes) { 455 synchronized (repStrToByteArray){ 456 repStrToByteArray.put(repStr, repStrBytes); 457 } 458 } 459 460 public final boolean isSequence() { 461 return isSequence; 462 } 463 464 public final boolean isSupportedFormat() { 465 return isSupportedFormat; 466 } 467 468 469 // This method will return the classname from the typestring OR if the classname turns out to be 470 // a special class "pseudo" name, then the matching real classname is returned. 471 public final String getClassName() { 472 473 if (isRMIValueType) 474 return typeString; 475 else if (isIDLType) 476 return completeClassName; 477 else return null; 478 479 } 480 481 // This method calls getClazzFromType() and falls back to the repStrToClass 482 // cache if no class was found. It's used where any class matching the 483 // given repid is an acceptable result. 484 public final Class getAnyClassFromType() throws ClassNotFoundException { 485 try { 486 return getClassFromType(); 487 } catch (ClassNotFoundException cnfe) { 488 Class clz = (Class)repStrToClass.get(repId); 489 if (clz != null) 490 return clz; 491 else 492 throw cnfe; 493 } 494 } 495 496 public final Class getClassFromType() 497 throws ClassNotFoundException { 498 if (clazz != null) 499 return clazz; 500 501 Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); 502 503 if (specialCase != null){ 504 clazz = specialCase; 505 return specialCase; 506 } 507 else 508 { 509 try{ 510 return Util.loadClass(getClassName(), null, null); 511 } 512 catch(ClassNotFoundException cnfe){ 513 if (defaultServerURL != null) { 514 try{ 515 return getClassFromType(defaultServerURL); 516 } 517 catch(MalformedURLException mue){ 518 throw cnfe; 519 } 520 } 521 else throw cnfe; 522 } 523 } 524 525 } 526 527 public final Class getClassFromType(Class expectedType, String codebase) 528 throws ClassNotFoundException { 529 if (clazz != null) 530 return clazz; 531 532 Class specialCase = (Class)kSpecialCasesClasses.get(getClassName()); 533 534 if (specialCase != null){ 535 clazz = specialCase; 536 return specialCase; 537 } else { 538 ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader()); 539 return Utility.loadClassOfType(getClassName(), 540 codebase, 541 expectedTypeClassLoader, 542 expectedType, 543 expectedTypeClassLoader); 544 } 545 546 } 547 548 public final Class getClassFromType(String url) 549 throws ClassNotFoundException, MalformedURLException { 550 return Util.loadClass(getClassName(), url, null); 551 } 552 553 public final String toString() { 554 return repId; 555 } 556 557 /** 558 * Checks to see if the FullValueDescription should be retrieved. 559 * @exception Throws IOException if suids do not match or if the repositoryID 560 * is not an RMIValueType 561 */ 562 public static boolean useFullValueDescription(Class clazz, String repositoryID) 563 throws IOException{ 564 565 String clazzRepIDStr = createForAnyType(clazz); 566 567 if (clazzRepIDStr.equals(repositoryID)) 568 return false; 569 570 RepositoryId targetRepid; 571 RepositoryId clazzRepid; 572 573 synchronized(cache) { 574 // to avoid race condition where multiple threads could be 575 // accessing this method, and their access to the cache may 576 // be interleaved giving unexpected results 577 578 targetRepid = cache.getId(repositoryID); 579 clazzRepid = cache.getId(clazzRepIDStr); 580 } 581 //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); 582 583 if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){ 584 if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) { 585 586 String mssg = "Mismatched serialization UIDs : Source (Rep. ID" + 587 clazzRepid + ") = " + 588 clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID + 589 ") = " + targetRepid.getSerialVersionUID(); 590 //com.sun.corba.se.impl.io.ValueUtility.log("RepositoryId",mssg); 591 throw new IOException(mssg); 592 } 593 else { 594 return true; 595 } 596 } 597 else { 598 599 throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")"); 600 } 601 } 602 603 private static String createHashString(java.io.Serializable ser) { 604 605 return createHashString(ser.getClass()); 606 } 607 608 private static String createHashString(java.lang.Class clazz) { 609 610 if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz)) 611 return kInterfaceHashCode; 612 613 //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); 614 615 long actualLong = ObjectStreamClass.getActualSerialVersionUID(clazz); 616 String hash = null; 617 if (actualLong == 0) 618 hash = kInterfaceOnlyHashStr; 619 else if (actualLong == 1) 620 hash = kExternalizableHashStr; 621 else 622 hash = Long.toHexString(actualLong).toUpperCase(); 623 while(hash.length() < 16){ 624 hash = "0" + hash; 625 } 626 627 long declaredLong = ObjectStreamClass.getSerialVersionUID(clazz); 628 String declared = null; 629 if (declaredLong == 0) 630 declared = kInterfaceOnlyHashStr; 631 else if (declaredLong == 1) 632 declared = kExternalizableHashStr; 633 else 634 declared = Long.toHexString(declaredLong).toUpperCase(); 635 while (declared.length() < 16){ 636 declared = "0" + declared; 637 } 638 hash = hash + ":" + declared; 639 640 return ":" + hash; 641 } 642 643 /** 644 * Creates a repository ID for a sequence. This is for expert users only as 645 * this method assumes the object passed is an array. If passed an object 646 * that is not an array, it will produce a rep id for a sequence of zero 647 * length. This would be an error. 648 * @param ser The Java object to create a repository ID for 649 **/ 650 public static String createSequenceRepID(java.lang.Object ser){ 651 return createSequenceRepID(ser.getClass()); 652 } 653 654 /** 655 * Creates a repository ID for a sequence. This is for expert users only as 656 * this method assumes the object passed is an array. If passed an object 657 * that is not an array, it will produce a malformed rep id. 658 * @param clazz The Java class to create a repository ID for 659 **/ 660 public static String createSequenceRepID(java.lang.Class clazz){ 661 synchronized (classSeqToRepStr){ 662 663 String repid = (String)classSeqToRepStr.get(clazz); 664 if (repid != null) 665 return repid; 666 667 Class originalClazz = clazz; 668 669 Class type = null; 670 int numOfDims = 0; 671 672 while ((type = clazz.getComponentType()) != null) { 673 numOfDims++; 674 clazz = type; 675 } 676 677 if (clazz.isPrimitive()) 678 repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash; 679 else { 680 StringBuffer buf = new StringBuffer(); 681 buf.append(kValuePrefix); 682 while(numOfDims-- > 0) { 683 buf.append("["); 684 } 685 buf.append("L"); 686 buf.append(convertToISOLatin1(clazz.getName())); 687 buf.append(";"); 688 buf.append(createHashString(clazz)); 689 repid = buf.toString(); 690 } 691 classSeqToRepStr.put(originalClazz,repid); 692 return repid; 693 } 694 695 } 696 697 698 public static String createForSpecialCase(java.lang.Class clazz){ 699 if (clazz.isArray()){ 700 return createSequenceRepID(clazz); 701 } 702 else { 703 return (String)kSpecialCasesRepIDs.get(clazz); 704 } 705 } 706 707 public static String createForSpecialCase(java.io.Serializable ser){ 708 Class clazz = ser.getClass(); 709 if (clazz.isArray()){ 710 return createSequenceRepID(ser); 711 } 712 else 713 return createForSpecialCase(clazz); 714 } 715 716 /** 717 * Creates a repository ID for a normal Java Type. 718 * @param ser The Java object to create a repository ID for 719 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the 720 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. 721 **/ 722 public static String createForJavaType(java.io.Serializable ser) 723 throws com.sun.corba.se.impl.io.TypeMismatchException 724 { 725 synchronized (classToRepStr) { 726 String repid = createForSpecialCase(ser); 727 if (repid != null) 728 return repid; 729 Class clazz = ser.getClass(); 730 repid = (String)classToRepStr.get(clazz); 731 732 if (repid != null) 733 return repid; 734 735 repid = kValuePrefix + convertToISOLatin1(clazz.getName()) + 736 createHashString(clazz); 737 738 classToRepStr.put(clazz, repid); 739 repStrToClass.put(repid, clazz); 740 return repid; 741 } 742 } 743 744 /** 745 * Creates a repository ID for a normal Java Type. 746 * @param clz The Java class to create a repository ID for 747 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the 748 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. 749 **/ 750 public static String createForJavaType(Class clz) 751 throws com.sun.corba.se.impl.io.TypeMismatchException 752 { 753 synchronized (classToRepStr){ 754 String repid = createForSpecialCase(clz); 755 if (repid != null) 756 return repid; 757 758 repid = (String)classToRepStr.get(clz); 759 if (repid != null) 760 return repid; 761 762 repid = kValuePrefix + convertToISOLatin1(clz.getName()) + 763 createHashString(clz); 764 765 classToRepStr.put(clz, repid); 766 repStrToClass.put(repid, clz); 767 return repid; 768 } 769 } 770 771 /** 772 * Creates a repository ID for an IDL Java Type. 773 * @param ser The IDL Value object to create a repository ID for 774 * @param major The major version number 775 * @param minor The minor version number 776 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the 777 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type. 778 **/ 779 public static String createForIDLType(Class ser, int major, int minor) 780 throws com.sun.corba.se.impl.io.TypeMismatchException 781 { 782 synchronized (classIDLToRepStr){ 783 String repid = (String)classIDLToRepStr.get(ser); 784 if (repid != null) 785 return repid; 786 787 repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') + 788 ":" + major + "." + minor; 789 classIDLToRepStr.put(ser, repid); 790 return repid; 791 } 792 } 793 794 private static String getIdFromHelper(Class clazz){ 795 try { 796 Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null, 797 clazz.getClassLoader(), clazz, clazz.getClassLoader()); 798 Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes); 799 return (String)idMethod.invoke(null, kNoArgs); 800 } 801 catch(java.lang.ClassNotFoundException cnfe) 802 { 803 throw new org.omg.CORBA.MARSHAL(cnfe.toString()); 804 } 805 catch(java.lang.NoSuchMethodException nsme) 806 { 807 throw new org.omg.CORBA.MARSHAL(nsme.toString()); 808 } 809 catch(java.lang.reflect.InvocationTargetException ite) 810 { 811 throw new org.omg.CORBA.MARSHAL(ite.toString()); 812 } 813 catch(java.lang.IllegalAccessException iae) 814 { 815 throw new org.omg.CORBA.MARSHAL(iae.toString()); 816 } 817 } 818 819 /** 820 * Createa a repository ID for the type if it is either a java type 821 * or an IDL type. 822 * @param type The type to create rep. id for 823 * @return The rep. id. 824 **/ 825 public static String createForAnyType(Class type) { 826 try{ 827 if (type.isArray()) 828 return createSequenceRepID(type); 829 else if (IDLEntity.class.isAssignableFrom(type)) 830 { 831 try{ 832 return getIdFromHelper(type); 833 } 834 catch(Throwable t) { 835 return createForIDLType(type, 1, 0); 836 } 837 } 838 else return createForJavaType(type); 839 } 840 catch(com.sun.corba.se.impl.io.TypeMismatchException e){ 841 return null; 842 } 843 844 } 845 846 public static boolean isAbstractBase(Class clazz) { 847 return (clazz.isInterface() && 848 IDLEntity.class.isAssignableFrom(clazz) && 849 (!ValueBase.class.isAssignableFrom(clazz)) && 850 (!org.omg.CORBA.Object.class.isAssignableFrom(clazz))); 851 852 } 853 854 public static boolean isAnyRequired(Class clazz) { 855 return ((clazz == java.lang.Object.class) || 856 (clazz == java.io.Serializable.class) || 857 (clazz == java.io.Externalizable.class)); 858 } 859 860 public static long fromHex(String hexNumber) { 861 if (hexNumber.startsWith("0x")) 862 return Long.valueOf(hexNumber.substring(2), 16).longValue(); 863 else return Long.valueOf(hexNumber, 16).longValue(); 864 } 865 866 /** 867 * Convert strings with illegal IDL identifier characters. 868 * <p> 869 * Section 5.5.7 of OBV spec. 870 */ 871 public static String convertToISOLatin1 (String name) { 872 873 int length = name.length(); 874 if (length == 0) { 875 return name; 876 } 877 StringBuffer buffer = null; 878 879 for (int i = 0; i < length; i++) { 880 881 char c = name.charAt(i); 882 883 if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) { 884 885 // We gotta convert. Have we already started? 886 887 if (buffer == null) { 888 889 // No, so get set up... 890 891 buffer = new StringBuffer(name.substring(0,i)); 892 } 893 894 // Convert the character into the IDL escape syntax... 895 buffer.append( 896 "\\U" + 897 (char)ASCII_HEX[(c & 0xF000) >>> 12] + 898 (char)ASCII_HEX[(c & 0x0F00) >>> 8] + 899 (char)ASCII_HEX[(c & 0x00F0) >>> 4] + 900 (char)ASCII_HEX[(c & 0x000F)]); 901 902 } else { 903 if (buffer != null) { 904 buffer.append(c); 905 } 906 } 907 } 908 909 if (buffer != null) { 910 name = buffer.toString(); 911 } 912 913 return name; 914 } 915 916 /** 917 * Convert strings with ISO Latin 1 escape sequences back to original strings. 918 * <p> 919 * Section 5.5.7 of OBV spec. 920 */ 921 private static String convertFromISOLatin1 (String name) { 922 923 int index = -1; 924 StringBuffer buf = new StringBuffer(name); 925 926 while ((index = buf.toString().indexOf("\\U")) != -1){ 927 String str = "0000" + buf.toString().substring(index+2, index+6); 928 929 // Convert Hexadecimal 930 byte[] buffer = new byte[(str.length() - 4) / 2]; 931 for (int i=4, j=0; i < str.length(); i +=2, j++) { 932 buffer[j] = (byte)((Utility.hexOf(str.charAt(i)) << 4) & 0xF0); 933 buffer[j] |= (byte)((Utility.hexOf(str.charAt(i+1)) << 0) & 0x0F); 934 } 935 buf = new StringBuffer(delete(buf.toString(), index, index+6)); 936 buf.insert(index, (char)buffer[1]); 937 } 938 939 return buf.toString(); 940 941 942 } 943 944 private static String delete(String str, int from, int to) 945 { 946 return str.substring(0, from) + str.substring(to, str.length()); 947 } 948 949 private static String replace(String target, String arg, String source) 950 { 951 int i = 0; 952 i = target.indexOf(arg); 953 954 while(i != -1) 955 { 956 String left = target.substring(0, i); 957 String right = target.substring(i+arg.length()); 958 target = new String(left+source+right); 959 i = target.indexOf(arg); 960 } 961 return target; 962 } 963 964 public static int computeValueTag(boolean codeBasePresent, int typeInfo, boolean chunkedEncoding){ 965 int value_tag = kInitialValueTag; 966 967 if (codeBasePresent) 968 value_tag = value_tag | 0x00000001; 969 970 value_tag = value_tag | typeInfo; 971 972 if (chunkedEncoding) 973 value_tag = value_tag | kChunkedMask; 974 975 return value_tag; 976 } 977 978 public static boolean isCodeBasePresent(int value_tag){ 979 return ((value_tag & 0x00000001) == 1); 980 } 981 982 public static int getTypeInfo(int value_tag){ 983 return (value_tag & 0x00000006); 984 } 985 986 public static boolean isChunkedEncoding(int value_tag){ 987 return ((value_tag & kChunkedMask) != 0); 988 } 989 990 public static String getServerURL(){ 991 return defaultServerURL; 992 } 993} 994