use of org.openksavi.sponge.core.util.TreeNode in project sponge by softelnet.
the class AbstractRuleAdapterRuntime method buildEventTree.
/**
* Continues building the event tree for the incoming event starting at the specified node.
*
* @param node event tree node.
* @param event incoming event.
*/
protected void buildEventTree(TreeNode<NodeValue> node, Event event) {
// Check if this event is the first event that starts the rule instance.
boolean isFirstNode = (node == null);
// Create a new node for the incoming event and add to the event tree. This node may be removed later when the event doesn't match.
TreeNode<NodeValue> newNode = new TreeNode<>(new NodeValue(event));
if (isFirstNode) {
// First event that starts the rule.
node = newNode;
// Add the new node to the event tree as root.
eventTree.setRoot(node);
} else {
// Recursively try to continue building the event tree, but only for modes FIRST, LAST and ALL.
node.getChildren().forEach(child -> {
// NONE events are processed in shouldAddToEventTreeForNMode(), not here.
if (adapter.getEventMode(getEventIndex(child)) != EventMode.NONE) {
buildEventTree(child, event);
}
});
// Return if reached the last level.
if (node.getLevel() + 1 >= adapter.getEventCount()) {
return;
}
// Add the new node to the event tree.
node.addChild(newNode);
}
// Should this event be added to the event tree in this place.
boolean rememberEvent = false;
EventMode eventMode = getEventMode(newNode);
if (eventMode != null) {
switch(eventMode) {
case FIRST:
case LAST:
case ALL:
rememberEvent = shouldAddToEventTreeForFlaModes(newNode, event);
break;
case NONE:
Mutable<TreeNode<NodeValue>> newNodeHolder = new MutableObject<>(newNode);
rememberEvent = shouldAddToEventTreeForNMode(node, newNodeHolder, event);
// shouldAddToEventTreeForNMode() may change newNode.
newNode = newNodeHolder.getValue();
break;
default:
throw new SpongeException("Unsupported value: " + eventMode);
}
}
// Remove the node for the incoming event if the event doesn't match.
if (!rememberEvent) {
if (isFirstNode) {
eventTree.setRoot(null);
} else {
node.removeChild(newNode);
}
}
}
use of org.openksavi.sponge.core.util.TreeNode in project sponge by softelnet.
the class UnorderedRuleAdapterRuntime method resolveSubNodesToRun.
protected List<TreeNode<NodeValue>> resolveSubNodesToRun(TreeNode<NodeValue> node) {
List<TreeNode<NodeValue>> result = new ArrayList<>();
Map<Integer, TreeNode<NodeValue>> mapFirst = new LinkedHashMap<>();
Map<Integer, TreeNode<NodeValue>> mapLast = new LinkedHashMap<>();
boolean endLoop = false;
Iterator<TreeNode<NodeValue>> treeNodeIterator = node.getChildren().listIterator();
while (!endLoop && treeNodeIterator.hasNext()) {
TreeNode<NodeValue> child = treeNodeIterator.next();
int index = getEventIndex(child);
EventMode eventMode = adapter.getEventModes()[index];
switch(eventMode) {
case FIRST:
if (!mapFirst.containsKey(index)) {
mapFirst.put(index, child);
result.add(child);
}
break;
case LAST:
TreeNode<NodeValue> oldLast = mapLast.get(index);
mapLast.put(index, child);
if (oldLast != null) {
result.remove(oldLast);
}
result.add(child);
break;
case ALL:
result.add(child);
break;
case NONE:
throw new SpongeException(EventMode.NONE + " mode event should not be present in the event tree");
default:
throw new SpongeException("Unsupported value: " + eventMode);
}
}
return result;
}
use of org.openksavi.sponge.core.util.TreeNode in project sponge by softelnet.
the class OrderedRuleAdapterRuntime method runRuleForNonFinalNode.
@Override
protected boolean runRuleForNonFinalNode(TreeNode<NodeValue> node) {
int maxLevel = adapter.getEventCount() - 1;
boolean fired = false;
TreeNode<NodeValue> child;
EventMode eventMode = adapter.getEventModes()[node.getLevel() + 1];
switch(eventMode) {
case FIRST:
// For FIRST mode consider only the first event in the next level.
if (node.hasChildren()) {
if ((child = node.getChildren().get(0)) != null) {
return runRule(child);
}
}
break;
case LAST:
// For LAST mode consider only the last event in the next level.
if (node.hasChildren()) {
if ((child = Iterables.getLast(node.getChildren())) != null) {
return runRule(child);
}
}
break;
case ALL:
// For ALL mode consider all events in the next level.
Iterator<TreeNode<NodeValue>> treeNodeIterator = node.getChildren().listIterator();
while (treeNodeIterator.hasNext()) {
child = treeNodeIterator.next();
if (runRule(child)) {
fired = true;
}
// Remove the child node from the tree because its event has already caused the rule to fire.
if (child.getValue() == null) {
treeNodeIterator.remove();
}
}
break;
case NONE:
// If duration has been triggered and there is no child node and the next level is the leaf level (maxLevel).
if (adapter.isDurationTriggered() && !node.hasChildren() && node.getLevel() + 1 == maxLevel) {
// Add a new node with no event since there should be none.
node.addChild(new TreeNode<>(new NodeValue(null)));
}
// Consider the first (and only) node.
if (node.hasChildren()) {
child = node.getChildren().get(0);
if (child != null) {
return runRule(child);
}
}
break;
default:
throw new SpongeException("Unsupported value: " + eventMode);
}
return fired;
}
Aggregations