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; }
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); }