public override FilterValueSetParam[][] PopulateFilterAddendum(
            FilterSpecActivatable filterSpec,
            bool forStatement,
            int nestingLevel,
            object partitionKey,
            ContextControllerStatementDesc optionalStatementDesc,
            IDictionary<int, ContextControllerStatementDesc> statements,
            AgentInstanceContext agentInstanceContextStatement)
        {
            if (!forStatement) {
                if (!EventTypeUtility.IsTypeOrSubTypeOf(
                    filterSpec.FilterForEventType,
                    CategorySpec.FilterSpecActivatable.FilterForEventType)) {
                    return null;
                }
            }

            var categoryNum = partitionKey.AsInt32();
            var item = CategorySpec.Items[categoryNum];
            FilterValueSetParam[][] filters = item.FilterPlan.EvaluateValueSet(
                null,
                agentInstanceContextStatement,
                agentInstanceContextStatement.StatementContextFilterEvalEnv);
            if (filters == null) {
                throw new EPException(
                    "Category context '" + ContextName + "' for category '" + item.Name + "' has evaluated to a condition that cannot become true");
            }

            return filters;
        }
Example #2
0
        public override bool Equals(object o)
        {
            if (this == o) return true;
            if (o == null || GetType() != o.GetType()) return false;

            AggregationStateKeyWStream that = (AggregationStateKeyWStream) o;

            if (streamNum != that.streamNum) return false;
            if (stateType != that.stateType) return false;
            if (!ExprNodeUtilityCompare.DeepEquals(criteraExprNodes, that.criteraExprNodes, false)) return false;
            if (eventType != null) {
                if (that.eventType == null) {
                    return false;
                }

                if (!EventTypeUtility.IsTypeOrSubTypeOf(that.eventType, eventType)) return false;
            }

            if (filterExprNode == null) {
                return that.filterExprNode == null;
            }

            return that.filterExprNode != null &&
                   ExprNodeUtilityCompare.DeepEquals(filterExprNode, that.filterExprNode, false);
        }
        // Compare filters in statement with filters in segmented context, addendum filter compilation
        private static void GetAddendumFilters(
            IDictionary <FilterSpecCompiled, FilterValueSetParam[][]> addendums,
            ContextDetailCategoryItem category,
            ContextDetailCategory categorySpec,
            IList <FilterSpecCompiled> filters,
            ContextControllerStatementDesc statement)
        {
            // determine whether create-named-window
            var isCreateWindow = statement != null && statement.Statement.StatementSpec.CreateWindowDesc != null;

            if (!isCreateWindow)
            {
                foreach (var filtersSpec in filters)
                {
                    var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(filtersSpec.FilterForEventType, categorySpec.FilterSpecCompiled.FilterForEventType);
                    if (!typeOrSubtype)
                    {
                        continue;       // does not apply
                    }
                    AddAddendums(addendums, filtersSpec, category, categorySpec);
                }
            }
            // handle segmented context for create-window
            else
            {
                var declaredAsName = statement.Statement.StatementSpec.CreateWindowDesc.AsEventTypeName;
                if (declaredAsName != null)
                {
                    foreach (var filtersSpec in filters)
                    {
                        AddAddendums(addendums, filtersSpec, category, categorySpec);
                    }
                }
            }
        }
Example #4
0
        internal static void ValidateStatementForContext(String contextName, ContextControllerStatementBase statement, StatementSpecCompiledAnalyzerResult streamAnalysis, ICollection <EventType> itemEventTypes, NamedWindowService namedWindowService)
        {
            IList <FilterSpecCompiled> filters = streamAnalysis.Filters;

            bool isCreateWindow = statement.StatementSpec.CreateWindowDesc != null;

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow)
            {
                foreach (FilterSpecCompiled filter in filters)
                {
                    foreach (EventType itemEventType in itemEventTypes)
                    {
                        EventType stmtFilterType = filter.FilterForEventType;
                        if (stmtFilterType == itemEventType)
                        {
                            return;
                        }
                        if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, itemEventType))
                        {
                            return;
                        }

                        NamedWindowProcessor processor = namedWindowService.GetProcessor(stmtFilterType.Name);
                        if (processor != null && processor.ContextName != null && processor.ContextName.Equals(contextName))
                        {
                            return;
                        }
                    }
                }

                if (filters.IsNotEmpty())
                {
                    throw new ExprValidationException(GetTypeValidationMessage(contextName, filters[0].FilterForEventType.Name));
                }
                return;
            }

            // validate create-window with column definition: not allowed, requires typed
            if (statement.StatementSpec.CreateWindowDesc.Columns != null &&
                statement.StatementSpec.CreateWindowDesc.Columns.Count > 0)
            {
                throw new ExprValidationException("Segmented context '" + contextName +
                                                  "' requires that named windows are associated to an existing event type and that the event type is listed among the partitions defined by the create-context statement");
            }

            // validate create-window declared type
            String declaredAsName = statement.StatementSpec.CreateWindowDesc.AsEventTypeName;

            if (declaredAsName != null)
            {
                if (itemEventTypes.Any(itemEventType => itemEventType.Name == declaredAsName))
                {
                    return;
                }

                throw new ExprValidationException(GetTypeValidationMessage(contextName, declaredAsName));
            }
        }
Example #5
0
 public static void ValidateEventType(EventType requiredType, EventType providedType)
 {
     if (!EventTypeUtility.IsTypeOrSubTypeOf(providedType, requiredType))
     {
         throw new ExprValidationException("The required event type is '" +
                                           requiredType.Name +
                                           "' and provided is '" + providedType.Name + "'");
     }
 }
