package jnpf.flowable.model.util; /** Server-only, single-operator attribution for the development approval tool. */ public final class DevApprovalActor implements AutoCloseable { private static final ThreadLocal CURRENT = new ThreadLocal<>(); private final String operatorId; private final String actorId; private final String taskId; private DevApprovalActor(String operatorId, String actorId, String taskId) { this.operatorId = operatorId; this.actorId = actorId; this.taskId = taskId; } public static DevApprovalActor open(String operatorId, String actorId) { return open(operatorId, actorId, null); } public static DevApprovalActor open(String operatorId, String actorId, String taskId) { if (CURRENT.get() != null) throw new IllegalStateException("Nested development approval"); DevApprovalActor scope = new DevApprovalActor(operatorId, actorId, taskId); CURRENT.set(scope); return scope; } public static String resolve(String operatorId, String assignedActor) { DevApprovalActor scope = CURRENT.get(); return scope != null && scope.operatorId.equals(operatorId) ? scope.actorId : assignedActor; } /** Candidate override is confined to the workflow validated by the development service. */ public static String candidateForTask(String taskId) { DevApprovalActor scope = CURRENT.get(); return scope != null && taskId != null && taskId.equals(scope.taskId) ? scope.actorId : null; } public static boolean active() { return CURRENT.get() != null; } public static boolean isActing(String operatorId, String callerId) { DevApprovalActor scope = CURRENT.get(); return scope != null && scope.operatorId.equals(operatorId) && scope.actorId.equals(callerId); } @Override public void close() { CURRENT.remove(); } }