Beispiel #1
0
 public ExprEvalEnumerationAtBeanSingleForge(
     ExprEnumerationForge enumerationForge,
     EventType eventTypeSingle)
 {
     this.enumerationForge = enumerationForge;
     this.eventTypeSingle = eventTypeSingle;
 }
Beispiel #2
0
 public ExprEvalEnumerationAtBeanColl(
     ExprEnumerationForge enumerationForge,
     EventType eventTypeColl)
 {
     this.enumerationForge = enumerationForge;
     this.eventTypeColl = eventTypeColl;
 }
Beispiel #3
0
 public ExprEvalEnumerationAtBeanCollTable(
     ExprEnumerationForge enumerationForge,
     TableMetaData table)
 {
     this.enumerationForge = enumerationForge;
     this.table = table;
 }
Beispiel #4
0
        public ExprDotNodeForgeRootChild(
            ExprDotNodeImpl parent,
            FilterExprAnalyzerAffector filterExprAnalyzerAffector,
            int? streamNumReferenced,
            string rootPropertyName,
            bool hasEnumerationMethod,
            ExprForge rootNodeForge,
            ExprEnumerationForge rootLambdaEvaluator,
            EPType typeInfo,
            ExprDotForge[] forgesIteratorEventBean,
            ExprDotForge[] forgesUnpacking,
            bool checkedUnpackEvent)
        {
            Parent = parent;
            FilterExprAnalyzerAffector = filterExprAnalyzerAffector;
            StreamNumReferenced = streamNumReferenced;
            RootPropertyName = rootPropertyName;
            if (rootLambdaEvaluator != null) {
                if (typeInfo is EventMultiValuedEPType eventMultiValuedEpType) {
                    innerForge = new InnerDotEnumerableEventCollectionForge(
                        rootLambdaEvaluator,
                        eventMultiValuedEpType.Component);
                }
                else if (typeInfo is EventEPType eventEpType) {
                    innerForge = new InnerDotEnumerableEventBeanForge(
                        rootLambdaEvaluator,
                        eventEpType.EventType);
                }
                else {
                    innerForge = new InnerDotEnumerableScalarCollectionForge(
                        rootLambdaEvaluator,
                        ((ClassMultiValuedEPType) typeInfo).Component);
                }
            }
            else {
                if (checkedUnpackEvent) {
                    innerForge = new InnerDotScalarUnpackEventForge(rootNodeForge);
                }
                else {
                    var returnType = rootNodeForge.EvaluationType;
                    if (hasEnumerationMethod && returnType.IsArray) {
                        if (returnType.GetElementType().CanNotBeNull()) {
                            innerForge = new InnerDotArrPrimitiveToCollForge(rootNodeForge);
                        }
                        else {
                            innerForge = new InnerDotArrObjectToCollForge(rootNodeForge);
                        }
                    }
                    else if (hasEnumerationMethod && returnType.IsGenericCollection()) {
                        innerForge = new InnerDotCollForge(rootNodeForge);
                    }
                    else {
                        innerForge = new InnerDotScalarForge(rootNodeForge);
                    }
                }
            }

            this.forgesUnpacking = forgesUnpacking;
            this.forgesIteratorEventBean = forgesIteratorEventBean;
        }
Beispiel #5
0
 public InnerDotEnumerableScalarCollectionForge(
     ExprEnumerationForge rootLambdaForge,
     Type componentType)
 {
     this.rootLambdaForge = rootLambdaForge;
     this.componentType = componentType;
 }
 public InnerDotEnumerableEventBeanForge(
     ExprEnumerationForge rootLambdaForge,
     EventType eventType)
 {
     this.rootLambdaForge = rootLambdaForge;
     this.eventType = eventType;
 }
 public ExprEvalEnumerationSingleToCollForge(
     ExprEnumerationForge enumerationForge,
     EventType targetType)
 {
     this._ = enumerationForge;
     this._targetType = targetType;
 }
Beispiel #8
0
 public EnumExceptForge(
     int numStreams,
     ExprEnumerationForge evaluatorForge,
     bool scalar)
 {
     StreamNumSize = numStreams;
     this.evaluatorForge = evaluatorForge;
     this.scalar = scalar;
 }
 public ExprDotEnumerationSourceForgeForProps(
     ExprEnumerationForge enumeration,
     EPType returnType,
     int? streamOfProviderIfApplicable,
     ExprEnumerationGivenEventForge enumerationGivenEvent)
     : base(returnType, streamOfProviderIfApplicable, enumeration)
 {
     EnumerationGivenEvent = enumerationGivenEvent;
 }