Example #6
0
        public override EnumEval GetEnumEval(MethodResolutionService methodResolutionService, EventAdapterService eventAdapterService, StreamTypeService streamTypeService, int statementId, string enumMethodUsedName, IList <ExprDotEvalParam> bodiesAndParameters, EventType inputEventType, Type collectionComponentType, int numStreamsIncoming, bool disablePropertyExpressionEventCollCache)
        {
            ExprDotEvalParam first = bodiesAndParameters[0];

            ExprDotEnumerationSource enumSrc = ExprDotNodeUtility.GetEnumerationSource(
                first.Body, streamTypeService, eventAdapterService, statementId, true,
                disablePropertyExpressionEventCollCache);

            if (inputEventType != null)
            {
                base.TypeInfo = EPTypeHelper.CollectionOfEvents(inputEventType);
            }
            else
            {
                base.TypeInfo = EPTypeHelper.CollectionOfSingleValue(collectionComponentType);
            }

            if (enumSrc.Enumeration == null)
            {
                String message = "Enumeration method '" + enumMethodUsedName +
                                 "' requires an expression yielding an event-collection as input paramater";
                throw new ExprValidationException(message);
            }

            var setType = enumSrc.Enumeration.GetEventTypeCollection(eventAdapterService, statementId);

            if (!Equals(setType, inputEventType))
            {
                bool isSubtype = EventTypeUtility.IsTypeOrSubTypeOf(setType, inputEventType);
                if (!isSubtype)
                {
                    String message = "Enumeration method '" + enumMethodUsedName + "' expects event type '" +
                                     inputEventType.Name + "' but receives event type '" +
                                     enumSrc.Enumeration.GetEventTypeCollection(eventAdapterService, statementId).Name +
                                     "'";
                    throw new ExprValidationException(message);
                }
            }

            if (EnumMethodEnum == EnumMethodEnum.UNION)
            {
                return(new EnumEvalUnion(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null));
            }
            else if (EnumMethodEnum == EnumMethodEnum.INTERSECT)
            {
                return(new EnumEvalIntersect(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null));
            }
            else if (EnumMethodEnum == EnumMethodEnum.EXCEPT)
            {
                return(new EnumEvalExcept(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null));
            }
            else
            {
                throw new ArgumentException("Invalid enumeration method for this factory: " + EnumMethodEnum);
            }
        }
Example #7
0
        public static ContextDetailHashItem FindHashItemSpec(ContextDetailHash hashSpec, FilterSpecCompiled filterSpec)
        {
            ContextDetailHashItem foundPartition = null;

            foreach (var partitionItem in hashSpec.Items)
            {
                var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(filterSpec.FilterForEventType, partitionItem.FilterSpecCompiled.FilterForEventType);
                if (typeOrSubtype)
                {
                    foundPartition = partitionItem;
                }
            }

            return(foundPartition);
        }
Example #8
0
        private void ValidateAsName(
            IDictionary<string, EventType> asNames,
            string asName,
            EventType filterForType)
        {
            var existing = asNames.Get(asName);
            if (existing != null && !EventTypeUtility.IsTypeOrSubTypeOf(filterForType, existing)) {
                throw new ExprValidationException(
                    "Name '" + asName + "' already used for type '" + existing.Name + "'");
            }

            if (existing == null) {
                asNames.Put(asName, filterForType);
            }
        }
        public void ValidateStatement(
            string contextName,
            StatementSpecCompiled spec,
            StatementCompileTimeServices compileTimeServices)
        {
            var streamAnalysis = StatementSpecCompiledAnalyzer.AnalyzeFilters(spec);
            var filters = streamAnalysis.Filters;

            // Category validation
            var isCreateWindow = spec.Raw.CreateWindowDesc != null;
            var message = "Category context '" +
                          contextName +
                          "' requires that any of the events types that are listed in the category context also appear in any of the filter expressions of the statement";

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow) {
                foreach (var filter in filters) {
                    var stmtFilterType = filter.FilterForEventType;
                    if (stmtFilterType == CategoryEventType) {
                        return;
                    }

                    if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, CategoryEventType)) {
                        return;
                    }
                }

                if (!filters.IsEmpty()) {
                    throw new ExprValidationException(message);
                }

                return;
            }

            // validate create-window
            var declaredAsName = spec.Raw.CreateWindowDesc.AsEventTypeName;
            if (declaredAsName != null) {
                if (CategoryEventType.Name.Equals(declaredAsName)) {
                    return;
                }

                throw new ExprValidationException(message);
            }
        }
        public override bool Equals(Object o)
        {
            if (this == o)
            {
                return(true);
            }
            if (o == null || GetType() != o.GetType())
            {
                return(false);
            }

            AggregationStateKeyWStream that = (AggregationStateKeyWStream)o;

            if (_streamNum != that._streamNum)
            {
                return(false);
            }
            if (_stateType != that._stateType)
            {
                return(false);
            }
            if (!ExprNodeUtility.DeepEquals(_criteriaExprNodes, that._criteriaExprNodes, false))
            {
                return(false);
            }
            if (_eventType != null)
            {
                if (that._eventType == null)
                {
                    return(false);
                }

                if (!EventTypeUtility.IsTypeOrSubTypeOf(that._eventType, _eventType))
                {
                    return(false);
                }
            }

            if (_filterExprNode == null)
            {
                return(that._filterExprNode == null);
            }
            return(that._filterExprNode != null && ExprNodeUtility.DeepEquals(_filterExprNode, that._filterExprNode, false));
        }
        private void ValidateStatementForContext(ContextControllerStatementBase statement, StatementSpecCompiledAnalyzerResult streamAnalysis)

        {
            var filters = streamAnalysis.Filters;

            var isCreateWindow = statement.StatementSpec.CreateWindowDesc != null;
            var message        = "Category context '" + _factoryContext.ContextName + "' requires that any of the events types that are listed in the category context also appear in any of the filter expressions of the statement";

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow)
            {
                foreach (var filter in filters)
                {
                    var stmtFilterType = filter.FilterForEventType;
                    var contextType    = _categorySpec.FilterSpecCompiled.FilterForEventType;
                    if (Equals(stmtFilterType, contextType))
                    {
                        return;
                    }
                    if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, contextType))
                    {
                        return;
                    }
                }

                if (!filters.IsEmpty())
                {
                    throw new ExprValidationException(message);
                }
                return;
            }

            // validate create-window
            var declaredAsName = statement.StatementSpec.CreateWindowDesc.AsEventTypeName;

            if (declaredAsName != null)
            {
                if (_categorySpec.FilterSpecCompiled.FilterForEventType.Name.Equals(declaredAsName))
                {
                    return;
                }
                throw new ExprValidationException(message);
            }
        }
