Trigger reference controls¶
No propagate event handler¶
An event handler method can prevent its method triggering a notification by setting the propagate attribute to false
on any event handler annotation, @OnEventHandler(propagate = false)
See sample - NoPropagateHandler.java
public class NoPropagateHandler {
public static class MyNode {
@OnEventHandler
public boolean handleStringEvent(String stringToProcess) {
System.out.println("MyNode::handleStringEvent received:" + stringToProcess);
return true;
}
@OnEventHandler(propagate = false)
public boolean handleIntEvent(int intToProcess) {
System.out.println("MyNode::handleIntEvent received:" + intToProcess);
return true;
}
}
public static class Child {
private final MyNode myNode;
public Child(MyNode myNode) {
this.myNode = myNode;
}
@OnTrigger
public boolean triggered(){
System.out.println("Child:triggered");
return true;
}
}
public static void main(String[] args) {
var processor = DataFlowBuilder
.subscribeToNode(new Child(new MyNode()))
.build();
processor.onEvent("test");
System.out.println();
processor.onEvent(200);
}
}
Output
MyNode::handleStringEvent received:test
Child:triggered
MyNode::handleIntEvent received:200
No trigger reference¶
A child can isolate itself from a parent's event notification by marking the reference with a @NoTriggerReference
annotation. This will stop the onTrigger method from firing even when the parent has triggered.
See sample - NoPropagateHandler.java
public class NoPropagateHandler {
public static class MyNode {
@OnEventHandler
public boolean handleStringEvent(String stringToProcess) {
System.out.println("MyNode::handleStringEvent received:" + stringToProcess);
return true;
}
@OnEventHandler(propagate = false)
public boolean handleIntEvent(int intToProcess) {
System.out.println("MyNode::handleIntEvent received:" + intToProcess);
return true;
}
}
public static class Child {
private final MyNode myNode;
public Child(MyNode myNode) {
this.myNode = myNode;
}
@OnTrigger
public boolean triggered(){
System.out.println("Child:triggered");
return true;
}
}
public static void main(String[] args) {
var processor = DataFlowBuilder
.subscribeToNode(new Child(new MyNode()))
.build();
processor.onEvent("test");
System.out.println();
processor.onEvent(200);
}
}
Output
MyNode::handleStringEvent received:test
Child:triggered
MyNode2::handleIntEvent received:200
Override trigger reference¶
A child can force only a single parent to fire its trigger, all other parents will be treated as if they were annotated with
@NoTriggerReference
and removed from the event notification triggers for this class.
See sample - SingleTriggerOverride.java
public class SingleTriggerOverride {
public static class MyNode {
@OnEventHandler
public boolean handleStringEvent(String stringToProcess) {
System.out.println("MyNode::handleStringEvent received:" + stringToProcess);
return true;
}
}
public static class MyNode2 {
@OnEventHandler
public boolean handleIntEvent(int intToProcess) {
System.out.println("MyNode2::handleIntEvent received:" + intToProcess);
return true;
}
}
public static class Child {
private final MyNode myNode;
@TriggerEventOverride
private final MyNode2 myNode2;
public Child(MyNode myNode, MyNode2 myNode2) {
this.myNode = myNode;
this.myNode2 = myNode2;
}
@OnTrigger
public boolean triggered() {
System.out.println("Child:triggered");
return true;
}
}
public static void main(String[] args) {
var processor = DataFlowBuilder
.subscribeToNode(new Child(new MyNode(), new MyNode2()))
.build();
processor.onEvent("test");
System.out.println();
processor.onEvent(200);
}
}
Output
MyNode::handleStringEvent received:test
MyNode2::handleIntEvent received:200
Child:triggered
Non-dirty triggering¶
The condition that causes a trigger callback to fire can be inverted so that an indication of no change from the parent will cause the trigger to fire.
See sample - InvertDirtyTrigger.java
public class InvertDirtyTrigger {
public static class MyNode {
@OnEventHandler
public boolean handleStringEvent(int intToProcess) {
boolean propagate = intToProcess > 100;
System.out.println("conditional propagate:" + propagate);
return propagate;
}
}
public static class Child {
private final MyNode myNode;
public Child(MyNode myNode) {
this.myNode = myNode;
}
@OnTrigger
public boolean triggered() {
System.out.println("Child:triggered");
return true;
}
}
public static class NonDirtyChild {
private final MyNode myNode;
public NonDirtyChild(MyNode myNode) {
this.myNode = myNode;
}
@OnTrigger(dirty = false)
public boolean triggered() {
System.out.println("NonDirtyChild:triggered");
return true;
}
}
public static void main(String[] args) {
MyNode myNode = new MyNode();
DataFlowBuilder.subscribeToNode(new Child(myNode)).build();
var processor = DataFlowBuilder
.subscribeToNode( new NonDirtyChild(myNode))
.build();
processor.onEvent("test");
System.out.println();
processor.onEvent(200);
System.out.println();
processor.onEvent(50);
}
}
Output
conditional propagate:true
Child:triggered
conditional propagate:false
NonDirtyChild:triggered
Push trigger¶
Invert the trigger order so the instance holding the reference receives the event notification before the reference target
and can push data into the target. Annotate the reference to be a push target with the @PushReference
annotation.
See sample - PushTrigger.java
The normal order is to trigger the target first, which can perform internal calculations if required. Then the instance holding the reference is triggered so it can pull calculated data from the target reference.
public class PushTrigger {
public static class MyNode {
@PushReference
private final PushTarget pushTarget;
public MyNode(PushTarget pushTarget) {
this.pushTarget = pushTarget;
}
@OnEventHandler
public boolean handleStringEvent(String stringToProcess) {
System.out.println("MyNode::handleStringEvent " + stringToProcess);
if (stringToProcess.startsWith("PUSH")) {
pushTarget.myValue = stringToProcess;
return true;
}
return false;
}
}
public static class PushTarget {
public String myValue;
@OnTrigger
public boolean onTrigger() {
System.out.println("PushTarget::onTrigger -> myValue:'" + myValue + "'");
return true;
}
}
public static void main(String[] args) {
var processor = DataFlowBuilder
.subscribeToNode(new MyNode(new PushTarget()))
.build();
processor.onEvent("PUSH - test 1");
System.out.println();
processor.onEvent("ignore me - XXXXX");
System.out.println();
processor.onEvent("PUSH - test 2");
}
}
Output
MyNode::handleStringEvent PUSH - test 1
PushTarget::onTrigger -> myValue:'PUSH - test 1'
MyNode::handleStringEvent ignore me - XXXXX
MyNode::handleStringEvent PUSH - test 2
PushTarget::onTrigger -> myValue:'PUSH - test 2'