Beispiel #10
0
 public ExprEnumerationForgeDesc(
     ExprEnumerationForge forge,
     bool istreamOnly,
     int directIndexStreamNumber)
 {
     Forge = forge;
     IsIstreamOnly = istreamOnly;
     DirectIndexStreamNumber = directIndexStreamNumber;
 }
Beispiel #11
0
 public EnumUnionForge(
     int numStreams,
     ExprEnumerationForge evaluatorForge,
     bool scalar)
 {
     _numStreams = numStreams;
     this.evaluatorForge = evaluatorForge;
     this.scalar = scalar;
 }
Beispiel #12
0
 public ExprDotEnumerationSourceForge(
     EPType returnType,
     int? streamOfProviderIfApplicable,
     ExprEnumerationForge enumeration)
 {
     ReturnType = returnType;
     StreamOfProviderIfApplicable = streamOfProviderIfApplicable;
     Enumeration = enumeration;
 }
 public ExprEvalEnumerationCollForge(
     ExprEnumerationForge enumerationForge,
     EventType targetType,
     bool firstRowOnly)
 {
     this._enumerationForge = enumerationForge;
     this._targetType = targetType;
     this._firstRowOnly = firstRowOnly;
 }
Beispiel #14
0
 public EnumIntersectForge(
     int numStreams,
     ExprEnumerationForge evaluatorForge,
     bool scalar)
 {
     this.numStreams = numStreams;
     this.evaluatorForge = evaluatorForge;
     this.scalar = scalar;
 }
Beispiel #15
0
        public static ExprDotEnumerationSourceForge GetEnumerationSource(
            ExprNode inputExpression,
            StreamTypeService streamTypeService,
            bool hasEnumerationMethod,
            bool disablePropertyExpressionEventCollCache,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices compileTimeServices)
        {
            var rootNodeForge = inputExpression.Forge;
            ExprEnumerationForge rootLambdaForge = null;
            EPType info = null;

            if (rootNodeForge is ExprEnumerationForge) {
                rootLambdaForge = (ExprEnumerationForge) rootNodeForge;
                var eventTypeCollection =
                    rootLambdaForge.GetEventTypeCollection(statementRawInfo, compileTimeServices);
                if (eventTypeCollection != null) {
                    info = EPTypeHelper.CollectionOfEvents(eventTypeCollection);
                }

                if (info == null) {
                    var eventTypeSingle =
                        rootLambdaForge.GetEventTypeSingle(statementRawInfo, compileTimeServices);
                    if (eventTypeSingle != null) {
                        info = EPTypeHelper.SingleEvent(eventTypeSingle);
                    }
                }

                if (info == null) {
                    var componentType = rootLambdaForge.ComponentTypeCollection;
                    if (componentType != null) {
                        info = EPTypeHelper.CollectionOfSingleValue(
                            rootLambdaForge.ComponentTypeCollection,
                            typeof(ICollection<>).MakeGenericType(componentType));
                    }
                }

                if (info == null) {
                    rootLambdaForge = null; // not a lambda evaluator
                }
            }
            else if (inputExpression is ExprIdentNode) {
                var identNode = (ExprIdentNode) inputExpression;
                var streamId = identNode.StreamId;
                var streamType = streamTypeService.EventTypes[streamId];
                return GetPropertyEnumerationSource(
                    identNode.ResolvedPropertyName,
                    streamId,
                    streamType,
                    hasEnumerationMethod,
                    disablePropertyExpressionEventCollCache);
            }

            return new ExprDotEnumerationSourceForge(info, null, rootLambdaForge);
        }
Beispiel #16
0
        public ExprEvalStreamNumEnumCollForge(ExprEnumerationForge enumeration)
        {
            _enumeration = enumeration;

            // NOTE: the forge knows the type that needs to be rendered.  In Java, they use the
            //   generic "Collection" type which allows them to not specify which type of collection
            //   they are using.  In C# we have strong type checking which means we need to know.
            //   Unfortunately, this data is only known in the ExprForge.  Revisit this.

            _evaluationType = typeof(FlexCollection);
        }
Beispiel #17
0
        private bool IsEventProviding(
            ExprNode parameter,
            ExprValidationContext validationContext)
        {
            if (parameter is ExprEnumerationForgeProvider) {
                ExprEnumerationForgeProvider provider = (ExprEnumerationForgeProvider) parameter;
                ExprEnumerationForgeDesc desc = provider.GetEnumerationForge(
                    validationContext.StreamTypeService,
                    validationContext.ContextDescriptor);

                EventType eventType = desc?.Forge.GetEventTypeSingle(validationContext.StatementRawInfo, validationContext.StatementCompileTimeService);
                return eventType != null;
            }

            ExprForge forge = parameter.Forge;
            ExprEnumerationForge enumerationForge = forge as ExprEnumerationForge;
            return enumerationForge?.GetEventTypeSingle(
                validationContext.StatementRawInfo, validationContext.StatementCompileTimeService) != null;
        }
