]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.api.uuid/src/org/argeo/api/uuid/AbstractAsyncUuidFactory.java
Introduce Makefile and JNI support
[lgpl/argeo-commons.git] / org.argeo.api.uuid / src / org / argeo / api / uuid / AbstractAsyncUuidFactory.java
index 2b4c27f3fac693defff64b53ea2141767022a6b7..52becc85ac0946a018e692b1065e3b20c999c83a 100644 (file)
@@ -1,6 +1,9 @@
 package org.argeo.api.uuid;
 
+import java.security.DrbgParameters;
+import java.security.DrbgParameters.Capability;
 import java.security.SecureRandom;
+import java.security.SecureRandomParameters;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
@@ -23,16 +26,17 @@ public abstract class AbstractAsyncUuidFactory extends AbstractUuidFactory imple
        protected ConcurrentTimeUuidState timeUuidState;
 
        private NodeIdSupplier nodeIdSupplier;
+       private long currentClockSequenceRange = 0;
 
        public AbstractAsyncUuidFactory() {
-               secureRandom = newSecureRandom();
+               secureRandom = createSecureRandom();
                timeUuidState = new ConcurrentTimeUuidState(secureRandom, null);
        }
        /*
         * ABSTRACT METHODS
         */
 
-       protected abstract SecureRandom newSecureRandom();
+       protected abstract SecureRandom createSecureRandom();
 
        /*
         * STATE
@@ -41,7 +45,7 @@ public abstract class AbstractAsyncUuidFactory extends AbstractUuidFactory imple
                if (nodeIdSupplier == null)
                        throw new IllegalStateException("No node id supplier available");
                long nodeIdBase = nodeIdSupplier.get();
-               timeUuidState.reset(nodeIdBase);
+               timeUuidState.reset(nodeIdBase, currentClockSequenceRange);
        }
 
        public void setNodeIdSupplier(NodeIdSupplier nodeIdSupplier) {
@@ -49,18 +53,46 @@ public abstract class AbstractAsyncUuidFactory extends AbstractUuidFactory imple
                reset();
        }
 
+       public void setNodeIdSupplier(NodeIdSupplier nodeIdSupplier, long range) {
+               this.currentClockSequenceRange = range >= 0 ? range & 0x3F00 : range;
+               setNodeIdSupplier(nodeIdSupplier);
+       }
+
+       protected NodeIdSupplier getNodeIdSupplier() {
+               return nodeIdSupplier;
+       }
+
+       /**
+        * If positive, only clock_hi is taken from the argument (range & 0x3F00), if
+        * negative, the full range of possible values is used.
+        */
+       public void setCurrentClockSequenceRange(long range) {
+               this.currentClockSequenceRange = range >= 0 ? range & 0x3F00 : range;
+               reset();
+       }
+
        /*
         * SYNC OPERATIONS
         */
-       protected UUID newRandomUUIDStrong() {
-               return newRandomUUID(secureRandom);
+       protected UUID createRandomUUIDStrong() {
+               SecureRandomParameters parameters = secureRandom.getParameters();
+               if (parameters != null) {
+                       if (parameters instanceof DrbgParameters.Instantiation) {
+                               Capability capability = ((DrbgParameters.Instantiation) parameters).getCapability();
+                               if (capability.equals(DrbgParameters.Capability.PR_AND_RESEED)
+                                               || capability.equals(DrbgParameters.Capability.RESEED_ONLY)) {
+                                       secureRandom.reseed();
+                               }
+                       }
+               }
+               return createRandomUUID(secureRandom);
        }
 
        public UUID randomUUIDWeak() {
-               return newRandomUUID(ThreadLocalRandom.current());
+               return createRandomUUID(ThreadLocalRandom.current());
        }
 
-       protected UUID newTimeUUID() {
+       protected UUID createTimeUUID() {
                if (nodeIdSupplier == null)
                        throw new IllegalStateException("No node id supplier available");
                UUID uuid = new UUID(timeUuidState.getMostSignificantBits(), timeUuidState.getLeastSignificantBits());
@@ -109,21 +141,21 @@ public abstract class AbstractAsyncUuidFactory extends AbstractUuidFactory imple
 
        @Override
        public ForkJoinTask<UUID> futureNameUUIDv5(UUID namespace, byte[] data) {
-               return submit(() -> newNameUUIDv5(namespace, data));
+               return submit(() -> createNameUUIDv5(namespace, data));
        }
 
        @Override
        public ForkJoinTask<UUID> futureNameUUIDv3(UUID namespace, byte[] data) {
-               return submit(() -> newNameUUIDv3(namespace, data));
+               return submit(() -> createNameUUIDv3(namespace, data));
        }
 
        @Override
        public ForkJoinTask<UUID> futureRandomUUIDStrong() {
-               return submit(this::newRandomUUIDStrong);
+               return submit(this::createRandomUUIDStrong);
        }
 
        @Override
        public ForkJoinTask<UUID> futureTimeUUID() {
-               return submit(this::newTimeUUID);
+               return submit(this::createTimeUUID);
        }
 }