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