public LogicalChannelBinding( LogicalChannel logicalChannel, LogicalChannelBindingMethodDesc consumingBindingDesc, LogicalChannelBindingMethodDesc consumingSignalBindingDesc) { LogicalChannel = logicalChannel; ConsumingBindingDesc = consumingBindingDesc; ConsumingSignalBindingDesc = consumingSignalBindingDesc; }
private static LogicalChannelBindingMethodDesc FindMatchingMethod( string operatorName, Type target, LogicalChannel channelDesc, bool isPunctuation) { if (isPunctuation) { foreach (var method in target.GetMethods()) { if (method.Name.Equals("OnSignal")) { return new LogicalChannelBindingMethodDesc(method, LogicalChannelBindingTypePassAlong.INSTANCE); } } return null; } var outputPort = channelDesc.OutputPort; Type[] expectedIndividual; Type expectedUnderlying; EventType expectedUnderlyingType; var typeDesc = outputPort.GraphTypeDesc; if (typeDesc.IsWildcard) { expectedIndividual = new Type[0]; expectedUnderlying = null; expectedUnderlyingType = null; } else { expectedIndividual = new Type[typeDesc.EventType.PropertyNames.Length]; var i = 0; foreach (var descriptor in typeDesc.EventType.PropertyDescriptors) { expectedIndividual[i] = descriptor.PropertyType; i++; } expectedUnderlying = typeDesc.EventType.UnderlyingType; expectedUnderlyingType = typeDesc.EventType; } string channelSpecificMethodName = null; if (channelDesc.ConsumingOptStreamAliasName != null) { channelSpecificMethodName = "On" + channelDesc.ConsumingOptStreamAliasName; } var methods = target.GetMethods(); foreach (var method in methods) { var eligible = method.Name.Equals("OnInput"); if (!eligible && method.Name.Equals(channelSpecificMethodName)) { eligible = true; } if (!eligible) { continue; } // handle Object[] var paramTypes = method.GetParameterTypes(); var numParams = paramTypes.Length; if (expectedUnderlying != null) { if (numParams == 1 && TypeHelper.IsAssignmentCompatible(expectedUnderlying, paramTypes[0])) { return new LogicalChannelBindingMethodDesc( method, LogicalChannelBindingTypePassAlong.INSTANCE); } if (numParams == 2 && paramTypes[0].GetBoxedType() == typeof(int?) && TypeHelper.IsAssignmentCompatible(expectedUnderlying, paramTypes[1])) { return new LogicalChannelBindingMethodDesc( method, new LogicalChannelBindingTypePassAlongWStream(channelDesc.ConsumingOpStreamNum)); } } if (numParams == 1 && (paramTypes[0] == typeof(object) || paramTypes[0] == typeof(object[]) && method.IsVarArgs())) { return new LogicalChannelBindingMethodDesc( method, LogicalChannelBindingTypePassAlong.INSTANCE); } if (numParams == 2 && paramTypes[0] == typeof(int) && (paramTypes[1] == typeof(object) || paramTypes[1] == typeof(object[]) && method.IsVarArgs())) { return new LogicalChannelBindingMethodDesc( method, new LogicalChannelBindingTypePassAlongWStream(channelDesc.ConsumingOpStreamNum)); } // if exposing a method that exactly matches each property type in order, use that, i.e. "onInut(String p0, int p1)" if (expectedUnderlyingType is ObjectArrayEventType && TypeHelper.IsSignatureCompatible(expectedIndividual, paramTypes)) { return new LogicalChannelBindingMethodDesc(method, LogicalChannelBindingTypeUnwind.INSTANCE); } } ISet<string> choices = new LinkedHashSet<string>(); choices.Add(typeof(object).Name); choices.Add("Object[]"); if (expectedUnderlying != null) { choices.Add(expectedUnderlying.Name); } throw new ExprValidationException( "Failed to find OnInput method on for operator '" + operatorName + "' class " + target.Name + ", expected an OnInput method that takes any of {" + CollectionUtil.ToString(choices) + "}"); }