/**************************************************************************************
* 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.view.window;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.collection.ViewUpdatedCollection;
import com.espertech.esper.core.context.util.AgentInstanceViewFactoryChainContext;
import com.espertech.esper.core.service.EPStatementHandleCallback;
import com.espertech.esper.core.service.ExtensionServicesContext;
import com.espertech.esper.epl.agg.service.AggregationService;
import com.espertech.esper.epl.agg.service.AggregationServiceAggExpressionDesc;
import com.espertech.esper.epl.agg.service.AggregationServiceFactoryDesc;
import com.espertech.esper.epl.expression.ExprEvaluator;
import com.espertech.esper.epl.variable.VariableChangeCallback;
import com.espertech.esper.epl.variable.VariableReader;
import com.espertech.esper.epl.variable.VariableService;
import com.espertech.esper.event.map.MapEventBean;
import com.espertech.esper.schedule.ScheduleHandleCallback;
import com.espertech.esper.schedule.ScheduleSlot;
import com.espertech.esper.util.StopCallback;
import com.espertech.esper.view.CloneableView;
import com.espertech.esper.view.DataWindowView;
import com.espertech.esper.view.StoppableView;
import com.espertech.esper.view.ViewSupport;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* This view is a moving window extending the into the past until the expression passed to it returns false.
*/
public abstract class ExpressionViewBase extends ViewSupport implements DataWindowView, CloneableView, StoppableView, VariableChangeCallback, StopCallback {
protected final ViewUpdatedCollection viewUpdatedCollection;
protected final ExprEvaluator expiryExpression;
protected final MapEventBean builtinEventProps;
protected final EventBean[] eventsPerStream;
protected final Set<String> variableNames;
protected final AgentInstanceViewFactoryChainContext agentInstanceContext;
protected final ScheduleSlot scheduleSlot;
protected final EPStatementHandleCallback scheduleHandle;
protected final AggregationService aggregationService;
protected final List<AggregationServiceAggExpressionDesc> aggregateNodes;
/**
* Implemented to check the expiry expression.
*/
public abstract void scheduleCallback();
public ExpressionViewBase(ViewUpdatedCollection viewUpdatedCollection,
ExprEvaluator expiryExpression,
AggregationServiceFactoryDesc aggregationServiceFactoryDesc,
MapEventBean builtinEventProps,
Set<String> variableNames,
AgentInstanceViewFactoryChainContext agentInstanceContext)
{
this.viewUpdatedCollection = viewUpdatedCollection;
this.expiryExpression = expiryExpression;
this.builtinEventProps = builtinEventProps;
this.eventsPerStream = new EventBean[] {null, builtinEventProps};
this.variableNames = variableNames;
this.agentInstanceContext = agentInstanceContext;
if (variableNames != null && !variableNames.isEmpty()) {
for (String variable : variableNames) {
final VariableService variableService = agentInstanceContext.getStatementContext().getVariableService();
final VariableReader reader = variableService.getReader(variable);
agentInstanceContext.getStatementContext().getVariableService().registerCallback(reader.getVariableNumber(), this);
agentInstanceContext.getTerminationCallbacks().add(new StopCallback() {
public void stop() {
variableService.unregisterCallback(reader.getVariableNumber(), ExpressionViewBase.this);
}
});
}
ScheduleHandleCallback callback = new ScheduleHandleCallback() {
public void scheduledTrigger(ExtensionServicesContext extensionServicesContext)
{
scheduleCallback();
}
};
scheduleSlot = agentInstanceContext.getStatementContext().getScheduleBucket().allocateSlot();
scheduleHandle = new EPStatementHandleCallback(agentInstanceContext.getEpStatementAgentInstanceHandle(), callback);
agentInstanceContext.getTerminationCallbacks().add(this);
}
else {
scheduleSlot = null;
scheduleHandle = null;
}
if (aggregationServiceFactoryDesc != null) {
aggregationService = aggregationServiceFactoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext.getAgentInstanceContext(), agentInstanceContext.getAgentInstanceContext().getStatementContext().getMethodResolutionService());
aggregateNodes = aggregationServiceFactoryDesc.getExpressions();
}
else {
aggregationService = null;
aggregateNodes = Collections.emptyList();
}
}
public final EventType getEventType()
{
// The event type is the parent view's event type
return parent.getEventType();
}
public final String toString()
{
return this.getClass().getName();
}
public void stopView() {
stopScheduleAndVar();
agentInstanceContext.getTerminationCallbacks().remove(this);
}
public void stop() {
stopScheduleAndVar();
}
public void stopScheduleAndVar() {
if (variableNames != null && !variableNames.isEmpty()) {
for (String variable : variableNames) {
VariableReader reader = agentInstanceContext.getStatementContext().getVariableService().getReader(variable);
if (reader != null) {
agentInstanceContext.getStatementContext().getVariableService().unregisterCallback(reader.getVariableNumber(), this);
}
}
if (agentInstanceContext.getStatementContext().getSchedulingService().isScheduled(scheduleHandle)) {
agentInstanceContext.getStatementContext().getSchedulingService().remove(scheduleHandle, scheduleSlot);
}
}
}
// Handle variable updates by scheduling a re-evaluation with timers
public void update(Object newValue, Object oldValue) {
if (!agentInstanceContext.getStatementContext().getSchedulingService().isScheduled(scheduleHandle)) {
agentInstanceContext.getStatementContext().getSchedulingService().add(0, scheduleHandle, scheduleSlot);
}
}
public ViewUpdatedCollection getViewUpdatedCollection() {
return viewUpdatedCollection;
}
public AggregationService getAggregationService() {
return aggregationService;
}
}