1. /*
  2. * @(#)Stub.java 1.32 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package javax.rmi.CORBA;
  16. import org.omg.CORBA.ORB;
  17. import org.omg.CORBA.INITIALIZE;
  18. import org.omg.CORBA_2_3.portable.ObjectImpl;
  19. import java.io.IOException;
  20. import java.rmi.RemoteException;
  21. import java.io.File;
  22. import java.io.FileInputStream;
  23. import java.net.MalformedURLException ;
  24. import java.security.AccessController;
  25. import java.security.PrivilegedAction;
  26. import java.util.Properties;
  27. import java.rmi.server.RMIClassLoader;
  28. import com.sun.corba.se.impl.orbutil.GetPropertyAction;
  29. /**
  30. * Base class from which all RMI-IIOP stubs must inherit.
  31. */
  32. public abstract class Stub extends ObjectImpl
  33. implements java.io.Serializable {
  34. private static final long serialVersionUID = 1087775603798577179L;
  35. // This can only be set at object construction time (no sync necessary).
  36. private transient StubDelegate stubDelegate = null;
  37. private static Class stubDelegateClass = null;
  38. private static final String StubClassKey = "javax.rmi.CORBA.StubClass";
  39. private static final String defaultStubImplName = "com.sun.corba.se.impl.javax.rmi.CORBA.StubDelegateImpl";
  40. static {
  41. Object stubDelegateInstance = (Object) createDelegateIfSpecified(StubClassKey, defaultStubImplName);
  42. if (stubDelegateInstance != null)
  43. stubDelegateClass = stubDelegateInstance.getClass();
  44. }
  45. /**
  46. * Returns a hash code value for the object which is the same for all stubs
  47. * that represent the same remote object.
  48. * @return the hash code value.
  49. */
  50. public int hashCode() {
  51. if (stubDelegate == null) {
  52. setDefaultDelegate();
  53. }
  54. if (stubDelegate != null) {
  55. return stubDelegate.hashCode(this);
  56. }
  57. return 0;
  58. }
  59. /**
  60. * Compares two stubs for equality. Returns <code>true</code> when used to compare stubs
  61. * that represent the same remote object, and <code>false</code> otherwise.
  62. * @param obj the reference object with which to compare.
  63. * @return <code>true</code> if this object is the same as the <code>obj</code>
  64. * argument; <code>false</code> otherwise.
  65. */
  66. public boolean equals(java.lang.Object obj) {
  67. if (stubDelegate == null) {
  68. setDefaultDelegate();
  69. }
  70. if (stubDelegate != null) {
  71. return stubDelegate.equals(this, obj);
  72. }
  73. return false;
  74. }
  75. /**
  76. * Returns a string representation of this stub. Returns the same string
  77. * for all stubs that represent the same remote object.
  78. * @return a string representation of this stub.
  79. */
  80. public String toString() {
  81. if (stubDelegate == null) {
  82. setDefaultDelegate();
  83. }
  84. String ior;
  85. if (stubDelegate != null) {
  86. ior = stubDelegate.toString(this);
  87. if (ior == null) {
  88. return super.toString();
  89. } else {
  90. return ior;
  91. }
  92. }
  93. return super.toString();
  94. }
  95. /**
  96. * Connects this stub to an ORB. Required after the stub is deserialized
  97. * but not after it is demarshalled by an ORB stream. If an unconnected
  98. * stub is passed to an ORB stream for marshalling, it is implicitly
  99. * connected to that ORB. Application code should not call this method
  100. * directly, but should call the portable wrapper method
  101. * {@link javax.rmi.PortableRemoteObject#connect}.
  102. * @param orb the ORB to connect to.
  103. * @exception RemoteException if the stub is already connected to a different
  104. * ORB, or if the stub does not represent an exported remote or local object.
  105. */
  106. public void connect(ORB orb) throws RemoteException {
  107. if (stubDelegate == null) {
  108. setDefaultDelegate();
  109. }
  110. if (stubDelegate != null) {
  111. stubDelegate.connect(this, orb);
  112. }
  113. }
  114. /**
  115. * Serialization method to restore the IOR state.
  116. */
  117. private void readObject(java.io.ObjectInputStream stream)
  118. throws IOException, ClassNotFoundException {
  119. if (stubDelegate == null) {
  120. setDefaultDelegate();
  121. }
  122. if (stubDelegate != null) {
  123. stubDelegate.readObject(this, stream);
  124. }
  125. }
  126. /**
  127. * Serialization method to save the IOR state.
  128. * @serialData The length of the IOR type ID (int), followed by the IOR type ID
  129. * (byte array encoded using ISO8859-1), followed by the number of IOR profiles
  130. * (int), followed by the IOR profiles. Each IOR profile is written as a
  131. * profile tag (int), followed by the length of the profile data (int), followed
  132. * by the profile data (byte array).
  133. */
  134. private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
  135. if (stubDelegate == null) {
  136. setDefaultDelegate();
  137. }
  138. if (stubDelegate != null) {
  139. stubDelegate.writeObject(this, stream);
  140. }
  141. }
  142. private void setDefaultDelegate() {
  143. if (stubDelegateClass != null) {
  144. try {
  145. stubDelegate = (javax.rmi.CORBA.StubDelegate) stubDelegateClass.newInstance();
  146. } catch (Exception ex) {
  147. // what kind of exception to throw
  148. // delegate not set therefore it is null and will return default
  149. // values
  150. }
  151. }
  152. }
  153. // Same code as in PortableRemoteObject. Can not be shared because they
  154. // are in different packages and the visibility needs to be package for
  155. // security reasons. If you know a better solution how to share this code
  156. // then remove it from PortableRemoteObject. Also in Util.java
  157. private static Object createDelegateIfSpecified(String classKey, String defaultClassName) {
  158. String className = (String)
  159. AccessController.doPrivileged(new GetPropertyAction(classKey));
  160. if (className == null) {
  161. Properties props = getORBPropertiesFile();
  162. if (props != null) {
  163. className = props.getProperty(classKey);
  164. }
  165. }
  166. if (className == null) {
  167. className = defaultClassName;
  168. }
  169. try {
  170. return loadDelegateClass(className).newInstance();
  171. } catch (ClassNotFoundException ex) {
  172. INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className);
  173. exc.initCause( ex ) ;
  174. throw exc ;
  175. } catch (Exception ex) {
  176. INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className);
  177. exc.initCause( ex ) ;
  178. throw exc ;
  179. }
  180. }
  181. private static Class loadDelegateClass( String className ) throws ClassNotFoundException
  182. {
  183. try {
  184. ClassLoader loader = Thread.currentThread().getContextClassLoader();
  185. return Class.forName(className, false, loader);
  186. } catch (ClassNotFoundException e) {
  187. // ignore, then try RMIClassLoader
  188. }
  189. try {
  190. return RMIClassLoader.loadClass(className);
  191. } catch (MalformedURLException e) {
  192. String msg = "Could not load " + className + ": " + e.toString();
  193. ClassNotFoundException exc = new ClassNotFoundException( msg ) ;
  194. throw exc ;
  195. }
  196. }
  197. /**
  198. * Load the orb.properties file.
  199. */
  200. private static Properties getORBPropertiesFile () {
  201. return (Properties) AccessController.doPrivileged(new GetORBPropertiesFileAction());
  202. }
  203. }