1. /*
  2. * @(#)POACurrent.java 1.16 03/08/13
  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 java.util.*;
  9. import org.omg.CORBA.INTERNAL;
  10. import org.omg.CORBA.CompletionStatus;
  11. import org.omg.PortableServer.CurrentPackage.NoContext;
  12. import org.omg.PortableServer.POA;
  13. import org.omg.PortableServer.Servant;
  14. import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
  15. //Needs to be turned into LocalObjectImpl.
  16. public class POACurrent extends org.omg.CORBA.portable.ObjectImpl
  17. implements org.omg.PortableServer.Current
  18. {
  19. private POAORB orb;
  20. private ThreadLocal threadLocal
  21. = new ThreadLocal()
  22. {
  23. protected Object initialValue() {
  24. return new Stack();
  25. }
  26. };
  27. // This is used for debugging only.
  28. public int size()
  29. {
  30. return ((Stack) threadLocal.get()).size();
  31. }
  32. POACurrent(POAORB orb)
  33. {
  34. this.orb = orb;
  35. }
  36. public String[] _ids()
  37. {
  38. String[] ids = new String[1];
  39. ids[0] = "IDL:omg.org/PortableServer/Current:1.0";
  40. return ids;
  41. }
  42. //
  43. // Standard OMG operations.
  44. //
  45. public POA get_POA()
  46. throws
  47. NoContext
  48. {
  49. POA poa = peekThrowNoContext().poa();
  50. throwNoContextIfNull(poa);
  51. return poa;
  52. }
  53. public byte[] get_object_id()
  54. throws
  55. NoContext
  56. {
  57. byte[] objectid = peekThrowNoContext().id();
  58. throwNoContextIfNull(objectid);
  59. return objectid;
  60. }
  61. //
  62. // Implementation operations used by POA package.
  63. //
  64. public POAImpl getPOA()
  65. {
  66. POAImpl poa = (POAImpl) peekThrowInternal().poa();
  67. throwInternalIfNull(poa);
  68. return poa;
  69. }
  70. public byte[] getObjectId()
  71. {
  72. byte[] objectid = peekThrowInternal().id();
  73. throwInternalIfNull(objectid);
  74. return objectid;
  75. }
  76. Servant getServant()
  77. {
  78. Servant servant = peekThrowInternal().getServant();
  79. // If is OK for the servant to be null.
  80. // This could happen if POAImpl.getServant is called but
  81. // POAImpl.internalGetServant throws an exception.
  82. return servant;
  83. }
  84. CookieHolder getCookieHolder()
  85. {
  86. CookieHolder cookieHolder = peekThrowInternal().getCookieHolder();
  87. throwInternalIfNull(cookieHolder);
  88. return cookieHolder;
  89. }
  90. // This is public so we can test the stack balance.
  91. // It is not a security hole since this same info can be obtained from
  92. // PortableInterceptors.
  93. public String getOperation()
  94. {
  95. String operation = peekThrowInternal().getOperation();
  96. throwInternalIfNull(operation);
  97. return operation;
  98. }
  99. void setServant(Servant servant)
  100. {
  101. peekThrowInternal().setServant( servant );
  102. }
  103. void setPreInvokeCalled()
  104. {
  105. peekThrowInternal().setPreInvokeCalled();
  106. }
  107. boolean preInvokeCalled()
  108. {
  109. return peekThrowInternal().preInvokeCalled();
  110. }
  111. void setPostInvokeCalled()
  112. {
  113. peekThrowInternal().setPostInvokeCalled();
  114. }
  115. boolean postInvokeCalled()
  116. {
  117. return peekThrowInternal().postInvokeCalled();
  118. }
  119. public void addThreadInfo(POA poa, byte[] id, CookieHolder cookieHolder,
  120. String operation)
  121. {
  122. //The first get() initializes the stack
  123. Stack stack = (Stack) threadLocal.get();
  124. stack.push(new InvocationInfo(poa, id, cookieHolder, operation));
  125. }
  126. public void removeThreadInfo()
  127. {
  128. try {
  129. ((Stack) threadLocal.get()).pop();
  130. } catch(EmptyStackException e){
  131. // REVISIT: It doesn't seem that doing extra pops should be OK.
  132. //Should not occur. If it does we are still OK.
  133. }
  134. }
  135. //
  136. // Class utilities.
  137. //
  138. public InvocationInfo peekThrowNoContext()
  139. throws
  140. NoContext
  141. {
  142. InvocationInfo invocationInfo = null;
  143. try {
  144. invocationInfo =
  145. (InvocationInfo) ((Stack) threadLocal.get()).peek();
  146. } catch (EmptyStackException e) {
  147. throw new NoContext();
  148. }
  149. return invocationInfo;
  150. }
  151. private InvocationInfo peekThrowInternal()
  152. {
  153. InvocationInfo invocationInfo = null;
  154. try {
  155. invocationInfo =
  156. (InvocationInfo) ((Stack) threadLocal.get()).peek();
  157. } catch (EmptyStackException e) {
  158. // The completion status is maybe because this could happen
  159. // after the servant has been invoked.
  160. throw new INTERNAL("POACurrent: unbalanced threadLocal stack.",
  161. MinorCodes.POACURRENT_UNBALANCED_STACK,
  162. CompletionStatus.COMPLETED_MAYBE);
  163. }
  164. return invocationInfo;
  165. }
  166. private void throwNoContextIfNull(Object o)
  167. throws
  168. NoContext
  169. {
  170. if ( o == null ) {
  171. throw new NoContext();
  172. }
  173. }
  174. private void throwInternalIfNull(Object o)
  175. {
  176. if ( o == null ) {
  177. throw new INTERNAL("POACurrent: null field.",
  178. MinorCodes.POACURRENT_NULL_FIELD,
  179. CompletionStatus.COMPLETED_MAYBE);
  180. }
  181. }
  182. }