1. /*
  2. * @(#)UID.java 1.11 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.io.*;
  9. /**
  10. * Abstraction for creating identifiers that are unique with respect
  11. * to the the host on which it is generated.
  12. * @version 1.11, 11/29/01
  13. * @author Ann Wollrath
  14. * @since JDK1.1
  15. */
  16. public final class UID implements java.io.Serializable {
  17. /**
  18. * @serial Integer that helps create a unique UID.
  19. */
  20. private int unique;
  21. /**
  22. * @serial Long used to record the time. The <code>time</code>
  23. * will be used to create a unique UID.
  24. */
  25. private long time;
  26. /**
  27. * @serial Short used to create a hash key for <code>this</code>
  28. * UID.
  29. */
  30. private short count;
  31. /** indicate compatibility with JDK 1.1.x version of class */
  32. private static final long serialVersionUID = 1086053664494604050L;
  33. /**
  34. * In the absence of an actual pid, just do something somewhat
  35. * random.
  36. */
  37. private static int getHostUniqueNum() {
  38. return (new Object()).hashCode();
  39. }
  40. private static int hostUnique = getHostUniqueNum();
  41. private static long lastTime = System.currentTimeMillis();
  42. private static short lastCount = Short.MIN_VALUE;
  43. private static Object mutex = new Object();
  44. private static long ONE_SECOND = 1000; // in milliseconds
  45. /**
  46. * Creates a pure identifier that is unique with respect to the
  47. * host on which it is generated. This UID is unique under the
  48. * following conditions: a) the machine takes more than one second
  49. * to reboot, and b) the machine's clock is never set backward.
  50. * In order to construct a UID that is globally unique, simply
  51. * pair a UID with an InetAddress.
  52. * @since JDK1.1
  53. */
  54. public UID() {
  55. synchronized (mutex) {
  56. if (lastCount == Short.MAX_VALUE) {
  57. boolean done = false;
  58. while (!done) {
  59. time = System.currentTimeMillis();
  60. if (time < lastTime+ONE_SECOND) {
  61. // pause for a second to wait for time to change
  62. try {
  63. Thread.currentThread().sleep(ONE_SECOND);
  64. } catch (java.lang.InterruptedException e) {
  65. } // ignore exception
  66. continue;
  67. } else {
  68. lastTime = time;
  69. lastCount = Short.MIN_VALUE;
  70. done = true;
  71. }
  72. }
  73. } else {
  74. time = lastTime;
  75. }
  76. unique = hostUnique;
  77. count = lastCount++;
  78. }
  79. }
  80. /**
  81. * Creates a "well-known" ID. There are 2^16 -1 such possible
  82. * well-known ids. An id generated via this constructor will not
  83. * clash with any id generated via the default UID
  84. * constructor which will generates a genuinely unique identifier
  85. * with respect to this host.
  86. * @since JDK1.1
  87. */
  88. public UID(short num)
  89. {
  90. unique = 0;
  91. time = 0;
  92. count = num;
  93. }
  94. private UID(int unique, long time, short count)
  95. {
  96. this.unique = unique;
  97. this.time = time;
  98. this.count = count;
  99. }
  100. /**
  101. * Returns a hashcode for the <code>UID</code>. Two <code>UID</code>s
  102. * will have the same hashcode if they are equal with respect to their
  103. * content.
  104. *
  105. * @return the hashcode
  106. * @see java.util.Hashtable
  107. * @since JDK1.1
  108. */
  109. public int hashCode() {
  110. return (int)time + (int)count;
  111. }
  112. /**
  113. * Compares two <code>UID</code>s for content equality.
  114. *
  115. * @param obj the Object to compare with
  116. * @return true if these Objects are equal; false otherwise.
  117. * @see java.util.Hashtable
  118. * @since JDK1.1
  119. */
  120. public boolean equals(Object obj) {
  121. if ((obj != null) && (obj instanceof UID)) {
  122. UID uid = (UID)obj;
  123. return (unique == uid.unique &&
  124. count == uid.count &&
  125. time == uid.time);
  126. } else {
  127. return false;
  128. }
  129. }
  130. /**
  131. * Returns the string representation of the <code>UID</code>.
  132. * @since JDK1.1
  133. */
  134. public String toString() {
  135. return Integer.toString(unique,16) + ":" +
  136. Long.toString(time,16) + ":" +
  137. Integer.toString(count,16);
  138. }
  139. /**
  140. * Write the <code>UID</code> to output stream, <code>out</code>.
  141. *
  142. * @param out the output stream to which the <code>UID</code> is
  143. * written
  144. * @exception IOException if writing the <code>UID</code> to the
  145. * stream fails.
  146. * @since JDK1.1
  147. */
  148. public void write(DataOutput out) throws java.io.IOException
  149. {
  150. out.writeInt(unique);
  151. out.writeLong(time);
  152. out.writeShort(count);
  153. }
  154. /**
  155. * Reads the <code>UID</code> from the input stream.
  156. *
  157. * @param in the input stream
  158. * @return the <code>UID</code>
  159. * @exception IOException if uid could not be read
  160. * (due to stream failure or malformed <code>UID</code>)
  161. * @since JDK1.1
  162. */
  163. public static UID read(DataInput in)
  164. throws java.io.IOException
  165. {
  166. int unique = in.readInt();
  167. long time = in.readLong();
  168. short count = in.readShort();
  169. return new UID(unique, time, count);
  170. }
  171. }