Frames | No Frames |
1: /* UID.java -- The unique object Id 2: Copyright (c) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.rmi.server; 40: 41: import java.io.DataInput; 42: import java.io.DataOutput; 43: import java.io.IOException; 44: import java.io.Serializable; 45: import java.net.InetAddress; 46: 47: /** 48: * Represents the unique identifier over time for the host which has generated 49: * it. It contains time (when created), counter (the number of the UID 50: * creation order) and virtual machine id components. The UID can also be 51: * constructed specifying a "well known" identifier in the for of short: 52: * this identifier defines the UID uniqueness alone. 53: * 54: * @author Audrius Meskauskas (audriusa@bioinformatics.org) 55: */ 56: public final class UID 57: implements Serializable 58: { 59: /** 60: * Use the serial version uid for interoperability. 61: */ 62: private static final long serialVersionUID = 1086053664494604050L; 63: 64: /** 65: * The UID counter (the ordinary number in the sequence of number of UID's, 66: * created during the recent millisecond). In the next millisecond, it 67: * starts from the minimal value again. In the unlikely case of creating 68: * more than 65536 uids per millisecond the process pauses till the next 69: * ms. 70: */ 71: private static short uidCounter = Short.MIN_VALUE; 72: 73: /** 74: * The time, when the last UID has been created. 75: */ 76: private static long last; 77: 78: /** 79: * This constant tries to be the unique identifier of the virtual machine. 80: */ 81: private static final int machineId = getMachineId(); 82: 83: /** 84: * The UID number in the UID creation sequence. 85: */ 86: private short count; 87: 88: /** 89: * Always gets the uniqueNr value. 90: */ 91: private int unique; 92: 93: /** 94: * The time stamp, when the UID was created. 95: */ 96: private long time; 97: 98: /** 99: * Create the new UID that would have the described features of the 100: * uniqueness. 101: */ 102: public UID() 103: { 104: synchronized (UID.class) 105: { 106: time = System.currentTimeMillis(); 107: unique = machineId; 108: if (time > last) 109: { 110: last = time; 111: count = uidCounter = Short.MIN_VALUE; 112: } 113: else 114: { 115: if (uidCounter == Short.MAX_VALUE) 116: { 117: // Make a 2 ms pause if the counter has reached the maximal 118: // value. This should seldom happen. 119: try 120: { 121: Thread.sleep(2); 122: } 123: catch (InterruptedException e) 124: { 125: } 126: uidCounter = Short.MIN_VALUE; 127: time = last = System.currentTimeMillis(); 128: } 129: count = ++uidCounter; 130: } 131: } 132: } 133: 134: /** 135: * Create the new UID with the well known id (number). All UIDs, creates 136: * with the this constructor having the same parameter are equal to each 137: * other (regardless to the host and time where they were created. 138: * 139: * @param wellKnownId the well known UID. 140: */ 141: public UID(short wellKnownId) 142: { 143: unique = wellKnownId; 144: } 145: 146: /** 147: * Get the hashCode of this UID. 148: */ 149: public int hashCode() 150: { 151: return (int) (unique ^ time ^ count); 152: } 153: 154: /** 155: * Compare this UID with another UID for equality (not equal to other types of 156: * objects). 157: */ 158: public boolean equals(Object other) 159: { 160: if (other instanceof UID) 161: { 162: UID ui = (UID) other; 163: return unique == ui.unique && time == ui.time && count == ui.count; 164: } 165: else 166: return false; 167: } 168: 169: public static UID read(DataInput in) throws IOException 170: { 171: UID uid = new UID(); 172: uid.unique = in.readInt(); 173: uid.time = in.readLong(); 174: uid.count = in.readShort(); 175: return (uid); 176: } 177: 178: public void write(DataOutput out) throws IOException 179: { 180: out.writeInt(unique); 181: out.writeLong(time); 182: out.writeShort(count); 183: } 184: 185: /** 186: * Do our best to get the Id of this virtual machine. 187: */ 188: static int getMachineId() 189: { 190: int hostIpHash; 191: 192: try 193: { 194: // Try to get the host IP. 195: String host = InetAddress.getLocalHost().toString(); 196: // This hash is content - based, not the address based. 197: hostIpHash = host.hashCode(); 198: } 199: catch (Exception e) 200: { 201: // Failed due some reason. 202: hostIpHash = 0; 203: } 204: 205: // Should be the unque address if hashcodes are addresses. 206: // Additionally, add the time when the RMI system was probably started 207: // (this class was first instantiated). 208: return new Object().hashCode() ^ (int) System.currentTimeMillis() 209: ^ hostIpHash; 210: } 211: 212: /** 213: * Get the string representation of this UID. 214: * 215: * @return a string, uniquely identifying this id. 216: */ 217: public String toString() 218: { 219: int max = Character.MAX_RADIX; 220: // Translate into object count, counting from 0. 221: long lc = (count - Short.MIN_VALUE) & 0xFFFF; 222: return Long.toString(unique, max) + ":" + Long.toString(time, max) + "." 223: + Long.toString(lc, max); 224: } 225: }