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