/*
* *************************************************************************************
* 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.datetime.reformatop;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.epl.datetime.eval.*;
import com.espertech.esper.epl.expression.*;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class ReformatOpBetweenNonConstantParams implements ReformatOp {
private final ExprNode start;
private final ExprEvaluator startEval;
private final DatetimeLongCoercer startCoercer;
private final ExprNode end;
private final ExprEvaluator endEval;
private final DatetimeLongCoercer secondCoercer;
private boolean includeBoth;
private Boolean includeLow;
private Boolean includeHigh;
private ExprEvaluator evalIncludeLow;
private ExprEvaluator evalIncludeHigh;
public ReformatOpBetweenNonConstantParams(List<ExprNode> parameters)
throws ExprValidationException
{
start = parameters.get(0);
startEval = start.getExprEvaluator();
startCoercer = DatetimeLongCoercerFactory.getCoercer(startEval.getType());
end = parameters.get(1);
endEval = end.getExprEvaluator();
secondCoercer = DatetimeLongCoercerFactory.getCoercer(endEval.getType());
if (parameters.size() == 2) {
includeBoth = true;
includeLow = true;
includeHigh = true;
}
else {
if (parameters.get(2).isConstantResult()) {
includeLow = getBooleanValue(parameters.get(2));
}
else {
evalIncludeLow = parameters.get(2).getExprEvaluator();
}
if (parameters.get(3).isConstantResult()) {
includeHigh = getBooleanValue(parameters.get(3));
}
else {
evalIncludeHigh = parameters.get(3).getExprEvaluator();
}
if (includeLow != null && includeHigh != null && includeLow && includeHigh) {
includeBoth = true;
}
}
}
private boolean getBooleanValue(ExprNode exprNode)
throws ExprValidationException
{
Object value = exprNode.getExprEvaluator().evaluate(null, true, null);
if (value == null) {
throw new ExprValidationException("Date-time method 'between' requires non-null parameter values");
}
return (Boolean) value;
}
public Object evaluate(Long ts, EventBean[] eventsPerStream, boolean newData, ExprEvaluatorContext exprEvaluatorContext) {
if (ts == null) {
return null;
}
return evaluateInternal(ts, eventsPerStream, newData, exprEvaluatorContext);
}
public Object evaluate(Date d, EventBean[] eventsPerStream, boolean newData, ExprEvaluatorContext exprEvaluatorContext) {
if (d == null) {
return null;
}
return evaluateInternal(d.getTime(), eventsPerStream, newData, exprEvaluatorContext);
}
public Object evaluate(Calendar cal, EventBean[] eventsPerStream, boolean newData, ExprEvaluatorContext exprEvaluatorContext) {
if (cal == null) {
return null;
}
return evaluateInternal(cal.getTimeInMillis(), eventsPerStream, newData, exprEvaluatorContext);
}
public Class getReturnType() {
return Boolean.class;
}
public Object evaluateInternal(long ts, EventBean[] eventsPerStream, boolean newData, ExprEvaluatorContext exprEvaluatorContext) {
Object firstObj = startEval.evaluate(eventsPerStream, newData, exprEvaluatorContext);
if (firstObj == null) {
return null;
}
Object secondObj = endEval.evaluate(eventsPerStream, newData, exprEvaluatorContext);
if (secondObj == null) {
return null;
}
long first = startCoercer.coerce(firstObj);
long second = secondCoercer.coerce(secondObj);
if (includeBoth) {
if (first <= second) {
return first <= ts && ts <= second;
}
else {
return second <= ts && ts <= first;
}
}
else {
boolean includeLowEndpoint;
if (includeLow != null) {
includeLowEndpoint = includeLow;
}
else {
Object value = evalIncludeLow.evaluate(eventsPerStream, newData, exprEvaluatorContext);
if (value == null) {
return null;
}
includeLowEndpoint = (Boolean) value;
}
boolean includeHighEndpoint;
if (includeHigh != null) {
includeHighEndpoint = includeHigh;
}
else {
Object value = evalIncludeHigh.evaluate(eventsPerStream, newData, exprEvaluatorContext);
if (value == null) {
return null;
}
includeHighEndpoint = (Boolean) value;
}
if (includeLowEndpoint) {
if (ts < first) {
return false;
}
}
else {
if (ts <= first) {
return false;
}
}
if (includeHighEndpoint) {
if (ts > second) {
return false;
}
}
else {
if (ts >= second) {
return false;
}
}
return true;
}
}
public ExprDotNodeFilterAnalyzerDesc getFilterDesc(EventType[] typesPerStream, DatetimeMethodEnum currentMethod, List<ExprNode> currentParameters, ExprDotNodeFilterAnalyzerInput inputDesc) {
if (includeLow == null || includeHigh == null) {
return null;
}
int targetStreamNum;
String targetProperty;
if (inputDesc instanceof ExprDotNodeFilterAnalyzerInputStream) {
ExprDotNodeFilterAnalyzerInputStream targetStream = (ExprDotNodeFilterAnalyzerInputStream) inputDesc;
targetStreamNum = targetStream.getStreamNum();
EventType targetType = typesPerStream[targetStreamNum];
targetProperty = targetType.getStartTimestampPropertyName();
}
else if (inputDesc instanceof ExprDotNodeFilterAnalyzerInputProp) {
ExprDotNodeFilterAnalyzerInputProp targetStream = (ExprDotNodeFilterAnalyzerInputProp) inputDesc;
targetStreamNum = targetStream.getStreamNum();
targetProperty = targetStream.getPropertyName();
}
else {
return null;
}
return new ExprDotNodeFilterAnalyzerDTBetweenDesc(typesPerStream, targetStreamNum, targetProperty, start, end, includeLow, includeHigh);
}
}