Example #12
0
 internal static bool DetermineSubquerySameStream(StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec)
 {
     foreach (ExprSubselectNode subselect in statementSpec.SubSelectExpressions)
     {
         StreamSpecCompiled streamSpec = subselect.StatementSpecCompiled.StreamSpecs[0];
         if (!(streamSpec is FilterStreamSpecCompiled))
         {
             continue;
         }
         FilterStreamSpecCompiled filterStream = (FilterStreamSpecCompiled)streamSpec;
         EventType typeSubselect = filterStream.FilterSpec.FilterForEventType;
         EventType typeFiltered  = filterStreamSpec.FilterSpec.FilterForEventType;
         if (EventTypeUtility.IsTypeOrSubTypeOf(typeSubselect, typeFiltered) || EventTypeUtility.IsTypeOrSubTypeOf(typeFiltered, typeSubselect))
         {
             return(true);
         }
     }
     return(false);
 }
Example #13
0
        public override FilterValueSetParam[][] PopulateFilterAddendum(
            FilterSpecActivatable filterSpec,
            bool forStatement,
            int nestingLevel,
            object partitionKey,
            ContextControllerStatementDesc optionalStatementDesc,
            AgentInstanceContext agentInstanceContextStatement)
        {
            if (!forStatement) {
                if (!EventTypeUtility.IsTypeOrSubTypeOf(
                    filterSpec.FilterForEventType,
                    CategorySpec.FilterSpecActivatable.FilterForEventType)) {
                    return null;
                }
            }

            int categoryNum = partitionKey.AsInt32();
            ContextControllerDetailCategoryItem item = CategorySpec.Items[categoryNum];
            return FilterSpecActivatable.EvaluateValueSet(
                item.CompiledFilterParam,
                null,
                agentInstanceContextStatement);
        }
