1. /*
  2. * @(#)RemoteObject.java 1.18 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.rmi.server;
  8. import java.rmi.Remote;
  9. import java.rmi.UnmarshalException;
  10. import java.rmi.NoSuchObjectException;
  11. /**
  12. * The <code>RemoteObject</code> class implements the
  13. * <code>java.lang.Object</code> behavior for remote objects.
  14. * <code>RemoteObject</code> provides the remote semantics of Object by
  15. * implementing methods for hashCode, equals, and toString.
  16. *
  17. * @version 1.18, 11/29/01
  18. * @author Ann Wollrath
  19. * @since JDK1.1
  20. */
  21. public abstract class RemoteObject implements Remote, java.io.Serializable {
  22. /** the objects remote reference */
  23. transient protected RemoteRef ref;
  24. /** indicate compatibility with JDK 1.1.x version of class */
  25. private static final long serialVersionUID = -3215090123894869218L;
  26. /**
  27. * Creates a remote object.
  28. * @since JDK1.1
  29. */
  30. protected RemoteObject() {
  31. ref = null;
  32. }
  33. /**
  34. * Creates a remote object, initialized with the specified remote
  35. * reference.
  36. * @since JDK1.1
  37. */
  38. protected RemoteObject(RemoteRef newref) {
  39. ref = newref;
  40. }
  41. /**
  42. * Returns the remote reference for the remote object.
  43. * @since JDK1.2
  44. */
  45. public RemoteRef getRef() {
  46. return ref;
  47. }
  48. /**
  49. * Returns the stub for the remote object <code>obj</code> passed
  50. * as a parameter. This operation is only valid <i>after</i>
  51. * the object has been exported.
  52. * @param obj the remote object whose stub is neede
  53. * @return the stub for the remote object, <code>obj</code>.
  54. * @exception NoSuchObjectException if the stub for the
  55. * remote object could not be found.
  56. * @since JDK1.2
  57. */
  58. public static Remote toStub(Remote obj) throws NoSuchObjectException {
  59. if (obj instanceof RemoteStub) {
  60. return (RemoteStub)obj;
  61. } else {
  62. return sun.rmi.transport.ObjectTable.getStub(obj);
  63. }
  64. }
  65. /**
  66. * Returns a hashcode for a remote object. Two remote object stubs
  67. * that refer to the same remote object will have the same hash code
  68. * (in order to support remote objects as keys in hash tables).
  69. *
  70. * @see java.util.Hashtable
  71. * @since JDK1.1
  72. */
  73. public int hashCode() {
  74. return (ref == null) ? super.hashCode() : ref.remoteHashCode();
  75. }
  76. /**
  77. * Compares two remote objects for equality.
  78. * Returns a boolean that indicates whether this remote object is
  79. * equivalent to the specified Object. This method is used when a
  80. * remote object is stored in a hashtable.
  81. * If the specified Object is not itself an instance of RemoteObject,
  82. * then this method delegates by returning the result of invoking the
  83. * <code>equals</code> method of its parameter with this remote object
  84. * as the argument.
  85. * @param obj the Object to compare with
  86. * @return true if these Objects are equal; false otherwise.
  87. * @see java.util.Hashtable
  88. * @since JDK1.1
  89. */
  90. public boolean equals(Object obj) {
  91. if (obj instanceof RemoteObject) {
  92. if (ref == null) {
  93. return obj == this;
  94. } else {
  95. return ref.remoteEquals(((RemoteObject)obj).ref);
  96. }
  97. } else if (obj != null) {
  98. /*
  99. * Fix for 4099660: if object is not an instance of RemoteObject,
  100. * use the result of its equals method, to support symmetry is a
  101. * remote object implementation class that does not extend
  102. * RemoteObject wishes to support equality with its stub objects.
  103. */
  104. return obj.equals(this);
  105. } else {
  106. return false;
  107. }
  108. }
  109. /**
  110. * Returns a String that represents the value of this remote object.
  111. * @since JDK1.1
  112. */
  113. public String toString() {
  114. String classname = this.getClass().getName();
  115. return (ref == null) ? classname :
  116. classname + "[" +ref.remoteToString() + "]";
  117. }
  118. /**
  119. * writeObject for object serialization. Writes out the class
  120. * name of the remote reference contained in this class and
  121. * delegates to the reference to write out its representation.
  122. *
  123. * @serialData Writes out the unqualified class name of the remote
  124. * reference field, <code>ref</code>, in <code>UTF-8</code> and
  125. * delegates to the <code>ref</code> field to write out its
  126. * representation. Different information will be written to
  127. * <code>out</code> depending upon the <code>ref</code> field's
  128. * type. Default serialization is not used.
  129. */
  130. private void writeObject(java.io.ObjectOutputStream out)
  131. throws java.io.IOException, java.lang.ClassNotFoundException
  132. {
  133. if (ref == null) {
  134. throw new java.rmi.MarshalException("Invalid remote object");
  135. } else {
  136. String refClassName = ref.getRefClass(out);
  137. if (refClassName == null || refClassName.length() == 0) {
  138. /*
  139. * No reference class name specified, so serialize
  140. * remote reference.
  141. */
  142. out.writeUTF("");
  143. out.writeObject(ref);
  144. } else {
  145. /*
  146. * Built-in reference class specified, so delegate
  147. * to reference to write out its external form.
  148. */
  149. out.writeUTF(refClassName);
  150. ref.writeExternal(out);
  151. }
  152. }
  153. }
  154. /**
  155. * readObject for object serialization. Reads in the unqualified
  156. * class name of the remote reference field, <code>ref</code>, in
  157. * <code>UTF-8</code> and delegates to the <code>ref</code> field
  158. * to read in its representation. The <code>ref</code> field is
  159. * read via a direct call to
  160. * <code>ref.readExternal(ObjectInputStream in)</code>. Default
  161. * serialization is not used.
  162. */
  163. private void readObject(java.io.ObjectInputStream in)
  164. throws java.io.IOException, java.lang.ClassNotFoundException
  165. {
  166. try {
  167. String refClassName = in.readUTF();
  168. if (refClassName == null || refClassName.length() == 0) {
  169. /*
  170. * No reference class name specified, so construct
  171. * remote reference from its serialized form.
  172. */
  173. ref = (RemoteRef) in.readObject();
  174. } else {
  175. /*
  176. * Built-in reference class specified, so delegate
  177. * to reference to initialize its fields from its
  178. * external form.
  179. */
  180. Class refClass = Class.forName(RemoteRef.packagePrefix + "." +
  181. refClassName);
  182. ref = (RemoteRef) refClass.newInstance();
  183. ref.readExternal(in);
  184. }
  185. } catch (InstantiationException e) {
  186. throw new UnmarshalException("Unable to create remote reference",
  187. e);
  188. } catch (IllegalAccessException e) {
  189. throw new UnmarshalException("Illegal access creating remote reference");
  190. }
  191. }
  192. }