Package com.espertech.esper.epl.datetime.interval

Source Code of com.espertech.esper.epl.datetime.interval.IntervalOpImpl$IntervalOpEvalCalWithEnd

/*
* *************************************************************************************
*  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.interval;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventPropertyGetter;
import com.espertech.esper.client.EventType;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.epl.core.PropertyResolutionDescriptor;
import com.espertech.esper.epl.core.StreamTypeService;
import com.espertech.esper.epl.datetime.eval.DatetimeMethodEnum;
import com.espertech.esper.epl.datetime.eval.ExprDotNodeFilterAnalyzerDTIntervalDesc;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.util.JavaClassHelper;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class IntervalOpImpl implements IntervalOp {

    private ExprEvaluator evaluatorTimestamp;

    private Integer parameterStreamNum;
    private String parameterPropertyStart;
    private String parameterPropertyEnd;

    private final IntervalOpEval intervalOpEval;

    public IntervalOpImpl(DatetimeMethodEnum method, String methodNameUse, StreamTypeService streamTypeService, List<ExprNode> expressions)
        throws ExprValidationException {

        ExprEvaluator evaluatorEndTimestamp = null;
        Class timestampType;

        if (expressions.get(0) instanceof ExprStreamUnderlyingNode) {
            ExprStreamUnderlyingNode und = (ExprStreamUnderlyingNode) expressions.get(0);
            parameterStreamNum = und.getStreamId();
            EventType type = streamTypeService.getEventTypes()[parameterStreamNum];
            parameterPropertyStart = type.getStartTimestampPropertyName();
            if (parameterPropertyStart == null) {
                throw new ExprValidationException("For date-time method '" + methodNameUse + "' the first parameter is event type '" + type.getName() + "', however no timestamp property has been defined for this event type");
            }

            timestampType = type.getPropertyType(parameterPropertyStart);
            EventPropertyGetter getter = type.getGetter(parameterPropertyStart);
            evaluatorTimestamp = new ExprEvaluatorStreamLongProp(parameterStreamNum, getter);

            if (type.getEndTimestampPropertyName() != null) {
                parameterPropertyEnd = type.getEndTimestampPropertyName();
                EventPropertyGetter getterEndTimestamp = type.getGetter(type.getEndTimestampPropertyName());
                evaluatorEndTimestamp = new ExprEvaluatorStreamLongProp(parameterStreamNum, getterEndTimestamp);
            }
            else {
                parameterPropertyEnd = parameterPropertyStart;
            }
        }
        else {
            evaluatorTimestamp = expressions.get(0).getExprEvaluator();
            timestampType = evaluatorTimestamp.getType();

            String unresolvedPropertyName = null;
            if (expressions.get(0) instanceof ExprIdentNode) {
                ExprIdentNode identNode = (ExprIdentNode) expressions.get(0);
                parameterStreamNum = identNode.getStreamId();
                parameterPropertyStart = identNode.getResolvedPropertyName();
                parameterPropertyEnd = parameterPropertyStart;
                unresolvedPropertyName = identNode.getUnresolvedPropertyName();
            }

            if (!JavaClassHelper.isDatetimeClass(evaluatorTimestamp.getType())) {
                // ident node may represent a fragment
                if (unresolvedPropertyName != null) {
                    Pair<PropertyResolutionDescriptor, String> propertyDesc = ExprIdentNodeUtil.getTypeFromStream(streamTypeService, unresolvedPropertyName, false, true);
                    if (propertyDesc.getFirst().getFragmentEventType() != null) {
                        EventType type = propertyDesc.getFirst().getFragmentEventType().getFragmentType();
                        parameterPropertyStart = type.getStartTimestampPropertyName();
                        if (parameterPropertyStart == null) {
                            throw new ExprValidationException("For date-time method '" + methodNameUse + "' the first parameter is event type '" + type.getName() + "', however no timestamp property has been defined for this event type");
                        }

                        timestampType = type.getPropertyType(parameterPropertyStart);
                        EventPropertyGetter getterFragment = streamTypeService.getEventTypes()[parameterStreamNum].getGetter(unresolvedPropertyName);
                        EventPropertyGetter getterStartTimestamp = type.getGetter(parameterPropertyStart);
                        evaluatorTimestamp = new ExprEvaluatorStreamLongPropFragment(parameterStreamNum, getterFragment, getterStartTimestamp);

                        if (type.getEndTimestampPropertyName() != null) {
                            parameterPropertyEnd = type.getEndTimestampPropertyName();
                            EventPropertyGetter getterEndTimestamp = type.getGetter(type.getEndTimestampPropertyName());
                            evaluatorEndTimestamp = new ExprEvaluatorStreamLongPropFragment(parameterStreamNum, getterFragment, getterEndTimestamp);
                        }
                        else {
                            parameterPropertyEnd = parameterPropertyStart;
                        }
                    }
                }
                else {
                    throw new ExprValidationException("For date-time method '" + methodNameUse + "' the first parameter expression returns '" + evaluatorTimestamp.getType() + "', however requires a Date, Calendar, Long-type return value or event (with timestamp)");
                }
            }
        }

        IntervalComputer intervalComputer = IntervalComputerFactory.make(method, expressions);

        // evaluation without end timestamp
        if (evaluatorEndTimestamp == null) {
            if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Calendar.class)) {
                intervalOpEval = new IntervalOpEvalCal(intervalComputer);
            }
            else if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Date.class)) {
                intervalOpEval = new IntervalOpEvalDate(intervalComputer);
            }
            else if (JavaClassHelper.getBoxedType(timestampType) == Long.class) {
                intervalOpEval = new IntervalOpEvalLong(intervalComputer);
            }
            else {
                throw new IllegalArgumentException("Invalid interval first parameter type '" + timestampType + "'");
            }
        }
        else {
            if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Calendar.class)) {
                intervalOpEval = new IntervalOpEvalCalWithEnd(intervalComputer, evaluatorEndTimestamp);
            }
            else if (JavaClassHelper.isSubclassOrImplementsInterface(timestampType, Date.class)) {
                intervalOpEval = new IntervalOpEvalDateWithEnd(intervalComputer, evaluatorEndTimestamp);
            }
            else if (JavaClassHelper.getBoxedType(timestampType) == Long.class) {
                intervalOpEval = new IntervalOpEvalLongWithEnd(intervalComputer, evaluatorEndTimestamp);
            }
            else {
                throw new IllegalArgumentException("Invalid interval first parameter type '" + timestampType + "'");
            }
        }
    }

    /**
     * Obtain information used by filter analyzer to handle this dot-method invocation as part of query planning/indexing.
     *
     * @param typesPerStream event types
     * @param currentMethod
     * @param currentParameters
     * @param inputDesc descriptor of what the input to this interval method is
     * */
    public ExprDotNodeFilterAnalyzerDTIntervalDesc getFilterDesc(EventType[] typesPerStream, DatetimeMethodEnum currentMethod, List<ExprNode> currentParameters, ExprDotNodeFilterAnalyzerInput inputDesc) {

        // with intervals is not currently query planned
        if (currentParameters.size() > 1) {
            return null;
        }

        // Get input (target)
        int targetStreamNum;
        String targetPropertyStart;
        String targetPropertyEnd;
        if (inputDesc instanceof ExprDotNodeFilterAnalyzerInputStream) {
            ExprDotNodeFilterAnalyzerInputStream targetStream = (ExprDotNodeFilterAnalyzerInputStream) inputDesc;
            targetStreamNum = targetStream.getStreamNum();
            EventType targetType = typesPerStream[targetStreamNum];
            targetPropertyStart = targetType.getStartTimestampPropertyName();
            targetPropertyEnd = targetType.getEndTimestampPropertyName() != null ? targetType.getEndTimestampPropertyName() : targetPropertyStart;
        }
        else if (inputDesc instanceof ExprDotNodeFilterAnalyzerInputProp) {
            ExprDotNodeFilterAnalyzerInputProp targetStream = (ExprDotNodeFilterAnalyzerInputProp) inputDesc;
            targetStreamNum = targetStream.getStreamNum();
            targetPropertyStart = targetStream.getPropertyName();
            targetPropertyEnd = targetStream.getPropertyName();
        }
        else {
            return null;
        }

        // check parameter info
        if (parameterPropertyStart == null) {
            return null;
        }

        return new ExprDotNodeFilterAnalyzerDTIntervalDesc(currentMethod, typesPerStream,
                targetStreamNum, targetPropertyStart, targetPropertyEnd,
                parameterStreamNum, parameterPropertyStart, parameterPropertyEnd);
    }

    public Object evaluate(long startTs, long endTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
        Object parameter = evaluatorTimestamp.evaluate(eventsPerStream, isNewData, context);
        if (parameter == null) {
            return parameter;
        }

        return intervalOpEval.evaluate(startTs, endTs, parameter, eventsPerStream, isNewData, context);
    }

    public static interface IntervalOpEval {
        public Object evaluate(long startTs, long endTs, Object parameter, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context);
    }

    public abstract static class IntervalOpEvalDateBase implements IntervalOpEval {
        protected final IntervalComputer intervalComputer;

        public IntervalOpEvalDateBase(IntervalComputer intervalComputer) {
            this.intervalComputer = intervalComputer;
        }
    }

    public static class IntervalOpEvalDate extends IntervalOpEvalDateBase {

        public IntervalOpEvalDate(IntervalComputer intervalComputer) {
            super(intervalComputer);
        }

        public Object evaluate(long startTs, long endTs, Object parameter, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            long time = ((Date) parameter).getTime();
            return intervalComputer.compute(startTs, endTs, time, time, eventsPerStream, isNewData, context);
        }
    }

    public static class IntervalOpEvalLong extends IntervalOpEvalDateBase {

        public IntervalOpEvalLong(IntervalComputer intervalComputer) {
            super(intervalComputer);
        }

        public Object evaluate(long startTs, long endTs, Object parameter, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            long time = (Long) parameter;
            return intervalComputer.compute(startTs, endTs, time, time, eventsPerStream, isNewData, context);
        }
    }

    public static class IntervalOpEvalCal extends IntervalOpEvalDateBase {

        public IntervalOpEvalCal(IntervalComputer intervalComputer) {
            super(intervalComputer);
        }

        public Object evaluate(long startTs, long endTs, Object parameter, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            long time = ((Calendar) parameter).getTimeInMillis();
            return intervalComputer.compute(startTs, endTs, time, time, eventsPerStream, isNewData, context);
        }
    }

    public abstract static class IntervalOpEvalDateWithEndBase implements IntervalOpEval {
        protected final IntervalComputer intervalComputer;
        private final ExprEvaluator evaluatorEndTimestamp;

        protected IntervalOpEvalDateWithEndBase(IntervalComputer intervalComputer, ExprEvaluator evaluatorEndTimestamp) {
            this.intervalComputer = intervalComputer;
            this.evaluatorEndTimestamp = evaluatorEndTimestamp;
        }

        public abstract Object evaluate(long startTs, long endTs, Object parameterStartTs, Object parameterEndTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context);

        public Object evaluate(long startTs, long endTs, Object parameterStartTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            Object paramEndTs = evaluatorEndTimestamp.evaluate(eventsPerStream, isNewData, context);
            if (paramEndTs == null) {
                return null;
            }
            return evaluate(startTs, endTs, parameterStartTs, paramEndTs, eventsPerStream, isNewData, context);
        }
    }

    public static class IntervalOpEvalDateWithEnd extends IntervalOpEvalDateWithEndBase {

        public IntervalOpEvalDateWithEnd(IntervalComputer intervalComputer, ExprEvaluator evaluatorEndTimestamp) {
            super(intervalComputer, evaluatorEndTimestamp);
        }

        public Object evaluate(long startTs, long endTs, Object parameterStartTs, Object parameterEndTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            return intervalComputer.compute(startTs, endTs, ((Date) parameterStartTs).getTime(), ((Date) parameterEndTs).getTime(), eventsPerStream, isNewData, context);
        }
    }

    public static class IntervalOpEvalLongWithEnd extends IntervalOpEvalDateWithEndBase {

        public IntervalOpEvalLongWithEnd(IntervalComputer intervalComputer, ExprEvaluator evaluatorEndTimestamp) {
            super(intervalComputer, evaluatorEndTimestamp);
        }

        public Object evaluate(long startTs, long endTs, Object parameterStartTs, Object parameterEndTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            return intervalComputer.compute(startTs, endTs, (Long) parameterStartTs, (Long) parameterEndTs, eventsPerStream, isNewData, context);
        }
    }

    public static class IntervalOpEvalCalWithEnd extends IntervalOpEvalDateWithEndBase {

        public IntervalOpEvalCalWithEnd(IntervalComputer intervalComputer, ExprEvaluator evaluatorEndTimestamp) {
            super(intervalComputer, evaluatorEndTimestamp);
        }

        public Object evaluate(long startTs, long endTs, Object parameterStartTs, Object parameterEndTs, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
            return intervalComputer.compute(startTs, endTs, ((Calendar) parameterStartTs).getTimeInMillis(), ((Calendar) parameterEndTs).getTimeInMillis(), eventsPerStream, isNewData, context);
        }
    }
}
TOP

Related Classes of com.espertech.esper.epl.datetime.interval.IntervalOpImpl$IntervalOpEvalCalWithEnd

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.