Package com.espertech.esper.pattern

Source Code of com.espertech.esper.pattern.EvalFilterStateNode

/**************************************************************************************
* 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.client.EventBean;
import com.espertech.esper.core.EPStatementHandleCallback;
import com.espertech.esper.filter.FilterHandleCallback;
import com.espertech.esper.filter.FilterValueSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* This class contains the state of a single filter expression in the evaluation state tree.
*/
public final class EvalFilterStateNode extends EvalStateNode implements FilterHandleCallback
{
    private final EvalFilterNode evalFilterNode;
    private final MatchedEventMap beginState;

    private boolean isStarted;
    private EPStatementHandleCallback handle;

    /**
     * Constructor.
     * @param parentNode is the parent evaluator to call to indicate truth value
     * @param beginState contains the events that make up prior matches
     * @param evalFilterNode is the factory node associated to the state
     */
    public EvalFilterStateNode(Evaluator parentNode,
                                     EvalFilterNode evalFilterNode,
                                     MatchedEventMap beginState)
    {
        super(parentNode, null);

        this.evalFilterNode = evalFilterNode;
        this.beginState = beginState;
    }

    @Override
    public EvalNode getFactoryNode() {
        return evalFilterNode;
    }

    public String getStatementId()
    {
        return evalFilterNode.getContext().getStatementId();
    }

    public final void start()
    {
        if (isStarted)
        {
            throw new IllegalStateException("Filter state node already active");
        }

        // Start the filter
        isStarted = true;
        startFiltering();
    }

    public final void quit()
    {
        isStarted = false;
        stopFiltering();
    }

    private void evaluateTrue(MatchedEventMap event, boolean isQuitted)
    {
        this.getParentEvaluator().evaluateTrue(event, this, isQuitted);
    }

    public final void matchFound(EventBean event)
    {
        if (!isStarted)
        {
            return;
        }

        MatchedEventMap passUp = beginState.shallowCopy();

        if (evalFilterNode.getFilterSpec().getOptionalPropertyEvaluator() != null)
        {
            EventBean[] propertyEvents = evalFilterNode.getFilterSpec().getOptionalPropertyEvaluator().getProperty(event, evalFilterNode.getContext());
            if (propertyEvents == null)
            {
                return; // no results, ignore match
            }
            // Add event itself to the match event structure if a tag was provided
            if (evalFilterNode.getEventAsName() != null)
            {
                passUp.add(evalFilterNode.getEventAsName(), propertyEvents);
            }
        }
        else
        {
            // Add event itself to the match event structure if a tag was provided
            if (evalFilterNode.getEventAsName() != null)
            {
                passUp.add(evalFilterNode.getEventAsName(), event);
            }
        }

        // Explanation for the type cast...
        // Each state node stops listening if it resolves to true, and all nodes newState
        // new listeners again. However this would be a performance drain since
        // and expression such as "on all b()" would remove the listener for b() for every match
        // and the all node would newState a new listener. The remove operation and the add operation
        // therefore don't take place if the EvalEveryStateNode node sits on top of a EvalFilterStateNode node.
        boolean isQuitted = false;
        if (!(this.getParentEvaluator().isFilterChildNonQuitting()))
        {
            stopFiltering();
            isQuitted = true;
        }

        this.evaluateTrue(passUp, isQuitted);
    }

    public final Object accept(EvalStateNodeVisitor visitor, Object data) {
        return visitor.visit(this, data);
    }

    public final Object childrenAccept(EvalStateNodeVisitor visitor, Object data)
    {
        return data;
    }

    public boolean isSubSelect()
    {
        return false;
    }

    public final String toString()
    {
        StringBuilder buffer = new StringBuilder();
        buffer.append("EvalFilterStateNode");
        buffer.append(" tag=");
        buffer.append(evalFilterNode.getFilterSpec());
        buffer.append(" spec=");
        buffer.append(evalFilterNode.getFilterSpec());
        return buffer.toString();
    }

    public boolean isFilterStateNode() {
        return true;
    }

    public boolean isNotOperator() {
        return false;
    }

    private void startFiltering()
    {
        PatternContext context = evalFilterNode.getContext();
        handle = new EPStatementHandleCallback(context.getEpStatementHandle(), this);
        FilterValueSet filterValues = evalFilterNode.getFilterSpec().getValueSet(beginState);
        context.getFilterService().add(filterValues, handle);
        long filtersVersion = context.getFilterService().getFiltersVersion();
        context.getStatementFilterVersion().setStmtFilterVersion(filtersVersion);
    }

    private void stopFiltering()
    {
        PatternContext context = evalFilterNode.getContext();
        if (handle != null) {
            context.getFilterService().remove(handle);
        }
        handle = null;
        isStarted = false;
        long filtersVersion = context.getFilterService().getFiltersVersion();
        context.getStatementFilterVersion().setStmtFilterVersion(filtersVersion);
    }

    private static final Log log = LogFactory.getLog(EvalFilterStateNode.class);
}
TOP

Related Classes of com.espertech.esper.pattern.EvalFilterStateNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.