X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.uuid%2Fsrc%2Forg%2Fargeo%2Fapi%2Fuuid%2FUuidFactory.java;h=4ab6c2e4b754d7818be29a24fece361373b5f6e9;hb=5f820a14abf7371714514ed5f20580ceb5edaeec;hp=a2970618403f45002a2706ad9e48e0badf649c88;hpb=580e8ff2af47001eb3e0947488395b48773be469;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.uuid/src/org/argeo/api/uuid/UuidFactory.java b/org.argeo.api.uuid/src/org/argeo/api/uuid/UuidFactory.java index a29706184..4ab6c2e4b 100644 --- a/org.argeo.api.uuid/src/org/argeo/api/uuid/UuidFactory.java +++ b/org.argeo.api.uuid/src/org/argeo/api/uuid/UuidFactory.java @@ -2,6 +2,7 @@ package org.argeo.api.uuid; import static java.nio.charset.StandardCharsets.UTF_8; +import java.nio.charset.Charset; import java.util.Objects; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -16,36 +17,101 @@ import java.util.function.Supplier; * @see https://datatracker.ietf.org/doc/html/rfc4122 */ public interface UuidFactory extends Supplier { + /* - * TIME-BASED (version 1) + * DEFAULT */ + /** + * The default {@link UUID} to provide, either random (v4) or time based (v1). + * It SHOULD wrap either {@link #timeUUID()} (recommended) or + * {@link #randomUUID()}. + */ + @Override + UUID get(); + /* + * TIME-BASED (version 1) + */ + /** + * A new time based {@link UUID} (v1) with efforts to make it unique on this + * node. + */ UUID timeUUID(); - UUID timeUUIDwithMacAddress(); - /* * NAME BASED (version 3 and 5) */ - + /** + * A new {@link UUID} v5, which an SHA1 digest of namespace and the provided + * bytes. This use to build names and implementation MAY restrict the maximal + * size of the byte array. + * + * @see UuidFactory#NAMESPACE_UUID_DNS + * @see UuidFactory#NAMESPACE_UUID_URL + * @see UuidFactory#NAMESPACE_UUID_OID + * @see UuidFactory#NAMESPACE_UUID_X500 + */ UUID nameUUIDv5(UUID namespace, byte[] data); + /** + * A new {@link UUID} v3, which a MD5 digest of namespace and the provided + * bytes. This use to build names and implementation MAY restrict the maximal + * size of the byte array. + * + * @see UuidFactory#NAMESPACE_UUID_DNS + * @see UuidFactory#NAMESPACE_UUID_URL + * @see UuidFactory#NAMESPACE_UUID_OID + * @see UuidFactory#NAMESPACE_UUID_X500 + */ UUID nameUUIDv3(UUID namespace, byte[] data); + /** + * A convenience method to generate a name based UUID v5 based on a string, + * using the UTF-8 charset. + * + * @see UuidFactory#nameUUIDv5(UUID, byte[]) + */ default UUID nameUUIDv5(UUID namespace, String name) { + return nameUUIDv5(namespace, name, UTF_8); + } + + /** + * A convenience method to generate a name based UUID v5 based on a string. + * + * @see UuidFactory#nameUUIDv5(UUID, byte[]) + */ + default UUID nameUUIDv5(UUID namespace, String name, Charset charset) { Objects.requireNonNull(name, "Name cannot be null"); - return nameUUIDv5(namespace, name.getBytes(UTF_8)); + return nameUUIDv5(namespace, name.getBytes(charset)); } + /** + * A convenience method to generate a name based UUID v3 based on a string, + * using the UTF-8 charset. + * + * @see UuidFactory#nameUUIDv3(UUID, byte[]) + */ default UUID nameUUIDv3(UUID namespace, String name) { + return nameUUIDv3(namespace, name, UTF_8); + } + + /** + * A convenience method to generate a name based UUID v3 based on a string. + * + * @see UuidFactory#nameUUIDv3(UUID, byte[]) + */ + default UUID nameUUIDv3(UUID namespace, String name, Charset charset) { Objects.requireNonNull(name, "Name cannot be null"); - return nameUUIDv3(namespace, name.getBytes(UTF_8)); + return nameUUIDv3(namespace, name.getBytes(charset)); } /* * RANDOM (version 4) */ - /** A random UUID at least as good as {@link UUID#randomUUID()}. */ + /** + * A random UUID at least as good as {@link UUID#randomUUID()}, but with efforts + * to make it even more random, using more secure algorithms and resseeding. + */ UUID randomUUIDStrong(); /** @@ -56,21 +122,16 @@ public interface UuidFactory extends Supplier { /** * The default random {@link UUID} (v4) generator to use. This default - * implementation returns {@link #randomUUIDStrong()}. + * implementation returns {@link #randomUUIDStrong()}. In general, one should + * use {@link UUID#randomUUID()} to generate random UUID, as it is certainly the + * best balanced and to avoid unnecessary dependencies with an API. The + * implementations provided here are either when is looking for something + * "stronger" ({@link #randomUUIDStrong()} or faster {@link #randomUUIDWeak()}. */ default UUID randomUUID() { return randomUUIDStrong(); } - /** - * The default {@link UUID} to provide, either random (v4) or time based (v1). - * This default implementations returns {@link #randomUUID()}. - */ - @Override - default UUID get() { - return randomUUID(); - } - /* * STANDARD UUIDs */ @@ -81,31 +142,40 @@ public interface UuidFactory extends Supplier { * Standard DNS namespace ID for type 3 or 5 UUID (as defined in Appendix C of * RFC4122). */ - final static UUID NS_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"); + final static UUID NAMESPACE_UUID_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"); /** * Standard URL namespace ID for type 3 or 5 UUID (as defined in Appendix C of * RFC4122). */ - final static UUID NS_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); + final static UUID NAMESPACE_UUID_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); /** * Standard OID namespace ID (typically an LDAP type) for type 3 or 5 UUID (as * defined in Appendix C of RFC4122). */ - final static UUID NS_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); + final static UUID NAMESPACE_UUID_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); /** * Standard X500 namespace ID (typically an LDAP DN) for type 3 or 5 UUID (as * defined in Appendix C of RFC4122). */ - final static UUID NS_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"); + final static UUID NAMESPACE_UUID_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"); /* - * UTILITIES + * BIT LEVEL CONSTANTS */ + /** Base for the most significant bit of version 1 (time based) UUIDs. */ + long MOST_SIG_VERSION1 = (1l << 12); + /** Base for the least significant part of RFC4122 (variant 2) UUIDs. */ + long LEAST_SIG_RFC4122_VARIANT = (1l << 63); + /* + * UTILITIES + */ + /** Whether this {@link UUID} is random (v4). */ static boolean isRandom(UUID uuid) { return uuid.version() == 4; } + /** Whether this {@link UUID} is time based (v1). */ static boolean isTimeBased(UUID uuid) { return uuid.version() == 1; } @@ -123,7 +193,34 @@ public interface UuidFactory extends Supplier { return false; } + /** Whether this {@link UUID} is name based (v3 or v5). */ static boolean isNameBased(UUID uuid) { return uuid.version() == 3 || uuid.version() == 5; } + + /** + * The state of a time based UUID generator, as described and discussed in + * section 4.2.1 of RFC4122. + * + * @see https://datatracker.ietf.org/doc/html/rfc4122#section-4.2.1 + */ + interface TimeUuidState { + /** Current node id and clock sequence for this thread. */ + long getLeastSignificantBits(); + + /** A new current timestamp for this thread. */ + long getMostSignificantBits(); + + /** + * The last timestamp which was produced by this thread, as returned by + * {@link UUID#timestamp()}. + */ + long getLastTimestamp(); + + /** + * The current clock sequence for this thread, as returned by + * {@link UUID#clockSequence()}. + */ + long getClockSequence(); + } }