1. /*
  2. * @(#)SubcontractRegistry.java 1.43 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. package com.sun.corba.se.internal.core;
  8. import java.util.*;
  9. import org.omg.IOP.TAG_INTERNET_IOP ;
  10. import com.sun.corba.se.internal.ior.ObjectKey ;
  11. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  12. import com.sun.corba.se.internal.ior.ObjectKeyFactory ;
  13. import com.sun.corba.se.internal.ior.IORTemplate ;
  14. import com.sun.corba.se.internal.ior.IIOPProfileTemplate ;
  15. import com.sun.corba.se.internal.ior.WireObjectKeyTemplate ;
  16. import com.sun.corba.se.internal.ior.ObjectId ;
  17. import com.sun.corba.se.internal.corba.INSSubcontract;
  18. import com.sun.corba.se.internal.orbutil.MinorCodes ;
  19. import com.sun.corba.se.internal.orbutil.ORBConstants ;
  20. import org.omg.CORBA.BAD_PARAM ;
  21. import org.omg.CORBA.INTERNAL ;
  22. import org.omg.CORBA.CompletionStatus ;
  23. import org.omg.CORBA.ORB ;
  24. /**
  25. * This is a registry of all client subcontract classes and
  26. * server subcontract instances.
  27. *
  28. * In order to allow reuse of this in more than one context
  29. * (that is, ORBs), we try not to throw any CORBA specific
  30. * exceptions. Most of the methods either throw Java exceptions
  31. * or return nulls or false on failure.
  32. */
  33. public class SubcontractRegistry {
  34. protected ORB orb;
  35. protected int size;
  36. protected ServerSubcontract[] serverRegistry;
  37. protected Class[] clientFactory;
  38. protected int defaultId;
  39. private INSSubcontract insSubcontract = null;
  40. public void dumpServers()
  41. {
  42. System.out.println( "Dump of registered server subcontracts:" ) ;
  43. for (int ctr=0; ctr<serverRegistry.length; ctr++ ) {
  44. ServerSubcontract sc = serverRegistry[ctr] ;
  45. if (sc != null)
  46. System.out.println( "serverRegistry[" + ctr + "] = " + sc ) ;
  47. }
  48. }
  49. public SubcontractRegistry(ORB orb, int defaultId) {
  50. this(orb, defaultId, 256);
  51. }
  52. public SubcontractRegistry(ORB orb, int defaultId, int size) {
  53. this.orb = orb;
  54. this.size = size;
  55. this.defaultId = defaultId;
  56. serverRegistry = new ServerSubcontract[size];
  57. clientFactory = new Class[size];
  58. }
  59. public synchronized boolean registerClient(Class clientSC,
  60. int scid)
  61. {
  62. if (scid < size) {
  63. clientFactory[scid] = clientSC;
  64. return true;
  65. }
  66. return false;
  67. }
  68. public synchronized boolean registerServer(ServerSubcontract sc,
  69. int scid) {
  70. if (scid < size) {
  71. serverRegistry[scid] = sc;
  72. return true;
  73. }
  74. return false;
  75. }
  76. // REVISIT replace this with a more general registration mechanism
  77. protected ServerSubcontract bootstrapServer = null;
  78. public void registerBootstrapServer(ServerSubcontract sc)
  79. {
  80. this.bootstrapServer = sc;
  81. }
  82. // **************************************************
  83. // Methods to find the subcontract side subcontract
  84. // **************************************************
  85. public ServerSubcontract getServerSubcontract(int scid)
  86. {
  87. ServerSubcontract sc=null;
  88. if ((scid >= 0) && (scid < size))
  89. sc = serverRegistry[scid];
  90. if ( sc == null )
  91. return serverRegistry[defaultId];
  92. else
  93. return sc;
  94. }
  95. /** Find a server subcontract based on the object key.
  96. * This is a key method in the server side dispatch of
  97. * requests. This method is called from the ORB process method
  98. * in response to an incoming request.
  99. * <p>
  100. * Note that we should probably at some point replace the fixed
  101. * names with a name registry for subcontracts whose entire
  102. * object key is a name.
  103. */
  104. public ServerSubcontract getServerSubcontract(ObjectKey objKey)
  105. {
  106. ObjectKeyTemplate oktemp = objKey.getTemplate() ;
  107. if (oktemp instanceof WireObjectKeyTemplate) {
  108. String okstring = new String( objKey.getBytes(orb) );
  109. // The orginal (circa 1997) bootstrap protocol used a 32 bit int
  110. // corresponding to the characters "INIT". We allow for this
  111. // to be marshalled either big endian or little endian here.
  112. // If it had always been a string, we would not need to do this.
  113. if (okstring.equals( "INIT" ) || okstring.equals( "TINI" ))
  114. return bootstrapServer ;
  115. // INS Object Key strings will be in the ASCII format, Like
  116. // for example NameService. If we are successful in finding
  117. // the subcontract based on the key then just return that, else
  118. // there is an error.
  119. INSObjectKeyEntry keyEntry =
  120. INSObjectKeyMap.getInstance( ).getEntry(okstring);
  121. if( keyEntry != null ) {
  122. return getINSSubcontract( );
  123. }
  124. } else {
  125. int scid = oktemp.getSubcontractId();
  126. return getServerSubcontract( scid );
  127. }
  128. throw new INTERNAL( MinorCodes.NO_SERVER_SUBCONTRACT,
  129. CompletionStatus.COMPLETED_NO ) ;
  130. }
  131. private synchronized INSSubcontract getINSSubcontract ( ) {
  132. if( insSubcontract == null ) {
  133. insSubcontract = new INSSubcontract( orb );
  134. }
  135. return insSubcontract;
  136. }
  137. // **************************************************
  138. // Methods to find the client side subcontract
  139. // **************************************************
  140. public ClientSubcontract getClientSubcontract(ObjectKey key)
  141. {
  142. return getClientSubcontract( key.getTemplate() ) ;
  143. }
  144. public ClientSubcontract getClientSubcontract( IORTemplate temp )
  145. {
  146. // REVISIT we eventually need to fix this if we need to handle
  147. // multi-profile IORs. For now, it only returns a subcontract
  148. // if the template has exactly one IIOP profile template and no
  149. // other templates. In this case, we simply delegate to
  150. // getClientSubcontract( ObjectKeyTemplate ).
  151. //
  152. // Note that this is the place to insert a lookup for subcontracts
  153. // for fault tolerance or client side load balancing.
  154. if (temp.size() != 1)
  155. throw new INTERNAL( MinorCodes.SERVER_SC_TEMP_SIZE,
  156. CompletionStatus.COMPLETED_NO ) ;
  157. Iterator iter = temp.iteratorById( TAG_INTERNET_IOP.value ) ;
  158. Object obj = iter.next() ;
  159. if (!(obj instanceof IIOPProfileTemplate))
  160. throw new INTERNAL( MinorCodes.SERVER_SC_NO_IIOP_PROFILE,
  161. CompletionStatus.COMPLETED_NO ) ;
  162. IIOPProfileTemplate iptemp = (IIOPProfileTemplate)(obj) ;
  163. return getClientSubcontract( iptemp.getObjectKeyTemplate() ) ;
  164. }
  165. public ClientSubcontract getClientSubcontract( ObjectKeyTemplate temp )
  166. {
  167. int scid = temp.getSubcontractId() ;
  168. return getClientSubcontract( scid ) ;
  169. }
  170. public ClientSubcontract getClientSubcontract( int scid )
  171. {
  172. Class repClass = null ;
  173. ClientSubcontract rep = null ;
  174. if ((scid >= 0) && (scid < size))
  175. repClass = clientFactory[scid] ;
  176. if (repClass == null) {
  177. scid = defaultId ;
  178. repClass = clientFactory[scid] ;
  179. }
  180. try {
  181. rep = (ClientSubcontract)(repClass.newInstance()) ;
  182. } catch (Exception e1){
  183. // Serious error: could not create instance of class.
  184. // Should not happen.
  185. throw new INTERNAL( MinorCodes.NO_CLIENT_SC_CLASS,
  186. CompletionStatus.COMPLETED_NO ) ;
  187. }
  188. rep.setId( scid ) ;
  189. return rep ;
  190. }
  191. }