Package com.espertech.esper.epl.named

Source Code of com.espertech.esper.epl.named.NamedWindowUpdateHelper

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

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventPropertyDescriptor;
import com.espertech.esper.client.EventType;
import com.espertech.esper.client.FragmentEventType;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.epl.spec.OnTriggerSetAssignment;
import com.espertech.esper.event.EventBeanCopyMethod;
import com.espertech.esper.event.EventPropertyWriter;
import com.espertech.esper.event.EventTypeSPI;
import com.espertech.esper.event.EventTypeUtility;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.util.TypeWidener;
import com.espertech.esper.util.TypeWidenerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class NamedWindowUpdateHelper
{
    private static final Log log = LogFactory.getLog(NamedWindowUpdateHelper.class);

    private final EventBeanCopyMethod copyMethod;
    private final NamedWindowUpdateItem[] updateItems;

    public NamedWindowUpdateHelper(EventBeanCopyMethod copyMethod, NamedWindowUpdateItem[] updateItems) {
        this.copyMethod = copyMethod;
        this.updateItems = updateItems;
    }

    public static NamedWindowUpdateHelper make(String namedWindowName,
                                               EventTypeSPI eventTypeSPI,
                                               List<OnTriggerSetAssignment> assignments,
                                               String namedWindowAlias,
                                               EventType optionalTriggeringEventType)
            throws ExprValidationException
    {
        List<NamedWindowUpdateItem> updateItems = new ArrayList<NamedWindowUpdateItem>();
        List<String> properties = new ArrayList<String>();

        for (int i = 0; i < assignments.size(); i++)
        {
            OnTriggerSetAssignment assignment = assignments.get(i);
            NamedWindowUpdateItem updateItem;

            // determine whether this is a "property=value" assignment, we use property setters in this case
            Pair<String, ExprNode> possibleAssignment = ExprNodeUtility.checkGetAssignmentToProp(assignment.getExpression());

            // handle assignment "property = value"
            if (possibleAssignment != null) {

                String propertyName = possibleAssignment.getFirst();
                EventPropertyDescriptor writableProperty = eventTypeSPI.getWritableProperty(propertyName);

                // check assignment to indexed or mapped property
                if (writableProperty == null) {
                    Pair<String, EventPropertyDescriptor> nameWriteablePair = checkIndexedOrMappedProp(possibleAssignment.getFirst(), namedWindowName, namedWindowAlias, eventTypeSPI);
                    propertyName = nameWriteablePair.getFirst();
                    writableProperty = nameWriteablePair.getSecond();
                }

                ExprEvaluator evaluator = possibleAssignment.getSecond().getExprEvaluator();
                EventPropertyWriter writers = eventTypeSPI.getWriter(propertyName);
                boolean notNullableField = writableProperty.getPropertyType().isPrimitive();

                properties.add(propertyName);
                TypeWidener widener = TypeWidenerFactory.getCheckPropertyAssignType(possibleAssignment.getSecond().toExpressionString(), possibleAssignment.getSecond().getExprEvaluator().getType(),
                        writableProperty.getPropertyType(), propertyName);

                // check event type assignment
                if (optionalTriggeringEventType != null && possibleAssignment.getSecond() instanceof ExprIdentNode) {
                    ExprIdentNode node = (ExprIdentNode) possibleAssignment.getSecond();
                    FragmentEventType fragmentRHS = optionalTriggeringEventType.getFragmentType(node.getResolvedPropertyName());
                    FragmentEventType fragmentLHS = eventTypeSPI.getFragmentType(possibleAssignment.getFirst());
                    if (fragmentRHS != null && fragmentLHS != null && !EventTypeUtility.isTypeOrSubTypeOf(fragmentRHS.getFragmentType(), fragmentLHS.getFragmentType())) {
                        throw new ExprValidationException("Invalid assignment to property '" +
                            possibleAssignment.getFirst() + "' event type '" + fragmentLHS.getFragmentType().getName() +
                            "' from event type '" + fragmentRHS.getFragmentType().getName() + "'");
                    }
                }

                updateItem = new NamedWindowUpdateItem(evaluator, propertyName, writers, notNullableField, widener);
            }
            // handle non-assignment, i.e. UDF or other expression
            else {
                ExprEvaluator evaluator = assignment.getExpression().getExprEvaluator();
                updateItem = new NamedWindowUpdateItem(evaluator, null, null, false, null);
            }

            updateItems.add(updateItem);
        }

        // obtain copy method
        List<String> propertiesUniqueList = new ArrayList<String>(new HashSet<String>(properties));
        String[] propertiesArray = propertiesUniqueList.toArray(new String[propertiesUniqueList.size()]);
        EventBeanCopyMethod copyMethod = eventTypeSPI.getCopyMethod(propertiesArray);
        if (copyMethod == null) {
            throw new ExprValidationException("Event type does not support event bean copy");
        }

        NamedWindowUpdateItem[] updateItemsArray = updateItems.toArray(new NamedWindowUpdateItem[updateItems.size()]);

        return new NamedWindowUpdateHelper(copyMethod, updateItemsArray);
    }

    public EventBean update(EventBean matchingEvent, EventBean[] eventsPerStream, ExprEvaluatorContext exprEvaluatorContext)
    {
        if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().qNamedWindowUpdate(matchingEvent, eventsPerStream, updateItems.length);}

        EventBean copy = copyMethod.copy(matchingEvent);
        eventsPerStream[0] = copy;
        eventsPerStream[2] = matchingEvent; // initial value

        for (int i = 0; i < updateItems.length; i++) {
            NamedWindowUpdateItem updateItem = updateItems[i];

            if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().qNamedWindowUpdateRHSExpr(i, updateItem);}
            Object result = updateItem.getExpression().evaluate(eventsPerStream, true, exprEvaluatorContext);
            if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().aNamedWindowUpdateRHSExpr(result);}

            if (updateItem.getOptionalWriter() != null) {
                if (result == null && updateItem.isNotNullableField()) {
                    log.warn("Null value returned by expression for assignment to property '" + updateItem.getOptionalPropertyName() + " is ignored as the property type is not nullable for expression");
                    continue;
                }

                if (updateItem.getOptionalWidener() != null) {
                    result = updateItem.getOptionalWidener().widen(result);
                }
                updateItem.getOptionalWriter().write(result, copy);
            }
        }

        if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().aNamedWindowUpdate(copy);}
        return copy;
    }

    private static Pair<String, EventPropertyDescriptor> checkIndexedOrMappedProp(String propertyName, String namedWindowName, String namedWindowAlias, EventTypeSPI eventTypeSPI) throws ExprValidationException {

        EventPropertyDescriptor writableProperty = null;

        int indexDot = propertyName.indexOf(".");
        if ((namedWindowAlias != null) && (indexDot != -1)) {
            String prefix = propertyName.substring(0, indexDot);
            String name = propertyName.substring(indexDot + 1);
            if (prefix.equals(namedWindowAlias)) {
                writableProperty = eventTypeSPI.getWritableProperty(name);
                propertyName = name;
            }
        }
        if (writableProperty == null && indexDot != -1) {
            String prefix = propertyName.substring(0, indexDot);
            String name = propertyName.substring(indexDot + 1);
            if (prefix.equals(namedWindowName)) {
                writableProperty = eventTypeSPI.getWritableProperty(name);
                propertyName = name;
            }
        }
        if (writableProperty == null) {
            throw new ExprValidationException("Property '" + propertyName + "' is not available for write access");
        }
        return new Pair<String, EventPropertyDescriptor>(propertyName, writableProperty);
    }
}
TOP

Related Classes of com.espertech.esper.epl.named.NamedWindowUpdateHelper

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.