Return-Path:
Constructs a UUID from a 128 bit java.math.BigInteger. Method is protected as their is no standard as to the internal representation of a UUID.
- * In this case a BigInteger is used with signum always positive. Copy constructor. Constructs a UUID from a 16 byte array. Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block. Constructs a UUID from two long values in most significant byte, and least significant bytes order. Constructs a UUID from a UUID formatted String. Parses a string for a UUID. Returns a string representation of the UUID. Returns a urn representation of the UUID. This is same as the
- * toString() value prefixed with Compares two UUID for equality. Returns a hash code value for the object. Compares two UUID's for equality Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that
- * generated the time in the timestamp of a time based UUID. Returns the version of the UUID.
- * urn:uuid:
- *
- *
Returns the variant field of the UUID.
- * - * @return Returns the variant field of the UUID. - * @see UUID#VARIANT_NCS_COMPAT - * @see UUID#VARIANT_IETF_DRAFT - * @see UUID#VARIANT_MS - * @see UUID#VARIANT_FUTURE - */ - public int variant() { - if (variant == -1) { - if ((rawBytes[8] & 0x80) == 0x0) { - variant = VARIANT_NCS_COMPAT; - } else if ((rawBytes[8] & 0x40) == 0x0) { - variant = VARIANT_IETF_DRAFT; - } else if ((rawBytes[8] & 0x20) == 0x0) { - variant = VARIANT_MS; - } else { - variant = VARIANT_FUTURE; - } - } - return variant; - } - - /** - *Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC - * address. The specification permits this value to be calculated from other sources other than the MAC.
- * - * @return the node identifier found in this UUID. - * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. - */ - public long node() throws UnsupportedOperationException { - //if variant is not mealling leach salz throw unsupported operation exception - if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { - throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); - } - if (node == null) { - byte[] b = new byte[8]; - System.arraycopy(rawBytes, 10, b, 2, 6); - node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL)); - } - return node.longValue(); - } - - /** - *Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15 - * October 1582 ).
- * - * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset. - * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. - */ - public long timestamp() throws UnsupportedOperationException { - //if variant is not mealling leach salz throw unsupported operation exception - if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { - throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); - } - if (timestamp == -1) { - byte[] longVal = new byte[8]; - System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN); - System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN); - System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN); - longVal[TIME_HI_TS_POS] &= 0x0F; - timestamp = Bytes.toLong(longVal); - } - return timestamp; - } - - /** - *Returns the least significant bits stored in the uuid's internal structure.
- * - * @return the least significant bits stored in the uuid's internal structure. - */ - long getLeastSignificantBits() { - byte[] lsb = new byte[8]; - System.arraycopy(rawBytes, 8, lsb, 0, 8); - return Bytes.toLong(lsb); - } - - /** - *Returns the least significant bits stored in the uuid's internal structure.
- * - * @return the least significant bits stored in the uuid's internal structure. - */ - long getMostSignificantBits() { - byte[] msb = new byte[8]; - System.arraycopy(rawBytes, 0, msb, 0, 8); - return Bytes.toLong(msb); - } - - /** - *Returns a copy of the byte values contained in this UUID. - * - * @return a copy of the byte values contained in this UUID. - */ - public byte[] getRawBytes() { - byte[] ret = new byte[UUID_BYTE_LENGTH]; - System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH); - return ret; - } - - /** - *
Returns a new version 4 UUID, based upon Random bits.
- * - * @return a new version 4 UUID, based upon Random bits. - */ - static UUID randomUUID() { - return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier(); - } - - /** - *Returns a new version 1 UUID, based upon node identifier and time stamp.
- * - * @return a new version 1 UUID, based upon node identifier and time stamp. - */ - static UUID timeUUID() { - return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier(); - } - - /** - *Returns a new version three (MD5) or five (SHA-1) UUID, using the specified encoding - * given a name and the namespace's UUID.
- * - * @param name String the name to calculate the UUID for. - * @param namespace UUID assigned to this namespace. - * @param encoding The encoding to use, either #{link UUID.MD5_ENCODING} or #{link UUID.SHA1_ENCODING} - * @return a new version three UUID given a name and the namespace's UUID. - */ - static UUID nameUUIDFromString(String name, UUID namespace, String encoding) { - byte[] nameAsBytes = name.getBytes(); - byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length]; - System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH); - System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length); - - byte[] raw = null; - - if(encoding.equals(UUID.MD5_ENCODING)) { - raw = DigestUtils.md5(concat); - } - else if(encoding.equals(UUID.SHA1_ENCODING)) { - byte[] shaDigest = DigestUtils.sha(concat); - // Truncate digest to 16 bytes (SHA-1 returns a 20-byte digest) - raw = new byte[16]; - System.arraycopy(shaDigest, 0, raw, 0, 16); - } - else { - throw new RuntimeException("Unsupported encoding " + encoding); + + /** byte array to store 128-bits composing this UUID */ + private byte[] rawBytes = new byte[UUID_BYTE_LENGTH]; + + /** Holds node identifier for this UUID */ + private Long node = null; + + /** Holds timestamp for this UUID */ + private long timestamp = -1; + + /** Holds the clock sequence field */ + private Short clockSq = null; + + /** Holds the version field of this UUID */ + private int version = -1; + + /** Holds the variant field of this UUID */ + private int variant = -1; + + /** Holds the internal string value of the UUID */ + private String stringValue = null; + + + /** Constructs a nil UUID */ + public UUID() { + super(); } + /** + *Constructs a UUID from a 128 bit java.math.BigInteger.
+ *Method is protected as their is no standard as to the internal representation of a UUID. + * In this case a BigInteger is used with signum always positive.
+ * + * @param bigIntValue the 128 bit BigInteger to construct this UUID from. + * @throws IllegalArgumentException argument must be 128 bit + */ + /* protected UUID(BigInteger bigIntValue) throws IllegalArgumentException { + super(); + if (bigIntValue.bitLength() > UUID.UUID_BIT_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 128 bit BigInteger"); + } + numberValue = bigIntValue; + } */ + + /** + *Copy constructor.
+ * + * @param copyFrom the UUID to copy to create this UUID. + */ + public UUID(UUID copyFrom) { + super(); + rawBytes = copyFrom.getRawBytes(); + } + + /** + *Constructs a UUID from a 16 byte array.
+ * + * @param byteArray the 16 byte array to construct this UUID from. + * @throws IllegalArgumentException argument must be 16 bytes + */ + public UUID(byte[] byteArray) throws IllegalArgumentException { + super(); + if (byteArray.length != UUID_BYTE_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 16 byte array."); + } + // UUID must be immutable so a copy is used. + System.arraycopy(byteArray, 0, rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block.
+ * + * @param input the datainput with 16 bytes to read in from. + * @throws IOException exception if there is an IO problem also argument must contain 16 bytes. + */ + public UUID(DataInput input) throws IOException { + super(); + input.readFully(rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *Constructs a UUID from two long values in most significant byte, and least significant bytes order.
+ * + * @param mostSignificant - the most significant 8 bytes of the uuid to be constructed. + * @param leastSignificant - the least significant 8 bytes of the uuid to be constructed. + */ + public UUID(long mostSignificant, long leastSignificant) { + rawBytes = Bytes.append(Bytes.toBytes(mostSignificant), Bytes.toBytes(leastSignificant)); + } + + /** + *Constructs a UUID from a UUID formatted String.
+ * + * @param uuidString the String representing a UUID to construct this UUID + * @throws UUIDFormatException String must be a properly formatted UUID string + */ + public UUID(String uuidString) throws UUIDFormatException { + //Calls the copy constructor + this(UUID.fromString(uuidString)); + } + + /** + *Parses a string for a UUID.
+ * + * @param uuidString the UUID formatted String to parse. + * @throws UUIDFormatException the String must be a properly formatted UUID String. + * @return Returns a UUID or null if the formatted string could not be parsed. + */ + public static UUID fromString(String uuidString) + throws UUIDFormatException { + String leanString = uuidString.toLowerCase(); + UUID tmpUUID = null; + + //Handle prefixed UUIDs + // e.g. urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + int pos = uuidString.lastIndexOf(":"); + if (pos > 1) { + leanString = uuidString.substring(++pos, uuidString.length()); + } + + //Check for 36 char length + if (leanString.length() != UUID_FORMATTED_LENGTH) { + throw new UUIDFormatException(); + } + + //Check for 5 fields + StringTokenizer tok = new StringTokenizer(leanString, "-"); + if ( tok.countTokens() != TOKENS_IN_UUID ) { + throw new UUIDFormatException(); + } + + //Remove the "-" from the formatted string and test token sizes + StringBuffer buf = new StringBuffer(UUID_UNFORMATTED_LENGTH); + String token = null; + int count = 0; + while (tok.hasMoreTokens()) { + token = tok.nextToken(); + if (token.length() != TOKEN_LENGTHS[count++]) { + throw new UUIDFormatException(); + } + buf.append(token); + } + + //Create from the hex value + try { + char[] chars = buf.toString().toCharArray(); + tmpUUID = new UUID(Hex.decodeHex(chars)); + } catch (DecoderException de) { + throw new UUIDFormatException(de.getMessage()); + } + return tmpUUID; + } + + /** + *Returns a string representation of the UUID.
+ * + * @return a string representation of the UUID formatted according to the specification. + */ + public String toString() { + //set string value if not set + if (stringValue == null) { + StringBuffer buf = new StringBuffer(new String(Hex.encodeHex(rawBytes))); + while (buf.length() != UUID_UNFORMATTED_LENGTH) { + buf.insert(0, "0"); + } + buf.ensureCapacity(UUID_FORMATTED_LENGTH); + buf.insert(FORMAT_POSITION1, '-'); + buf.insert(FORMAT_POSITION2, '-'); + buf.insert(FORMAT_POSITION3, '-'); + buf.insert(FORMAT_POSITION4, '-'); + stringValue = buf.toString(); + } + return stringValue; + } + + /** + *Returns a urn representation of the UUID. This is same as the
+ * toString() value prefixed with urn:uuid:
Compares two UUID for equality.
+ * + * @see java.lang.Object#equals(Object) + */ + + public boolean equals(Object obj) { + if (!(obj instanceof UUID)) { + return false; + } + return Bytes.areEqual( ((UUID) obj).getRawBytes(), rawBytes); + } + + /** + *Returns a hash code value for the object.
+ * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int iConstant = 37; + int iTotal = 17; + for (int i = 0; i < rawBytes.length; i++) { + iTotal = iTotal * iConstant + rawBytes[i]; + } + return iTotal; + } + + /** + *Compares two UUID's for equality
+ * + * @see Comparable#compareTo(Object) + */ + public int compareTo(Object compareTo) throws ClassCastException { + if (!(compareTo instanceof UUID)) { + throw new ClassCastException(); + } + return (Bytes.compareTo(rawBytes, ((UUID) compareTo).getRawBytes())); + } + + /** + *Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that + * generated the time in the timestamp of a time based UUID.
+ * + * @return the clock sequence value in the UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public int clockSequence() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (clockSq == null) { + byte[] b = {((byte) (rawBytes[8] & 0x3F)), rawBytes[9]}; + clockSq = new Short(Bytes.toShort(b)); + } + return clockSq.intValue(); + } + + /** + *Returns the version of the UUID. + *
Returns the variant field of the UUID.
+ * + * @return Returns the variant field of the UUID. + * @see UUID#VARIANT_NCS_COMPAT + * @see UUID#VARIANT_IETF_DRAFT + * @see UUID#VARIANT_MS + * @see UUID#VARIANT_FUTURE + */ + public int variant() { + if (variant == -1) { + if ((rawBytes[8] & 0x80) == 0x0) { + variant = VARIANT_NCS_COMPAT; + } else if ((rawBytes[8] & 0x40) == 0x0) { + variant = VARIANT_IETF_DRAFT; + } else if ((rawBytes[8] & 0x20) == 0x0) { + variant = VARIANT_MS; + } else { + variant = VARIANT_FUTURE; + } + } + return variant; + } + + /** + *Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC + * address. The specification permits this value to be calculated from other sources other than the MAC.
+ * + * @return the node identifier found in this UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long node() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (node == null) { + byte[] b = new byte[8]; + System.arraycopy(rawBytes, 10, b, 2, 6); + node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL)); + } + return node.longValue(); + } + + /** + *Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15 + * October 1582 ).
+ * + * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long timestamp() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (timestamp == -1) { + byte[] longVal = new byte[8]; + System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN); + System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN); + System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN); + longVal[TIME_HI_TS_POS] &= 0x0F; + timestamp = Bytes.toLong(longVal); + } + return timestamp; + } + + /** + *Returns the least significant bits stored in the uuid's internal structure.
+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getLeastSignificantBits() { + byte[] lsb = new byte[8]; + System.arraycopy(rawBytes, 8, lsb, 0, 8); + return Bytes.toLong(lsb); + } + + /** + *Returns the least significant bits stored in the uuid's internal structure.
+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getMostSignificantBits() { + byte[] msb = new byte[8]; + System.arraycopy(rawBytes, 0, msb, 0, 8); + return Bytes.toLong(msb); + } + + /** + *Returns a copy of the byte values contained in this UUID. + * + * @return a copy of the byte values contained in this UUID. + */ + public byte[] getRawBytes() { + byte[] ret = new byte[UUID_BYTE_LENGTH]; + System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH); + return ret; + } + + /** + *
Returns a new version 4 UUID, based upon Random bits.
+ * + * @return a new version 4 UUID, based upon Random bits. + */ + public static UUID randomUUID() { + return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier(); + } + + /** + *Returns a new version 1 UUID, based upon node identifier and time stamp.
+ * + * @return a new version 1 UUID, based upon node identifier and time stamp. + */ + public static UUID timeUUID() { + return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier(); + } + + /** + *Returns a new version three (MD5) or five (SHA-1) UUID, using the specified encoding + * given a name and the namespace's UUID.
+ * + * @param name String the name to calculate the UUID for. + * @param namespace UUID assigned to this namespace. + * @param encoding The encoding to use, either #{link UUID.MD5_ENCODING} or #{link UUID.SHA1_ENCODING} + * @return a new version three UUID given a name and the namespace's UUID. + */ + public static UUID nameUUIDFromString(String name, UUID namespace, String encoding) { + byte[] nameAsBytes = name.getBytes(); + byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length]; + System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH); + System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length); + + byte[] raw = null; + + if(encoding.equals(UUID.MD5_ENCODING)) { + raw = DigestUtils.md5(concat); + } + else if(encoding.equals(UUID.SHA1_ENCODING)) { + byte[] shaDigest = DigestUtils.sha(concat); + // Truncate digest to 16 bytes (SHA-1 returns a 20-byte digest) + raw = new byte[16]; + System.arraycopy(shaDigest, 0, raw, 0, 16); + } + else { + throw new RuntimeException("Unsupported encoding " + encoding); + } + + + //Set version (version 3 and version 5 are identical on a bit-level, + //thus we only need ever set one of them + raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F; + raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4); + + //Set variant + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111 + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000 + + return new UUID(raw); + } + + /** + *Returns a new version three UUID given a name and the namespace's UUID.
+ * + * @param name String the name to calculate the UUID for. + * @param namespace UUID assigned to this namespace. + * @return a new version three UUID given a name and the namespace's UUID. + * + */ + public static UUID nameUUIDFromString(String name, UUID namespace) { + return nameUUIDFromString(name, namespace, UUID.MD5_ENCODING); + } - //Set version (version 3 and version 5 are identical on a bit-level, - //thus we only need ever set one of them - raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F; - raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4); - - //Set variant - raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111 - raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000 - - return new UUID(raw); - } - - /** - *Returns a new version three UUID given a name and the namespace's UUID.
- * - * @param name String the name to calculate the UUID for. - * @param namespace UUID assigned to this namespace. - * @return a new version three UUID given a name and the namespace's UUID. - * - */ - static UUID nameUUIDFromString(String name, UUID namespace) { - return nameUUIDFromString(name, namespace, UUID.MD5_ENCODING); - } - } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org