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