1. /*
  2. * @(#)ActivationID.java 1.24 03/01/23
  3. *
  4. * Copyright 2003 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:
  19. * <ul>
  20. * <li> a remote reference to the object's activator (a {@link
  21. * java.rmi.server.RemoteRef RemoteRef}
  22. * instance), and
  23. * <li> a unique identifier (a {@link java.rmi.server.UID UID}
  24. * instance) for the object. </ul> <p>
  25. *
  26. * An activation identifier for an object can be obtained by registering
  27. * an object with the activation system. Registration is accomplished
  28. * in a few ways: <ul>
  29. * <li>via the <code>Activatable.register</code> method
  30. * <li>via the first <code>Activatable</code> constructor (that takes
  31. * three arguments and both registers and exports the object, and
  32. * <li>via the first <code>Activatable.exportObject</code> method
  33. * that takes the activation descriptor, object and port as arguments;
  34. * this method both registers and exports the object. </ul>
  35. *
  36. * @author Ann Wollrath
  37. * @version 1.24, 03/01/23
  38. * @see Activatable
  39. * @since 1.2
  40. */
  41. public class ActivationID implements java.io.Serializable {
  42. /**
  43. * the object's activator
  44. */
  45. private transient Activator activator;
  46. /**
  47. * the object's unique id
  48. */
  49. private transient UID uid = new UID();
  50. /** indicate compatibility with the Java 2 SDK v1.2 version of class */
  51. private static final long serialVersionUID = -4608673054848209235L;
  52. /**
  53. * The constructor for <code>ActivationID</code> takes a single
  54. * argument, activator, that specifies a remote reference to the
  55. * activator responsible for activating the object associated with
  56. * this identifier. An instance of <code>ActivationID</code> is globally
  57. * unique.
  58. *
  59. * @param activator reference to the activator responsible for
  60. * activating the object
  61. * @since 1.2
  62. */
  63. public ActivationID(Activator activator) {
  64. this.activator = activator;
  65. }
  66. /**
  67. * Activate the object for this id.
  68. *
  69. * @param force if true, forces the activator to contact the group
  70. * when activating the object (instead of returning a cached reference);
  71. * if false, returning a cached value is acceptable.
  72. * @return the reference to the active remote object
  73. * @exception ActivationException if activation fails
  74. * @exception UnknownObjectException if the object is unknown
  75. * @exception RemoteException if remote call fails
  76. * @since 1.2
  77. */
  78. public Remote activate(boolean force)
  79. throws ActivationException, UnknownObjectException, RemoteException
  80. {
  81. try {
  82. MarshalledObject mobj =
  83. (MarshalledObject)(activator.activate(this, force));
  84. return (Remote)mobj.get();
  85. } catch (RemoteException e) {
  86. throw e;
  87. } catch (java.io.IOException e) {
  88. throw new UnmarshalException("activation failed", e);
  89. } catch (java.lang.ClassNotFoundException e) {
  90. throw new UnmarshalException("activation failed", e);
  91. }
  92. }
  93. /**
  94. * Returns a hashcode for the activation id. Two identifiers that
  95. * refer to the same remote object will have the same hash code.
  96. *
  97. * @see java.util.Hashtable
  98. * @since 1.2
  99. */
  100. public int hashCode() {
  101. return uid.hashCode();
  102. }
  103. /**
  104. * Compares two activation ids for content equality.
  105. * Returns true if both of the following conditions are true:
  106. * 1) the unique identifiers equivalent (by content), and
  107. * 2) the activator specified in each identifier
  108. * refers to the same remote object.
  109. *
  110. * @param obj the Object to compare with
  111. * @return true if these Objects are equal; false otherwise.
  112. * @see java.util.Hashtable
  113. * @since 1.2
  114. */
  115. public boolean equals(Object obj) {
  116. if (obj instanceof ActivationID) {
  117. ActivationID id = (ActivationID)obj;
  118. return (uid.equals(id.uid) && activator.equals(id.activator));
  119. } else {
  120. return false;
  121. }
  122. }
  123. /**
  124. * <code>writeObject</code> for custom serialization.
  125. *
  126. * <p>This method writes this object's serialized form for
  127. * this class as follows:
  128. *
  129. * <p>The <code>writeObject</code> method is invoked on
  130. * <code>out</code> passing this object's unique identifier
  131. * (a {@link java.rmi.server.UID UID} instance) as the argument.
  132. *
  133. * <p>Next, the {@link
  134. * java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
  135. * getRefClass} method is invoked on the activator's
  136. * <code>RemoteRef</code> instance to obtain its external ref
  137. * type name. Next, the <code>writeUTF</code> method is
  138. * invoked on <code>out</code> with the value returned by
  139. * <code>getRefClass</code>, and then the
  140. * <code>writeExternal</code> method is invoked on the
  141. * <code>RemoteRef</code> instance passing <code>out</code>
  142. * as the argument.
  143. *
  144. * @serialData The serialized data for this class comprises a
  145. * <code>java.rmi.server.UID</code> (written with
  146. * <code>ObjectOutput.writeObject</code>) followed by the
  147. * external ref type name of the activator's
  148. * <code>RemoteRef</code> instance (a string written with
  149. * <code>ObjectOutput.writeUTF</code>), followed by the
  150. * external form of the <code>RemoteRef</code> instance as
  151. * written by its <code>writeExternal</code> method.
  152. *
  153. * <p>The external ref type name of the
  154. * <code>RemoteRef</Code> instance is
  155. * determined using the definitions of external ref type
  156. * names specified in the {@link java.rmi.server.RemoteObject
  157. * RemoteObject} <code>writeObject</code> method
  158. * <b>serialData</b> specification. Similarly, the data
  159. * written by the <code>writeExternal</code> method and read
  160. * by the <code>readExternal</code> method of
  161. * <code>RemoteRef</code> implementation classes
  162. * corresponding to each of the defined external ref type
  163. * names is specified in the {@link
  164. * java.rmi.server.RemoteObject RemoteObject}
  165. * <code>writeObject</code> method <b>serialData</b>
  166. * specification. */
  167. private void writeObject(java.io.ObjectOutputStream out)
  168. throws java.io.IOException, java.lang.ClassNotFoundException
  169. {
  170. out.writeObject(uid);
  171. RemoteRef ref = ((RemoteObject)activator).getRef();
  172. out.writeUTF(ref.getRefClass(out));
  173. ref.writeExternal(out);
  174. }
  175. /**
  176. * <code>readObject</code> for custom serialization.
  177. *
  178. * <p>This method reads this object's serialized form for this
  179. * class as follows:
  180. *
  181. * <p>The <code>readObject</code> method is invoked on
  182. * <code>in</code> to read this object's unique identifier
  183. * (a {@link java.rmi.server.UID UID} instance).
  184. *
  185. * <p>Next, the <code>readUTF</code> method is invoked on
  186. * <code>in</code> to read the external ref type name of the
  187. * <code>RemoteRef</code> instance for this object's
  188. * activator. Next, the <code>RemoteRef</code>
  189. * instance is created of an implementation-specific class
  190. * corresponding to the external ref type name (returned by
  191. * <code>readUTF</code>), and the <code>readExternal</code>
  192. * method is invoked on that <code>RemoteRef</code> instance
  193. * to read the external form corresponding to the external
  194. * ref type name.
  195. *
  196. * <p>Note: If the external ref type name is
  197. * <code>"UnicastRef"</code>, <code>"UnicastServerRef"</code>,
  198. * <code>"UnicastRef2"</code>, <code>"UnicastServerRef2"</code>,
  199. * <code>"ActivatableRef"</code>, or
  200. * <code>"ActivatableServerRef"</code>, a corresponding
  201. * implementation-specific class must be found, and its
  202. * <code>readExternal</code> method must read the serial data
  203. * for that external ref type name as specified to be written
  204. * in the <b>serialData</b> documentation for this class.
  205. * If the external ref type name is any other string (of non-zero
  206. * length), a <code>ClassNotFoundException</code> will be thrown,
  207. * unless the implementation provides an implementation-specific
  208. * class corresponding to that external ref type name, in which
  209. * case the <code>RemoteRef</code> will be an instance of
  210. * that implementation-specific class.
  211. */
  212. private void readObject(java.io.ObjectInputStream in)
  213. throws java.io.IOException, java.lang.ClassNotFoundException
  214. {
  215. uid = (UID)in.readObject();
  216. try {
  217. Class refClass = Class.forName(RemoteRef.packagePrefix + "." +
  218. in.readUTF());
  219. RemoteRef ref = (RemoteRef)refClass.newInstance();
  220. ref.readExternal(in);
  221. activator =
  222. (Activator)RemoteProxy.getStub(activatorClassName, ref);
  223. } catch (InstantiationException e) {
  224. throw new UnmarshalException("Unable to create remote reference",
  225. e);
  226. } catch (IllegalAccessException e) {
  227. throw new UnmarshalException("Illegal access creating remote reference");
  228. }
  229. }
  230. private static String activatorClassName;
  231. static
  232. {
  233. activatorClassName = (String) java.security.AccessController.doPrivileged(
  234. new GetPropertyAction("java.rmi.activation.activator.class",
  235. "sun.rmi.server.Activation$ActivatorImpl"));
  236. }
  237. }