示例#1
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int?streamOfProviderIfApplicable,
            EPType inputType,
            IList <ExprChainedSpec> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            var            methodEvals      = new List <ExprDotEval>();
            var            currentInputType = inputType;
            EnumMethodEnum?lastLambdaFunc   = null;
            var            lastElement      = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc = null;

            var chainSpecStack = new ArrayDeque <ExprChainedSpec>(chainSpec);

            while (!chainSpecStack.IsEmpty())
            {
                var chainElement = chainSpecStack.RemoveFirst();
                lastLambdaFunc = null;  // reset

                // compile parameters for chain element
                var paramEvals = new ExprEvaluator[chainElement.Parameters.Count];
                var paramTypes = new Type[chainElement.Parameters.Count];
                for (var i = 0; i < chainElement.Parameters.Count; i++)
                {
                    paramEvals[i] = chainElement.Parameters[i].ExprEvaluator;
                    paramTypes[i] = paramEvals[i].ReturnType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType)
                {
                    var type = (ClassMultiValuedEPType)currentInputType;
                    if ((chainElement.Name.ToLower() == "size") && paramTypes.Length == 0 && Equals(lastElement, chainElement))
                    {
                        var sizeExpr = new ExprDotEvalArraySize();
                        methodEvals.Add(sizeExpr);
                        currentInputType = sizeExpr.TypeInfo;
                        continue;
                    }
                    if ((chainElement.Name.ToLower() == "get") && paramTypes.Length == 1 && paramTypes[0].GetBoxedType() == typeof(int?))
                    {
                        var componentType = type.Component;
                        var get           = new ExprDotEvalArrayGet(paramEvals[0], componentType);
                        methodEvals.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method
                var matchingMethod = false;
                var methodTarget   = GetMethodTarget(currentInputType);
                if (methodTarget != null)
                {
                    try
                    {
                        GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException)
                    {
                        // expected
                    }
                }

                // resolve lambda
                if (chainElement.Name.IsEnumerationMethod() && (!matchingMethod || methodTarget.IsArray || methodTarget.IsImplementsInterface(typeof(ICollection <object>))))
                {
                    var enumerationMethod = EnumMethodEnumExtensions.FromName(chainElement.Name);
                    var eval = TypeHelper.Instantiate <ExprDotEvalEnumMethod>(enumerationMethod.GetImplementation());
                    eval.Init(streamOfProviderIfApplicable, enumerationMethod, chainElement.Name, currentInputType, chainElement.Parameters, validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Enumeration method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (chainElement.Name.IsDateTimeMethod() && (!matchingMethod || methodTarget == typeof(DateTimeOffset?)))
                {
                    var datetimeMethod = DatetimeMethodEnumExtensions.FromName(chainElement.Name);
                    var datetimeImpl   = ExprDotEvalDTFactory.ValidateMake(
                        validationContext.StreamTypeService, chainSpecStack, datetimeMethod, chainElement.Name,
                        currentInputType, chainElement.Parameters, inputDesc,
                        validationContext.EngineImportService.TimeZone,
                        validationContext.EngineImportService.TimeAbacus);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Date-time method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(datetimeImpl.Eval);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType)
                {
                    var inputEventType = ((EventEPType)currentInputType).EventType;
                    var type           = inputEventType.GetPropertyType(chainElement.Name);
                    var getter         = inputEventType.GetGetter(chainElement.Name);
                    if (type != null && getter != null)
                    {
                        var noduck = new ExprDotEvalProperty(getter, EPTypeHelper.SingleValue(type.GetBoxedType()));
                        methodEvals.Add(noduck);
                        currentInputType = EPTypeHelper.SingleValue(EPTypeHelper.GetClassSingleValued(noduck.TypeInfo));
                        continue;
                    }
                }

                // Finally try to resolve the method
                if (methodTarget != null)
                {
                    try
                    {
                        // find descriptor again, allow for duck typing
                        var desc       = GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        var fastMethod = desc.FastMethod;
                        paramEvals = desc.ChildEvals;

                        ExprDotEval eval;
                        if (currentInputType is ClassEPType)
                        {
                            // if followed by an enumeration method, convert array to collection
                            if (fastMethod.ReturnType.IsArray && !chainSpecStack.IsEmpty() && chainSpecStack.First.Name.IsEnumerationMethod())
                            {
                                eval = new ExprDotMethodEvalNoDuckWrapArray(validationContext.StatementName, fastMethod, paramEvals);
                            }
                            else
                            {
                                eval = new ExprDotMethodEvalNoDuck(validationContext.StatementName, fastMethod, paramEvals);
                            }
                        }
                        else
                        {
                            eval = new ExprDotMethodEvalNoDuckUnderlying(validationContext.StatementName, fastMethod, paramEvals);
                        }
                        methodEvals.Add(eval);
                        currentInputType = eval.TypeInfo;
                    }
                    catch (Exception e)
                    {
                        if (!isDuckTyping)
                        {
                            throw new ExprValidationException(e.Message, e);
                        }
                        else
                        {
                            var duck = new ExprDotMethodEvalDuck(validationContext.StatementName, validationContext.EngineImportService, chainElement.Name, paramTypes, paramEvals);
                            methodEvals.Add(duck);
                            currentInputType = duck.TypeInfo;
                        }
                    }
                    continue;
                }

                var message = "Could not find event property, enumeration method or instance method named '" +
                              chainElement.Name + "' in " + currentInputType.ToTypeDescriptive();
                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodEvals.ToArray();

            if (lastLambdaFunc != null)
            {
                ExprDotEval finalEval = null;
                if (currentInputType is EventMultiValuedEPType)
                {
                    var mvType        = (EventMultiValuedEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(mvType.Component);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType)
                {
                    var epType        = (EventEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(epType.EventType);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackBean(epType.EventType);
                    }
                }
                if (finalEval != null)
                {
                    methodEvals.Add(finalEval);
                }
            }

            var unpackingEvals = methodEvals.ToArray();

            return(new ExprDotNodeRealizedChain(intermediateEvals, unpackingEvals, filterAnalyzerDesc));
        }
示例#2
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            // validate all parameters
            ExprNodeUtility.Validate(ExprNodeOrigin.DOTNODEPARAMETER, _chainSpec, validationContext);

            // determine if there are enumeration method expressions in the chain
            bool hasEnumerationMethod = false;

            foreach (ExprChainedSpec chain in _chainSpec)
            {
                if (chain.Name.IsEnumerationMethod())
                {
                    hasEnumerationMethod = true;
                    break;
                }
            }

            // determine if there is an implied binding, replace first chain element with evaluation node if there is
            if (validationContext.StreamTypeService.HasTableTypes &&
                validationContext.TableService != null &&
                _chainSpec.Count > 1 && _chainSpec[0].IsProperty)
            {
                Pair <ExprNode, IList <ExprChainedSpec> > tableNode =
                    validationContext.TableService.GetTableNodeChainable(
                        validationContext.StreamTypeService, _chainSpec,
                        validationContext.EngineImportService);
                if (tableNode != null)
                {
                    ExprNode node = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.DOTNODE, tableNode.First, validationContext);
                    if (tableNode.Second.IsEmpty())
                    {
                        return(node);
                    }
                    _chainSpec.Clear();
                    _chainSpec.AddAll(tableNode.Second);
                    AddChildNode(node);
                }
            }

            // The root node expression may provide the input value:
            //   Such as "window(*).doIt(...)" or "(select * from Window).doIt()" or "prevwindow(sb).doIt(...)", in which case the expression to act on is a child expression
            //
            StreamTypeService streamTypeService = validationContext.StreamTypeService;

            if (ChildNodes.Length != 0)
            {
                // the root expression is the first child node
                ExprNode      rootNode          = ChildNodes[0];
                ExprEvaluator rootNodeEvaluator = rootNode.ExprEvaluator;

                // the root expression may also provide a lambda-function input (GetEnumerator<EventBean>)
                // Determine collection-type and evaluator if any for root node
                ExprDotEnumerationSource enumSrc = ExprDotNodeUtility.GetEnumerationSource(rootNode, validationContext.StreamTypeService, validationContext.EventAdapterService, validationContext.StatementId, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache);

                EPType typeInfo;
                if (enumSrc.ReturnType == null)
                {
                    typeInfo = EPTypeHelper.SingleValue(rootNodeEvaluator.ReturnType);        // not a collection type, treat as scalar
                }
                else
                {
                    typeInfo = enumSrc.ReturnType;
                }

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(enumSrc.StreamOfProviderIfApplicable, typeInfo, _chainSpec, validationContext, _isDuckTyping, new ExprDotNodeFilterAnalyzerInputExpr());
                _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumSrc.Enumeration, typeInfo, evals.Chain, evals.ChainWithUnpack, false);
                return(null);
            }

            // No root node, and this is a 1-element chain i.e. "something(param,...)".
            // Plug-in single-row methods are not handled here.
            // Plug-in aggregation methods are not handled here.
            if (_chainSpec.Count == 1)
            {
                ExprChainedSpec spec = _chainSpec[0];
                if (spec.Parameters.IsEmpty())
                {
                    throw HandleNotFound(spec.Name);
                }

                // single-parameter can resolve to a property
                Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null;
                try {
                    propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, spec.Name, streamTypeService.HasPropertyAgnosticType, false);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }

                // if not a property then try built-in single-row non-grammar functions
                if (propertyInfoPair == null && string.Equals(spec.Name, EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE, StringComparison.OrdinalIgnoreCase))
                {
                    if (spec.Parameters.Count != 1)
                    {
                        throw new ExprValidationException("The " + EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE + " function requires a single parameter expression");
                    }
                    _exprEvaluator = new ExprDotEvalTransposeAsStream(_chainSpec[0].Parameters[0].ExprEvaluator);
                }
                else if (spec.Parameters.Count != 1)
                {
                    throw HandleNotFound(spec.Name);
                }
                else
                {
                    if (propertyInfoPair == null)
                    {
                        throw new ExprValidationException("Unknown single-row function, aggregation function or mapped or indexed property named '" + spec.Name + "' could not be resolved");
                    }
                    _exprEvaluator       = GetPropertyPairEvaluator(spec.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext);
                    _streamNumReferenced = propertyInfoPair.First.StreamNum;
                }
                return(null);
            }

            // handle the case where the first chain spec element is a stream name.
            ExprValidationException prefixedStreamNumException = null;
            int prefixedStreamNumber = PrefixedStreamName(_chainSpec, validationContext.StreamTypeService);

            if (prefixedStreamNumber != -1)
            {
                ExprChainedSpec specAfterStreamName = _chainSpec[1];

                // Attempt to resolve as property
                Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null;
                try {
                    string propName = _chainSpec[0].Name + "." + specAfterStreamName.Name;
                    propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, propName, streamTypeService.HasPropertyAgnosticType, false);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }
                if (propertyInfoPair != null)
                {
                    if (specAfterStreamName.Parameters.Count != 1)
                    {
                        throw HandleNotFound(specAfterStreamName.Name);
                    }
                    _exprEvaluator       = GetPropertyPairEvaluator(specAfterStreamName.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext);
                    _streamNumReferenced = propertyInfoPair.First.StreamNum;
                    return(null);
                }

                // Attempt to resolve as event-underlying object instance method
                EventType eventType = validationContext.StreamTypeService.EventTypes[prefixedStreamNumber];
                Type      type      = eventType.UnderlyingType;

                IList <ExprChainedSpec> remainderChain = new List <ExprChainedSpec>(_chainSpec);
                remainderChain.RemoveAt(0);

                ExprValidationException methodEx = null;
                ExprDotEval[]           underlyingMethodChain = null;
                try {
                    EPType typeInfo = EPTypeHelper.SingleValue(type);
                    underlyingMethodChain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber)).ChainWithUnpack;
                }
                catch (ExprValidationException ex) {
                    methodEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                ExprDotEval[]           eventTypeMethodChain = null;
                ExprValidationException enumDatetimeEx       = null;
                try {
                    EPType typeInfo = EPTypeHelper.SingleEvent(eventType);
                    ExprDotNodeRealizedChain chain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber));
                    eventTypeMethodChain           = chain.ChainWithUnpack;
                    _exprDotNodeFilterAnalyzerDesc = chain.FilterAnalyzerDesc;
                }
                catch (ExprValidationException ex) {
                    enumDatetimeEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                if (underlyingMethodChain != null)
                {
                    _exprEvaluator       = new ExprDotEvalStreamMethod(this, prefixedStreamNumber, underlyingMethodChain);
                    _streamNumReferenced = prefixedStreamNumber;
                }
                else if (eventTypeMethodChain != null)
                {
                    _exprEvaluator       = new ExprDotEvalStreamEventBean(this, prefixedStreamNumber, eventTypeMethodChain);
                    _streamNumReferenced = prefixedStreamNumber;
                }

                if (_exprEvaluator != null)
                {
                    return(null);
                }
                else
                {
                    if (ExprDotNodeUtility.IsDatetimeOrEnumMethod(remainderChain[0].Name))
                    {
                        prefixedStreamNumException = enumDatetimeEx;
                    }
                    else
                    {
                        prefixedStreamNumException = new ExprValidationException("Failed to solve '" + remainderChain[0].Name + "' to either a date-time or enumeration method, an event property or a method on the event underlying object: " + methodEx.Message, methodEx);
                    }
                }
            }

            // There no root node, in this case the classname or property name is provided as part of the chain.
            // Such as "MyClass.myStaticLib(...)" or "mycollectionproperty.doIt(...)"
            //
            IList <ExprChainedSpec> modifiedChain = new List <ExprChainedSpec>(_chainSpec);
            ExprChainedSpec         firstItem     = modifiedChain.Delete(0);

            Pair <PropertyResolutionDescriptor, string> propertyInfoPairX = null;

            try {
                propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, firstItem.Name, streamTypeService.HasPropertyAgnosticType, true);
            }
            catch (ExprValidationPropertyException) {
                // not a property
            }

            // If property then treat it as such
            if (propertyInfoPairX != null)
            {
                string    propertyName = propertyInfoPairX.First.PropertyName;
                int       streamId     = propertyInfoPairX.First.StreamNum;
                EventType streamType   = streamTypeService.EventTypes[streamId];
                EPType    typeInfo;
                ExprEvaluatorEnumeration enumerationEval = null;
                EPType              inputType;
                ExprEvaluator       rootNodeEvaluator = null;
                EventPropertyGetter getter;

                if (firstItem.Parameters.IsEmpty())
                {
                    getter = streamType.GetGetter(propertyInfoPairX.First.PropertyName);

                    ExprDotEnumerationSourceForProps propertyEval = ExprDotNodeUtility.GetPropertyEnumerationSource(
                        propertyInfoPairX.First.PropertyName, streamId, streamType, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache);
                    typeInfo          = propertyEval.ReturnType;
                    enumerationEval   = propertyEval.Enumeration;
                    inputType         = propertyEval.ReturnType;
                    rootNodeEvaluator = new PropertyExprEvaluatorNonLambda(streamId, getter, propertyInfoPairX.First.PropertyType);
                }
                else
                {
                    // property with parameter - mapped or indexed property
                    EventPropertyDescriptor desc = EventTypeUtility.GetNestablePropertyDescriptor(streamTypeService.EventTypes[propertyInfoPairX.First.StreamNum], firstItem.Name);
                    if (firstItem.Parameters.Count > 1)
                    {
                        throw new ExprValidationException("Property '" + firstItem.Name + "' may not be accessed passing 2 or more parameters");
                    }
                    ExprEvaluator paramEval = firstItem.Parameters[0].ExprEvaluator;
                    typeInfo  = EPTypeHelper.SingleValue(desc.PropertyComponentType);
                    inputType = typeInfo;
                    getter    = null;
                    if (desc.IsMapped)
                    {
                        if (paramEval.ReturnType != typeof(string))
                        {
                            throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a string-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty());
                        }
                        EventPropertyGetterMapped mappedGetter = propertyInfoPairX.First.StreamEventType.GetGetterMapped(propertyInfoPairX.First.PropertyName);
                        if (mappedGetter == null)
                        {
                            throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }
                        rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaMapped(streamId, mappedGetter, paramEval, desc.PropertyComponentType);
                    }
                    if (desc.IsIndexed)
                    {
                        if (paramEval.ReturnType.GetBoxedType() != typeof(int?))
                        {
                            throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a Integer-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty());
                        }
                        EventPropertyGetterIndexed indexedGetter = propertyInfoPairX.First.StreamEventType.GetGetterIndexed(propertyInfoPairX.First.PropertyName);
                        if (indexedGetter == null)
                        {
                            throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }
                        rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaIndexed(streamId, indexedGetter, paramEval, desc.PropertyComponentType);
                    }
                }
                if (typeInfo == null)
                {
                    throw new ExprValidationException("Property '" + propertyName + "' is not a mapped or indexed property");
                }

                // try to build chain based on the input (non-fragment)
                ExprDotNodeRealizedChain           evals;
                ExprDotNodeFilterAnalyzerInputProp filterAnalyzerInputProp = new ExprDotNodeFilterAnalyzerInputProp(propertyInfoPairX.First.StreamNum, propertyInfoPairX.First.PropertyName);
                bool rootIsEventBean = false;
                try {
                    evals = ExprDotNodeUtility.GetChainEvaluators(streamId, inputType, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp);
                }
                catch (ExprValidationException ex) {
                    // try building the chain based on the fragment event type (i.e. A.after(B) based on A-configured start time where A is a fragment)
                    FragmentEventType fragment = propertyInfoPairX.First.FragmentEventType;
                    if (fragment == null)
                    {
                        throw;
                    }

                    EPType fragmentTypeInfo;
                    if (fragment.IsIndexed)
                    {
                        fragmentTypeInfo = EPTypeHelper.CollectionOfEvents(fragment.FragmentType);
                    }
                    else
                    {
                        fragmentTypeInfo = EPTypeHelper.SingleEvent(fragment.FragmentType);
                    }

                    rootIsEventBean   = true;
                    evals             = ExprDotNodeUtility.GetChainEvaluators(propertyInfoPairX.First.StreamNum, fragmentTypeInfo, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp);
                    rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaFragment(streamId, getter, fragment.FragmentType.UnderlyingType);
                }

                _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumerationEval, inputType, evals.Chain, evals.ChainWithUnpack, !rootIsEventBean);
                _exprDotNodeFilterAnalyzerDesc = evals.FilterAnalyzerDesc;
                _streamNumReferenced           = propertyInfoPairX.First.StreamNum;
                _rootPropertyName = propertyInfoPairX.First.PropertyName;
                return(null);
            }

            // If variable then resolve as such
            string contextNameVariable = validationContext.VariableService.IsContextVariable(firstItem.Name);

            if (contextNameVariable != null)
            {
                throw new ExprValidationException("Method invocation on context-specific variable is not supported");
            }
            VariableReader variableReader = validationContext.VariableService.GetReader(firstItem.Name, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);

            if (variableReader != null)
            {
                EPType typeInfo;
                ExprDotStaticMethodWrap wrap;
                if (variableReader.VariableMetaData.VariableType.IsArray)
                {
                    typeInfo = EPTypeHelper.CollectionOfSingleValue(variableReader.VariableMetaData.VariableType.GetElementType());
                    wrap     = new ExprDotStaticMethodWrapArrayScalar(variableReader.VariableMetaData.VariableName, variableReader.VariableMetaData.VariableType.GetElementType());
                }
                else if (variableReader.VariableMetaData.EventType != null)
                {
                    typeInfo = EPTypeHelper.SingleEvent(variableReader.VariableMetaData.EventType);
                    wrap     = null;
                }
                else
                {
                    typeInfo = EPTypeHelper.SingleValue(variableReader.VariableMetaData.VariableType);
                    wrap     = null;
                }

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());
                _exprEvaluator = new ExprDotEvalVariable(this, variableReader, wrap, evals.ChainWithUnpack);
                return(null);
            }

            // try resolve as enumeration class with value
            object enumconstant = TypeHelper.ResolveIdentAsEnumConst(firstItem.Name, validationContext.EngineImportService, false);

            if (enumconstant != null)
            {
                // try resolve method
                ExprChainedSpec methodSpec = modifiedChain[0];
                string          enumvalue  = firstItem.Name;
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler
                {
                    ProcHandle = ex => new ExprValidationException("Failed to resolve method '" + methodSpec.Name + "' on enumeration value '" + enumvalue + "': " + ex.Message),
                };
                EventType wildcardType            = validationContext.StreamTypeService.EventTypes.Length != 1 ? null : validationContext.StreamTypeService.EventTypes[0];
                ExprNodeUtilMethodDesc methodDesc =
                    ExprNodeUtility.ResolveMethodAllowWildcardAndStream(
                        enumconstant.GetType().Name, enumconstant.GetType(), methodSpec.Name, methodSpec.Parameters,
                        validationContext.EngineImportService, validationContext.EventAdapterService,
                        validationContext.StatementId, wildcardType != null, wildcardType, handler, methodSpec.Name,
                        validationContext.TableService);

                // method resolved, hook up
                modifiedChain.RemoveAt(0);        // we identified this piece
                ExprDotStaticMethodWrap optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make(methodDesc.ReflectionMethod, validationContext.EventAdapterService, modifiedChain);
                EPType typeInfo = optionalLambdaWrap != null ? optionalLambdaWrap.TypeInfo : EPTypeHelper.SingleValue(methodDesc.FastMethod.ReturnType);

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());
                _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, methodDesc.FastMethod,
                                                             methodDesc.ChildEvals, false, optionalLambdaWrap, evals.ChainWithUnpack, false, enumconstant);
                return(null);
            }

            // if prefixed by a stream name, we are giving up
            if (prefixedStreamNumException != null)
            {
                throw prefixedStreamNumException;
            }

            // If class then resolve as class
            ExprChainedSpec secondItem = modifiedChain.Delete(0);

            bool      allowWildcard  = validationContext.StreamTypeService.EventTypes.Length == 1;
            EventType streamZeroType = null;

            if (validationContext.StreamTypeService.EventTypes.Length > 0)
            {
                streamZeroType = validationContext.StreamTypeService.EventTypes[0];
            }

            ExprNodeUtilMethodDesc method = ExprNodeUtility.ResolveMethodAllowWildcardAndStream(
                firstItem.Name, null, secondItem.Name, secondItem.Parameters, validationContext.EngineImportService,
                validationContext.EventAdapterService, validationContext.StatementId, allowWildcard, streamZeroType,
                new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name + "." + secondItem.Name, false),
                secondItem.Name, validationContext.TableService);

            bool isConstantParameters = method.IsAllConstants && _isUDFCache;

            _isReturnsConstantResult = isConstantParameters && modifiedChain.IsEmpty();

            // this may return a pair of null if there is no lambda or the result cannot be wrapped for lambda-function use
            ExprDotStaticMethodWrap optionalLambdaWrapX = ExprDotStaticMethodWrapFactory.Make(method.ReflectionMethod, validationContext.EventAdapterService, modifiedChain);
            EPType typeInfoX = optionalLambdaWrapX != null ? optionalLambdaWrapX.TypeInfo : EPTypeHelper.SingleValue(method.ReflectionMethod.ReturnType);

            ExprDotNodeRealizedChain evalsX = ExprDotNodeUtility.GetChainEvaluators(null, typeInfoX, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());

            _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, method.FastMethod, method.ChildEvals, isConstantParameters, optionalLambdaWrapX, evalsX.ChainWithUnpack, false, null);
            return(null);
        }
