1. /*
  2. * @(#)ShutdownUtilDelegate.java 1.18 04/01/13
  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.internal.iiop;
  8. import org.omg.CORBA.*;
  9. import java.util.*;
  10. import java.rmi.*;
  11. import java.io.*;
  12. import org.omg.CORBA.portable.OutputStream;
  13. import org.omg.CORBA.portable.UnknownException;
  14. import javax.transaction.TransactionRequiredException;
  15. import javax.transaction.TransactionRolledbackException;
  16. import javax.transaction.InvalidTransactionException;
  17. import javax.rmi.CORBA.Tie;
  18. import com.sun.corba.se.internal.util.Utility;
  19. import com.sun.corba.se.internal.orbutil.*;
  20. import com.sun.corba.se.internal.core.ORBVersionImpl;
  21. import com.sun.corba.se.internal.core.ORBVersion;
  22. import com.sun.corba.se.internal.core.ClientSubcontract;
  23. public class ShutdownUtilDelegate extends com.sun.corba.se.internal.javax.rmi.CORBA.Util
  24. {
  25. static ShutdownUtilDelegate instance = null;
  26. public ShutdownUtilDelegate() {
  27. instance = this;
  28. }
  29. public boolean isLocal(javax.rmi.CORBA.Stub stub) throws RemoteException {
  30. try {
  31. org.omg.CORBA.portable.Delegate delegate = stub._get_delegate() ;
  32. if (delegate instanceof ClientSubcontract)
  33. return ((ClientSubcontract)delegate).useLocalInvocation( stub ) ;
  34. else
  35. return delegate.is_local( stub );
  36. } catch (SystemException e) {
  37. throw javax.rmi.CORBA.Util.mapSystemException(e);
  38. }
  39. }
  40. protected void unregisterTargetsForORB(ORB orb) {
  41. super.unregisterTargetsForORB(orb);
  42. }
  43. /**
  44. * Maps a SystemException to a RemoteException.
  45. * @param ex the SystemException to map.
  46. * @return the mapped exception.
  47. */
  48. public RemoteException mapSystemException(SystemException ex) {
  49. if (ex instanceof UnknownException) {
  50. Throwable orig = ((UnknownException)ex).originalEx;
  51. if (orig instanceof Error) {
  52. return new ServerError("Error occurred in server thread",(Error)orig);
  53. } else if (orig instanceof RemoteException) {
  54. return new ServerException("RemoteException occurred in server thread",(Exception)orig);
  55. } else if (orig instanceof RuntimeException) {
  56. throw (RuntimeException) orig;
  57. }
  58. }
  59. // Build the message string...
  60. String name = ex.getClass().getName();
  61. String corbaName = name.substring(name.lastIndexOf('.')+1);
  62. String status;
  63. switch (ex.completed.value()) {
  64. case CompletionStatus._COMPLETED_YES:
  65. status = "Yes";
  66. break;
  67. case CompletionStatus._COMPLETED_NO:
  68. status = "No";
  69. break;
  70. case CompletionStatus._COMPLETED_MAYBE:
  71. default:
  72. status = "Maybe";
  73. break;
  74. }
  75. String message = "CORBA "+corbaName+" "+ex.minor+" "+status;
  76. // Now map to the correct RemoteException type...
  77. if (ex instanceof COMM_FAILURE) {
  78. return new MarshalException(message, ex);
  79. } else if (ex instanceof INV_OBJREF) {
  80. RemoteException newEx = new NoSuchObjectException(message);
  81. newEx.detail = ex;
  82. return newEx;
  83. } else if (ex instanceof NO_PERMISSION) {
  84. return new AccessException(message, ex);
  85. } else if (ex instanceof MARSHAL) {
  86. return new MarshalException(message, ex);
  87. } else if (ex instanceof OBJECT_NOT_EXIST) {
  88. RemoteException newEx = new NoSuchObjectException(message);
  89. newEx.detail = ex;
  90. return newEx;
  91. } else if (ex instanceof TRANSACTION_REQUIRED) {
  92. RemoteException newEx = new TransactionRequiredException(message);
  93. newEx.detail = ex;
  94. return newEx;
  95. } else if (ex instanceof TRANSACTION_ROLLEDBACK) {
  96. RemoteException newEx = new TransactionRolledbackException(message);
  97. newEx.detail = ex;
  98. return newEx;
  99. } else if (ex instanceof INVALID_TRANSACTION) {
  100. RemoteException newEx = new InvalidTransactionException(message);
  101. newEx.detail = ex;
  102. return newEx;
  103. } else if (ex instanceof BAD_PARAM) {
  104. Exception inner = ex;
  105. // Pre-Merlin Sun ORBs used the incorrect minor code for
  106. // this case. See Java to IDL ptc-00-01-08 1.4.8.
  107. if (ex.minor == MinorCodes.LEGACY_SUN_NOT_SERIALIZABLE ||
  108. ex.minor == MinorCodes.NOT_SERIALIZABLE) {
  109. if (ex.getMessage() != null)
  110. inner = new NotSerializableException(ex.getMessage());
  111. else
  112. inner = new NotSerializableException();
  113. }
  114. return new MarshalException(message,inner);
  115. }
  116. // Just map to a generic RemoteException...
  117. return new RemoteException(message, ex);
  118. }
  119. // Duplicated from the se delegate superclass. The subtle
  120. // difference is that it uses ORBUtility instead of Utility.
  121. // This is required since we can't assume that the Utility
  122. // version we're running with (may be from the JDK) has
  123. // the throwNotSerializableForCorba method that takes a
  124. // String parameter (added for JDK 1.4/J2EE 1.3).
  125. // Warning: Assumes Utility.autoConnect is available
  126. /**
  127. * Writes any java.lang.Object as a CORBA any.
  128. * @param out the stream in which to write the any.
  129. * @param obj the object to write as an any.
  130. */
  131. public void writeAny(org.omg.CORBA.portable.OutputStream out,
  132. java.lang.Object obj) {
  133. org.omg.CORBA.ORB orb = out.orb();
  134. // Create Any
  135. Any any = orb.create_any();
  136. // Make sure we have a connected object...
  137. java.lang.Object newObj = Utility.autoConnect(obj,orb,false);
  138. if (newObj instanceof org.omg.CORBA.Object) {
  139. any.insert_Object((org.omg.CORBA.Object)newObj);
  140. } else {
  141. if (newObj == null) {
  142. // Handle the null case, including backwards
  143. // compatibility issues
  144. any.insert_Value(null, createTypeCodeForNull(orb));
  145. } else {
  146. if (newObj instanceof Serializable) {
  147. // If they're our Any and ORB implementations,
  148. // we may want to do type code related versioning.
  149. TypeCode tc = createTypeCode((Serializable)newObj, any, orb);
  150. if (tc == null)
  151. any.insert_Value((Serializable)newObj);
  152. else
  153. any.insert_Value((Serializable)newObj, tc);
  154. } else if (newObj instanceof Remote) {
  155. ORBUtility.throwNotSerializableForCorba(newObj.getClass().getName());
  156. } else {
  157. ORBUtility.throwNotSerializableForCorba(newObj.getClass().getName());
  158. }
  159. }
  160. }
  161. //d11638 Write the Any
  162. out.write_any(any);
  163. }
  164. /**
  165. * When using our own ORB and Any implementations, we need to get
  166. * the ORB version and create the type code appropriately. This is
  167. * to overcome a bug in which the JDK 1.3.x ORBs used a tk_char
  168. * rather than a tk_wchar to describe a Java char field.
  169. *
  170. * This only works in RMI-IIOP with Util.writeAny since we actually
  171. * know what ORB and stream we're writing with when we insert
  172. * the value.
  173. *
  174. * Returns null if it wasn't possible to create the TypeCode (means
  175. * it wasn't our ORB or Any implementation).
  176. *
  177. * This does not handle null objs.
  178. */
  179. private TypeCode createTypeCode(Serializable obj,
  180. org.omg.CORBA.Any any,
  181. org.omg.CORBA.ORB orb) {
  182. if (any instanceof com.sun.corba.se.internal.corba.AnyImpl &&
  183. orb instanceof com.sun.corba.se.internal.corba.ORB) {
  184. com.sun.corba.se.internal.corba.AnyImpl anyImpl
  185. = (com.sun.corba.se.internal.corba.AnyImpl)any;
  186. com.sun.corba.se.internal.corba.ORB ourORB
  187. = (com.sun.corba.se.internal.corba.ORB)orb;
  188. return anyImpl.createTypeCodeForClass(obj.getClass(), ourORB);
  189. } else
  190. return null;
  191. }
  192. /**
  193. * This is used to create the TypeCode for a null reference.
  194. * It also handles backwards compatibility with JDK 1.3.x.
  195. *
  196. * This method will not return null.
  197. */
  198. private TypeCode createTypeCodeForNull(org.omg.CORBA.ORB orb) {
  199. if (orb instanceof com.sun.corba.se.internal.corba.ORB) {
  200. com.sun.corba.se.internal.corba.ORB ourORB
  201. = (com.sun.corba.se.internal.corba.ORB)orb;
  202. // Preserve backwards compatibility with Kestrel and Ladybird
  203. // by not fully implementing interop issue resolution 3857,
  204. // and returning a null TypeCode with a tk_value TCKind.
  205. // If we're not talking to Kestrel or Ladybird, fall through
  206. // to the abstract interface case (also used for foreign ORBs).
  207. if (!ORBVersionImpl.FOREIGN.equals(ourORB.getORBVersion()) &&
  208. ORBVersionImpl.NEWER.compareTo(ourORB.getORBVersion()) > 0) {
  209. return orb.get_primitive_tc(TCKind.tk_value);
  210. }
  211. }
  212. // Use tk_abstract_interface as detailed in the resolution
  213. // REVISIT: Define this in IDL and get the ID in generated code
  214. String abstractBaseID = "IDL:omg.org/CORBA/AbstractBase:1.0";
  215. return orb.create_abstract_interface_tc(abstractBaseID, "");
  216. }
  217. }