1. /*
  2. * @(#)CorbaClientDelegateImpl.java 1.56 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. package com.sun.corba.se.impl.protocol;
  8. import java.util.Iterator;
  9. import java.util.HashMap;
  10. import javax.rmi.CORBA.Tie;
  11. import org.omg.CORBA.CompletionStatus;
  12. import org.omg.CORBA.Context;
  13. import org.omg.CORBA.ContextList;
  14. import org.omg.CORBA.ExceptionList;
  15. import org.omg.CORBA.NamedValue;
  16. import org.omg.CORBA.NVList;
  17. import org.omg.CORBA.Request;
  18. import org.omg.CORBA.TypeCode;
  19. import org.omg.CORBA.portable.ApplicationException;
  20. import org.omg.CORBA.portable.Delegate;
  21. import org.omg.CORBA.portable.InputStream;
  22. import org.omg.CORBA.portable.OutputStream;
  23. import org.omg.CORBA.portable.RemarshalException;
  24. import org.omg.CORBA.portable.ServantObject;
  25. import com.sun.corba.se.pept.broker.Broker;
  26. import com.sun.corba.se.pept.encoding.InputObject;
  27. import com.sun.corba.se.pept.encoding.OutputObject;
  28. import com.sun.corba.se.pept.protocol.ClientInvocationInfo;
  29. import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;
  30. import com.sun.corba.se.pept.transport.ContactInfo;
  31. import com.sun.corba.se.pept.transport.ContactInfoList;
  32. import com.sun.corba.se.pept.transport.ContactInfoListIterator;
  33. import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
  34. import com.sun.corba.se.spi.ior.IOR;
  35. import com.sun.corba.se.spi.logging.CORBALogDomains;
  36. import com.sun.corba.se.spi.orb.ORB;
  37. import com.sun.corba.se.spi.protocol.CorbaClientDelegate ;
  38. import com.sun.corba.se.spi.transport.CorbaContactInfo;
  39. import com.sun.corba.se.spi.transport.CorbaContactInfoList;
  40. import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
  41. import com.sun.corba.se.impl.corba.RequestImpl;
  42. import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
  43. import com.sun.corba.se.impl.transport.CorbaContactInfoListImpl;
  44. import com.sun.corba.se.impl.util.JDKBridge;
  45. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  46. // implements com.sun.corba.se.impl.core.ClientRequestDispatcher
  47. // so RMI-IIOP Util.isLocal can call ClientRequestDispatcher.useLocalInvocation.
  48. /**
  49. * @author Harold Carr
  50. */
  51. public class CorbaClientDelegateImpl extends CorbaClientDelegate
  52. {
  53. private ORB orb;
  54. private ORBUtilSystemException wrapper ;
  55. private CorbaContactInfoList contactInfoList;
  56. public CorbaClientDelegateImpl(ORB orb,
  57. CorbaContactInfoList contactInfoList)
  58. {
  59. this.orb = orb;
  60. this.wrapper = ORBUtilSystemException.get( orb,
  61. CORBALogDomains.RPC_PROTOCOL ) ;
  62. this.contactInfoList = contactInfoList;
  63. }
  64. //
  65. // framework.subcontract.Delegate
  66. //
  67. public Broker getBroker()
  68. {
  69. return orb;
  70. }
  71. public ContactInfoList getContactInfoList()
  72. {
  73. return contactInfoList;
  74. }
  75. //
  76. // CORBA_2_3.portable.Delegate
  77. //
  78. public OutputStream request(org.omg.CORBA.Object self,
  79. String operation,
  80. boolean responseExpected)
  81. {
  82. ClientInvocationInfo invocationInfo =
  83. orb.createOrIncrementInvocationInfo();
  84. Iterator contactInfoListIterator =
  85. invocationInfo.getContactInfoListIterator();
  86. if (contactInfoListIterator == null) {
  87. contactInfoListIterator = contactInfoList.iterator();
  88. invocationInfo.setContactInfoListIterator(contactInfoListIterator);
  89. }
  90. if (! contactInfoListIterator.hasNext()) {
  91. throw ((CorbaContactInfoListIterator)contactInfoListIterator)
  92. .getFailureException();
  93. }
  94. CorbaContactInfo contactInfo = (CorbaContactInfo) contactInfoListIterator.next();
  95. ClientRequestDispatcher subcontract = contactInfo.getClientRequestDispatcher();
  96. // Remember chosen subcontract for invoke and releaseReply.
  97. // NOTE: This is necessary since a stream is not available in
  98. // releaseReply if there is a client marshaling error or an
  99. // error in _invoke.
  100. invocationInfo.setClientRequestDispatcher(subcontract);
  101. return (OutputStream)
  102. subcontract.beginRequest(self, operation,
  103. !responseExpected, contactInfo);
  104. }
  105. public InputStream invoke(org.omg.CORBA.Object self, OutputStream output)
  106. throws
  107. ApplicationException,
  108. RemarshalException
  109. {
  110. ClientRequestDispatcher subcontract = getClientRequestDispatcher();
  111. return (InputStream)
  112. subcontract.marshalingComplete((Object)self, (OutputObject)output);
  113. }
  114. public void releaseReply(org.omg.CORBA.Object self, InputStream input)
  115. {
  116. // NOTE: InputStream may be null (e.g., exception request from PI).
  117. ClientRequestDispatcher subcontract = getClientRequestDispatcher();
  118. subcontract.endRequest(orb, self, (InputObject)input);
  119. orb.releaseOrDecrementInvocationInfo();
  120. }
  121. private ClientRequestDispatcher getClientRequestDispatcher()
  122. {
  123. return (ClientRequestDispatcher)
  124. ((CorbaInvocationInfo)orb.getInvocationInfo())
  125. .getClientRequestDispatcher();
  126. }
  127. public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object obj)
  128. {
  129. InputStream is = null;
  130. // instantiate the stub
  131. org.omg.CORBA.Object stub = null ;
  132. try {
  133. OutputStream os = request(null, "_interface", true);
  134. is = (InputStream) invoke((org.omg.CORBA.Object)null, os);
  135. org.omg.CORBA.Object objimpl =
  136. (org.omg.CORBA.Object) is.read_Object();
  137. // check if returned object is of correct type
  138. if ( !objimpl._is_a("IDL:omg.org/CORBA/InterfaceDef:1.0") )
  139. throw wrapper.wrongInterfaceDef(CompletionStatus.COMPLETED_MAYBE);
  140. try {
  141. stub = (org.omg.CORBA.Object)
  142. JDKBridge.loadClass("org.omg.CORBA._InterfaceDefStub").
  143. newInstance();
  144. } catch (Exception ex) {
  145. throw wrapper.noInterfaceDefStub( ex ) ;
  146. }
  147. org.omg.CORBA.portable.Delegate del =
  148. StubAdapter.getDelegate( objimpl ) ;
  149. StubAdapter.setDelegate( stub, del ) ;
  150. } catch (ApplicationException e) {
  151. // This cannot happen.
  152. throw wrapper.applicationExceptionInSpecialMethod( e ) ;
  153. } catch (RemarshalException e) {
  154. return get_interface_def(obj);
  155. } finally {
  156. releaseReply((org.omg.CORBA.Object)null, (InputStream)is);
  157. }
  158. return stub;
  159. }
  160. public boolean is_a(org.omg.CORBA.Object obj, String dest)
  161. {
  162. // dest is the typeId of the interface to compare against.
  163. // repositoryIds is the list of typeIds that the stub knows about.
  164. // First we look for an answer using local information.
  165. String [] repositoryIds = StubAdapter.getTypeIds( obj ) ;
  166. String myid = contactInfoList.getTargetIOR().getTypeId();
  167. if ( dest.equals(myid) ) {
  168. return true;
  169. }
  170. for ( int i=0; i<repositoryIds.length; i++ ) {
  171. if ( dest.equals(repositoryIds[i]) ) {
  172. return true;
  173. }
  174. }
  175. // But repositoryIds may not be complete, so it may be necessary to
  176. // go to server.
  177. InputStream is = null;
  178. try {
  179. OutputStream os = request(null, "_is_a", true);
  180. os.write_string(dest);
  181. is = (InputStream) invoke((org.omg.CORBA.Object) null, os);
  182. return is.read_boolean();
  183. } catch (ApplicationException e) {
  184. // This cannot happen.
  185. throw wrapper.applicationExceptionInSpecialMethod( e ) ;
  186. } catch (RemarshalException e) {
  187. return is_a(obj, dest);
  188. } finally {
  189. releaseReply((org.omg.CORBA.Object)null, (InputStream)is);
  190. }
  191. }
  192. public boolean non_existent(org.omg.CORBA.Object obj)
  193. {
  194. InputStream is = null;
  195. try {
  196. OutputStream os = request(null, "_non_existent", true);
  197. is = (InputStream) invoke((org.omg.CORBA.Object)null, os);
  198. return is.read_boolean();
  199. } catch (ApplicationException e) {
  200. // This cannot happen.
  201. throw wrapper.applicationExceptionInSpecialMethod( e ) ;
  202. } catch (RemarshalException e) {
  203. return non_existent(obj);
  204. } finally {
  205. releaseReply((org.omg.CORBA.Object)null, (InputStream)is);
  206. }
  207. }
  208. public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object obj)
  209. {
  210. return obj;
  211. }
  212. public void release(org.omg.CORBA.Object obj)
  213. {
  214. // DO NOT clear out internal variables to release memory
  215. // This delegate may be pointed-to by other objrefs.
  216. }
  217. // obj._get_delegate() == this due to the argument passing conventions in
  218. // portable.ObjectImpl, so we just ignore obj here.
  219. public boolean is_equivalent(org.omg.CORBA.Object obj,
  220. org.omg.CORBA.Object ref)
  221. {
  222. if ( ref == null )
  223. return false;
  224. // If ref is a local object, it is not a Stub!
  225. if (!StubAdapter.isStub(ref))
  226. return false ;
  227. Delegate del = StubAdapter.getDelegate(ref) ;
  228. if (del == null)
  229. return false ;
  230. // Optimize the x.is_equivalent( x ) case
  231. if (del == this)
  232. return true;
  233. // If delegate was created by a different ORB, return false
  234. if (!(del instanceof CorbaClientDelegateImpl))
  235. return false ;
  236. CorbaClientDelegateImpl corbaDelegate = (CorbaClientDelegateImpl)del ;
  237. CorbaContactInfoList ccil =
  238. (CorbaContactInfoList)corbaDelegate.getContactInfoList() ;
  239. return this.contactInfoList.getTargetIOR().isEquivalent(
  240. ccil.getTargetIOR() );
  241. }
  242. /**
  243. * This method overrides the org.omg.CORBA.portable.Delegate.equals method,
  244. * and does the equality check based on IOR equality.
  245. */
  246. public boolean equals(org.omg.CORBA.Object self, java.lang.Object other)
  247. {
  248. if (other == null)
  249. return false ;
  250. if (!StubAdapter.isStub(other)) {
  251. return false;
  252. }
  253. Delegate delegate = StubAdapter.getDelegate( other ) ;
  254. if (delegate == null)
  255. return false ;
  256. if (delegate instanceof CorbaClientDelegateImpl) {
  257. CorbaClientDelegateImpl otherDel = (CorbaClientDelegateImpl)
  258. delegate ;
  259. IOR otherIor = otherDel.contactInfoList.getTargetIOR();
  260. return this.contactInfoList.getTargetIOR().equals(otherIor);
  261. }
  262. // Come here if other is not implemented by our ORB.
  263. return false;
  264. }
  265. public int hashCode(org.omg.CORBA.Object obj)
  266. {
  267. return this.hashCode() ;
  268. }
  269. public int hash(org.omg.CORBA.Object obj, int maximum)
  270. {
  271. int h = this.hashCode();
  272. if ( h > maximum )
  273. return 0;
  274. return h;
  275. }
  276. public Request request(org.omg.CORBA.Object obj, String operation)
  277. {
  278. return new RequestImpl(orb, obj, null, operation, null, null, null,
  279. null);
  280. }
  281. public Request create_request(org.omg.CORBA.Object obj,
  282. Context ctx,
  283. String operation,
  284. NVList arg_list,
  285. NamedValue result)
  286. {
  287. return new RequestImpl(orb, obj, ctx, operation, arg_list,
  288. result, null, null);
  289. }
  290. public Request create_request(org.omg.CORBA.Object obj,
  291. Context ctx,
  292. String operation,
  293. NVList arg_list,
  294. NamedValue result,
  295. ExceptionList exclist,
  296. ContextList ctxlist)
  297. {
  298. return new RequestImpl(orb, obj, ctx, operation, arg_list, result,
  299. exclist, ctxlist);
  300. }
  301. public org.omg.CORBA.ORB orb(org.omg.CORBA.Object obj)
  302. {
  303. return this.orb;
  304. }
  305. /**
  306. * Returns true if this object is implemented by a local servant.
  307. *
  308. * REVISIT: locatedIOR should be replaced with a method call that
  309. * returns the current IOR for this request (e.g. ContactInfoChooser).
  310. *
  311. * @param self The object reference which delegated to this delegate.
  312. * @return true only if the servant incarnating this object is located in
  313. * this ORB.
  314. */
  315. public boolean is_local(org.omg.CORBA.Object self)
  316. {
  317. // XXX this need to check isNextCallValid
  318. return contactInfoList.getEffectiveTargetIOR().getProfile().
  319. isLocal();
  320. }
  321. public ServantObject servant_preinvoke(org.omg.CORBA.Object self,
  322. String operation,
  323. Class expectedType)
  324. {
  325. return
  326. contactInfoList.getLocalClientRequestDispatcher()
  327. .servant_preinvoke(self, operation, expectedType);
  328. }
  329. public void servant_postinvoke(org.omg.CORBA.Object self,
  330. ServantObject servant)
  331. {
  332. contactInfoList.getLocalClientRequestDispatcher()
  333. .servant_postinvoke(self, servant);
  334. }
  335. // XXX Should this be public?
  336. /* Returns the codebase for object reference provided.
  337. * @param self the object reference whose codebase needs to be returned.
  338. * @return the codebase as a space delimited list of url strings or
  339. * null if none.
  340. */
  341. public String get_codebase(org.omg.CORBA.Object self)
  342. {
  343. if (contactInfoList.getTargetIOR() != null) {
  344. return contactInfoList.getTargetIOR().getProfile().getCodebase();
  345. }
  346. return null;
  347. }
  348. public String toString(org.omg.CORBA.Object self)
  349. {
  350. return contactInfoList.getTargetIOR().stringify();
  351. }
  352. ////////////////////////////////////////////////////
  353. //
  354. // java.lang.Object
  355. //
  356. public int hashCode()
  357. {
  358. return this.contactInfoList.hashCode();
  359. }
  360. }
  361. // End of file.