1. /*
  2. * @(#)ServantCachePOAClientSC.java 1.14 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.POA;
  8. import org.omg.CORBA.*;
  9. import org.omg.CORBA.portable.*;
  10. import com.sun.corba.se.internal.core.*;
  11. import com.sun.corba.se.internal.core.NoSuchServiceContext ;
  12. import com.sun.corba.se.internal.core.DuplicateServiceContext ;
  13. import com.sun.corba.se.internal.orbutil.ORBUtility; //d11638
  14. import com.sun.corba.se.internal.orbutil.ORBConstants;
  15. import com.sun.corba.se.internal.corba.ClientDelegate;
  16. import com.sun.corba.se.internal.corba.ServerDelegate;
  17. import com.sun.corba.se.internal.iiop.Connection ;
  18. import com.sun.corba.se.internal.iiop.ClientRequestImpl;
  19. import com.sun.corba.se.internal.iiop.messages.ReplyMessage;
  20. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  21. import com.sun.corba.se.internal.ior.POAObjectKeyTemplate ;
  22. import com.sun.corba.se.internal.ior.POAId ;
  23. import com.sun.corba.se.internal.POA.POAORB ;
  24. import com.sun.corba.se.internal.orbutil.MinorCodes;
  25. public class ServantCachePOAClientSC extends GenericPOAClientSC implements ClientSC
  26. {
  27. protected ServantObject servant = null ;
  28. protected boolean servantIsLocal = false ;
  29. protected ClassLoader servantClassLoader = null ;
  30. protected POAImpl servantPOA = null ;
  31. // If isNextIsLocalValid.get() == null, the next call to isLocal should be
  32. // valid
  33. protected ThreadLocal isNextIsLocalValid = new ThreadLocal() ;
  34. private boolean useLocalInvocation_ClassLoader( org.omg.CORBA.Object self )
  35. {
  36. // Access to ClassLoader is quite slow
  37. ClassLoader myClassLoader = self.getClass().getClassLoader() ;
  38. return
  39. (myClassLoader == servantClassLoader) &&
  40. servantIsLocal ;
  41. }
  42. private boolean useLocalInvocation_reflection( org.omg.CORBA.Object self )
  43. {
  44. Class[] interfaces = self.getClass().getInterfaces() ;
  45. // Since self is an RMI-IIOP stub, interfaces should contain exactly
  46. // one element, which is the remote interface that the servant
  47. // must implement.
  48. return interfaces[0].isInstance( servant.servant ) && servantIsLocal ;
  49. }
  50. /*
  51. * Possible paths through useLocalInvocation/servant_preinvoke/servant_postinvoke:
  52. *
  53. * A: call useLocalInvocation
  54. * If useLocalInvocation returns false, servant_preinvoke is not called.
  55. * If useLocalInvocation returns true,
  56. * call servant_preinvoke
  57. * If servant_preinvoke returns null,
  58. * goto A
  59. * else
  60. * (local invocation proceeds normally)
  61. * servant_postinvoke is called
  62. *
  63. */
  64. private boolean useLocalInvocation_tlcache( org.omg.CORBA.Object self )
  65. {
  66. if (isNextIsLocalValid.get() == null)
  67. return servantIsLocal ;
  68. else
  69. isNextIsLocalValid.set( null ) ;
  70. return false ;
  71. }
  72. public boolean useLocalInvocation( org.omg.CORBA.Object self )
  73. {
  74. return useLocalInvocation_tlcache( self ) ;
  75. }
  76. public void setOrb( com.sun.corba.se.internal.core.ORB orb )
  77. {
  78. super.setOrb( orb ) ;
  79. initServant() ;
  80. }
  81. public void unmarshal( IOR ior )
  82. {
  83. super.unmarshal( ior ) ;
  84. initServant() ;
  85. }
  86. private void initServant()
  87. {
  88. if ((ior != null) && (orb != null)) {
  89. servantIsLocal = orb.allowLocalOptimization && ior.isLocal() ;
  90. if (servantIsLocal) {
  91. servant = serversc.preinvoke( ior, "", java.lang.Object.class ) ;
  92. serversc.postinvoke( ior, servant ) ;
  93. POAId poaid = ior.getPOAId() ;
  94. servantPOA = (POAImpl)(serversc.getPOA( poaid ) ) ;
  95. servantClassLoader = servant.servant.getClass().getClassLoader() ;
  96. }
  97. }
  98. }
  99. public ServantObject servant_preinvoke( org.omg.CORBA.Object self,
  100. String operation, Class expectedType )
  101. {
  102. // Normally, this test will never fail. However, if the servant
  103. // and the stub were loaded in different class loaders, this test
  104. // will fail.
  105. if (!expectedType.isInstance( servant.servant )) {
  106. // set the flag to a non-null object. "this" is always
  107. // available and requires no allocation.
  108. isNextIsLocalValid.set( this ) ;
  109. // When servant_preinvoke returns null, the RMI-IIOP stub will
  110. // recursively re-invoke itself. Thus, the next call made from
  111. // the stub is another useLocalInvocation call.
  112. return null ;
  113. }
  114. try {
  115. servantPOA.enter() ;
  116. } catch (Exception exc) {}
  117. return servant ;
  118. }
  119. public void servant_postinvoke(org.omg.CORBA.Object self,
  120. ServantObject servantobj)
  121. {
  122. // NOP
  123. servantPOA.exit() ;
  124. }
  125. }