public override IList<StmtClassForgeableFactory> Validate(
            StreamTypeService typeService,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            // validate and visit
            var validationContext = new ExprValidationContextBuilder(typeService, @base.StatementRawInfo, services)
                .WithAllowBindingConsumption(true)
                .Build();

            var visitor = new ExprNodeIdentifierAndStreamRefVisitor(true);
            var validatedInputParameters = new List<ExprNode>();

            foreach (var exprNode in methodStreamSpec.Expressions) {
                var validated = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.METHODINVJOIN,
                    exprNode,
                    validationContext);
                validatedInputParameters.Add(validated);
                validated.Accept(visitor);
            }

            // determine required streams
            foreach (ExprNodePropOrStreamDesc @ref in visitor.Refs) {
                SubordinateStreams.Add(@ref.StreamNum);
            }

            // class-based evaluation
            MethodInfo targetMethod = null;
            if (metadata.MethodProviderClass != null) {
                // resolve actual method to use
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler {
                    ProcHandle = e => {
                        if (methodStreamSpec.Expressions.Count == 0) {
                            return new ExprValidationException(
                                "Method footprint does not match the number or type of expression parameters, expecting no parameters in method: " +
                                e.Message);
                        }

                        var resultTypes = ExprNodeUtilityQuery.GetExprResultTypes(validatedInputParameters);
                        return new ExprValidationException(
                            "Method footprint does not match the number or type of expression parameters, expecting a method where parameters are typed '" +
                            TypeHelper.GetParameterAsString(resultTypes) +
                            "': " +
                            e.Message);
                    }
                };
                var desc = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                    metadata.MethodProviderClass.FullName,
                    metadata.IsStaticMethod ? null : metadata.MethodProviderClass,
                    methodStreamSpec.MethodName,
                    validatedInputParameters,
                    false,
                    null,
                    handler,
                    methodStreamSpec.MethodName,
                    @base.StatementRawInfo,
                    services);
                InputParamEvaluators = desc.ChildForges;
                targetMethod = desc.ReflectionMethod;
            }
            else {
                // script-based evaluation
                InputParamEvaluators = ExprNodeUtilityQuery.GetForges(ExprNodeUtilityQuery.ToArray(validatedInputParameters));
            }
            
            // plan multikey
            MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKey(InputParamEvaluators, false, @base.StatementRawInfo, services.SerdeResolver);
            MultiKeyClassRef = multiKeyPlan.ClassRef;

            Pair<MethodTargetStrategyForge, MethodConversionStrategyForge> strategies =
                PollExecStrategyPlanner.Plan(metadata, targetMethod, EventType);
            target = strategies.First;
            conversion = strategies.Second;
            
            return multiKeyPlan.MultiKeyForgeables;
        }
Exemplo n.º 2
0
        public static Pair<MethodTargetStrategyForge, MethodConversionStrategyForge> Plan(
            MethodPollingViewableMeta metadata,
            MethodInfo targetMethod,
            EventType eventType)
        {
            MethodTargetStrategyForge target = null;
            MethodConversionStrategyForge conversion = null;

            // class-based evaluation
            if (metadata.MethodProviderClass != null) {
                // Construct polling strategy as a method invocation
                MethodPollingExecStrategyEnum strategy = metadata.Strategy;
                VariableMetaData variable = metadata.Variable;
                if (variable == null) {
                    target = new MethodTargetStrategyStaticMethodForge(metadata.MethodProviderClass, targetMethod);
                }
                else {
                    target = new MethodTargetStrategyVariableForge(variable, targetMethod);
                }

                if (metadata.EventTypeEventBeanArray != null) {
                    conversion = new MethodConversionStrategyForge(
                        eventType,
                        typeof(MethodConversionStrategyEventBeans));
                }
                else if (metadata.OptionalMapType != null) {
                    if (targetMethod.ReturnType.IsArray) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyArrayMap));
                    }
                    else if (metadata.IsCollection) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyCollectionMap));
                    }
                    else if (metadata.IsIterator) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyIteratorMap));
                    }
                    else {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyPlainMap));
                    }
                }
                else if (metadata.OptionalOaType != null) {
                    if (targetMethod.ReturnType == typeof(object[][])) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyArrayOA));
                    }
                    else if (metadata.IsCollection) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyCollectionOA));
                    }
                    else if (metadata.IsIterator) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyIteratorOA));
                    }
                    else {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyPlainOA));
                    }
                }
                else {
                    if (targetMethod.ReturnType.IsArray) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyArrayPONO));
                    }
                    else if (metadata.IsCollection) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyCollectionPONO));
                    }
                    else if (metadata.IsIterator) {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyIteratorPONO));
                    }
                    else {
                        conversion = new MethodConversionStrategyForge(
                            eventType,
                            typeof(MethodConversionStrategyPlainPONO));
                    }
                }
            }
            else {
                target = new MethodTargetStrategyScriptForge(metadata.ScriptExpression);
                conversion = new MethodConversionStrategyForge(eventType, typeof(MethodConversionStrategyScript));
            }

            return new Pair<MethodTargetStrategyForge, MethodConversionStrategyForge>(target, conversion);
        }