001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.java.util;
032:
033: import java.io.Serializable;
034: import java.security.*;
035: import java.util.*;
036:
037: /**
038: * @author Taras Puchko
039: */
040: public class UUID_ implements Serializable, Comparable<UUID_> {
041:
042: private static final long serialVersionUID = 4759128571957838954L;
043: private static final SecureRandom randomGenerator = new SecureRandom();
044:
045: private long mostSignificantBits;
046: private long leastSignificantBits;
047:
048: public UUID_(long mostSigBits, long leastSigBits) {
049: mostSignificantBits = mostSigBits;
050: leastSignificantBits = leastSigBits;
051: }
052:
053: public static UUID_ randomUUID() {
054: byte[] bytes = new byte[16];
055: randomGenerator.nextBytes(bytes);
056: return newInstance(bytes, 4);
057: }
058:
059: public static UUID_ nameUUIDFromBytes(byte[] name) {
060: try {
061: return newInstance(MessageDigest.getInstance("MD5").digest(
062: name), 3);
063: } catch (NoSuchAlgorithmException e) {
064: throw new InternalError(e.getMessage());
065: }
066: }
067:
068: public static UUID_ fromString(String name) {
069: Long[] values = new Long[5];
070: StringTokenizer tokenizer = new StringTokenizer(name, "-", true);
071: try {
072: for (int i = 0; i < 5; i++) {
073: if (i > 0 && !tokenizer.nextToken().equals("-")) {
074: throw new IllegalArgumentException(name);
075: }
076: values[i] = Long.parseLong(tokenizer.nextToken(), 16);
077: }
078: } catch (NoSuchElementException e) {
079: throw new IllegalArgumentException(name, e);
080: }
081: while (tokenizer.hasMoreTokens()) {
082: if (!tokenizer.nextToken().equals("-")) {
083: throw new IllegalArgumentException(name);
084: }
085: }
086: return new UUID_(values[0] << 32 | values[1] << 16 | values[2],
087: values[3] << 48 | values[4]);
088: }
089:
090: public long getMostSignificantBits() {
091: return mostSignificantBits;
092: }
093:
094: public long getLeastSignificantBits() {
095: return leastSignificantBits;
096: }
097:
098: public int version() {
099: return (int) (mostSignificantBits >>> 12) & 0x0F;
100: }
101:
102: public int variant() {
103: if (leastSignificantBits >>> 63 == 0)
104: return 0;
105: if (leastSignificantBits >>> 62 == 2)
106: return 2;
107: return (int) (leastSignificantBits >>> 61);
108: }
109:
110: public long timestamp() {
111: assertVersion1();
112: return (mostSignificantBits & 0x00000FFFL) << 48
113: | (mostSignificantBits & 0xFFFF0000L) << 16
114: | mostSignificantBits >>> 32;
115: }
116:
117: public int clockSequence() {
118: assertVersion1();
119: return (int) (leastSignificantBits >>> 48) & 0x3FFF;
120: }
121:
122: public long node() {
123: assertVersion1();
124: return leastSignificantBits & 0x0000FFFFFFFFFFFFL;
125: }
126:
127: public String toString() {
128: return hex(mostSignificantBits >> 32, 8) + '-'
129: + hex(mostSignificantBits >> 16, 4) + '-'
130: + hex(mostSignificantBits, 4) + '-'
131: + hex(leastSignificantBits >> 48, 4) + '-'
132: + hex(leastSignificantBits, 12);
133: }
134:
135: public int hashCode() {
136: return (int) (mostSignificantBits >> 32 ^ mostSignificantBits
137: ^ leastSignificantBits >> 32 ^ leastSignificantBits);
138: }
139:
140: public boolean equals(Object obj) {
141: if (obj instanceof UUID_) {
142: UUID_ val = (UUID_) obj;
143: return mostSignificantBits == val.mostSignificantBits
144: && leastSignificantBits == val.leastSignificantBits;
145: }
146: return false;
147: }
148:
149: public int compareTo(UUID_ val) {
150: if (mostSignificantBits > val.mostSignificantBits)
151: return 1;
152: if (mostSignificantBits < val.mostSignificantBits)
153: return -1;
154: if (leastSignificantBits > val.leastSignificantBits)
155: return 1;
156: if (leastSignificantBits < val.leastSignificantBits)
157: return -1;
158: return 0;
159: }
160:
161: private static UUID_ newInstance(byte[] bytes, int version) {
162: return new UUID_(getLong(bytes, 0) & ~0xF000L | version << 12,
163: getLong(bytes, 8) & ~0xC000000000000000L
164: | 0x8000000000000000L);
165: }
166:
167: private static long getLong(byte[] bytes, int offset) {
168: long result = 0;
169: for (int i = 0; i < 8; i++) {
170: result = result << 8 | bytes[i + offset] & 0xFF;
171: }
172: return result;
173: }
174:
175: private static String hex(long value, int length) {
176: String s = Long.toHexString(1L << (length << 2) | value);
177: return s.substring(s.length() - length);
178: }
179:
180: private void assertVersion1() {
181: if (version() != 1)
182: throw new UnsupportedOperationException(
183: "Not a version 1 UUID");
184: }
185:
186: }
|