1. /*
  2. * @(#)RepositoryId.java 1.31 03/01/23
  3. *
  4. * Copyright 2003 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.internal.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.internal.util.JDKBridge;
  26. //import com.sun.corba.se.internal.util.IdentityHashtable;
  27. import com.sun.corba.se.internal.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. this.repId = aRepId;
  240. // Special case for remote
  241. if (aRepId.length() == 0) {
  242. clazz = java.rmi.Remote.class;
  243. typeString = "";
  244. isRMIValueType = true;
  245. suid = kInterfaceOnlyHashStr;
  246. return this;
  247. }
  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. }
  258. else {
  259. String repId = convertFromISOLatin1(aRepId);
  260. versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1));
  261. if (repId.startsWith(kIDLPrefix)) {
  262. typeString =
  263. repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength));
  264. isIDLType = true;
  265. if (typeString.startsWith(kIDLNamePrefix))
  266. completeClassName = kIDLClassnamePrefix +
  267. typeString.substring(kIDLNamePrefix.length()).replace('/','.');
  268. else completeClassName = typeString.replace('/','.');
  269. }
  270. else if (repId.startsWith(kValuePrefix)) {
  271. typeString =
  272. repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength));
  273. isRMIValueType = true;
  274. if (versionString.indexOf('.') == -1) {
  275. actualSuid = versionString.substring(1);
  276. suid = actualSuid; // default if not explicitly specified
  277. if (actualSuid.indexOf(':') != -1){
  278. // we have a declared hash also
  279. int pos = actualSuid.indexOf(':')+1;
  280. // actualSuid = suid.substring(pos);
  281. // suid = suid.substring(0, pos-1);
  282. suid = actualSuid.substring(pos);
  283. actualSuid = actualSuid.substring(0, pos-1);
  284. }
  285. }
  286. else {
  287. // _REVISIT_ : Special case version failure ?
  288. }
  289. }
  290. else isSupportedFormat = false;
  291. if (typeString.startsWith(kSequencePrefix)) {
  292. isSequence = true;
  293. }
  294. return this;
  295. }
  296. }
  297. public final String getUnqualifiedName() {
  298. if (unqualifiedName == null){
  299. String className = getClassName();
  300. int index = className.lastIndexOf('.');
  301. if (index == -1){
  302. unqualifiedName = className;
  303. definedInId = "IDL::1.0";
  304. }
  305. else {
  306. unqualifiedName = className.substring(index);
  307. definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0";
  308. }
  309. }
  310. return unqualifiedName;
  311. }
  312. public final String getDefinedInId() {
  313. if (definedInId == null){
  314. getUnqualifiedName();
  315. }
  316. return definedInId;
  317. }
  318. public final String getTypeString() {
  319. return typeString;
  320. }
  321. public final String getVersionString() {
  322. return versionString;
  323. }
  324. public final String getSerialVersionUID() {
  325. return suid;
  326. }
  327. public final String getActualSerialVersionUID() {
  328. return actualSuid;
  329. }
  330. public final long getSerialVersionUIDAsLong() {
  331. return suidLong;
  332. }
  333. public final long getActualSerialVersionUIDAsLong() {
  334. return actualSuidLong;
  335. }
  336. public final boolean isRMIValueType() {
  337. return isRMIValueType;
  338. }
  339. public final boolean isIDLType() {
  340. return isIDLType;
  341. }
  342. public final String getRepositoryId() {
  343. return repId;
  344. }
  345. public static byte[] getByteArray(String repStr) {
  346. synchronized (repStrToByteArray){
  347. return (byte[]) repStrToByteArray.get(repStr);
  348. }
  349. }
  350. public static void setByteArray(String repStr, byte[] repStrBytes) {
  351. synchronized (repStrToByteArray){
  352. repStrToByteArray.put(repStr, repStrBytes);
  353. }
  354. }
  355. public final boolean isSequence() {
  356. return isSequence;
  357. }
  358. public final boolean isSupportedFormat() {
  359. return isSupportedFormat;
  360. }
  361. // This method will return the classname from the typestring OR if the classname turns out to be
  362. // a special class "pseudo" name, then the matching real classname is returned.
  363. public final String getClassName() {
  364. if (isRMIValueType)
  365. return typeString;
  366. else if (isIDLType)
  367. return completeClassName;
  368. else return null;
  369. }
  370. // This method calls getClazzFromType() and falls back to the repStrToClass
  371. // cache if no class was found. It's used where any class matching the
  372. // given repid is an acceptable result.
  373. public final Class getAnyClassFromType() throws ClassNotFoundException {
  374. try {
  375. return getClassFromType();
  376. } catch (ClassNotFoundException cnfe) {
  377. Class clz = (Class)repStrToClass.get(repId);
  378. if (clz != null)
  379. return clz;
  380. else
  381. throw cnfe;
  382. }
  383. }
  384. public final Class getClassFromType()
  385. throws ClassNotFoundException {
  386. if (clazz != null)
  387. return clazz;
  388. Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
  389. if (specialCase != null){
  390. clazz = specialCase;
  391. return specialCase;
  392. }
  393. else
  394. {
  395. try{
  396. return Util.loadClass(getClassName(), null, null);
  397. }
  398. catch(ClassNotFoundException cnfe){
  399. if (defaultServerURL != null) {
  400. try{
  401. return getClassFromType(defaultServerURL);
  402. }
  403. catch(MalformedURLException mue){
  404. throw cnfe;
  405. }
  406. }
  407. else throw cnfe;
  408. }
  409. }
  410. }
  411. public final Class getClassFromType(Class expectedType, String codebase)
  412. throws ClassNotFoundException {
  413. if (clazz != null)
  414. return clazz;
  415. Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
  416. if (specialCase != null){
  417. clazz = specialCase;
  418. return specialCase;
  419. } else {
  420. ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader());
  421. return Utility.loadClassOfType(getClassName(),
  422. codebase,
  423. expectedTypeClassLoader,
  424. expectedType,
  425. expectedTypeClassLoader);
  426. }
  427. }
  428. public final Class getClassFromType(String url)
  429. throws ClassNotFoundException, MalformedURLException {
  430. return Util.loadClass(getClassName(), url, null);
  431. }
  432. public final String toString() {
  433. return repId;
  434. }
  435. /**
  436. * Checks to see if the FullValueDescription should be retrieved.
  437. * @exception Throws IOException if suids do not match or if the repositoryID
  438. * is not an RMIValueType
  439. */
  440. public static boolean useFullValueDescription(Class clazz, String repositoryID)
  441. throws IOException{
  442. String clazzRepIDStr = createForAnyType(clazz);
  443. if (clazzRepIDStr.equals(repositoryID))
  444. return false;
  445. RepositoryId targetRepid;
  446. RepositoryId clazzRepid;
  447. synchronized(cache) {
  448. // to avoid race condition where multiple threads could be
  449. // accessing this method, and their access to the cache may
  450. // be interleaved giving unexpected results
  451. targetRepid = cache.getId(repositoryID);
  452. clazzRepid = cache.getId(clazzRepIDStr);
  453. }
  454. //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
  455. if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){
  456. if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) {
  457. String mssg = "Mismatched serialization UIDs : Source (Rep. ID" +
  458. clazzRepid + ") = " +
  459. clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID +
  460. ") = " + targetRepid.getSerialVersionUID();
  461. //com.sun.corba.se.internal.io.ValueUtility.log("RepositoryId",mssg);
  462. throw new IOException(mssg);
  463. }
  464. else {
  465. return true;
  466. }
  467. }
  468. else {
  469. throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")");
  470. }
  471. }
  472. private static String createHashString(java.io.Serializable ser) {
  473. return createHashString(ser.getClass());
  474. }
  475. private static String createHashString(java.lang.Class clazz) {
  476. if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz))
  477. return kInterfaceHashCode;
  478. //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
  479. long actualLong = ObjectStreamClass.getActualSerialVersionUID(clazz);
  480. String hash = null;
  481. if (actualLong == 0)
  482. hash = kInterfaceOnlyHashStr;
  483. else if (actualLong == 1)
  484. hash = kExternalizableHashStr;
  485. else
  486. hash = Long.toHexString(actualLong).toUpperCase();
  487. while(hash.length() < 16){
  488. hash = "0" + hash;
  489. }
  490. long declaredLong = ObjectStreamClass.getSerialVersionUID(clazz);
  491. String declared = null;
  492. if (declaredLong == 0)
  493. declared = kInterfaceOnlyHashStr;
  494. else if (declaredLong == 1)
  495. declared = kExternalizableHashStr;
  496. else
  497. declared = Long.toHexString(declaredLong).toUpperCase();
  498. while (declared.length() < 16){
  499. declared = "0" + declared;
  500. }
  501. hash = hash + ":" + declared;
  502. return ":" + hash;
  503. }
  504. /**
  505. * Creates a repository ID for a sequence. This is for expert users only as
  506. * this method assumes the object passed is an array. If passed an object
  507. * that is not an array, it will produce a rep id for a sequence of zero
  508. * length. This would be an error.
  509. * @param ser The Java object to create a repository ID for
  510. **/
  511. public static String createSequenceRepID(java.lang.Object ser){
  512. return createSequenceRepID(ser.getClass());
  513. }
  514. /**
  515. * Creates a repository ID for a sequence. This is for expert users only as
  516. * this method assumes the object passed is an array. If passed an object
  517. * that is not an array, it will produce a malformed rep id.
  518. * @param clazz The Java class to create a repository ID for
  519. **/
  520. public static String createSequenceRepID(java.lang.Class clazz){
  521. synchronized (classSeqToRepStr){
  522. String repid = (String)classSeqToRepStr.get(clazz);
  523. if (repid != null)
  524. return repid;
  525. Class originalClazz = clazz;
  526. Class type = null;
  527. int numOfDims = 0;
  528. while ((type = clazz.getComponentType()) != null) {
  529. numOfDims++;
  530. clazz = type;
  531. }
  532. if (clazz.isPrimitive())
  533. repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash;
  534. else {
  535. StringBuffer buf = new StringBuffer();
  536. buf.append(kValuePrefix);
  537. while(numOfDims-- > 0) {
  538. buf.append("[");
  539. }
  540. buf.append("L");
  541. buf.append(convertToISOLatin1(clazz.getName()));
  542. buf.append(";");
  543. buf.append(createHashString(clazz));
  544. repid = buf.toString();
  545. }
  546. classSeqToRepStr.put(originalClazz,repid);
  547. return repid;
  548. }
  549. }
  550. public static String createForSpecialCase(java.lang.Class clazz){
  551. if (clazz.isArray()){
  552. return createSequenceRepID(clazz);
  553. }
  554. else {
  555. return (String)kSpecialCasesRepIDs.get(clazz);
  556. }
  557. }
  558. public static String createForSpecialCase(java.io.Serializable ser){
  559. Class clazz = ser.getClass();
  560. if (clazz.isArray()){
  561. return createSequenceRepID(ser);
  562. }
  563. else
  564. return createForSpecialCase(clazz);
  565. }
  566. /**
  567. * Creates a repository ID for a normal Java Type.
  568. * @param ser The Java object to create a repository ID for
  569. * @exception com.sun.corba.se.internal.io.TypeMismatchException if ser implements the
  570. * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
  571. **/
  572. public static String createForJavaType(java.io.Serializable ser)
  573. throws com.sun.corba.se.internal.io.TypeMismatchException
  574. {
  575. synchronized (classToRepStr) {
  576. String repid = createForSpecialCase(ser);
  577. if (repid != null)
  578. return repid;
  579. Class clazz = ser.getClass();
  580. repid = (String)classToRepStr.get(clazz);
  581. if (repid != null)
  582. return repid;
  583. repid = kValuePrefix + convertToISOLatin1(clazz.getName()) +
  584. createHashString(clazz);
  585. classToRepStr.put(clazz, repid);
  586. repStrToClass.put(repid, clazz);
  587. return repid;
  588. }
  589. }
  590. /**
  591. * Creates a repository ID for a normal Java Type.
  592. * @param clz The Java class to create a repository ID for
  593. * @exception com.sun.corba.se.internal.io.TypeMismatchException if ser implements the
  594. * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
  595. **/
  596. public static String createForJavaType(Class clz)
  597. throws com.sun.corba.se.internal.io.TypeMismatchException
  598. {
  599. synchronized (classToRepStr){
  600. String repid = createForSpecialCase(clz);
  601. if (repid != null)
  602. return repid;
  603. repid = (String)classToRepStr.get(clz);
  604. if (repid != null)
  605. return repid;
  606. repid = kValuePrefix + convertToISOLatin1(clz.getName()) +
  607. createHashString(clz);
  608. classToRepStr.put(clz, repid);
  609. repStrToClass.put(repid, clz);
  610. return repid;
  611. }
  612. }
  613. /**
  614. * Creates a repository ID for an IDL Java Type.
  615. * @param ser The IDL Value object to create a repository ID for
  616. * @param major The major version number
  617. * @param minor The minor version number
  618. * @exception com.sun.corba.se.internal.io.TypeMismatchException if ser does not implement the
  619. * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
  620. **/
  621. public static String createForIDLType(Class ser, int major, int minor)
  622. throws com.sun.corba.se.internal.io.TypeMismatchException
  623. {
  624. synchronized (classIDLToRepStr){
  625. String repid = (String)classIDLToRepStr.get(ser);
  626. if (repid != null)
  627. return repid;
  628. repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') +
  629. ":" + major + "." + minor;
  630. classIDLToRepStr.put(ser, repid);
  631. return repid;
  632. }
  633. }
  634. private static String getIdFromHelper(Class clazz){
  635. try {
  636. Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null,
  637. clazz.getClassLoader(), clazz, clazz.getClassLoader());
  638. Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes);
  639. return (String)idMethod.invoke(null, kNoArgs);
  640. }
  641. catch(java.lang.ClassNotFoundException cnfe)
  642. {
  643. throw new org.omg.CORBA.MARSHAL(cnfe.toString());
  644. }
  645. catch(java.lang.NoSuchMethodException nsme)
  646. {
  647. throw new org.omg.CORBA.MARSHAL(nsme.toString());
  648. }
  649. catch(java.lang.reflect.InvocationTargetException ite)
  650. {
  651. throw new org.omg.CORBA.MARSHAL(ite.toString());
  652. }
  653. catch(java.lang.IllegalAccessException iae)
  654. {
  655. throw new org.omg.CORBA.MARSHAL(iae.toString());
  656. }
  657. }
  658. /**
  659. * Createa a repository ID for the type if it is either a java type
  660. * or an IDL type.
  661. * @param type The type to create rep. id for
  662. * @return The rep. id.
  663. **/
  664. public static String createForAnyType(Class type) {
  665. try{
  666. if (type.isArray())
  667. return createSequenceRepID(type);
  668. else if (IDLEntity.class.isAssignableFrom(type))
  669. {
  670. try{
  671. return getIdFromHelper(type);
  672. }
  673. catch(Throwable t) {
  674. return createForIDLType(type, 1, 0);
  675. }
  676. }
  677. else return createForJavaType(type);
  678. }
  679. catch(com.sun.corba.se.internal.io.TypeMismatchException e){
  680. return null;
  681. }
  682. }
  683. public static boolean isAbstractBase(Class clazz) {
  684. return (clazz.isInterface() &&
  685. IDLEntity.class.isAssignableFrom(clazz) &&
  686. (!ValueBase.class.isAssignableFrom(clazz)) &&
  687. (!org.omg.CORBA.Object.class.isAssignableFrom(clazz)));
  688. }
  689. public static boolean isAnyRequired(Class clazz) {
  690. return ((clazz == java.lang.Object.class) ||
  691. (clazz == java.io.Serializable.class) ||
  692. (clazz == java.io.Externalizable.class));
  693. }
  694. public static long fromHex(String hexNumber) {
  695. if (hexNumber.startsWith("0x"))
  696. return Long.valueOf(hexNumber.substring(2), 16).longValue();
  697. else return Long.valueOf(hexNumber, 16).longValue();
  698. }
  699. /**
  700. * Convert strings with illegal IDL identifier characters.
  701. * <p>
  702. * Section 5.5.7 of OBV spec.
  703. */
  704. private static String convertToISOLatin1 (String name) {
  705. int length = name.length();
  706. if (length == 0) {
  707. return name;
  708. }
  709. StringBuffer buffer = null;
  710. for (int i = 0; i < length; i++) {
  711. char c = name.charAt(i);
  712. if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
  713. // We gotta convert. Have we already started?
  714. if (buffer == null) {
  715. // No, so get set up...
  716. buffer = new StringBuffer(name.substring(0,i));
  717. }
  718. // Convert the character into the IDL escape syntax...
  719. buffer.append(
  720. "\\U" +
  721. (char)ASCII_HEX[(c & 0xF000) >>> 12] +
  722. (char)ASCII_HEX[(c & 0x0F00) >>> 8] +
  723. (char)ASCII_HEX[(c & 0x00F0) >>> 4] +
  724. (char)ASCII_HEX[(c & 0x000F)]);
  725. } else {
  726. if (buffer != null) {
  727. buffer.append(c);
  728. }
  729. }
  730. }
  731. if (buffer != null) {
  732. name = buffer.toString();
  733. }
  734. return name;
  735. }
  736. /**
  737. * Convert strings with ISO Latin 1 escape sequences back to original strings.
  738. * <p>
  739. * Section 5.5.7 of OBV spec.
  740. */
  741. private static String convertFromISOLatin1 (String name) {
  742. int index = -1;
  743. StringBuffer buf = new StringBuffer(name);
  744. while ((index = buf.toString().indexOf("\\U")) != -1){
  745. String str = "0000" + buf.toString().substring(index+2, index+6);
  746. // Convert Hexadecimal
  747. byte[] buffer = new byte[(str.length() - 4) / 2];
  748. for (int i=4, j=0; i < str.length(); i +=2, j++) {
  749. buffer[j] = (byte)((Utility.hexOf(str.charAt(i)) << 4) & 0xF0);
  750. buffer[j] |= (byte)((Utility.hexOf(str.charAt(i+1)) << 0) & 0x0F);
  751. }
  752. buf = new StringBuffer(delete(buf.toString(), index, index+6));
  753. buf.insert(index, (char)buffer[1]);
  754. }
  755. return buf.toString();
  756. }
  757. private static String delete(String str, int from, int to)
  758. {
  759. return str.substring(0, from) + str.substring(to, str.length());
  760. }
  761. private static String replace(String target, String arg, String source)
  762. {
  763. int i = 0;
  764. i = target.indexOf(arg);
  765. while(i != -1)
  766. {
  767. String left = target.substring(0, i);
  768. String right = target.substring(i+arg.length());
  769. target = new String(left+source+right);
  770. i = target.indexOf(arg);
  771. }
  772. return target;
  773. }
  774. public static int computeValueTag(boolean codeBasePresent, int typeInfo, boolean chunkedEncoding){
  775. int value_tag = kInitialValueTag;
  776. if (codeBasePresent)
  777. value_tag = value_tag | 0x00000001;
  778. value_tag = value_tag | typeInfo;
  779. if (chunkedEncoding)
  780. value_tag = value_tag | kChunkedMask;
  781. return value_tag;
  782. }
  783. public static boolean isCodeBasePresent(int value_tag){
  784. return ((value_tag & 0x00000001) == 1);
  785. }
  786. public static int getTypeInfo(int value_tag){
  787. return (value_tag & 0x00000006);
  788. }
  789. public static boolean isChunkedEncoding(int value_tag){
  790. return ((value_tag & kChunkedMask) != 0);
  791. }
  792. public static String getServerURL(){
  793. return defaultServerURL;
  794. }
  795. }