1 package com.ibm.webdav.impl; 2 3 17 18 import java.net.InetAddress ; 19 import java.util.Date ; 20 import java.util.Random ; 21 import java.io.*; 22 import java.security.MessageDigest ; 23 24 31 public class UUID implements Serializable { 32 private static byte[] internetAddress = null; 33 private static String uuidFile = null; 34 private long time; 35 private short clockSequence; 36 private byte version = 1; 37 private byte[] node = new byte[6]; 38 private static final int UUIDsPerTick = 128; 39 private static long lastTime = new Date ().getTime(); 40 private static int uuidsThisTick = UUIDsPerTick; 41 private static UUID previousUUID = null; private static long nextSave = new Date ().getTime(); 43 private static Random randomGenerator = new Random (new Date ().getTime()); 44 private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 45 46 48 static { 49 try { 50 internetAddress = InetAddress.getLocalHost().getAddress(); 51 } catch (Exception exc) { 52 System.err.println("Can't get host address: " + exc); 53 exc.printStackTrace(); 54 } 55 try { 56 uuidFile = System.getProperty("UUID_HOME"); 57 if (uuidFile == null) { 58 uuidFile = System.getProperty("java.home"); 59 } 60 if (!uuidFile.endsWith(File.separator)) { 61 uuidFile = uuidFile + File.separator; 62 } 63 uuidFile = uuidFile + "UUID"; 64 previousUUID = getUUIDState(); 65 } catch (Exception exc) { 66 exc.printStackTrace(); 67 } 68 } 69 71 public UUID() { 72 synchronized (this) { 73 time = getCurrentTime(); 74 node = previousUUID.getNode(); 76 if (previousUUID == null || nodeChanged(previousUUID)) { 77 clockSequence = (short) random(); 80 } else if (time < previousUUID.getTime()) { 81 clockSequence++; 83 } 84 previousUUID = this; 86 setUUIDState(this); 88 } 89 } 90 93 public UUID(byte[] node) { 94 synchronized (this) { 95 time = getCurrentTime(); 96 this.node = node; 97 98 setUUIDState(this); 100 } 101 } 102 104 public UUID(UUID context, String name) { 105 } 106 117 public int compare(UUID withUUID) { 118 if (time < withUUID.getTime()) { 119 return -1; 120 } else if (time > withUUID.getTime()) { 121 return 1; 122 } 123 if (version < withUUID.getVersion()) { 124 return -1; 125 } else if (version > withUUID.getVersion()) { 126 return 1; 127 } 128 if (clockSequence < withUUID.getClockSequence()) { 129 return -1; 130 } else if (clockSequence > withUUID.getClockSequence()) { 131 return 1; 132 } 133 byte[] withNode = withUUID.getNode(); 134 for (int i = 0; i < 6; i++) { 135 if (node[i] < withNode[i]) { 136 return -1; 137 } else if (node[i] > withNode[i]) { 138 return 1; 139 } 140 } 141 return 0; 142 } 143 150 private static byte[] computeNodeAddress() { 151 byte[] address = new byte[6]; 152 int thread = Thread.currentThread().hashCode(); 157 long time = System.currentTimeMillis(); 158 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 159 DataOutputStream out = new DataOutputStream(byteOut); 160 try { 161 if (internetAddress != null) { 162 out.write(internetAddress); 163 } 164 out.write(thread); 165 out.writeLong(time); 166 out.close(); 167 } catch (IOException exc) { 168 } 169 byte[] rand = byteOut.toByteArray(); 170 MessageDigest md5 = null; 171 try { 172 md5 = MessageDigest.getInstance("MD5"); 173 } catch (Exception exc) { 174 } 175 md5.update(rand); 176 byte[] temp = md5.digest(); 177 for (int i = 0; i < 6; i++) { 179 address[i] = temp[i+5]; 180 } 181 address[0] = (byte)(address[0] | (byte)0x80); 183 return address; 184 } 185 188 public int getClockSequence() { 189 return clockSequence; 190 } 191 196 private static long getCurrentTime() { 197 long now = 0; 198 boolean waitForTick = true; 199 while (waitForTick) { 200 now = new Date ().getTime(); 201 if (lastTime < now) { 202 uuidsThisTick = 0; 204 waitForTick = false; 205 } else if (uuidsThisTick < UUIDsPerTick) { 206 uuidsThisTick++; 208 waitForTick = false; 209 } 210 } 211 now += uuidsThisTick; 213 lastTime = now; 214 return now; 215 } 216 219 private static byte[] getIEEEAddress() { 220 byte[] address = new byte[6]; 221 return address; 223 } 224 229 public byte[] getNode() { 230 return node; 231 } 232 235 public long getTime() { 236 return time; 237 } 238 240 public byte[] getUUID() { 241 byte[] uuid = new byte[16]; 242 long t = time; 243 for (int i = 0; i < 8; i++) { 244 uuid[i] = (byte) ((t >> 8 * i) & 0xFF); } 246 uuid[7] |= (byte) (version << 12); uuid[8] = (byte) (clockSequence & 0xFF); 248 uuid[9] = (byte) ((clockSequence & 0x3F00) >> 8); 249 uuid[9] |= 0x80; for (int i = 0; i < 6; i++) { 251 uuid[10 + i] = node[i]; } 253 return uuid; 254 } 255 261 private static UUID getUUIDState() { 262 UUID uuid = null; 263 try { 264 FileInputStream in = new FileInputStream(uuidFile); 265 ObjectInputStream s = new ObjectInputStream(in); 266 uuid = (UUID) s.readObject(); 267 } catch (Exception exc) { 268 uuid = new UUID(computeNodeAddress()); 269 System.err.println("Can't get saved UUID state: " + exc); 270 } 271 return uuid; 272 } 273 275 public int getVersion() { 276 return version; 277 } 278 281 public boolean isEqual(UUID toUUID) { 282 return compare(toUUID) == 0; 283 } 284 288 private boolean nodeChanged(UUID previousUUID) { 289 byte[] previousNode = previousUUID.getNode(); 290 boolean nodeChanged = false; 291 int i = 0; 292 while (!nodeChanged && i < 6) { 293 nodeChanged = node[i] != previousNode[i]; 294 i++; 295 } 296 return nodeChanged; 297 } 298 302 private static int random() { 303 return randomGenerator.nextInt(); 304 } 305 308 private static void setUUIDState(UUID aUUID) { 309 if (aUUID.getTime() > nextSave) { 310 try { 311 FileOutputStream f = new FileOutputStream(uuidFile); 312 ObjectOutputStream s = new ObjectOutputStream(f); 313 s.writeObject(aUUID); 314 s.close(); 315 nextSave = aUUID.getTime() + 10 * 10 * 1000 * 1000; 316 } catch (Exception exc) { 317 System.err.println("Can't save UUID state: " + exc); 318 } 319 } 320 } 321 324 public String toString() { 325 byte[] uuid = getUUID(); 326 StringWriter s = new StringWriter(); 327 for (int i = 0; i < 16; i++) { 328 s.write(hexDigits[(uuid[i] & 0xF0) >> 4]); 329 s.write(hexDigits[uuid[i] & 0x0F]); 330 if (i == 3 || i == 5 || i == 7 || i == 9) { 331 s.write('-'); 332 } 333 } 334 return s.toString(); 335 } 336 } 337 | Popular Tags |