/**************************************************************************************
* 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.epl.expression;
import com.espertech.esper.epl.agg.access.*;
import com.espertech.esper.epl.agg.aggregator.AggregationMethod;
import com.espertech.esper.epl.agg.service.AggregationMethodFactory;
import com.espertech.esper.epl.agg.service.AggregationSpec;
import com.espertech.esper.epl.core.MethodResolutionService;
import com.espertech.esper.util.JavaClassHelper;
public class ExprAccessAggNodeFactory implements AggregationMethodFactory
{
private final AggregationAccessType accessType;
private final Class resultType;
private final int streamNum;
private final ExprEvaluator childNode;
private final ExprNode indexEvalNode;
private final boolean istreamOnly;
private final boolean ondemandQuery;
public ExprAccessAggNodeFactory(AggregationAccessType accessType, Class resultType, int streamNum, ExprEvaluator childNode, ExprNode indexEvalNode, boolean istreamOnly, boolean ondemandQuery)
{
this.accessType = accessType;
this.resultType = resultType;
this.streamNum = streamNum;
this.childNode = childNode;
this.indexEvalNode = indexEvalNode;
this.istreamOnly = istreamOnly;
this.ondemandQuery = ondemandQuery;
}
public Class getResultType()
{
if (accessType == AggregationAccessType.WINDOW) {
return JavaClassHelper.getArrayType(resultType);
}
else {
return resultType;
}
}
public AggregationSpec getSpec(boolean isMatchRecognize)
{
// For match-recognize we don't use the access functions
if (isMatchRecognize) {
return null;
}
// on-demand query allow window access type
if (ondemandQuery && accessType == AggregationAccessType.WINDOW) {
return new AggregationSpec(streamNum);
}
// no remove stream, use first-ever and last-ever functions
if (istreamOnly || ondemandQuery) {
return null;
}
return new AggregationSpec(streamNum);
}
public AggregationAccessor getAccessor()
{
if (indexEvalNode != null) {
boolean isFirst = accessType == AggregationAccessType.FIRST;
int constant = -1;
if (indexEvalNode.isConstantResult()) {
constant = (Integer) indexEvalNode.getExprEvaluator().evaluate(null, true, null);
}
return new AggregationAccessorFirstLastIndex(streamNum, childNode, indexEvalNode.getExprEvaluator(), constant, isFirst);
}
else {
if (accessType == AggregationAccessType.FIRST) {
return new AggregationAccessorFirst(streamNum, childNode);
}
else if (accessType == AggregationAccessType.LAST) {
return new AggregationAccessorLast(streamNum, childNode);
}
else if (accessType == AggregationAccessType.WINDOW) {
return new AggregationAccessorAll(streamNum, childNode, resultType);
}
}
throw new IllegalStateException("Access type is undefined or not known as code '" + accessType + "'");
}
public AggregationMethod make(MethodResolutionService methodResolutionService, int agentInstanceId, int groupId, int aggregationId) {
if (accessType == AggregationAccessType.FIRST) {
return methodResolutionService.makeFirstEverValueAggregator(agentInstanceId, groupId, aggregationId, resultType, false);
}
else if (accessType == AggregationAccessType.LAST) {
return methodResolutionService.makeLastEverValueAggregator(agentInstanceId, groupId, aggregationId, resultType, false);
}
throw new RuntimeException("Window aggregation function is not available");
}
public AggregationMethodFactory getPrototypeAggregator() {
return this;
}
}