1. /*
  2. * @(#)IOR.java 1.95 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.core;
  16. import java.io.StringWriter;
  17. import java.io.IOException;
  18. import java.util.Iterator ;
  19. import org.omg.CORBA.SystemException;
  20. import org.omg.CORBA.CompletionStatus;
  21. import org.omg.CORBA.INTERNAL;
  22. import org.omg.CORBA.INV_OBJREF;
  23. import org.omg.CORBA.DATA_CONVERSION;
  24. import org.omg.CORBA_2_3.portable.InputStream ;
  25. import org.omg.CORBA_2_3.portable.OutputStream ;
  26. import javax.rmi.CORBA.Util;
  27. import com.sun.corba.se.internal.orbutil.HexOutputStream;
  28. import com.sun.corba.se.internal.orbutil.MinorCodes;
  29. import com.sun.corba.se.internal.util.JDKBridge;
  30. import com.sun.corba.se.internal.core.GIOPVersion;
  31. import com.sun.corba.se.internal.core.StandardIIOPProfileTemplate;
  32. import com.sun.corba.se.internal.orbutil.ORBUtility;
  33. import com.sun.corba.se.internal.corba.EncapsInputStream;
  34. import com.sun.corba.se.internal.ior.JavaCodebaseComponent ;
  35. import com.sun.corba.se.internal.ior.CodeSetsComponent ;
  36. import com.sun.corba.se.internal.ior.ObjectKey ;
  37. import com.sun.corba.se.internal.ior.ObjectKeyFactory ;
  38. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  39. import com.sun.corba.se.internal.ior.POAObjectKeyTemplate ;
  40. import com.sun.corba.se.internal.ior.ObjectId ;
  41. import com.sun.corba.se.internal.ior.POAId ;
  42. import com.sun.corba.se.internal.ior.IIOPAddress ;
  43. import com.sun.corba.se.internal.ior.IIOPAddressImpl ;
  44. import com.sun.corba.se.internal.ior.IIOPProfileTemplate ;
  45. import com.sun.corba.se.internal.ior.IIOPProfile ;
  46. import com.sun.corba.se.internal.ior.IORTemplate ;
  47. import com.sun.corba.se.internal.ior.TaggedComponent ;
  48. import com.sun.corba.se.internal.ior.TaggedComponentFactoryFinder ;
  49. import com.sun.corba.se.internal.POA.POAORB ;
  50. import org.omg.IOP.TAG_JAVA_CODEBASE ;
  51. import org.omg.IOP.TAG_INTERNET_IOP ;
  52. public class IOR extends com.sun.corba.se.internal.ior.IOR
  53. {
  54. public static final IOR NULL = new IOR();
  55. protected ORB factory = null ;
  56. // Cached lookups
  57. protected IIOPProfile iop = null ;
  58. protected String codebase = null ;
  59. protected boolean cachedCodebase = false;
  60. private byte[] objectId = null ;
  61. private boolean lookedForPOAId = false ;
  62. private POAId poaid = null ;
  63. private boolean checkedIsLocal = false ;
  64. private boolean cachedIsLocal = false ;
  65. // initialize-on-demand holder
  66. private static class LocalCodeBaseSingletonHolder {
  67. public static JavaCodebaseComponent comp ;
  68. static {
  69. String localCodebase = JDKBridge.getLocalCodebase() ;
  70. if (localCodebase == null)
  71. comp = null ;
  72. else
  73. comp = new JavaCodebaseComponent( localCodebase ) ;
  74. }
  75. }
  76. private Object cookie ;
  77. public synchronized Object getCookie()
  78. {
  79. return cookie ;
  80. }
  81. public synchronized void setCookie( Object cookie )
  82. {
  83. this.cookie = cookie ;
  84. }
  85. /*
  86. * Only for the NULL instance.
  87. */
  88. private IOR() {
  89. this( (ORB)null ) ;
  90. }
  91. public IOR( ORB factory) {
  92. this( factory, "" ) ;
  93. }
  94. public IOR( ORB factory, String typeId )
  95. {
  96. super( typeId ) ;
  97. this.factory = factory ;
  98. }
  99. public IOR( ORB factory, String typeId, IORTemplate template,
  100. ObjectId id )
  101. {
  102. super( typeId, template, id ) ;
  103. this.factory = factory ;
  104. }
  105. public IOR( ORB factory, String typeId,
  106. String host, int port,
  107. byte[] key ) throws SystemException
  108. {
  109. this( factory, typeId, host, port,
  110. ObjectKeyFactory.get().create(factory, key)) ;
  111. }
  112. public IOR( ORB factory, String typeId,
  113. String host, int port,
  114. ObjectKey key ) throws SystemException
  115. {
  116. this( factory, typeId, host, port, key, null ) ;
  117. }
  118. public IOR( ORB factory, String typeId,
  119. String host, int port,
  120. ObjectKey okey, Object servant ) throws SystemException
  121. {
  122. this(factory, typeId );
  123. GIOPVersion version = factory.getGIOPVersion() ;
  124. int major = version.getMajor() ;
  125. int minor = version.getMinor() ;
  126. init( host, port, major, minor, okey, servant ) ;
  127. }
  128. public IOR( ORB factory, String typeId,
  129. String host, int port, int major, int minor,
  130. ObjectKey okey, Object servant ) throws SystemException
  131. {
  132. this(factory, typeId );
  133. init( host, port, major, minor, okey, servant ) ;
  134. }
  135. private void init( String host, int port, int major, int minor,
  136. ObjectKey okey, Object servant )
  137. {
  138. ObjectKeyTemplate ktemp = okey.getTemplate() ;
  139. ObjectId id = okey.getId() ;
  140. IIOPAddress addr = new IIOPAddressImpl( host, port ) ;
  141. IIOPProfileTemplate ptemp = new StandardIIOPProfileTemplate(
  142. addr, major, minor, ktemp, servant, factory ) ;
  143. IIOPProfile profile = new IIOPProfile( id, ptemp ) ;
  144. add( profile ) ;
  145. makeImmutable() ;
  146. }
  147. /** This constructor is added to create IOR's from the URL based
  148. * names for the INS. The constructor is same as others except for the
  149. * Object key which will be a String instead of octets. There will be no
  150. * conversion of the String to Hexadecimal Bytes.
  151. */
  152. public IOR( ORB factory, String typeId,
  153. String host, int port, int major, int minor,
  154. String asciiBasedKey, Object servant ) throws SystemException
  155. {
  156. this(factory, typeId, host, port, major, minor,
  157. ObjectKeyFactory.get().create( factory, asciiBasedKey.getBytes() ),
  158. servant );
  159. }
  160. private static final int NIBBLES_PER_BYTE = 2 ;
  161. private static final int UN_SHIFT = 4 ; // "UPPER NIBBLE" shift factor for <<
  162. /** This static method takes a Stringified IOR and converts it into IOR object.
  163. * It is the caller's responsibility to only pass strings that start with "IOR:".
  164. */
  165. public static org.omg.CORBA.Object getIORFromString(ORB factory,
  166. String str )
  167. {
  168. // Length must be even for str to be valid
  169. if ( (str.length() & 1) == 1 )
  170. throw new org.omg.CORBA.DATA_CONVERSION(
  171. MinorCodes.BAD_STRINGIFIED_IOR_LEN,
  172. CompletionStatus.COMPLETED_NO ) ;
  173. byte[] buf = new byte[(str.length() - PREFIX_LENGTH) / NIBBLES_PER_BYTE];
  174. for (int i=PREFIX_LENGTH, j=0; i < str.length(); i +=NIBBLES_PER_BYTE, j++) {
  175. buf[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << UN_SHIFT) & 0xF0);
  176. buf[j] |= (byte)(ORBUtility.hexOf(str.charAt(i+1)) & 0x0F);
  177. }
  178. EncapsInputStream s = new EncapsInputStream(factory, buf, buf.length);
  179. s.consumeEndian();
  180. return s.read_Object() ;
  181. }
  182. public IOR(InputStream s)
  183. {
  184. super( s ) ;
  185. this.factory = (ORB)(s.orb()) ;
  186. cachedCodebase = false;
  187. if (!is_nil()) {
  188. // If there is no codebase in this IOR and there IS a
  189. // java.rmi.server.codebase property set, we need to
  190. // update the IOR with the local codebase. Note that
  191. // there is only one instance of the local codebase, but it
  192. // can be safely shared in multiple IORs since it is immutable.
  193. if (uncachedGetCodeBase() == null) {
  194. JavaCodebaseComponent jcc = LocalCodeBaseSingletonHolder.comp ;
  195. if (jcc != null) {
  196. IIOPProfileTemplate temp = getProfile().getTemplate() ;
  197. temp.add( jcc ) ;
  198. codebase = jcc.getURLs() ;
  199. cachedCodebase = true;
  200. }
  201. }
  202. }
  203. makeImmutable() ;
  204. }
  205. private String uncachedGetCodeBase() {
  206. Iterator iter = getProfile().getTemplate().iteratorById(
  207. TAG_JAVA_CODEBASE.value ) ;
  208. if (iter.hasNext()) {
  209. JavaCodebaseComponent jcbc = (JavaCodebaseComponent)(iter.next()) ;
  210. return jcbc.getURLs() ;
  211. }
  212. return null ;
  213. }
  214. public synchronized String getCodebase() {
  215. if (!cachedCodebase) {
  216. cachedCodebase = true ;
  217. codebase = uncachedGetCodeBase() ;
  218. }
  219. return codebase ;
  220. }
  221. /** Get the IIOP Profile from this IOR. We are assuming that there
  222. * can be only one at present. If more than one IIOP profile is
  223. * present, we will throw an exception here.
  224. */
  225. public IIOPProfile getProfile()
  226. {
  227. if (iop == null) {
  228. Iterator iter = iteratorById( TAG_INTERNET_IOP.value ) ;
  229. if (iter.hasNext())
  230. iop = (IIOPProfile)(iter.next()) ;
  231. // If there are multiple profile we always return the first one.
  232. // if (iter.hasNext())
  233. // throw new INTERNAL( MinorCodes.MULT_IIOP_PROF_NOT_SUPPORTED,
  234. // CompletionStatus.COMPLETED_NO ) ;
  235. }
  236. if (iop != null)
  237. return iop ;
  238. // if we come to this point then no IIOP Profile
  239. // is present. Therefore, throw an INV_OBJREF exception.
  240. throw new INV_OBJREF( MinorCodes.NO_PROFILE_PRESENT,
  241. CompletionStatus.COMPLETED_NO );
  242. }
  243. public synchronized byte[] getObjectId()
  244. {
  245. if (objectId == null) {
  246. IIOPProfile prof = getProfile() ;
  247. ObjectId oid = prof.getObjectId() ;
  248. objectId = oid.getId() ;
  249. }
  250. return objectId ;
  251. }
  252. public synchronized POAId getPOAId()
  253. {
  254. if (!lookedForPOAId) {
  255. lookedForPOAId = true ;
  256. IIOPProfile prof = getProfile() ;
  257. ObjectKeyTemplate oktemp =
  258. prof.getTemplate().getObjectKeyTemplate() ;
  259. if (oktemp instanceof POAObjectKeyTemplate) {
  260. POAObjectKeyTemplate poktemp = (POAObjectKeyTemplate)oktemp ;
  261. poaid = poktemp.getPOAId() ;
  262. }
  263. }
  264. return poaid ;
  265. }
  266. /**
  267. * @return the ORBVersion associated with the object key in the IOR.
  268. */
  269. public ORBVersion getORBVersion() {
  270. return this.getProfile().getTemplate().
  271. getObjectKeyTemplate().getORBVersion();
  272. }
  273. public String stringify()
  274. {
  275. return stringify(factory);
  276. }
  277. public boolean is_nil()
  278. {
  279. //
  280. // The check for typeId length of 0 below is commented out
  281. // as a workaround for a bug in ORBs which send a
  282. // null objref with a non-empty typeId string.
  283. //
  284. return ((size() == 0) /* && (typeId.length() == 0) */);
  285. }
  286. public boolean isEquivalent(IOR ior)
  287. {
  288. return getProfile().isEquivalent(ior.getProfile());
  289. }
  290. public synchronized boolean isLocal()
  291. {
  292. if (factory == null)
  293. return false ;
  294. if (!checkedIsLocal) {
  295. checkedIsLocal = true ;
  296. IIOPProfile iop = getProfile() ;
  297. IIOPProfileTemplate ptemp = iop.getTemplate() ;
  298. String host = ptemp.getPrimaryAddress().getHost() ;
  299. ObjectKeyTemplate ktemp = ptemp.getObjectKeyTemplate() ;
  300. cachedIsLocal = factory.isLocalHost( host ) && factory.isLocalServerId(
  301. ktemp.getSubcontractId(), ktemp.getServerId() ) &&
  302. factory.isLocalServerPort( ptemp.getPrimaryAddress().getPort( ) );
  303. }
  304. return cachedIsLocal ;
  305. }
  306. /**
  307. * (Compute and) Return GIOPVersion for this IOR
  308. * Requests created against this IOR will be of the
  309. * return Version.
  310. */
  311. public synchronized GIOPVersion getGIOPVersion(){
  312. if (this.giopVersion != null) {
  313. return this.giopVersion;
  314. }
  315. byte major = getProfile().getTemplate().getMajorVersion();
  316. byte minor = getProfile().getTemplate().getMinorVersion();
  317. this.giopVersion = GIOPVersion.getInstance(major, minor);
  318. //REVISIT: Should we be cloning here before a return?
  319. return this.giopVersion;
  320. }
  321. private GIOPVersion giopVersion = null;
  322. public ServerSubcontract getServerSubcontract()
  323. {
  324. ObjectKeyTemplate temp = getProfile().getTemplate().getObjectKeyTemplate() ;
  325. int scid = temp.getSubcontractId() ;
  326. ServerSubcontract sc = factory.getSubcontractRegistry().getServerSubcontract( scid ) ;
  327. return sc ;
  328. }
  329. public com.sun.corba.se.internal.core.IOR addComponent(
  330. org.omg.IOP.TaggedComponent component
  331. )
  332. {
  333. // Get information from IOR
  334. String typeId = getTypeId() ;
  335. IIOPProfile iop = getProfile() ;
  336. // Get Information from IIOPProfile
  337. ObjectId oid = iop.getObjectId() ;
  338. IIOPProfileTemplate ptemp = iop.getTemplate() ;
  339. // Get Information from IIOPProfileTemplate
  340. byte major = ptemp.getMajorVersion() ;
  341. byte minor = ptemp.getMinorVersion() ;
  342. IIOPAddress addr = ptemp.getPrimaryAddress() ;
  343. ObjectKeyTemplate oktemp = ptemp.getObjectKeyTemplate() ;
  344. // Create new IIOPProfileTemplate
  345. IIOPProfileTemplate ptempResult = new IIOPProfileTemplate(
  346. major, minor, addr, oktemp ) ;
  347. // Add tagged components from old IIOPProfileTemplate to the new one
  348. Iterator iter = ptemp.iterator() ;
  349. while (iter.hasNext()) {
  350. Object obj = iter.next() ;
  351. ptempResult.add( obj ) ;
  352. }
  353. // Convert component to ior.TaggedComponent and add to the new
  354. // profile
  355. TaggedComponent comp = TaggedComponentFactoryFinder.getFinder().
  356. create( factory, component ) ;
  357. ptempResult.add( comp ) ;
  358. // Create new IIOPProfile
  359. IIOPProfile iopResult = new IIOPProfile( oid, ptempResult ) ;
  360. // Create new IOR
  361. IOR result = new IOR( factory, typeId ) ;
  362. result.add( iopResult ) ;
  363. result.makeImmutable() ;
  364. return result ;
  365. }
  366. public void dump( )
  367. {
  368. IIOPProfile prof = getProfile() ;
  369. IIOPProfileTemplate ptemp = prof.getTemplate() ;
  370. ObjectId oid = prof.getObjectId() ;
  371. ObjectKeyTemplate oktemp = ptemp.getObjectKeyTemplate() ;
  372. System.out.println( "Contents of IOR:" ) ;
  373. System.out.println( "\tTypeId = " + getTypeId() ) ;
  374. System.out.println( "\tIIOPProfileTemplate = " ) ;
  375. System.out.println( "\t\tmajor version = " + ptemp.getMajorVersion() ) ;
  376. System.out.println( "\t\tminor version = " + ptemp.getMinorVersion() ) ;
  377. System.out.println( "\t\thost name = " + ptemp.getPrimaryAddress().getHost() ) ;
  378. System.out.println( "\t\tport number = " + ptemp.getPrimaryAddress().getPort() ) ;
  379. System.out.println( "\t\tObject Key Template:" ) ;
  380. System.out.println( "\t\t\tSubcontract id = " + oktemp.getSubcontractId() ) ;
  381. System.out.println( "\t\t\tServer id = " + oktemp.getServerId() ) ;
  382. }
  383. public boolean isTransactional()
  384. {
  385. IIOPProfile prof = getProfile() ;
  386. IIOPProfileTemplate ptemp = prof.getTemplate() ;
  387. ObjectKeyTemplate oktemp = ptemp.getObjectKeyTemplate() ;
  388. int scid = oktemp.getSubcontractId() ;
  389. boolean result = ((scid & 1) == 1) ;
  390. if (factory != null)
  391. if (((POAORB)factory).subcontractDebugFlag)
  392. System.out.println( "core.IOR.isTransactional returns " +
  393. result ) ;
  394. return result ;
  395. }
  396. }