Example #14
0
        public static EventBeanUpdateHelper Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite)
        {
            IList <EventBeanUpdateItem> updateItems = new List <EventBeanUpdateItem>();
            IList <string> properties = new List <string>();

            for (var i = 0; i < assignments.Count; i++)
            {
                var assignment = assignments[i];
                EventBeanUpdateItem updateItem;

                // determine whether this is a "property=value" assignment, we use property setters in this case
                var possibleAssignment = ExprNodeUtility.CheckGetAssignmentToProp(assignment.Expression);

                // handle assignment "property = value"
                if (possibleAssignment != null)
                {
                    var propertyName     = possibleAssignment.First;
                    var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                    // check assignment to indexed or mapped property
                    if (writableProperty == null)
                    {
                        var nameWriteablePair = CheckIndexedOrMappedProp(possibleAssignment.First, updatedWindowOrTableName, updatedAlias, eventTypeSPI);
                        propertyName     = nameWriteablePair.First;
                        writableProperty = nameWriteablePair.Second;
                    }

                    var evaluator        = possibleAssignment.Second.ExprEvaluator;
                    var writers          = eventTypeSPI.GetWriter(propertyName);
                    var notNullableField = writableProperty.PropertyType.IsPrimitive;

                    properties.Add(propertyName);
                    var widener = TypeWidenerFactory.GetCheckPropertyAssignType(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(possibleAssignment.Second), possibleAssignment.Second.ExprEvaluator.ReturnType,
                                                                                writableProperty.PropertyType, propertyName);

                    // check event type assignment
                    if (optionalTriggeringEventType != null && possibleAssignment.Second is ExprIdentNode)
                    {
                        var node        = (ExprIdentNode)possibleAssignment.Second;
                        var fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                        var fragmentLHS = eventTypeSPI.GetFragmentType(possibleAssignment.First);
                        if (fragmentRHS != null && fragmentLHS != null && !EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                        {
                            throw new ExprValidationException("Invalid assignment to property '" +
                                                              possibleAssignment.First + "' event type '" + fragmentLHS.FragmentType.Name +
                                                              "' from event type '" + fragmentRHS.FragmentType.Name + "'");
                        }
                    }

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

                updateItems.Add(updateItem);
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethod copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                IList <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                var            propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethod(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                var propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    var propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethod(propertiesInitialValueArray);
                }
            }

            var updateItemsArray = updateItems.ToArray();

            return(new EventBeanUpdateHelper(copyMethod, updateItemsArray));
        }
        public static EventBeanUpdateHelperForge Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite,
            string statementName,
            EventTypeAvroHandler avroHandler)
        {
            IList <EventBeanUpdateItemForge> updateItems = new List <EventBeanUpdateItemForge>();
            IList <string> properties = new List <string>();

            TypeWidenerCustomizer typeWidenerCustomizer = avroHandler.GetTypeWidenerCustomizer(eventTypeSPI);

            for (int i = 0; i < assignments.Count; i++)
            {
                OnTriggerSetAssignment desc       = assignments[i];
                ExprAssignment         assignment = desc.Validated;
                if (assignment == null)
                {
                    throw new IllegalStateException("Assignment has not been validated");
                }

                try {
                    EventBeanUpdateItemForge updateItem;
                    if (assignment is ExprAssignmentStraight)
                    {
                        ExprAssignmentStraight straight = (ExprAssignmentStraight)assignment;

                        // handle assignment "property = value"
                        if (straight.Lhs is ExprAssignmentLHSIdent)
                        {
                            ExprAssignmentLHSIdent ident = (ExprAssignmentLHSIdent)straight.Lhs;

                            string propertyName = ident.Ident;
                            EventPropertyDescriptor writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                            // check assignment to indexed or mapped property
                            if (writableProperty == null)
                            {
                                Pair <string, EventPropertyDescriptor> nameWriteablePair = CheckIndexedOrMappedProp(
                                    propertyName,
                                    updatedWindowOrTableName,
                                    updatedAlias,
                                    eventTypeSPI);
                                propertyName     = nameWriteablePair.First;
                                writableProperty = nameWriteablePair.Second;
                            }

                            ExprNode  rhsExpr             = straight.Rhs;
                            ExprForge rhsForge            = rhsExpr.Forge;
                            EventPropertyWriterSPI writer = eventTypeSPI.GetWriter(propertyName);
                            bool notNullableField         = writableProperty.PropertyType.IsPrimitive;

                            properties.Add(propertyName);
                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(rhsExpr),
                                    rhsForge.EvaluationType,
                                    writableProperty.PropertyType,
                                    propertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            // check event type assignment
                            bool useUntypedAssignment = false;
                            bool useTriggeringEvent   = false;
                            if (optionalTriggeringEventType != null)
                            {
                                // handle RHS is ident node
                                if (rhsExpr is ExprIdentNode)
                                {
                                    ExprIdentNode     node        = (ExprIdentNode)rhsExpr;
                                    FragmentEventType fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                                    FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                    if (fragmentRHS != null && fragmentLHS != null)
                                    {
                                        if (!EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, fragmentRHS.FragmentType);
                                        }
                                    }

                                    // we don't need to cast if it is a self-assignment and LHS is an event and target needs no writer
                                    if (node.StreamId == 0 && fragmentLHS != null && eventTypeSPI is BaseNestableEventType)
                                    {
                                        useUntypedAssignment = true;
                                    }
                                }

                                // handle RHS is a stream of the triggering event itself
                                if (rhsExpr is ExprStreamUnderlyingNode)
                                {
                                    ExprStreamUnderlyingNode und = (ExprStreamUnderlyingNode)rhsExpr;
                                    if (und.StreamId == 1)
                                    {
                                        FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                        if (fragmentLHS != null &&
                                            optionalTriggeringEventType is BaseNestableEventType &&
                                            !EventTypeUtility.IsTypeOrSubTypeOf(optionalTriggeringEventType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, optionalTriggeringEventType);
                                        }

                                        // we use the event itself for assignment and target needs no writer
                                        if (eventTypeSPI is BaseNestableEventType)
                                        {
                                            useUntypedAssignment = true;
                                            useTriggeringEvent   = true;
                                        }
                                    }
                                }
                            }

                            updateItem = new EventBeanUpdateItemForge(
                                rhsForge,
                                propertyName,
                                writer,
                                notNullableField,
                                widener,
                                useUntypedAssignment,
                                useTriggeringEvent,
                                null);
                        }
                        else if (straight.Lhs is ExprAssignmentLHSArrayElement)
                        {
                            // handle "property[expr] = value"
                            ExprAssignmentLHSArrayElement arrayElementLHS = (ExprAssignmentLHSArrayElement)straight.Lhs;
                            string   arrayPropertyName = arrayElementLHS.Ident;
                            ExprNode rhs            = straight.Rhs;
                            Type     evaluationType = rhs.Forge.EvaluationType;
                            Type     propertyType   = eventTypeSPI.GetPropertyType(arrayPropertyName);
                            if (!eventTypeSPI.IsProperty(arrayPropertyName))
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' could not be found");
                            }

                            if (propertyType == null || !propertyType.IsArray)
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' is not an array");
                            }

                            EventPropertyGetterSPI getter = eventTypeSPI.GetGetterSPI(arrayPropertyName);
                            Type componentType            = propertyType.GetElementType();
                            if (!TypeHelper.IsAssignmentCompatible(evaluationType, componentType))
                            {
                                throw new ExprValidationException(
                                          "Invalid assignment to property '" +
                                          arrayPropertyName +
                                          "' component type '" +
                                          componentType.CleanName() +
                                          "' from expression returning '" +
                                          evaluationType.CleanName() +
                                          "'");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(straight.Rhs),
                                    evaluationType,
                                    componentType,
                                    arrayPropertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            EventBeanUpdateItemArray arrayInfo = new EventBeanUpdateItemArray(
                                arrayPropertyName,
                                arrayElementLHS.IndexExpression,
                                propertyType,
                                getter);
                            updateItem = new EventBeanUpdateItemForge(
                                rhs.Forge,
                                arrayPropertyName,
                                null,
                                false,
                                widener,
                                false,
                                false,
                                arrayInfo);
                        }
                        else
                        {
                            throw new IllegalStateException("Unrecognized LHS assignment " + straight);
                        }
                    }
                    else if (assignment is ExprAssignmentCurly)
                    {
                        // handle non-assignment, i.e. UDF or other expression
                        ExprAssignmentCurly dot = (ExprAssignmentCurly)assignment;
                        updateItem = new EventBeanUpdateItemForge(
                            dot.Expression.Forge,
                            null,
                            null,
                            false,
                            null,
                            false,
                            false,
                            null);
                    }
                    else
                    {
                        throw new IllegalStateException("Unrecognized assignment " + assignment);
                    }

                    updateItems.Add(updateItem);
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException(
                              "Failed to validate assignment expression '" +
                              ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.OriginalExpression) +
                              "': " +
                              ex.Message,
                              ex);
                }
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethodForge copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                List <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                string[]      propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                ISet <string> propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    string[] propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesInitialValueArray);
                }
            }

            EventBeanUpdateItemForge[] updateItemsArray = updateItems.ToArray();
            return(new EventBeanUpdateHelperForge(eventTypeSPI, copyMethod, updateItemsArray));
        }
Example #16
0
        public static void ValidateStatementKeyAndHash(
            IEnumerable<Supplier<EventType>> typeProvider,
            string contextName,
            StatementSpecCompiled spec,
            StatementCompileTimeServices compileTimeServices)
        {
            StatementSpecCompiledAnalyzerResult streamAnalysis = StatementSpecCompiledAnalyzer.AnalyzeFilters(spec);
            IList<FilterSpecCompiled> filters = streamAnalysis.Filters;

            var isCreateWindow = spec.Raw.CreateWindowDesc != null;

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow) {
                foreach (var filter in filters) {
                    foreach (var item in typeProvider) {
                        EventType itemEventType = item.Invoke();
                        var stmtFilterType = filter.FilterForEventType;
                        if (ReferenceEquals(stmtFilterType, itemEventType)) {
                            return;
                        }

                        if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, itemEventType)) {
                            return;
                        }

                        NamedWindowMetaData namedWindow =
                            compileTimeServices.NamedWindowCompileTimeResolver.Resolve(stmtFilterType.Name);
                        string namedWindowContextName = namedWindow?.ContextName;
                        if (namedWindowContextName != null && namedWindowContextName.Equals(contextName)) {
                            return;
                        }
                    }
                }

                if (!filters.IsEmpty()) {
                    throw new ExprValidationException(
                        GetTypeValidationMessage(contextName, filters[0].FilterForEventType.Name));
                }

                return;
            }

            // validate create-window with column definition: not allowed, requires typed
            if (spec.Raw.CreateWindowDesc.Columns != null &&
                spec.Raw.CreateWindowDesc.Columns.Count > 0) {
                throw new ExprValidationException(
                    "Segmented context '" +
                    contextName +
                    "' requires that named windows are associated to an existing event type and that the event type is listed among the partitions defined by the create-context statement");
            }

            // validate create-window declared type
            var declaredAsName = spec.Raw.CreateWindowDesc.AsEventTypeName;
            if (declaredAsName != null) {
                foreach (var item in typeProvider) {
                    EventType itemEventType = item.Invoke();
                    if (itemEventType.Name.Equals(declaredAsName)) {
                        return;
                    }
                }

                throw new ExprValidationException(GetTypeValidationMessage(contextName, declaredAsName));
            }
        }