Beispiel #18
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            this.exprValidationContext = validationContext;

            var prototype = PrototypeWVisibility;
            if (prototype.IsAlias) {
                if (!ChainParameters.IsEmpty()) {
                    throw new ExprValidationException("Expression '" + prototype.Name + " is an expression-alias and does not allow parameters");
                }
                try {
                    ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.ALIASEXPRBODY,
                        ExpressionBodyCopy,
                        validationContext);
                }
                catch (ExprValidationException ex) {
                    var message = "Failed to validate expression alias '" + prototype.Name + "': " + ex.Message;
                    throw new ExprValidationException(message, ex);
                }

                forge = ExpressionBodyCopy.Forge;
                return null;
            }

            if (forge != null) {
                return null; // already evaluated
            }

            if (ChildNodes.Length > 0) {
                throw new IllegalStateException("Execution node has its own child nodes");
            }

            // validate chain
            IList<ExprNode> validated = new List<ExprNode>();
            foreach (var expr in ChainParameters) {
                validated.Add(
                    ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.DECLAREDEXPRPARAM,
                        expr,
                        validationContext));
            }

            ChainParameters = validated;

            // validate parameter count
            CheckParameterCount();

            // collect event and value (non-event) parameters
            List<int> valueParameters = new List<int>();
            List<int> eventParameters = new List<int>();
            for (int i = 0; i < prototype.ParametersNames.Length; i++) {
                ExprNode parameter = ChainParameters[i];
                if (parameter is ExprWildcard) {
                    if (validationContext.StreamTypeService.EventTypes.Length != 1) {
                        throw new ExprValidationException("Expression '" + prototype.Name + "' only allows a wildcard parameter if there is a single stream available, please use a stream or tag name instead");
                    }
                }
                if (IsEventProviding(parameter, validationContext)) {
                    eventParameters.Add(i);
                } else {
                    valueParameters.Add(i);
                }
            }

            // determine value event type for holding non-event parameter values, if any
            ObjectArrayEventType valueEventType = null;
            List<ExprNode> valueExpressions = new List<ExprNode>(valueParameters.Count);
            if (!valueParameters.IsEmpty()) {
                var valuePropertyTypes = new LinkedHashMap<string, object>();
                foreach (int index in valueParameters) {
                    String name = prototype.ParametersNames[index];
                    ExprNode expr = ChainParameters[index];
                    var result = Boxing.GetBoxedType(expr.Forge.EvaluationType);
                    valuePropertyTypes.Put(name, result);
                    valueExpressions.Add(expr);
                }

                valueEventType = ExprDotNodeUtility.MakeTransientOAType(
                    PrototypeWVisibility.Name,
                    valuePropertyTypes,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
            }

            // create context for expression body
            int numEventTypes = eventParameters.Count + (valueEventType == null ? 0 : 1);
            EventType[] eventTypes = new EventType[numEventTypes];
            String[] streamNames = new String[numEventTypes];
            bool[] isIStreamOnly = new bool[numEventTypes];
            ExprEnumerationForge[] eventEnumerationForges = new ExprEnumerationForge[numEventTypes];
            allStreamIdsMatch = true;

            int offsetEventType = 0;
            if (valueEventType != null) {
                offsetEventType = 1;
                eventTypes[0] = valueEventType;
                streamNames[0] = INTERNAL_VALUE_STREAMNAME;
                isIStreamOnly[0] = true;
                allStreamIdsMatch = false;
            }

            bool forceOptionalStream = false;
            foreach (int index in eventParameters) {
                ExprNode parameter = ChainParameters[index];
                streamNames[offsetEventType] = prototype.ParametersNames[index];
                int streamId;
                bool istreamOnlyFlag;
                ExprEnumerationForge forge;

                if (parameter is ExprEnumerationForgeProvider) {
                    ExprEnumerationForgeProvider enumerationForgeProvider = (ExprEnumerationForgeProvider) parameter;
                    ExprEnumerationForgeDesc desc = enumerationForgeProvider.GetEnumerationForge(
                        validationContext.StreamTypeService, validationContext.ContextDescriptor);
                    forge = desc.Forge;
                    streamId = desc.DirectIndexStreamNumber;
                    istreamOnlyFlag = desc.IsIstreamOnly;
                } else {
                    forge = (ExprEnumerationForge) parameter.Forge;
                    istreamOnlyFlag = false;
                    streamId = -1;
                    forceOptionalStream = true; // since they may return null, i.e. subquery returning no row or multiple rows etc.
                }

                isIStreamOnly[offsetEventType] = istreamOnlyFlag;
                eventEnumerationForges[offsetEventType] = forge;
                eventTypes[offsetEventType] = forge.GetEventTypeSingle(validationContext.StatementRawInfo, validationContext.StatementCompileTimeService);

                if (streamId != index) {
                    allStreamIdsMatch = false;
                }
                offsetEventType++;
            }

            var streamTypeService = validationContext.StreamTypeService;
            var optionalStream = forceOptionalStream || streamTypeService.IsOptionalStreams;
            var copyTypes = new StreamTypeServiceImpl(
                eventTypes,
                streamNames,
                isIStreamOnly,
                streamTypeService.IsOnDemandStreams,
                optionalStream);

            copyTypes.RequireStreamNames = true;

            // validate expression body in this context
            try {
                var expressionBodyContext = new ExprValidationContext(copyTypes, validationContext);
                ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.DECLAREDEXPRBODY,
                    ExpressionBodyCopy,
                    expressionBodyContext);
            }
            catch (ExprValidationException ex) {
                var message = "Failed to validate expression declaration '" + prototype.Name + "': " + ex.Message;
                throw new ExprValidationException(message, ex);
            }

            // analyze child node
            var summaryVisitor = new ExprNodeSummaryVisitor();
            ExpressionBodyCopy.Accept(summaryVisitor);
            var isCache = !(summaryVisitor.HasAggregation || summaryVisitor.HasPreviousPrior);
            isCache &= validationContext.StatementCompileTimeService.Configuration.Compiler.Execution
                .IsEnabledDeclaredExprValueCache;

            // determine a suitable evaluation
            var audit = AuditEnum.EXPRDEF.GetAudit(validationContext.Annotations) != null;
            var statementName = validationContext.StatementName;
            if (ExpressionBodyCopy.Forge.ForgeConstantType.IsConstant) {
                // pre-evaluated
                forge = new ExprDeclaredForgeConstant(
                    this,
                    ExpressionBodyCopy.Forge.EvaluationType,
                    prototype,
                    ExpressionBodyCopy.Forge.ExprEvaluator.Evaluate(null, true, null),
                    audit,
                    statementName);
            }
            else if (valueEventType == null &&
                     prototype.ParametersNames.Length == 0 ||
                     allStreamIdsMatch && prototype.ParametersNames.Length == streamTypeService.EventTypes.Length) {
                forge = new ExprDeclaredForgeNoRewrite(
                    this, ExpressionBodyCopy.Forge, isCache, audit, statementName);
            }
            else if (valueEventType == null) {
                forge = new ExprDeclaredForgeRewrite(
                    this, ExpressionBodyCopy.Forge, isCache, eventEnumerationForges, audit, statementName);
            }
            else {
                // cache is always false
                forge = new ExprDeclaredForgeRewriteWValue(
                    this, ExpressionBodyCopy.Forge, false, audit, statementName, eventEnumerationForges, valueEventType, valueExpressions);
            }

            return null;
        }
