Package com.axelor.workflow.exec
Class Boundaries
java.lang.Object
com.axelor.workflow.exec.Boundaries
Reading a parked node's boundaries: when the next one comes due, and which one has fired. A
relative deadline is derived from the plan and when the park first opened, never from a re-park;
an
until is stored on the park's row and re-read when the record changes.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordWhat a park recorded: when it opened, its absolute deadlines, and which non-cancelling boundaries have fired.static final recordOne thing a park listens for: a name, the key narrowing it (null for a signal), and the boundary that asked, null for the node's own trigger. -
Method Summary
Modifier and TypeMethodDescriptionstatic LocalDateTimeasDateTime(Object value) The usual date shapes a script can hand back, or null for anything else.static WorkflowPlan.BoundarybyId(List<WorkflowPlan.Boundary> boundaries, String boundaryId) The boundary a wake source names, or null when the pinned revision has none by that id.static voidclearFired(String parkKey, String boundaryId) Clear a non-cancelling condition boundary's mark once its condition is false, so its next true is a new edge.static Optional<LocalDateTime> earliestDeadline(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, Map<String, LocalDateTime> resolved) The earliest deadline among these boundaries, given the absolute deadlines the park resolved.static Optional<LocalDateTime> earliestDeadline(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, Map<String, LocalDateTime> resolved, Map<String, String> fired) The same, skipping a non-cancelling boundary that has spent its occurrences on this park.static MetaWorkflowParkstatic Optional<WorkflowPlan.Boundary> fired(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, LocalDateTime now, Predicate<String> holds, Map<String, LocalDateTime> resolved, Map<String, String> fired) The first boundary that has fired, in declaration order; with noparkedAtonly conditions count.static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, Boundaries.Park park, LocalDateTime now) static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, String parkKey, LocalDateTime now) The deadline boundary due on this park, read from its row; none once the park has closed.static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, LocalDateTime now, Map<String, LocalDateTime> resolved) The first deadline boundary that has come due, ignoring conditions.static booleanhasConditional(List<WorkflowPlan.Boundary> boundaries) Whether any boundary waits on a condition, and so must be re-read when the record changes.static booleanRecord that a non-cancelling boundary fired, before acting on it.static booleanAs above, for a boundary that may fire up tomaxOccurrencestimes.markNextFired(String parkKey, WorkflowPlan.Boundary boundary, Map<String, String> fired) Mark a non-cancelling boundary's next occurrence fired, exactly once: a timed one advances its count up toWorkflowPlan.Boundary.occurrenceLimit(), anything else records"true".static intoccurrences(Map<String, String> fired, String boundaryId) How many times a boundary has fired: a repeating boundary stores its count; any other value means once.static List<WorkflowPlan.Boundary> of(WorkflowPlan.Step step) static voidopen(String parkKey, LocalDateTime parkedAt, Map<String, LocalDateTime> deadlines, List<Boundaries.Subscription> subscriptions, WorkflowParkOwner owner, Long ownerId) Open a park under a freshly minted key.static voidownedByBranch(String parkKey, Long tokenId) Names the branch holding a park that opened before the branch had a row; never renames an owned park.static Boundaries.Parkstatic Map<String, LocalDateTime> readDeadlines(String json) {"giveup":"2026-09-06T10:00"}as written bywriteDeadlines(java.util.Map<java.lang.String, java.time.LocalDateTime>).{"giveup":"2026-09-08T10:00", "remind":"true"}as written bymarkFired(java.lang.String, java.lang.String, java.lang.String): the instant a timed boundary fired, or"true"for a condition.static Map<String, LocalDateTime> rearmDeadlines(String parkKey, List<WorkflowPlan.Boundary> boundaries, Map<String, LocalDateTime> armed, Function<String, Object> eval) Re-read this park'suntildeadlines from the record and store what they now say; adelayis not stored and never moves.static voidreconcileConditions(List<WorkflowPlan.Boundary> boundaries, String parkKey, Predicate<String> holds) Clear the marks of non-cancelling condition boundaries whose condition has dropped.static LocalDateTimeReads oneuntilfrom the record, keeping the armed instant when it no longer answers.static Map<String, LocalDateTime> resolveDeadlines(List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) Resolve these boundaries' absolute deadlines as a park opens.static List<Boundaries.Subscription> resolveSubscriptions(EventKind ownKind, String ownName, String ownKey, List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) Resolve what this park listens for as it opens: the node's own correlating trigger, then each correlating boundary in declaration order.static List<Boundaries.Subscription> resolveSubscriptions(List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) The same, for a host with no correlating trigger of its own, such as a task or a subflow.static StringwriteDeadlines(Map<String, LocalDateTime> deadlines) static StringwriteFired(Map<String, String> fired)
-
Method Details
-
earliestDeadline
public static Optional<LocalDateTime> earliestDeadline(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, Map<String, LocalDateTime> resolved) The earliest deadline among these boundaries, given the absolute deadlines the park resolved. A boundary with no resolved entry is not counted. -
earliestDeadline
public static Optional<LocalDateTime> earliestDeadline(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, Map<String, LocalDateTime> resolved, Map<String, String> fired) The same, skipping a non-cancelling boundary that has spent its occurrences on this park. -
resolveDeadlines
public static Map<String,LocalDateTime> resolveDeadlines(List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) Resolve these boundaries' absolute deadlines as a park opens.- Parameters:
eval- evaluates one expression against the record- Throws:
WorkflowFailure- if anuntilis not a date or datetime
-
reread
public static LocalDateTime reread(String id, String expr, LocalDateTime armed, Function<String, Object> eval) Reads oneuntilfrom the record, keeping the armed instant when it no longer answers.- Parameters:
armed- the fallback instant, or null when the park is opening, where a non-date returns null and an unreadable expression throws
-
rearmDeadlines
public static Map<String,LocalDateTime> rearmDeadlines(String parkKey, List<WorkflowPlan.Boundary> boundaries, Map<String, LocalDateTime> armed, Function<String, Object> eval) Re-read this park'suntildeadlines from the record and store what they now say; adelayis not stored and never moves.- Parameters:
armed- the deadlines this park currently carries- Returns:
- the deadlines as they now stand, equal to
armedwhen nothing moved
-
asDateTime
The usual date shapes a script can hand back, or null for anything else. -
fired
public static Optional<WorkflowPlan.Boundary> fired(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, LocalDateTime now, Predicate<String> holds, Map<String, LocalDateTime> resolved, Map<String, String> fired) The first boundary that has fired, in declaration order; with noparkedAtonly conditions count. A non-cancelling boundary does not fire again once spent, or, for a condition, until it drops and rises again.- Parameters:
holds- evaluates one condition expression against the record
-
firedByTime
public static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, LocalDateTime parkedAt, LocalDateTime now, Map<String, LocalDateTime> resolved) The first deadline boundary that has come due, ignoring conditions. -
firedByTime
public static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, String parkKey, LocalDateTime now) The deadline boundary due on this park, read from its row; none once the park has closed. -
firedByTime
public static Optional<WorkflowPlan.Boundary> firedByTime(List<WorkflowPlan.Boundary> boundaries, Boundaries.Park park, LocalDateTime now) -
byId
The boundary a wake source names, or null when the pinned revision has none by that id. -
hasConditional
Whether any boundary waits on a condition, and so must be re-read when the record changes. -
park
-
find
-
open
public static void open(String parkKey, LocalDateTime parkedAt, Map<String, LocalDateTime> deadlines, List<Boundaries.Subscription> subscriptions, WorkflowParkOwner owner, Long ownerId) Open a park under a freshly minted key. Never called on a re-park, which keeps its row.- Parameters:
owner- what holds the park and its id, so the park leads back to what waits on it
-
ownedByBranch
Names the branch holding a park that opened before the branch had a row; never renames an owned park. -
resolveSubscriptions
public static List<Boundaries.Subscription> resolveSubscriptions(EventKind ownKind, String ownName, String ownKey, List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) Resolve what this park listens for as it opens: the node's own correlating trigger, then each correlating boundary in declaration order. Keys are evaluated once, here, so an edit cannot re-aim a live subscription.- Parameters:
ownKind- the parked node's own trigger, which decides whether its key is read at allownName- the node's own message or signal name, or nulleval- evaluates one expression against the record- Throws:
WorkflowFailure- if a message's key evaluates to nothing
-
resolveSubscriptions
public static List<Boundaries.Subscription> resolveSubscriptions(List<WorkflowPlan.Boundary> boundaries, String stepId, Function<String, Object> eval) The same, for a host with no correlating trigger of its own, such as a task or a subflow. -
readDeadlines
{"giveup":"2026-09-06T10:00"}as written bywriteDeadlines(java.util.Map<java.lang.String, java.time.LocalDateTime>). -
writeDeadlines
-
readFired
{"giveup":"2026-09-08T10:00", "remind":"true"}as written bymarkFired(java.lang.String, java.lang.String, java.lang.String): the instant a timed boundary fired, or"true"for a condition. -
writeFired
-
markFired
Record that a non-cancelling boundary fired, before acting on it. Two racing dispatches cannot both record it: the park's version column rejects the second save.- Returns:
- true only for the call that recorded it, which alone may act on the firing
-
markFired
public static boolean markFired(String parkKey, String boundaryId, String value, int maxOccurrences) As above, for a boundary that may fire up tomaxOccurrencestimes. -
occurrences
How many times a boundary has fired: a repeating boundary stores its count; any other value means once. -
markNextFired
public static Optional<Map<String,String>> markNextFired(String parkKey, WorkflowPlan.Boundary boundary, Map<String, String> fired) Mark a non-cancelling boundary's next occurrence fired, exactly once: a timed one advances its count up toWorkflowPlan.Boundary.occurrenceLimit(), anything else records"true".- Returns:
- the fired map with the new entry when this call won the mark; empty when a race took it
-
clearFired
Clear a non-cancelling condition boundary's mark once its condition is false, so its next true is a new edge. Timed and correlation boundaries are never cleared. -
reconcileConditions
public static void reconcileConditions(List<WorkflowPlan.Boundary> boundaries, String parkKey, Predicate<String> holds) Clear the marks of non-cancelling condition boundaries whose condition has dropped.- Parameters:
holds- evaluates one condition expression against the record
-
of
-