/************************************************************************************** * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package com.espertech.esper.pattern; import com.espertech.esper.pattern.guard.Guard; import com.espertech.esper.pattern.guard.Quitable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This class represents the state of a "within" operator in the evaluation state tree. * The within operator applies to a subexpression and is thus expected to only * have one child node. */ public class EvalGuardStateNode extends EvalStateNode implements Evaluator, Quitable { protected EvalGuardNode evalGuardNode; protected EvalStateNode activeChildNode; protected Guard guard; /** * Constructor. * @param parentNode is the parent evaluator to call to indicate truth value * @param evalGuardNode is the factory node associated to the state */ public EvalGuardStateNode(Evaluator parentNode, EvalGuardNode evalGuardNode) { super(parentNode); this.evalGuardNode = evalGuardNode; } @Override public EvalNode getFactoryNode() { return evalGuardNode; } public PatternAgentInstanceContext getContext() { return evalGuardNode.getContext(); } public void start(MatchedEventMap beginState) { guard = evalGuardNode.getFactoryNode().getGuardFactory().makeGuard(evalGuardNode.getContext(), beginState, this, null, null); activeChildNode = evalGuardNode.getChildNode().newState(this, null, 0L); // Start the single child state activeChildNode.start(beginState); // Start the guard guard.startGuard(); } public final void evaluateTrue(MatchedEventMap matchEvent, EvalStateNode fromNode, boolean isQuitted) { boolean haveQuitted = activeChildNode == null; // If one of the children quits, remove the child if (isQuitted) { activeChildNode = null; // Stop guard, since associated subexpression is gone guard.stopGuard(); } if (!(haveQuitted)) { boolean guardPass = guard.inspect(matchEvent); if (guardPass) { this.getParentEvaluator().evaluateTrue(matchEvent, this, isQuitted); } } } public final void evaluateFalse(EvalStateNode fromNode) { } public final void quit() { if (activeChildNode != null) { activeChildNode.quit(); guard.stopGuard(); } activeChildNode = null; } public final Object accept(EvalStateNodeVisitor visitor, Object data) { return visitor.visit(this, data); } public final Object childrenAccept(EvalStateNodeVisitor visitor, Object data) { if (activeChildNode != null) { activeChildNode.accept(visitor, data); } return data; } public final String toString() { return "EvaluationWitinStateNode activeChildNode=" + activeChildNode + " guard=" + guard; } public boolean isNotOperator() { return false; } public boolean isFilterStateNode() { return false; } public boolean isFilterChildNonQuitting() { return false; } public void guardQuit() { // It is possible that the child node has already been quit such as when the parent wait time was shorter. // 1. parent node's guard indicates quit to all children // 2. this node's guards also indicates quit, however that already occured if (activeChildNode != null) { activeChildNode.quit(); } activeChildNode = null; // Indicate to parent state that this is permanently false. this.getParentEvaluator().evaluateFalse(this); } private static final Log log = LogFactory.getLog(EvalGuardStateNode.class); }