Beispiel #19
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            // check for plannable methods: these are validated according to different rules
            var appDotMethod = GetAppDotMethod(validationContext.IsFilterExpression);
            if (appDotMethod != null) {
                return appDotMethod;
            }

            // validate all parameters
            ExprNodeUtilityValidate.Validate(ExprNodeOrigin.DOTNODEPARAMETER, ChainSpec, validationContext);

            // determine if there are enumeration method expressions in the chain
            var hasEnumerationMethod = false;
            foreach (var chain in ChainSpec) {
                if (EnumMethodEnumExtensions.IsEnumerationMethod(chain.Name)) {
                    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.TableCompileTimeResolver != null &&
                ChainSpec.Count > 1 &&
                ChainSpec[0].IsProperty) {
                var tableNode = TableCompileTimeUtil.GetTableNodeChainable(
                    validationContext.StreamTypeService,
                    ChainSpec,
                    validationContext.ImportService,
                    validationContext.TableCompileTimeResolver);
                if (tableNode != null) {
                    var node = ExprNodeUtilityValidate.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
            //
            var streamTypeService = validationContext.StreamTypeService;
            if (ChildNodes.Length != 0) {
                // the root expression is the first child node
                var rootNode = ChildNodes[0];

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

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

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    enumSrc.StreamOfProviderIfApplicable,
                    typeInfoX,
                    ChainSpec,
                    validationContext,
                    isDuckTyping,
                    new ExprDotNodeFilterAnalyzerInputExpr());
                forge = new ExprDotNodeForgeRootChild(
                    this,
                    null,
                    null,
                    null,
                    hasEnumerationMethod,
                    rootNode.Forge,
                    enumSrc.Enumeration,
                    typeInfoX,
                    evalsX.Chain,
                    evalsX.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) {
                var spec = ChainSpec[0];
                if (spec.Parameters.IsEmpty()) {
                    throw HandleNotFound(spec.Name);
                }

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

                // if not a property then try built-in single-row non-grammar functions
                if (propertyInfoPairX == null &&
                    spec.Name.ToLowerInvariant()
                        .Equals(ImportServiceCompileTime.EXT_SINGLEROW_FUNCTION_TRANSPOSE)) {
                    if (spec.Parameters.Count != 1) {
                        throw new ExprValidationException(
                            "The " +
                            ImportServiceCompileTime.EXT_SINGLEROW_FUNCTION_TRANSPOSE +
                            " function requires a single parameter expression");
                    }

                    forge = new ExprDotNodeForgeTransposeAsStream(this, ChainSpec[0].Parameters[0].Forge);
                }
                else if (spec.Parameters.Count != 1) {
                    throw HandleNotFound(spec.Name);
                }
                else {
                    if (propertyInfoPairX == null) {
                        throw new ExprValidationException(
                            "Unknown single-row function, aggregation function or mapped or indexed property named '" +
                            spec.Name +
                            "' could not be resolved");
                    }

                    forge = GetPropertyPairEvaluator(spec.Parameters[0].Forge, propertyInfoPairX, validationContext);
                }

                return null;
            }

            // handle the case where the first chain spec element is a stream name.
            ExprValidationException prefixedStreamNumException = null;
            var prefixedStreamNumber = PrefixedStreamName(ChainSpec, validationContext.StreamTypeService);
            if (prefixedStreamNumber != -1) {
                var specAfterStreamName = ChainSpec[1];

                // Attempt to resolve as property
                Pair<PropertyResolutionDescriptor, string> propertyInfoPairX = null;
                try {
                    var propName = ChainSpec[0].Name + "." + specAfterStreamName.Name;
                    propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(
                        streamTypeService,
                        propName,
                        streamTypeService.HasPropertyAgnosticType,
                        false,
                        validationContext.TableCompileTimeResolver);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }

                if (propertyInfoPairX != null) {
                    if (specAfterStreamName.Parameters.Count != 1) {
                        throw HandleNotFound(specAfterStreamName.Name);
                    }

                    forge = GetPropertyPairEvaluator(
                        specAfterStreamName.Parameters[0].Forge,
                        propertyInfoPairX,
                        validationContext);
                    return null;
                }

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

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

                ExprValidationException methodEx = null;
                ExprDotForge[] underlyingMethodChain = null;
                try {
                    var typeInfoX = EPTypeHelper.SingleValue(type);
                    if (validationContext.TableCompileTimeResolver.ResolveTableFromEventType(eventType) != null) {
                        typeInfoX = new ClassEPType(typeof(object[]));
                    }

                    underlyingMethodChain = ExprDotNodeUtility.GetChainEvaluators(
                            prefixedStreamNumber,
                            typeInfoX,
                            remainderChain,
                            validationContext,
                            false,
                            new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber))
                        .ChainWithUnpack;
                }
                catch (ExprValidationException ex) {
                    methodEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

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

                if (underlyingMethodChain != null) {
                    forge = new ExprDotNodeForgeStream(
                        this,
                        filterExprAnalyzerAffector,
                        prefixedStreamNumber,
                        eventType,
                        underlyingMethodChain,
                        true);
                }
                else if (eventTypeMethodChain != null) {
                    forge = new ExprDotNodeForgeStream(
                        this,
                        filterExprAnalyzerAffector,
                        prefixedStreamNumber,
                        eventType,
                        eventTypeMethodChain,
                        false);
                }

                if (forge != null) {
                    return null;
                }

                if (ExprDotNodeUtility.IsDatetimeOrEnumMethod(remainderChain[0].Name)) {
                    prefixedStreamNumException = enumDatetimeEx;
                }
                else {
                    prefixedStreamNumException = new ExprValidationException(
                        "Failed to solve '" +
                        remainderChain[0].Name +
                        "' to either an 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);
            var firstItem = modifiedChain.DeleteAt(0);

            Pair<PropertyResolutionDescriptor, string> propertyInfoPair = null;
            try {
                propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(
                    streamTypeService,
                    firstItem.Name,
                    streamTypeService.HasPropertyAgnosticType,
                    true,
                    validationContext.TableCompileTimeResolver);
            }
            catch (ExprValidationPropertyException) {
                // not a property
            }

            // If property then treat it as such
            if (propertyInfoPair != null) {
                var propertyName = propertyInfoPair.First.PropertyName;
                var streamId = propertyInfoPair.First.StreamNum;
                var streamType = streamTypeService.EventTypes[streamId];
                EPType typeInfoX;
                ExprEnumerationForge enumerationForge = null;
                EPType inputType;
                ExprForge rootNodeForge = null;
                EventPropertyGetterSPI getter;

                if (firstItem.Parameters.IsEmpty()) {
                    getter = ((EventTypeSPI) streamType).GetGetterSPI(propertyInfoPair.First.PropertyName);

                    var propertyEval =
                        ExprDotNodeUtility.GetPropertyEnumerationSource(
                            propertyInfoPair.First.PropertyName,
                            streamId,
                            streamType,
                            hasEnumerationMethod,
                            validationContext.IsDisablePropertyExpressionEventCollCache);
                    typeInfoX = propertyEval.ReturnType;
                    enumerationForge = propertyEval.Enumeration;
                    inputType = propertyEval.ReturnType;
                    rootNodeForge = new PropertyDotNonLambdaForge(
                        streamId,
                        getter,
                        propertyInfoPair.First.PropertyType.GetBoxedType());
                }
                else {
                    // property with parameter - mapped or indexed property
                    var desc = EventTypeUtility.GetNestablePropertyDescriptor(
                        streamTypeService.EventTypes[propertyInfoPair.First.StreamNum],
                        firstItem.Name);
                    if (firstItem.Parameters.Count > 1) {
                        throw new ExprValidationException(
                            "Property '" + firstItem.Name + "' may not be accessed passing 2 or more parameters");
                    }

                    var paramEval = firstItem.Parameters[0].Forge;
                    typeInfoX = EPTypeHelper.SingleValue(desc.PropertyComponentType);
                    inputType = typeInfoX;
                    getter = null;
                    if (desc.IsMapped) {
                        if (paramEval.EvaluationType != typeof(string)) {
                            throw new ExprValidationException(
                                "Parameter expression to mapped property '" +
                                propertyName +
                                "' is expected to return a string-type value but returns " +
                                paramEval.EvaluationType.CleanName());
                        }

                        var mappedGetter =
                            ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterMappedSPI(
                                propertyInfoPair.First.PropertyName);
                        if (mappedGetter == null) {
                            throw new ExprValidationException(
                                "Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }

                        rootNodeForge = new PropertyDotNonLambdaMappedForge(
                            streamId,
                            mappedGetter,
                            paramEval,
                            desc.PropertyComponentType);
                    }

                    if (desc.IsIndexed) {
                        if (paramEval.EvaluationType.GetBoxedType() != typeof(int?)) {
                            throw new ExprValidationException(
                                "Parameter expression to mapped property '" +
                                propertyName +
                                "' is expected to return a Integer-type value but returns " +
                                paramEval.EvaluationType.CleanName());
                        }

                        var indexedGetter =
                            ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterIndexedSPI(
                                propertyInfoPair.First.PropertyName);
                        if (indexedGetter == null) {
                            throw new ExprValidationException(
                                "Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }

                        rootNodeForge = new PropertyDotNonLambdaIndexedForge(
                            streamId,
                            indexedGetter,
                            paramEval,
                            desc.PropertyComponentType);
                    }
                }

                if (typeInfoX == null) {
                    throw new ExprValidationException(
                        "Property '" + propertyName + "' is not a mapped or indexed property");
                }

                // try to build chain based on the input (non-fragment)
                ExprDotNodeRealizedChain evalsX;
                var filterAnalyzerInputProp = new ExprDotNodeFilterAnalyzerInputProp(
                    propertyInfoPair.First.StreamNum,
                    propertyInfoPair.First.PropertyName);
                var rootIsEventBean = false;
                try {
                    evalsX = ExprDotNodeUtility.GetChainEvaluators(
                        streamId,
                        inputType,
                        modifiedChain,
                        validationContext,
                        isDuckTyping,
                        filterAnalyzerInputProp);
                }
                catch (ExprValidationException) {
                    // 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)
                    var fragment = propertyInfoPair.First.FragmentEventType;
                    if (fragment == null) {
                        throw;
                    }

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

                    rootIsEventBean = true;
                    evalsX = ExprDotNodeUtility.GetChainEvaluators(
                        propertyInfoPair.First.StreamNum,
                        fragmentTypeInfo,
                        modifiedChain,
                        validationContext,
                        isDuckTyping,
                        filterAnalyzerInputProp);
                    rootNodeForge = new PropertyDotNonLambdaFragmentForge(streamId, getter);
                }

                var filterExprAnalyzerAffector = evalsX.FilterAnalyzerDesc;
                var streamNumReferenced = propertyInfoPair.First.StreamNum;
                var rootPropertyName = propertyInfoPair.First.PropertyName;
                forge = new ExprDotNodeForgeRootChild(
                    this,
                    filterExprAnalyzerAffector,
                    streamNumReferenced,
                    rootPropertyName,
                    hasEnumerationMethod,
                    rootNodeForge,
                    enumerationForge,
                    inputType,
                    evalsX.Chain,
                    evalsX.ChainWithUnpack,
                    !rootIsEventBean);
                return null;
            }

            // If variable then resolve as such
            var variable = validationContext.VariableCompileTimeResolver.Resolve(firstItem.Name);
            if (variable != null) {
                if (variable.OptionalContextName != null) {
                    throw new ExprValidationException(
                        "Method invocation on context-specific variable is not supported");
                }

                EPType typeInfoX;
                ExprDotStaticMethodWrap wrap;
                if (variable.Type.IsArray) {
                    typeInfoX = EPTypeHelper.CollectionOfSingleValue(
                        variable.Type.GetElementType(),
                        variable.Type);
                    wrap = new ExprDotStaticMethodWrapArrayScalar(variable.VariableName, variable.Type);
                }
                else if (variable.EventType != null) {
                    typeInfoX = EPTypeHelper.SingleEvent(variable.EventType);
                    wrap = null;
                }
                else {
                    typeInfoX = EPTypeHelper.SingleValue(variable.Type);
                    wrap = null;
                }

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    null,
                    typeInfoX,
                    modifiedChain,
                    validationContext,
                    false,
                    new ExprDotNodeFilterAnalyzerInputStatic());
                forge = new ExprDotNodeForgeVariable(this, variable, wrap, evalsX.ChainWithUnpack);
                return null;
            }

            // try resolve as enumeration class with value
            var enumconstant = ImportCompileTimeUtil.ResolveIdentAsEnumConst(
                firstItem.Name,
                validationContext.ImportService,
                false);
            if (enumconstant != null) {
                // try resolve method
                var methodSpec = modifiedChain[0];
                var enumvalue = firstItem.Name;
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler {
                    ProcHandle = ex => {
                        return new ExprValidationException(
                            "Failed to resolve method '" +
                            methodSpec.Name +
                            "' on enumeration value '" +
                            enumvalue +
                            "': " +
                            ex.Message);
                    }
                };
                var wildcardType = validationContext.StreamTypeService.EventTypes.Length != 1
                    ? null
                    : validationContext.StreamTypeService.EventTypes[0];
                var methodDesc = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                    enumconstant.GetType().Name,
                    enumconstant.GetType(),
                    methodSpec.Name,
                    methodSpec.Parameters,
                    wildcardType != null,
                    wildcardType,
                    handler,
                    methodSpec.Name,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);

                // method resolved, hook up
                modifiedChain.RemoveAt(0); // we identified this piece
                var optionalLambdaWrapX = ExprDotStaticMethodWrapFactory.Make(
                    methodDesc.ReflectionMethod,
                    modifiedChain,
                    null,
                    validationContext);
                var typeInfoX = optionalLambdaWrapX != null
                    ? optionalLambdaWrapX.TypeInfo
                    : EPTypeHelper.SingleValue(methodDesc.ReflectionMethod.ReturnType);

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    null,
                    typeInfoX,
                    modifiedChain,
                    validationContext,
                    false,
                    new ExprDotNodeFilterAnalyzerInputStatic());
                forge = new ExprDotNodeForgeStaticMethod(
                    this,
                    false,
                    firstItem.Name,
                    methodDesc.ReflectionMethod,
                    methodDesc.ChildForges,
                    false,
                    evalsX.ChainWithUnpack,
                    optionalLambdaWrapX,
                    false,
                    enumconstant,
                    validationContext.StatementName);
                return null;
            }

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

            // If class then resolve as class
            var secondItem = modifiedChain.DeleteAt(0);

            var allowWildcard = validationContext.StreamTypeService.EventTypes.Length == 1;
            EventType streamZeroType = null;
            if (validationContext.StreamTypeService.EventTypes.Length > 0) {
                streamZeroType = validationContext.StreamTypeService.EventTypes[0];
            }

            var method = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                firstItem.Name,
                null,
                secondItem.Name,
                secondItem.Parameters,
                allowWildcard,
                streamZeroType,
                new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name + "." + secondItem.Name, false),
                secondItem.Name,
                validationContext.StatementRawInfo,
                validationContext.StatementCompileTimeService);

            var isConstantParameters = method.IsAllConstants && isUDFCache;
            var 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
            var optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make(
                method.ReflectionMethod,
                modifiedChain,
                null,
                validationContext);
            var typeInfo = optionalLambdaWrap != null
                ? optionalLambdaWrap.TypeInfo
                : EPTypeHelper.SingleValue(method.ReflectionMethod.ReturnType);

            var evals = ExprDotNodeUtility.GetChainEvaluators(
                null,
                typeInfo,
                modifiedChain,
                validationContext,
                false,
                new ExprDotNodeFilterAnalyzerInputStatic());
            forge = new ExprDotNodeForgeStaticMethod(
                this,
                isReturnsConstantResult,
                firstItem.Name,
                method.ReflectionMethod,
                method.ChildForges,
                isConstantParameters,
                evals.ChainWithUnpack,
                optionalLambdaWrap,
                false,
                null,
                validationContext.StatementName);

            return null;
        }
Beispiel #20
0
 public ExprEvalStreamNumEnumSingleForge(ExprEnumerationForge enumeration)
 {
     this.enumeration = enumeration;
 }
Beispiel #21
0
        public static ExprDotEnumerationSourceForgeForProps GetPropertyEnumerationSource(
            string propertyName,
            int streamId,
            EventType streamType,
            bool allowEnumType,
            bool disablePropertyExpressionEventCollCache)
        {
            var propertyType = streamType.GetPropertyType(propertyName);
            var typeInfo = EPTypeHelper.SingleValue(propertyType); // assume scalar for now

            // no enumeration methods, no need to expose as an enumeration
            if (!allowEnumType) {
                return new ExprDotEnumerationSourceForgeForProps(null, typeInfo, streamId, null);
            }

            var fragmentEventType = streamType.GetFragmentType(propertyName);
            var getter = ((EventTypeSPI) streamType).GetGetterSPI(propertyName);

            ExprEnumerationForge enumEvaluator = null;
            if (getter != null && fragmentEventType != null) {
                if (fragmentEventType.IsIndexed) {
                    enumEvaluator = new PropertyDotEventCollectionForge(
                        propertyName,
                        streamId,
                        fragmentEventType.FragmentType,
                        getter,
                        disablePropertyExpressionEventCollCache);
                    typeInfo = EPTypeHelper.CollectionOfEvents(fragmentEventType.FragmentType);
                }
                else { // we don't want native to require an eventbean instance
                    enumEvaluator = new PropertyDotEventSingleForge(streamId, fragmentEventType.FragmentType, getter);
                    typeInfo = EPTypeHelper.SingleEvent(fragmentEventType.FragmentType);
                }
            }
            else {
                var desc = EventTypeUtility.GetNestablePropertyDescriptor(streamType, propertyName);
                if (desc != null && desc.IsIndexed && !desc.IsRequiresIndex && desc.PropertyComponentType != null) {
                    if (propertyType == typeof(string)) {
                        enumEvaluator = new PropertyDotScalarStringForge(
                            propertyName,
                            streamId,
                            getter);
                    }
                    else if (propertyType.IsArray) {
                        enumEvaluator = new PropertyDotScalarArrayForge(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType,
                            desc.PropertyType);
                    }
                    else if (propertyType.IsGenericCollection()) {
                        enumEvaluator = new PropertyDotScalarCollection(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType);
                    }
                    else if (propertyType.IsGenericEnumerable()) {
                        enumEvaluator = new PropertyDotScalarIterable(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType,
                            propertyType);
                    }
                    else {
                        throw new IllegalStateException(
                            "Property indicated indexed-type but failed to find proper collection adapter for use with enumeration methods");
                    }

                    typeInfo = EPTypeHelper.CollectionOfSingleValue(
                        desc.PropertyComponentType,
                        desc.PropertyType);
                }
            }

            return new ExprDotEnumerationSourceForgeForProps(
                enumEvaluator,
                typeInfo,
                streamId,
                (ExprEnumerationGivenEventForge) enumEvaluator);
        }