Example #17
0
        public static String ComparePropType(String propName, Object setOneType, Object setTwoType, bool setTwoTypeFound, String otherName)
        {
            // allow null for nested event types
            if ((setOneType is String || setOneType is EventType) && setTwoType == null)
            {
                return(null);
            }
            if ((setTwoType is String || setTwoType is EventType) && setOneType == null)
            {
                return(null);
            }
            if (!setTwoTypeFound)
            {
                return("The property '" + propName + "' is not provided but required");
            }
            if (setTwoType == null)
            {
                return(null);
            }
            if (setOneType == null)
            {
                return("Type by name '" + otherName + "' in property '" + propName + "' incompatible with null-type or property name not found in target");
            }

            if ((setTwoType is Type) && (setOneType is Type))
            {
                var boxedOther = ((Type)setTwoType).GetBoxedType();
                var boxedThis  = ((Type)setOneType).GetBoxedType();
                if (boxedOther != boxedThis)
                {
                    if (!TypeHelper.IsSubclassOrImplementsInterface(boxedOther, boxedThis))
                    {
                        return(string.Format("Type by name '{0}' in property '{1}' expected {2} but receives {3}",
                                             otherName, propName, Name.Of(boxedThis), Name.Of(boxedOther)));
                    }
                }
            }
            else if ((setTwoType is BeanEventType) && (setOneType is Type))
            {
                Type boxedOther = ((BeanEventType)setTwoType).UnderlyingType.GetBoxedType();
                var  boxedThis  = ((Type)setOneType).GetBoxedType();
                if (boxedOther != boxedThis)
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected " + boxedThis + " but receives " + boxedOther);
                }
            }
            else if (setTwoType is EventType[] && ((EventType[])setTwoType)[0] is BeanEventType && setOneType is Type && ((Type)setOneType).IsArray)
            {
                var boxedOther = (((EventType[])setTwoType)[0]).UnderlyingType.GetBoxedType();
                var boxedThis  = ((Type)setOneType).GetElementType().GetBoxedType();
                if (boxedOther != boxedThis)
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected " + boxedThis + " but receives " + boxedOther);
                }
            }
            else if ((setTwoType is IDictionary <String, Object>) && (setOneType is IDictionary <String, Object>))
            {
                var messageIsDeepEquals = BaseNestableEventType.IsDeepEqualsProperties(propName, (IDictionary <String, Object>)setOneType, (IDictionary <String, Object>)setTwoType);
                if (messageIsDeepEquals != null)
                {
                    return(messageIsDeepEquals);
                }
            }
            else if ((setTwoType is EventType) && (setOneType is EventType))
            {
                bool mismatch;
                if (setTwoType is EventTypeSPI && setOneType is EventTypeSPI)
                {
                    mismatch = !((EventTypeSPI)setOneType).EqualsCompareType((EventTypeSPI)setTwoType);
                }
                else
                {
                    mismatch = !setOneType.Equals(setTwoType);
                }
                if (mismatch)
                {
                    var setOneEventType = (EventType)setOneType;
                    var setTwoEventType = (EventType)setTwoType;
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneEventType.Name + "' but receives event type '" + setTwoEventType.Name + "'");
                }
            }
            else if ((setTwoType is String) && (setOneType is EventType))
            {
                var setOneEventType = (EventType)setOneType;
                var setTwoEventType = (String)setTwoType;
                if (!EventTypeUtility.IsTypeOrSubTypeOf(setTwoEventType, setOneEventType))
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneEventType.Name + "' but receives event type '" + setTwoEventType + "'");
                }
            }
            else if ((setTwoType is EventType) && (setOneType is String))
            {
                var setTwoEventType = (EventType)setTwoType;
                var setOneEventType = (String)setOneType;
                if (!EventTypeUtility.IsTypeOrSubTypeOf(setOneEventType, setTwoEventType))
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneEventType + "' but receives event type '" + setTwoEventType.Name + "'");
                }
            }
            else if ((setTwoType is String) && (setOneType is String))
            {
                if (!setTwoType.Equals(setOneType))
                {
                    var setOneEventType = (String)setOneType;
                    var setTwoEventType = (String)setTwoType;
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneEventType + "' but receives event type '" + setTwoEventType + "'");
                }
            }
            else if ((setTwoType is EventType[]) && (setOneType is String))
            {
                var setTwoTypeArr      = (EventType[])setTwoType;
                var setTwoFragmentType = setTwoTypeArr[0];
                var setOneTypeString   = (String)setOneType;
                if (!(setOneTypeString.EndsWith("[]")))
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneType + "' but receives event type '" + setTwoFragmentType.Name + "[]'");
                }
                var setOneTypeNoArray = (setOneTypeString).RegexReplaceAll("\\[\\]", "");
                if (!(setTwoFragmentType.Name.Equals(setOneTypeNoArray)))
                {
                    return("Type by name '" + otherName + "' in property '" + propName + "' expected event type '" + setOneTypeNoArray + "[]' but receives event type '" + setTwoFragmentType.Name + "'");
                }
            }
            else
            {
                var typeOne = GetTypeName(setOneType);
                var typeTwo = GetTypeName(setTwoType);
                if (typeOne.Equals(typeTwo))
                {
                    return(null);
                }
                return("Type by name '" + otherName + "' in property '" + propName + "' expected " + typeOne + " but receives " + typeTwo);
            }

            return(null);
        }
