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