1. /*
  2. * @(#)ObjectAdapter.java 1.27 03/12/19
  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.spi.oa ;
  8. import org.omg.CORBA.Policy ;
  9. import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
  10. import org.omg.PortableInterceptor.ObjectReferenceFactory ;
  11. import com.sun.corba.se.spi.orb.ORB ;
  12. import com.sun.corba.se.spi.oa.OADestroyed ;
  13. import com.sun.corba.se.spi.ior.IORTemplate ;
  14. // REVISIT: What should the order be? enter/push...pop/exit?
  15. /** ObjectAdapter represents the abstract model of an object
  16. * adapter that was introduced by ORT. This means that all
  17. * object adapters must:
  18. * <UL>
  19. * <LI>Have an ORB</LI>
  20. * <LI>Have a name</LI>
  21. * <LI>Have an adapter manager (represented by an ID)</LI>
  22. * <LI>Have an adapter template</LI>
  23. * <LI>Support getting and setting their ObjectReferenceFactory</LI>
  24. * <LI>Provide access to their current state</LI>
  25. * <LI>Support adding components to their profiles expressed in the adapter template</LI>
  26. * </UL>
  27. * Other requirements:
  28. * <UL>
  29. * <LI>All object adapters must invoke ORB.AdapterCreated when they are created.
  30. * </LI>
  31. * <LI>All adapter managers must invoke ORB.AdapterManagerStateChanged when
  32. * their state changes, mapping the internal state to an ORT state.</LI>
  33. * <LI>AdapterStateChanged must be invoked (from somewhere) whenever
  34. * an adapter state changes that is not due to an adapter manager state change.</LI>
  35. * </UL>
  36. * <P>
  37. * Object adapters must also provide mechanisms for:
  38. * <UL>
  39. * <LI>Managing object reference lifecycle</LI>
  40. * <LI>Controlling how servants are associated with object references</LI>
  41. * <LI>Manage the state of the adapter, if the adapter desires to implement such mechanisms</LI>
  42. * </UL>
  43. * Such mechanisms are all object adapter specific, and so we do not attempt to
  44. * create general APIs for these functions here. The object adapter itself
  45. * must provide these APIs directly to the user, and they do not affect the rest of the
  46. * ORB. This interface basically makes it possible to plug any object adapter into the
  47. * ORB and have the OA work propertly with portable interceptors, and also have requests
  48. * dispatched properly to the object adapter.
  49. * <P>
  50. * The basic function of an ObjectAdapter is to map object IDs to servants and to support
  51. * the dispatch operation of the subcontract, which dispatches requests to servants.
  52. * This is the purpose of the getInvocationServant method. In addition, ObjectAdapters must be
  53. * able to change state gracefully in the presence of executing methods. This
  54. * requires the use of the enter/exit methods. Finally, ObjectAdapters often
  55. * require access to information about requests. This is accomodated through the
  56. * OAInvocationInfo class and the thread local stack maintained by push/pop/peekInvocationInfo
  57. * on the ORB.
  58. * <P>
  59. * To be useful, this dispatch cycle must be extremely efficient. There are several
  60. * scenarios that matter:
  61. * <ol>
  62. * <li>A remote invocation, where the dispatch is handled in the server subcontract.</li>
  63. * <li>A local invocation, where the dispatch is handled in the client subcontract.</li>
  64. * <li>A cached local invocation, where the servant is cached when the IOR is established
  65. * for the client subcontract, and the dispatch is handled in the client subcontract
  66. * to the cached subcontract.<li>
  67. * </ol>
  68. * <p>
  69. * Each of these 3 cases is handled a bit differently. On each request, assume as known
  70. * ObjectId and ObjectAdapterId, which can be obtained from the object key.
  71. * The ObjectAdaptorFactory is available in the subcontract registry, where it is
  72. * registered under the subcontract ID. The Subcontract ID is also available in the
  73. * object key.
  74. * <ol>
  75. * <li>The remote pattern:
  76. * <ol>
  77. * <li>oa = oaf.find( oaid )</li>
  78. * <li>oa.enter()</li>
  79. * <li>info = oa.makeInvocationInfo( oid )</li>
  80. * <li>info.setOperation( operation )</li>
  81. * <li>push info</li>
  82. * <li>oa.getInvocationServant( info )</li>
  83. * <li>sreq.setExecuteReturnServantInResponseConstructor( true )</li>
  84. * <li>dispatch to servant</li>
  85. * <li>oa.returnServant()</li>
  86. * <li>oa.exit()</li>
  87. * <li>pop info</li>
  88. * <ol>
  89. * </li>
  90. * REVISIT: Is this the required order for exit/pop? Cna they be nested instead?
  91. * Note that getInvocationServant and returnServant may throw exceptions. In such cases,
  92. * returnServant, exit, and pop must be called in the correct order.
  93. * <li>The local pattern:
  94. * <ol>
  95. * <li>oa = oaf.find( oaid )</li>
  96. * <li>oa.enter()</li>
  97. * <li>info = oa.makeInvocationInfo( oid )</li>
  98. * <li>info.setOperation( operation )</li>
  99. * <li>push info</li>
  100. * <li>oa.getInvocationServant( info )</li>
  101. * <li>dispatch to servant</li>
  102. * <li>oa.returnServant()</li>
  103. * <li>oa.exit()</li>
  104. * <li>pop info</li>
  105. * <ol>
  106. * </li>
  107. * This is the same as the remote case, except that setExecuteReturnServantInResponseConstructor
  108. * is not needed (or possible, since there is no server request).
  109. * <li>The fast local pattern: When delegate is constructed,
  110. * first extract ObjectKey from IOR in delegate,
  111. * then get ObjectId, ObjectAdapterId, and ObjectAdapterFactory (oaf). Then:
  112. * <ol>
  113. * <li>oa = oaf.find( oaid )</li>
  114. * <li>info = oa.makeInvocationInfo( oid ) (note: no operation!)</li>
  115. * <li>push info (needed for the correct functioning of getInvocationServant)</li>
  116. * <li>oa.getInvocationServant( info )</li>
  117. * <li>pop info
  118. * </ol>
  119. * The info instance (which includes the Servant) is cached in the client subcontract.
  120. * <p>Then, on each invocation:</p>
  121. * <ol>
  122. * <li>newinfo = copy of info (clone)</li>
  123. * <li>info.setOperation( operation )</li>
  124. * <li>push newinfo</li>
  125. * <li>oa.enter()</li>
  126. * <li>dispatch to servant</li>
  127. * <li>oa.returnServant()</li> // XXX This is probably wrong: remove it.
  128. * <li>oa.exit()</li>
  129. * <li>pop info</li>
  130. * </ol>
  131. * </li>
  132. * </ol>
  133. * XXX fast local should not call returnServant: what is correct here?
  134. */
  135. public interface ObjectAdapter
  136. {
  137. ////////////////////////////////////////////////////////////////////////////
  138. // Basic methods for supporting interceptors
  139. ////////////////////////////////////////////////////////////////////////////
  140. /** Returns the ORB associated with this adapter.
  141. */
  142. ORB getORB() ;
  143. Policy getEffectivePolicy( int type ) ;
  144. /** Returns the IOR template of this adapter. The profiles
  145. * in this template may be updated only during the AdapterCreated call.
  146. * After that call completes, the IOR template must be made immutable.
  147. * Note that the server ID, ORB ID, and adapter name are all available
  148. * from the IOR template.
  149. */
  150. IORTemplate getIORTemplate() ;
  151. ////////////////////////////////////////////////////////////////////////////
  152. // Methods needed to support ORT.
  153. ////////////////////////////////////////////////////////////////////////////
  154. /** Return the ID of the AdapterManager for this object adapter.
  155. */
  156. int getManagerId() ;
  157. /** Return the current state of this object adapter (see
  158. * org.omg.PortableInterceptors for states.
  159. */
  160. short getState() ;
  161. ObjectReferenceTemplate getAdapterTemplate() ;
  162. ObjectReferenceFactory getCurrentFactory() ;
  163. /** Change the current factory. This may only be called during the
  164. * AdapterCreated call.
  165. */
  166. void setCurrentFactory( ObjectReferenceFactory factory ) ;
  167. ////////////////////////////////////////////////////////////////////////////
  168. // Methods required for dispatching to servants
  169. ////////////////////////////////////////////////////////////////////////////
  170. /** Get the servant corresponding to the given objectId, if this is supported.
  171. * This method is only used for models where the servant is an ObjectImpl,
  172. * which allows the servant to be used directly as the stub. This allows an object
  173. * reference to be replaced by its servant when it is unmarshalled locally.
  174. * Such objects are not ORB mediated.
  175. */
  176. org.omg.CORBA.Object getLocalServant( byte[] objectId ) ;
  177. /** Get the servant for the request given by the parameters.
  178. * info must contain a valid objectId in this call.
  179. * The servant is set in the InvocationInfo argument that is passed into
  180. * this call.
  181. * @param info is the InvocationInfo object for the object reference
  182. * @exception ForwardException (a runtime exception) is thrown if the request
  183. * is to be handled by a different object reference.
  184. */
  185. void getInvocationServant( OAInvocationInfo info ) ;
  186. /** enter must be called before each request is invoked on a servant.
  187. * @exception OADestroyed is thrown when an OA has been destroyed, which
  188. * requires a retry in the case where an AdapterActivator is present.
  189. */
  190. void enter( ) throws OADestroyed ;
  191. /** exit must be called after each request has been completed. If enter
  192. * is called, there must always be a corresponding exit.
  193. */
  194. void exit( ) ;
  195. /** Must be called every time getInvocationServant is called after
  196. * the request has completed.
  197. */
  198. public void returnServant() ;
  199. /** Create an instance of InvocationInfo that is appropriate for this
  200. * Object adapter.
  201. */
  202. OAInvocationInfo makeInvocationInfo( byte[] objectId ) ;
  203. /** Return the most derived interface for the given servant and objectId.
  204. */
  205. String[] getInterfaces( Object servant, byte[] objectId ) ;
  206. }