Example #18
0
        public override EnumForge GetEnumForge(StreamTypeService streamTypeService,
            string enumMethodUsedName,
            IList<ExprDotEvalParam> bodiesAndParameters,
            EventType inputEventType,
            Type collectionComponentType,
            int numStreamsIncoming,
            bool disablePropertyExpressionEventCollCache,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            var first = bodiesAndParameters[0];

            var enumSrc = ExprDotNodeUtility.GetEnumerationSource(
                first.Body,
                streamTypeService,
                true,
                disablePropertyExpressionEventCollCache,
                statementRawInfo,
                services);
            if (inputEventType != null) {
                TypeInfo = EPTypeHelper.CollectionOfEvents(inputEventType);
            }
            else {
                TypeInfo = EPTypeHelper.CollectionOfSingleValue(collectionComponentType, null);
            }

            if (inputEventType != null) {
                var setType = enumSrc.Enumeration == null
                    ? null
                    : enumSrc.Enumeration.GetEventTypeCollection(statementRawInfo, services);
                if (setType == null) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' requires an expression yielding a " +
                                     "collection of events of type '" +
                                     inputEventType.Name +
                                     "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (setType != inputEventType) {
                    var isSubtype = EventTypeUtility.IsTypeOrSubTypeOf(setType, inputEventType);
                    if (!isSubtype) {
                        var message = "Enumeration method '" +
                                         enumMethodUsedName +
                                         "' expects event type '" +
                                         inputEventType.Name +
                                         "' but receives event type '" +
                                         setType.Name +
                                         "'";
                        throw new ExprValidationException(message);
                    }
                }
            }
            else {
                var setType = enumSrc.Enumeration?.ComponentTypeCollection;
                if (setType == null) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' requires an expression yielding a " +
                                     "collection of values of type '" +
                                     collectionComponentType.CleanName() +
                                     "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (!TypeHelper.IsAssignmentCompatible(setType, collectionComponentType)) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' expects scalar type '" +
                                     collectionComponentType.Name +
                                     "' but receives event type '" +
                                     setType.Name +
                                     "'";
                    throw new ExprValidationException(message);
                }
            }

            if (EnumMethodEnum == EnumMethodEnum.UNION) {
                return new EnumUnionForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else if (EnumMethodEnum == EnumMethodEnum.INTERSECT) {
                return new EnumIntersectForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else if (EnumMethodEnum == EnumMethodEnum.EXCEPT) {
                return new EnumExceptForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else {
                throw new ArgumentException("Invalid enumeration method for this factory: " + EnumMethodEnum);
            }
        }
Example #19
0
        public static FilterValueSetParam[][] GetAddendumFilters(
            object keyValue,
            FilterSpecCompiled filtersSpec,
            ContextDetailPartitioned segmentedSpec,
            StatementSpecCompiled optionalStatementSpecCompiled)
        {
            // determine whether create-named-window
            var isCreateWindow = optionalStatementSpecCompiled != null &&
                                 optionalStatementSpecCompiled.CreateWindowDesc != null;
            ContextDetailPartitionItem foundPartition = null;

            if (!isCreateWindow)
            {
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(
                        filtersSpec.FilterForEventType, partitionItem.FilterSpecCompiled.FilterForEventType);
                    if (typeOrSubtype)
                    {
                        foundPartition = partitionItem;
                    }
                }
            }
            else
            {
                var declaredAsName = optionalStatementSpecCompiled.CreateWindowDesc.AsEventTypeName;
                if (declaredAsName == null)
                {
                    return(null);
                }
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    if (partitionItem.FilterSpecCompiled.FilterForEventType.Name.Equals(declaredAsName))
                    {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }

            if (foundPartition == null)
            {
                return(null);
            }

            var addendumFilters = new List <FilterValueSetParam>(foundPartition.PropertyNames.Count);

            if (foundPartition.PropertyNames.Count == 1)
            {
                var propertyName           = foundPartition.PropertyNames[0];
                var getter                 = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(propertyName);
                var resultType             = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(propertyName);
                var lookupable             = new FilterSpecLookupable(propertyName, getter, resultType, false);
                FilterValueSetParam filter = new FilterValueSetParamImpl(lookupable, FilterOperator.EQUAL, keyValue);
                addendumFilters.Add(filter);
            }
            else
            {
                var keys = ((MultiKeyUntyped)keyValue).Keys;
                for (var i = 0; i < foundPartition.PropertyNames.Count; i++)
                {
                    var partitionPropertyName = foundPartition.PropertyNames[i];
                    var getter                 = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(partitionPropertyName);
                    var resultType             = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(partitionPropertyName);
                    var lookupable             = new FilterSpecLookupable(partitionPropertyName, getter, resultType, false);
                    FilterValueSetParam filter = new FilterValueSetParamImpl(lookupable, FilterOperator.EQUAL, keys[i]);
                    addendumFilters.Add(filter);
                }
            }

            var addendum = new FilterValueSetParam[1][];

            addendum[0] = addendumFilters.ToArray();

            var partitionFilters = foundPartition.ParametersCompiled;

            if (partitionFilters != null)
            {
                addendum = ContextControllerAddendumUtil.AddAddendum(partitionFilters, addendum[0]);
            }

            return(addendum);
        }
Example #20
0
        public static FilterValueSetParam[][] GetAddendumFilters(
            object getterKey,
            FilterSpecActivatable filtersSpec,
            ContextControllerDetailKeyed keyedSpec,
            bool includePartition,
            ContextControllerStatementDesc optionalStatementDesc,
            AgentInstanceContext agentInstanceContext)
        {
            // determine whether create-named-window
            var isCreateWindow = optionalStatementDesc != null &&
                                 optionalStatementDesc.Lightweight.StatementContext.StatementInformationals
                                     .StatementType ==
                                 StatementType.CREATE_WINDOW;
            ContextControllerDetailKeyedItem foundPartition = null;

            if (!isCreateWindow) {
                foreach (var partitionItem in keyedSpec.Items) {
                    var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(
                        filtersSpec.FilterForEventType,
                        partitionItem.FilterSpecActivatable.FilterForEventType);
                    if (typeOrSubtype) {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }
            else {
                var factory = (StatementAgentInstanceFactoryCreateNW) optionalStatementDesc.Lightweight.StatementContext
                    .StatementAIFactoryProvider
                    .Factory;
                var declaredAsName = factory.AsEventTypeName;
                foreach (var partitionItem in keyedSpec.Items) {
                    if (partitionItem.FilterSpecActivatable.FilterForEventType.Name.Equals(declaredAsName)) {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }

            if (foundPartition == null) {
                return null;
            }

            var lookupables = foundPartition.Lookupables;
            var addendumFilters = new FilterValueSetParam[lookupables.Length];
            if (lookupables.Length == 1) {
                addendumFilters[0] = GetFilterMayEqualOrNull(lookupables[0], getterKey);
            }
            else {
                var keys = getterKey is HashableMultiKey ? ((HashableMultiKey) getterKey).Keys : (object[]) getterKey;
                for (var i = 0; i < lookupables.Length; i++) {
                    addendumFilters[i] = GetFilterMayEqualOrNull(lookupables[i], keys[i]);
                }
            }

            var addendum = new FilterValueSetParam[1][];
            addendum[0] = addendumFilters;

            var partitionFilters = foundPartition.FilterSpecActivatable.GetValueSet(
                null,
                null,
                agentInstanceContext,
                agentInstanceContext.StatementContextFilterEvalEnv);
            if (partitionFilters != null && includePartition) {
                addendum = FilterAddendumUtil.AddAddendum(partitionFilters, addendum[0]);
            }

            return addendum;
        }
Example #21
0
        // Compare filters in statement with filters in segmented context, addendum filter compilation
        public static void PopulateAddendumFilters(
            Object keyValue,
            IList <FilterSpecCompiled> filtersSpecs,
            ContextDetailPartitioned segmentedSpec,
            StatementSpecCompiled optionalStatementSpecCompiled,
            IDictionary <FilterSpecCompiled, FilterValueSetParam[][]> addendums)
        {
            // determine whether create-named-window
            bool isCreateWindow = optionalStatementSpecCompiled != null && optionalStatementSpecCompiled.CreateWindowDesc != null;

            if (!isCreateWindow)
            {
                foreach (FilterSpecCompiled filtersSpec in filtersSpecs)
                {
                    ContextDetailPartitionItem foundPartition = null;
                    foreach (ContextDetailPartitionItem partitionItem in segmentedSpec.Items)
                    {
                        bool typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(filtersSpec.FilterForEventType, partitionItem.FilterSpecCompiled.FilterForEventType);
                        if (typeOrSubtype)
                        {
                            foundPartition = partitionItem;
                        }
                    }

                    if (foundPartition == null)
                    {
                        continue;
                    }

                    var addendumFilters = new List <FilterValueSetParam>(foundPartition.PropertyNames.Count);
                    if (foundPartition.PropertyNames.Count == 1)
                    {
                        var propertyName = foundPartition.PropertyNames[0];
                        var getter       = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(propertyName);
                        var resultType   = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(propertyName);
                        var lookupable   = new FilterSpecLookupable(propertyName, getter, resultType);
                        var filter       = new FilterValueSetParamImpl(lookupable, FilterOperator.EQUAL, keyValue);
                        addendumFilters.Add(filter);
                    }
                    else
                    {
                        var keys = ((MultiKeyUntyped)keyValue).Keys;
                        for (int i = 0; i < foundPartition.PropertyNames.Count; i++)
                        {
                            var partitionPropertyName = foundPartition.PropertyNames[i];
                            var getter     = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(partitionPropertyName);
                            var resultType = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(partitionPropertyName);
                            var lookupable = new FilterSpecLookupable(partitionPropertyName, getter, resultType);
                            var filter     = new FilterValueSetParamImpl(lookupable, FilterOperator.EQUAL, keys[i]);
                            addendumFilters.Add(filter);
                        }
                    }

                    // add those predefined filter parameters, if any
                    FilterValueSetParam[][] partitionFilters = foundPartition.ParametersCompiled;

                    // add to existing if any are present
                    AddAddendums(addendums, addendumFilters, filtersSpec, partitionFilters);
                }
            }
            // handle segmented context for create-window
            else
            {
                String declaredAsName = optionalStatementSpecCompiled.CreateWindowDesc.AsEventTypeName;
                if (declaredAsName != null)
                {
                    foreach (FilterSpecCompiled filtersSpec in filtersSpecs)
                    {
                        ContextDetailPartitionItem foundPartition = null;
                        foreach (ContextDetailPartitionItem partitionItem in segmentedSpec.Items)
                        {
                            if (partitionItem.FilterSpecCompiled.FilterForEventType.Name.Equals(declaredAsName))
                            {
                                foundPartition = partitionItem;
                                break;
                            }
                        }

                        if (foundPartition == null)
                        {
                            continue;
                        }

                        var addendumFilters = new List <FilterValueSetParam>(foundPartition.PropertyNames.Count);
                        var propertyNumber  = 0;
                        foreach (String partitionPropertyName in foundPartition.PropertyNames)
                        {
                            var getter     = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(partitionPropertyName);
                            var resultType = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(partitionPropertyName);
                            var lookupable = new FilterSpecLookupable(partitionPropertyName, getter, resultType);

                            Object propertyValue;
                            if (keyValue is MultiKeyUntyped)
                            {
                                propertyValue = ((MultiKeyUntyped)keyValue).Get(propertyNumber);
                            }
                            else
                            {
                                propertyValue = keyValue;
                            }

                            FilterValueSetParam filter = new FilterValueSetParamImpl(lookupable, FilterOperator.EQUAL, propertyValue);
                            addendumFilters.Add(filter);
                            propertyNumber++;
                        }

                        // add to existing if any are present
                        AddAddendums(addendums, addendumFilters, filtersSpec, foundPartition.ParametersCompiled);
                    }
                }
            }
        }
Example #22
0
        protected internal static Type[] ValidateContextDesc(string contextName, ContextDetailPartitioned segmentedSpec)
        {
            if (segmentedSpec.Items.IsEmpty())
            {
                throw new ExprValidationException("Empty list of partition items");
            }

            // verify properties exist
            foreach (var item in segmentedSpec.Items)
            {
                var type = item.FilterSpecCompiled.FilterForEventType;
                foreach (var property in item.PropertyNames)
                {
                    var getter = type.GetGetter(property);
                    if (getter == null)
                    {
                        throw new ExprValidationException(
                                  "For context '" + contextName + "' property name '" + property + "' not found on type " +
                                  type.Name);
                    }
                }
            }

            // verify property number and types compatible
            ContextDetailPartitionItem firstItem = segmentedSpec.Items[0];

            if (segmentedSpec.Items.Count > 1)
            {
                // verify the same filter event type is only listed once

                for (var i = 0; i < segmentedSpec.Items.Count; i++)
                {
                    EventType compareTo = segmentedSpec.Items[i].FilterSpecCompiled.FilterForEventType;

                    for (var j = 0; j < segmentedSpec.Items.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        EventType compareFrom = segmentedSpec.Items[j].FilterSpecCompiled.FilterForEventType;
                        if (compareFrom == compareTo)
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' the event type '" + compareFrom.Name +
                                      "' is listed twice");
                        }
                        if (EventTypeUtility.IsTypeOrSubTypeOf(compareFrom, compareTo) ||
                            EventTypeUtility.IsTypeOrSubTypeOf(compareTo, compareFrom))
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' the event type '" + compareFrom.Name +
                                      "' is listed twice: Event type '" +
                                      compareFrom.Name + "' is a subtype or supertype of event type '" + compareTo.Name + "'");
                        }
                    }
                }

                // build property type information
                var names      = new string[firstItem.PropertyNames.Count];
                var types      = new Type[firstItem.PropertyNames.Count];
                var typesBoxed = new Type[firstItem.PropertyNames.Count];
                for (var i = 0; i < firstItem.PropertyNames.Count; i++)
                {
                    string property = firstItem.PropertyNames[i];
                    names[i]      = property;
                    types[i]      = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
                    typesBoxed[i] = types[i].GetBoxedType();
                }

                // compare property types and numbers
                for (var item = 1; item < segmentedSpec.Items.Count; item++)
                {
                    ContextDetailPartitionItem nextItem = segmentedSpec.Items[item];

                    // compare number of properties
                    if (nextItem.PropertyNames.Count != types.Length)
                    {
                        throw new ExprValidationException(
                                  "For context '" + contextName +
                                  "' expected the same number of property names for each event type, found " +
                                  types.Length + " properties for event type '" +
                                  firstItem.FilterSpecCompiled.FilterForEventType.Name +
                                  "' and " + nextItem.PropertyNames.Count + " properties for event type '" +
                                  nextItem.FilterSpecCompiled.FilterForEventType.Name + "'");
                    }

                    // compare property types
                    for (var i = 0; i < nextItem.PropertyNames.Count; i++)
                    {
                        string property  = nextItem.PropertyNames[i];
                        var    type      = nextItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property).GetBoxedType();
                        var    typeBoxed = type.GetBoxedType();
                        var    left      = TypeHelper.IsSubclassOrImplementsInterface(typeBoxed, typesBoxed[i]);
                        var    right     = TypeHelper.IsSubclassOrImplementsInterface(typesBoxed[i], typeBoxed);
                        if (typeBoxed != typesBoxed[i] && !left && !right)
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' for context '" + contextName +
                                      "' found mismatch of property types, property '" + names[i] +
                                      "' of type '" + types[i].GetTypeNameFullyQualPretty() +
                                      "' compared to property '" + property +
                                      "' of type '" + typeBoxed.GetTypeNameFullyQualPretty() + "'");
                        }
                    }
                }
            }

            var propertyTypes = new Type[firstItem.PropertyNames.Count];

            for (var i = 0; i < firstItem.PropertyNames.Count; i++)
            {
                string property = firstItem.PropertyNames[i];
                propertyTypes[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
            }
            return(propertyTypes);
        }
