1. /*
  2. * @(#)ActivationID.java 1.16 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.activation;
  8. import java.rmi.*;
  9. import java.rmi.server.RemoteObject;
  10. import java.rmi.server.RemoteRef;
  11. import java.rmi.server.UID;
  12. import sun.rmi.server.RemoteProxy;
  13. import sun.security.action.GetPropertyAction;
  14. /**
  15. * Activation makes use of special identifiers to denote remote
  16. * objects that can be activated over time. An activation identifier
  17. * (an instance of the class <code>ActivationID</code>) contains several
  18. * pieces of information needed for activating an object: <ul>
  19. * <li> a remote reference to the object's activator, and
  20. * <li> a unique identifier for the object. </ul> <p>
  21. *
  22. * An activation id for an object can be obtained by registering
  23. * an object with the activation system. Registration is accomplished
  24. * in a few ways: <ul>
  25. * <li>via the <code>Activatable.register</code> method
  26. * <li>via the first <code>Activatable</code> constructor (that takes
  27. * three arguments and both registers and exports the object, and
  28. * <li>via the first <code>Activatable.exportObject</code> method
  29. * that takes the activation descriptor, object and port as arguments;
  30. * this method both registers and exports the object. </ul>
  31. *
  32. * @author Ann Wollrath
  33. * @version 1.16, 11/29/01
  34. * @see Activatable
  35. * @since JDK1.2
  36. */
  37. public class ActivationID implements java.io.Serializable {
  38. /**
  39. * @serial the object's activator
  40. */
  41. private Activator activator;
  42. /**
  43. * @serial the object's unique id
  44. */
  45. private UID uid = new UID();
  46. /** indicate compatibility with JDK 1.2 version of class */
  47. private static final long serialVersionUID = -4608673054848209235L;
  48. /**
  49. * The constructor for <code>ActivationID</code> takes a single
  50. * argument, activator, that specifies a remote reference to the
  51. * activator responsible for activating the object associated with
  52. * this identifier. An instance of <code>ActivationID</code> is globally
  53. * unique.
  54. *
  55. * @param activator reference to the activator responsible for
  56. * activating the object
  57. * @since JDK1.2
  58. */
  59. public ActivationID(Activator activator) {
  60. this.activator = activator;
  61. }
  62. /**
  63. * Activate the object for this id.
  64. *
  65. * @param force if true, forces the activator to contact the group
  66. * when activating the object (instead of returning a cached reference);
  67. * if false, returning a cached value is acceptable.
  68. * @return the reference to the active remote object
  69. * @exception ActivationException if activation fails
  70. * @exception UnknownObjectException if the object is unknown
  71. * @exception RemoteException if remote call fails
  72. * @since JDK1.2
  73. */
  74. public Remote activate(boolean force)
  75. throws ActivationException, UnknownObjectException, RemoteException
  76. {
  77. try {
  78. MarshalledObject mobj =
  79. (MarshalledObject)(activator.activate(this, force));
  80. return (Remote)mobj.get();
  81. } catch (UnknownObjectException e) {
  82. throw e;
  83. } catch (RemoteException e) {
  84. throw e;
  85. } catch (java.io.IOException e) {
  86. throw new ActivationException("activation failed", e);
  87. } catch (java.lang.ClassNotFoundException e) {
  88. throw new ActivationException("activation failed", e);
  89. }
  90. }
  91. /**
  92. * Returns a hashcode for the activation id. Two identifiers that
  93. * refer to the same remote object will have the same hash code.
  94. *
  95. * @see java.util.Hashtable
  96. * @since JDK1.2
  97. */
  98. public int hashCode() {
  99. return uid.hashCode();
  100. }
  101. /**
  102. * Compares two activation ids for content equality.
  103. * Returns true if both of the following conditions are true:
  104. * 1) the unique identifiers equivalent (by content), and
  105. * 2) the activator specified in each identifier
  106. * refers to the same remote object.
  107. *
  108. * @param obj the Object to compare with
  109. * @return true if these Objects are equal; false otherwise.
  110. * @see java.util.Hashtable
  111. * @since JDK1.2
  112. */
  113. public boolean equals(Object obj) {
  114. if (obj instanceof ActivationID) {
  115. ActivationID id = (ActivationID)obj;
  116. return (uid.equals(id.uid) && activator.equals(id.activator));
  117. } else {
  118. return false;
  119. }
  120. }
  121. /**
  122. * writeObject for object serialization. Writes out a
  123. * <code>java.rmi.server.UID</code> and the reference to the
  124. * activator responsible for activating the object associated with
  125. * this id, the remote reference contained in the
  126. * <code>activator</code> field.
  127. *
  128. * @serialData Writes out a <code>java.rmi.server.UID</code>, and
  129. * the unqualified class name, in <code>UTF-8</code>, of the
  130. * remote reference contained in the <code>activator</code>
  131. * field. Delegates to the <code>activator</code>'s remote
  132. * reference to write itself to <code>out</code>. Directly calls
  133. * <code>writeExternal(ObjectStream out)</code> on the return
  134. * value of <code>activator.getRef()</code>. Default serialization
  135. * is not used.
  136. */
  137. private void writeObject(java.io.ObjectOutputStream out)
  138. throws java.io.IOException, java.lang.ClassNotFoundException
  139. {
  140. out.writeObject(uid);
  141. RemoteRef ref = ((RemoteObject)activator).getRef();
  142. out.writeUTF(ref.getRefClass(out));
  143. ref.writeExternal(out);
  144. }
  145. /**
  146. * readObject for object serialization. Reads in a
  147. * <code>java.rmi.server.UID</code> and a remote reference. The
  148. * remote reference is read via a direct call to
  149. * <code>readExternal(ObjectInputStream in)</code>. Default
  150. * serialization is not used. The reference is used to create the
  151. * <code>activator</code> field in this object. That is, the
  152. * <code>activator</code> field is set to the stub returned from
  153. * <code>RemoteProxy.getStub(activatorClassName, ref)</code>.
  154. */
  155. private void readObject(java.io.ObjectInputStream in)
  156. throws java.io.IOException, java.lang.ClassNotFoundException
  157. {
  158. uid = (UID)in.readObject();
  159. try {
  160. Class refClass = Class.forName(RemoteRef.packagePrefix + "." +
  161. in.readUTF());
  162. RemoteRef ref = (RemoteRef)refClass.newInstance();
  163. ref.readExternal(in);
  164. activator =
  165. (Activator)RemoteProxy.getStub(activatorClassName, ref);
  166. } catch (InstantiationException e) {
  167. throw new UnmarshalException("Unable to create remote reference",
  168. e);
  169. } catch (IllegalAccessException e) {
  170. throw new UnmarshalException("Illegal access creating remote reference");
  171. }
  172. }
  173. private static String activatorClassName;
  174. static
  175. {
  176. activatorClassName = (String) java.security.AccessController.doPrivileged(
  177. new GetPropertyAction("java.rmi.activation.activator.class",
  178. "sun.rmi.server.Activation$ActivatorImpl"));
  179. }
  180. }