示例#3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ExprDotNodeRealizedChain"/> class.
 /// </summary>
 /// <param name="chain">The chain.</param>
 /// <param name="chainWithUnpack">The chain with unpack.</param>
 /// <param name="filterAnalyzerDesc">The filter analyzer desc.</param>
 public ExprDotNodeRealizedChain(ExprDotEval[] chain, ExprDotEval[] chainWithUnpack, ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc)
 {
     Chain              = chain;
     ChainWithUnpack    = chainWithUnpack;
     FilterAnalyzerDesc = filterAnalyzerDesc;
 }
示例#4
0
        public static ExprDotEvalDTMethodDesc ValidateMake(
            StreamTypeService streamTypeService,
            Deque <ExprChainedSpec> chainSpecStack,
            DatetimeMethodEnum dtMethod,
            String dtMethodName,
            EPType inputType,
            IList <ExprNode> parameters,
            ExprDotNodeFilterAnalyzerInput inputDesc,
            TimeZoneInfo timeZone)
        {
            // verify input
            String message = "Date-time enumeration method '" + dtMethodName +
                             "' requires either a DateTime or long value as input or events of an event type that declares a timestamp property";

            if (inputType is EventEPType)
            {
                if (((EventEPType)inputType).EventType.StartTimestampPropertyName == null)
                {
                    throw new ExprValidationException(message);
                }
            }
            else
            {
                if (!(inputType is ClassEPType || inputType is NullEPType))
                {
                    throw new ExprValidationException(message + " but received " + EPTypeHelper.ToTypeDescriptive(inputType));
                }
                if (inputType is ClassEPType)
                {
                    ClassEPType classEPType = (ClassEPType)inputType;
                    if (!TypeHelper.IsDateTime(classEPType.Clazz))
                    {
                        throw new ExprValidationException(
                                  message + " but received " + classEPType.Clazz.GetTypeNameFullyQualPretty());
                    }
                }
            }

            IList <CalendarOp> calendarOps       = new List <CalendarOp>();
            ReformatOp         reformatOp        = null;
            IntervalOp         intervalOp        = null;
            DatetimeMethodEnum currentMethod     = dtMethod;
            IList <ExprNode>   currentParameters = parameters;
            String             currentMethodName = dtMethodName;

            // drain all calendar ops
            ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc = null;

            while (true)
            {
                // handle the first one only if its a calendar op
                var evaluators = GetEvaluators(currentParameters);
                var opFactory  = currentMethod.MetaData().OpFactory;

                // compile parameter abstract for validation against available footprints
                var footprintProvided = DotMethodUtil.GetProvidedFootprint(currentParameters);

                // validate parameters
                DotMethodUtil.ValidateParametersDetermineFootprint(
                    currentMethod.Footprints(),
                    DotMethodTypeEnum.DATETIME,
                    currentMethodName, footprintProvided,
                    DotMethodInputTypeMatcherImpl.DEFAULT_ALL);

                if (opFactory is CalendarOpFactory)
                {
                    CalendarOp calendarOp = ((CalendarOpFactory)opFactory).GetOp(currentMethod, currentMethodName, currentParameters, evaluators);
                    calendarOps.Add(calendarOp);
                }
                else if (opFactory is ReformatOpFactory)
                {
                    reformatOp = ((ReformatOpFactory)opFactory).GetOp(timeZone, currentMethod, currentMethodName, currentParameters);

                    // compile filter analyzer information if there are no calendar ops in the chain
                    if (calendarOps.IsEmpty())
                    {
                        filterAnalyzerDesc = reformatOp.GetFilterDesc(streamTypeService.EventTypes, currentMethod, currentParameters, inputDesc);
                    }
                    else
                    {
                        filterAnalyzerDesc = null;
                    }
                }
                else if (opFactory is IntervalOpFactory)
                {
                    intervalOp = ((IntervalOpFactory)opFactory).GetOp(streamTypeService, currentMethod, currentMethodName, currentParameters, evaluators);

                    // compile filter analyzer information if there are no calendar ops in the chain
                    if (calendarOps.IsEmpty())
                    {
                        filterAnalyzerDesc = intervalOp.GetFilterDesc(streamTypeService.EventTypes, currentMethod, currentParameters, inputDesc);
                    }
                    else
                    {
                        filterAnalyzerDesc = null;
                    }
                }
                else
                {
                    throw new IllegalStateException("Invalid op factory class " + opFactory);
                }

                // see if there is more
                if (chainSpecStack.IsEmpty() || !DatetimeMethodEnumExtensions.IsDateTimeMethod(chainSpecStack.First.Name))
                {
                    break;
                }

                // pull next
                var next = chainSpecStack.RemoveFirst();
                currentMethod     = DatetimeMethodEnumExtensions.FromName(next.Name);
                currentParameters = next.Parameters;
                currentMethodName = next.Name;

                if ((reformatOp != null || intervalOp != null))
                {
                    throw new ExprValidationException("Invalid input for date-time method '" + next.Name + "'");
                }
            }

            ExprDotEval dotEval;
            EPType      returnType;

            dotEval    = new ExprDotEvalDT(calendarOps, timeZone, reformatOp, intervalOp, EPTypeHelper.GetClassSingleValued(inputType), EPTypeHelper.GetEventTypeSingleValued(inputType));
            returnType = dotEval.TypeInfo;
            return(new ExprDotEvalDTMethodDesc(dotEval, returnType, filterAnalyzerDesc));
        }
示例#5
0
 public ExprDotEvalDTMethodDesc(ExprDotEval eval, EPType returnType, ExprDotNodeFilterAnalyzerDesc intervalFilterDesc)
 {
     Eval               = eval;
     ReturnType         = returnType;
     IntervalFilterDesc = intervalFilterDesc;
 }