Example #23
0
        public override EnumForgeDescFactory GetForgeFactory(
            DotMethodFP footprint,
            IList<ExprNode> parameters,
            EnumMethodEnum enumMethod,
            String enumMethodUsedName,
            EventType inputEventType,
            Type collectionComponentType,
            ExprValidationContext validationContext)
        {
            var first = parameters[0];

            var enumSrc = ExprDotNodeUtility.GetEnumerationSource(
                first,
                validationContext.StreamTypeService,
                true,
                validationContext.IsDisablePropertyExpressionEventCollCache,
                validationContext.StatementRawInfo,
                validationContext.StatementCompileTimeService);

            EPType type;
            if (inputEventType != null) {
                type = EPTypeHelper.CollectionOfEvents(inputEventType);
            }
            else {
                type = EPTypeHelper.CollectionOfSingleValue(collectionComponentType, null);
            }

            if (inputEventType != null) {
                var setType = enumSrc.Enumeration?.GetEventTypeCollection(
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);

                if (setType == null) {
                    var message = "Enumeration method '" +
                                  enumMethodUsedName +
                                  "' requires an expression yielding a " +
                                  "collection of events of type '" +
                                  inputEventType.Name +
                                  "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (setType != inputEventType) {
                    var isSubtype = EventTypeUtility.IsTypeOrSubTypeOf(setType, inputEventType);
                    if (!isSubtype) {
                        var message = "Enumeration method '" +
                                      enumMethodUsedName +
                                      "' expects event type '" +
                                      inputEventType.Name +
                                      "' but receives event type '" +
                                      setType.Name +
                                      "'";
                        throw new ExprValidationException(message);
                    }
                }
            }
            else {
                var setType = enumSrc.Enumeration?.ComponentTypeCollection;
                if (setType == null) {
                    var message = "Enumeration method '" +
                                  enumMethodUsedName +
                                  "' requires an expression yielding a " +
                                  "collection of values of type '" +
                                  collectionComponentType.Name +
                                  "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (!setType.IsAssignmentCompatible(collectionComponentType)) {
                    var message = "Enumeration method '" +
                                  enumMethodUsedName +
                                  "' expects scalar type '" +
                                  collectionComponentType.Name +
                                  "' but receives event type '" +
                                  setType.Name +
                                  "'";
                    throw new ExprValidationException(message);
                }
            }

            return new EnumForgeDescFactoryEIU(enumMethod, type, enumSrc);
        }