/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* 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.EngineLevelExtensionServicesContext;
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.core.ExprEvaluator;
import com.espertech.esper.epl.variable.VariableChangeCallback;
import com.espertech.esper.epl.variable.VariableService;
import com.espertech.esper.event.arr.ObjectArrayEventBean;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.schedule.ScheduleHandleCallback;
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 ObjectArrayEventBean builtinEventProps;
protected final EventBean[] eventsPerStream;
protected final Set<String> variableNames;
protected final AgentInstanceViewFactoryChainContext agentInstanceContext;
protected final long 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 abstract String getViewName();
public ExpressionViewBase(ViewUpdatedCollection viewUpdatedCollection,
ExprEvaluator expiryExpression,
AggregationServiceFactoryDesc aggregationServiceFactoryDesc,
ObjectArrayEventBean 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 String variableName = variable;
final int agentInstanceId = agentInstanceContext.getAgentInstanceId();
final VariableService variableService = agentInstanceContext.getStatementContext().getVariableService();
agentInstanceContext.getStatementContext().getVariableService().registerCallback(variable, agentInstanceId, this);
agentInstanceContext.addTerminationCallback(new StopCallback() {
public void stop() {
variableService.unregisterCallback(variableName, agentInstanceId, ExpressionViewBase.this);
}
});
}
ScheduleHandleCallback callback = new ScheduleHandleCallback() {
public void scheduledTrigger(EngineLevelExtensionServicesContext extensionServicesContext) {
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qViewScheduledEval(ExpressionViewBase.this, getViewName());
}
scheduleCallback();
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aViewScheduledEval();
}
}
};
scheduleSlot = agentInstanceContext.getStatementContext().getScheduleBucket().allocateSlot();
scheduleHandle = new EPStatementHandleCallback(agentInstanceContext.getEpStatementAgentInstanceHandle(), callback);
agentInstanceContext.addTerminationCallback(this);
} else {
scheduleSlot = -1;
scheduleHandle = null;
}
if (aggregationServiceFactoryDesc != null) {
aggregationService = aggregationServiceFactoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext.getAgentInstanceContext(), agentInstanceContext.getAgentInstanceContext().getStatementContext().getEngineImportService(), false, null);
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.removeTerminationCallback(this);
}
public void stop() {
stopScheduleAndVar();
}
public void stopScheduleAndVar() {
if (variableNames != null && !variableNames.isEmpty()) {
for (String variable : variableNames) {
agentInstanceContext.getStatementContext().getVariableService().unregisterCallback(variable, agentInstanceContext.getAgentInstanceId(), 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;
}
}