GNU Classpath (0.91) | |
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: time = System.currentTimeMillis(); 105: unique = machineId; 106: if (time > last) 107: { 108: last = time; 109: count = uidCounter = Short.MIN_VALUE; 110: } 111: else 112: { 113: synchronized (UID.class) 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: 130: count = uidCounter++; 131: } 132: } 133: } 134: 135: /** 136: * Create the new UID with the well known id (number). All UIDs, creates 137: * with the this constructor having the same parameter are equal to each 138: * other (regardless to the host and time where they were created. 139: * 140: * @param wellKnownId the well known UID. 141: */ 142: public UID(short wellKnownId) 143: { 144: unique = wellKnownId; 145: } 146: 147: /** 148: * Get the hashCode of this UID. 149: */ 150: public int hashCode() 151: { 152: return (int) (unique ^ time ^ count); 153: } 154: 155: /** 156: * Compare this UID with another UID for equality (not equal to other types of 157: * objects). 158: */ 159: public boolean equals(Object other) 160: { 161: if (other instanceof UID) 162: { 163: UID ui = (UID) other; 164: return unique == ui.unique && time == ui.time && count == ui.count; 165: } 166: else 167: return false; 168: } 169: 170: public static UID read(DataInput in) throws IOException 171: { 172: UID uid = new UID(); 173: uid.unique = in.readInt(); 174: uid.time = in.readLong(); 175: uid.count = in.readShort(); 176: return (uid); 177: } 178: 179: public void write(DataOutput out) throws IOException 180: { 181: out.writeInt(unique); 182: out.writeLong(time); 183: out.writeShort(count); 184: } 185: 186: /** 187: * Do our best to get the Id of this virtual machine. 188: */ 189: static int getMachineId() 190: { 191: int hostIpHash; 192: 193: try 194: { 195: // Try to get the host IP. 196: String host = InetAddress.getLocalHost().toString(); 197: // This hash is content - based, not the address based. 198: hostIpHash = host.hashCode(); 199: } 200: catch (Exception e) 201: { 202: // Failed due some reason. 203: hostIpHash = 0; 204: } 205: 206: // Should be the unque address if hashcodes are addresses. 207: // Additionally, add the time when the RMI system was probably started 208: // (this class was first instantiated). 209: return new Object().hashCode() ^ (int) System.currentTimeMillis() 210: ^ hostIpHash; 211: } 212: 213: /** 214: * Get the string representation of this UID. 215: * 216: * @return a string, uniquely identifying this id. 217: */ 218: public String toString() 219: { 220: int max = Character.MAX_RADIX; 221: // Translate into object count, counting from 0. 222: long lc = (count + Short.MIN_VALUE) & 0xFFFF; 223: return Long.toString(time, max) + ":" 224: + Long.toString(unique, max) + ":" 225: + Long.toString(lc, max); 226: } 227: }
GNU Classpath (0.91) |