public void SetUp() { _eventService = SupportEventAdapterService.Service; EventType underlyingEventTypeSimple = _eventService.AddBeanType("UnderlyingSimpleBean", typeof(SupportBeanSimple), true, true, true); EventType underlyingEventTypeCombined = _eventService.AddBeanType("UnderlyingCombinedBean", typeof(SupportBeanCombinedProps), true, true, true); IDictionary <String, Object> typeMap = new Dictionary <String, Object>(); typeMap["string"] = typeof(string); typeMap["int"] = typeof(int); EventTypeMetadata meta = EventTypeMetadata.CreateWrapper("test", true, false, false); _eventTypeSimple = new WrapperEventType(meta, "mytype", 1, underlyingEventTypeSimple, typeMap, _eventService); _eventTypeCombined = new WrapperEventType(meta, "mytype", 1, underlyingEventTypeCombined, typeMap, _eventService); _properties = new Dictionary <String, Object>(); _properties["string"] = "xx"; _properties["int"] = 11; EventBean wrappedSimple = _eventService.AdapterForObject(new SupportBeanSimple("EventString", 0)); _eventBeanSimple = _eventService.AdapterForTypedWrapper(wrappedSimple, _properties, _eventTypeSimple); EventBean wrappedCombined = _eventService.AdapterForObject(SupportBeanCombinedProps.MakeDefaultBean()); _eventBeanCombined = _eventService.AdapterForTypedWrapper(wrappedCombined, _properties, _eventTypeCombined); }
public void AddEventType(string eventTypeName, string eventTypeTypeName) { CheckTableExists(eventTypeName); try { _eventAdapterService.AddBeanType(eventTypeName, eventTypeTypeName, false, false, true, true); } catch (EventAdapterException t) { throw new ConfigurationException(t.Message, t); } }
public static ExprDotStaticMethodWrap Make( MethodInfo method, EventAdapterService eventAdapterService, IList <ExprChainedSpec> modifiedChain, string optionalEventTypeName) { if (modifiedChain.IsEmpty() || (!modifiedChain[0].Name.IsEnumerationMethod())) { return(null); } if (method.ReturnType.IsArray) { var componentType = method.ReturnType.GetElementType(); if (componentType == typeof(EventBean)) { EventType eventType = RequireEventType(method, eventAdapterService, optionalEventTypeName); return(new ExprDotStaticMethodWrapEventBeanArr(eventType)); } if (componentType == null || componentType.IsBuiltinDataType()) { return(new ExprDotStaticMethodWrapArrayScalar(method.Name, componentType)); } var type = (BeanEventType)eventAdapterService.AddBeanType(componentType.GetDefaultTypeName(), componentType, false, false, false); return(new ExprDotStaticMethodWrapArrayEvents(eventAdapterService, type)); } #if DEFUNCT if (method.ReturnType.IsGenericCollection()) { var genericType = TypeHelper.GetGenericReturnType(method, true); if (genericType == null || genericType.IsBuiltinDataType()) { return(new ExprDotStaticMethodWrapCollection(method.Name, genericType)); } } #endif if (method.ReturnType.IsGenericEnumerable()) { var genericType = TypeHelper.GetGenericReturnType(method, true); if (genericType == typeof(EventBean)) { EventType eventType = RequireEventType(method, eventAdapterService, optionalEventTypeName); return(new ExprDotStaticMethodWrapEventBeanColl(eventType)); } if (genericType == null || genericType.IsBuiltinDataType()) { return(new ExprDotStaticMethodWrapIterableScalar(method.Name, genericType)); } var type = (BeanEventType)eventAdapterService.AddBeanType(genericType.GetDefaultTypeName(), genericType, false, false, false); return(new ExprDotStaticMethodWrapIterableEvents(eventAdapterService, type)); } return(null); }
public void SetUp() { _container = SupportContainer.Reset(); _eventSource = _container.Resolve <EventAdapterService>(); _types = new EventType[5]; _types[0] = _eventSource.AddBeanType("D1", typeof(SupportDeltaOne), false, false, false); _types[1] = _eventSource.AddBeanType("D2", typeof(SupportDeltaTwo), false, false, false); _types[2] = _eventSource.AddBeanType("D3", typeof(SupportDeltaThree), false, false, false); _types[3] = _eventSource.AddBeanType("D4", typeof(SupportDeltaFour), false, false, false); _types[4] = _eventSource.AddBeanType("D5", typeof(SupportDeltaFive), false, false, false); }
public static EPLTreeWalkerListener ParseAndWalkEPL(String expression, EngineImportService engineImportService, VariableService variableService) { Log.Debug(".parseAndWalk Trying text=" + expression); Pair <ITree, CommonTokenStream> ast = SupportParserHelper.ParseEPL(expression); Log.Debug(".parseAndWalk success, tree walking..."); SupportParserHelper.DisplayAST(ast.First); EventAdapterService eventAdapterService = SupportEventAdapterService.Service; eventAdapterService.AddBeanType("SupportBean_N", typeof(SupportBean_N), true, true, true); EPLTreeWalkerListener listener = SupportEPLTreeWalkerFactory.MakeWalker(ast.Second, engineImportService, variableService); ParseTreeWalker walker = new ParseTreeWalker(); // create standard walker walker.Walk(listener, (IParseTree)ast.First); // initiate walk of tree with listener return(listener); }
/// <summary> /// Creates an event type from the query meta data. /// </summary> /// <param name="statementId">The statement id.</param> /// <param name="streamNumber">The stream number.</param> /// <param name="queryMetaData">The query meta data.</param> /// <param name="eventAdapterService">The event adapter service.</param> /// <param name="databaseStreamSpec">The database stream spec.</param> /// <param name="columnTypeConversionHook">The column type conversion hook.</param> /// <param name="outputRowConversionHook">The output row conversion hook.</param> /// <returns></returns> private static EventType CreateEventType( int statementId, int streamNumber, QueryMetaData queryMetaData, EventAdapterService eventAdapterService, DBStatementStreamSpec databaseStreamSpec, Func <SQLColumnTypeContext, Type> columnTypeConversionHook, Func <SQLOutputRowTypeContext, Type> outputRowConversionHook) { var columnNum = 1; var eventTypeFields = new Dictionary <String, Object>(); foreach (var entry in queryMetaData.OutputParameters) { var name = entry.Key; var dbOutputDesc = entry.Value; Type clazz; if (dbOutputDesc.OptionalBinding != null) { clazz = dbOutputDesc.OptionalBinding.DataType; } else { clazz = dbOutputDesc.DataType; } if (columnTypeConversionHook != null) { var newValue = columnTypeConversionHook.Invoke( new SQLColumnTypeContext( databaseStreamSpec.DatabaseName, databaseStreamSpec.SqlWithSubsParams, name, clazz, dbOutputDesc.SqlType, columnNum)); if (newValue != null) { clazz = newValue; } } eventTypeFields[name] = clazz.GetBoxedType(); columnNum++; } EventType eventType; if (outputRowConversionHook == null) { var outputEventType = statementId + "_dbpoll_" + streamNumber; eventType = eventAdapterService.CreateAnonymousMapType(outputEventType, eventTypeFields, true); } else { var carrierClass = outputRowConversionHook.Invoke( new SQLOutputRowTypeContext( databaseStreamSpec.DatabaseName, databaseStreamSpec.SqlWithSubsParams, eventTypeFields)); if (carrierClass == null) { throw new ExprValidationException("Output row conversion hook returned no type"); } eventType = eventAdapterService.AddBeanType(carrierClass.FullName, carrierClass, false, false, false); } return(eventType); }
public EventPropertyGetterSPI GetGetterSPI(string propertyName) { var desc = _propertyDesc.Get(propertyName); if (desc != null) { return(desc.RevisionGetter); } // dynamic property names note allowed if (propertyName.IndexOf('?') != -1) { return(null); } // see if this is a nested property var index = ASTUtil.UnescapedIndexOfDot(propertyName); if (index == -1) { var prop = PropertyParser.ParseAndWalkLaxToSimple(propertyName); if (prop is SimpleProperty) { // there is no such property since it wasn't found earlier return(null); } string atomic = null; if (prop is IndexedProperty) { var indexedprop = (IndexedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } if (prop is MappedProperty) { var indexedprop = (MappedProperty)prop; atomic = indexedprop.PropertyNameAtomic; } desc = _propertyDesc.Get(atomic); if (desc == null) { return(null); } if (!(desc.PropertyType is Type)) { return(null); } var nestedClass = (Type)desc.PropertyType; var complexProperty = (BeanEventType)_eventAdapterService.AddBeanType(nestedClass.GetDefaultTypeName(), nestedClass, false, false, false); return(prop.GetGetter(complexProperty, _eventAdapterService)); } // Map event types allow 2 types of properties inside: // - a property that is a Java object is interrogated via bean property getters and BeanEventType // - a property that is a Map itself is interrogated via map property getters // Take apart the nested property into a map key and a nested value class property name var propertyMap = ASTUtil.UnescapeDot(propertyName.Substring(0, index)); var propertyNested = propertyName.Substring(index + 1); desc = _propertyDesc.Get(propertyMap); if (desc == null) { return(null); // prefix not a known property } // only nested classes supported for revision event types since deep property information not currently exposed by EventType if (desc.PropertyType is Type) { // ask the nested class to resolve the property var simpleClass = (Type)desc.PropertyType; var nestedEventType = (EventTypeSPI)_eventAdapterService.AddBeanType( simpleClass.Name, simpleClass, false, false, false); var nestedGetter = nestedEventType.GetGetterSPI(propertyNested); if (nestedGetter == null) { return(null); } // construct getter for nested property return(new RevisionNestedPropertyGetter(desc.RevisionGetter, nestedGetter, _eventAdapterService)); } else { return(null); } }
public void CreateNewVariable(string optionalContextName, string variableName, string variableType, bool constant, bool array, bool arrayOfPrimitive, object value, EngineImportService engineImportService) { // Determime the variable type var primitiveType = TypeHelper.GetPrimitiveTypeForName(variableType); var type = TypeHelper.GetTypeForSimpleName(variableType); Type arrayType = null; EventType eventType = null; if (type == null) { if (variableType.ToLower() == "object") { type = typeof(Object); } if (type == null) { eventType = _eventAdapterService.GetEventTypeByName(variableType); if (eventType != null) { type = eventType.UnderlyingType; } } if (type == null) { try { type = engineImportService.ResolveType(variableType, false); if (array) { arrayType = TypeHelper.GetArrayType(type.GetBoxedType()); } } catch (EngineImportException e) { Log.Debug("Not found '" + type + "': " + e.Message, e); // expected } } if (type == null) { throw new VariableTypeException("Cannot create variable '" + variableName + "', type '" + variableType + "' is not a recognized type"); } if (array && eventType != null) { throw new VariableTypeException("Cannot create variable '" + variableName + "', type '" + variableType + "' cannot be declared as an array type"); } } else { if (array) { if (arrayOfPrimitive) { if (primitiveType == null) { throw new VariableTypeException("Cannot create variable '" + variableName + "', type '" + variableType + "' is not a primitive type"); } arrayType = TypeHelper.GetArrayType(primitiveType); } else { arrayType = TypeHelper.GetArrayType(type.GetBoxedType()); } } } if ((eventType == null) && (!type.IsBuiltinDataType()) && (type != typeof(object)) && !type.IsArray && !type.IsEnum) { if (array) { throw new VariableTypeException("Cannot create variable '" + variableName + "', type '" + variableType + "' cannot be declared as an array, only scalar types can be array"); } eventType = _eventAdapterService.AddBeanType(type.Name, type, false, false, false); } if (arrayType != null) { type = arrayType; } CreateNewVariable(variableName, optionalContextName, type, eventType, constant, value); }
/// <summary>Resolves a given event name to an event type. </summary> /// <param name="eventName">is the name to resolve</param> /// <param name="eventAdapterService">for resolving event types</param> /// <param name="engineURI">the provider URI</param> /// <param name="optionalResolutionURIs">is URIs for resolving the event name against plug-inn event representations, if any</param> /// <returns>event type</returns> /// <throws>ExprValidationException if the info cannot be resolved</throws> public static EventType ResolveType(String engineURI, String eventName, EventAdapterService eventAdapterService, IList <Uri> optionalResolutionURIs) { var eventType = eventAdapterService.GetEventTypeByName(eventName); // may already be known if (eventType != null) { return(eventType); } var engineURIQualifier = engineURI; if (engineURI == null || EPServiceProviderConstants.DEFAULT_ENGINE_URI.Equals(engineURI)) { engineURIQualifier = EPServiceProviderConstants.DEFAULT_ENGINE_URI__QUALIFIER; } // The event name can be prefixed by the engine URI, i.e. "select * from default.MyEvent" if (eventName.StartsWith(engineURIQualifier)) { var indexDot = eventName.IndexOf('.'); if (indexDot > 0) { var eventNameURI = eventName.Substring(0, indexDot); var eventNameRemainder = eventName.Substring(indexDot + 1); if (engineURIQualifier.Equals(eventNameURI)) { eventType = eventAdapterService.GetEventTypeByName(eventNameRemainder); } } } // may now be known if (eventType != null) { return(eventType); } // The type is not known yet, attempt to add as an object type with the same name String message = null; try { eventType = eventAdapterService.AddBeanType(eventName, eventName, true, false, false, false); } catch (EventAdapterException ex) { Log.Debug(".resolveType Event type named '" + eventName + "' not resolved as Type event"); message = "Failed to resolve event type: " + ex.Message; } // Attempt to use plug-in event types try { eventType = eventAdapterService.AddPlugInEventType(eventName, optionalResolutionURIs, null); } catch (EventAdapterException) { Log.Debug(".resolveType Event type named '" + eventName + "' not resolved by plug-in event representations"); // remains unresolved } if (eventType == null) { throw new ExprValidationException(message); } return(eventType); }
/// <summary>Initialize event adapter service for config snapshot. </summary> /// <param name="eventAdapterService">is events adapter</param> /// <param name="configSnapshot">is the config snapshot</param> internal static void Init(EventAdapterService eventAdapterService, ConfigurationInformation configSnapshot) { // Extract legacy event type definitions for each event type name, if supplied. // // We supply this information as setup information to the event adapter service // to allow discovery of superclasses and interfaces during event type construction for bean events, // such that superclasses and interfaces can use the legacy type definitions. IDictionary <String, ConfigurationEventTypeLegacy> classLegacyInfo = new Dictionary <String, ConfigurationEventTypeLegacy>(); foreach (KeyValuePair <String, String> entry in configSnapshot.EventTypeNames) { String typeName = entry.Key; String className = entry.Value; ConfigurationEventTypeLegacy legacyDef = configSnapshot.EventTypesLegacy.Get(typeName); if (legacyDef != null) { classLegacyInfo.Put(className, legacyDef); } } eventAdapterService.TypeLegacyConfigs = classLegacyInfo; eventAdapterService.DefaultPropertyResolutionStyle = configSnapshot.EngineDefaults.EventMetaConfig.ClassPropertyResolutionStyle; eventAdapterService.DefaultAccessorStyle = configSnapshot.EngineDefaults.EventMetaConfig.DefaultAccessorStyle; foreach (String typeNamespace in configSnapshot.EventTypeAutoNamePackages) { eventAdapterService.AddAutoNamePackage(typeNamespace); } // Add from the configuration the event class names IDictionary <String, String> typeNames = configSnapshot.EventTypeNames; foreach (KeyValuePair <String, String> entry in typeNames) { // Add class try { String typeName = entry.Key; eventAdapterService.AddBeanType(typeName, entry.Value, false, true, true, true); } catch (EventAdapterException ex) { throw new ConfigurationException("Error configuring engine: " + ex.Message, ex); } } // Add from the configuration the XML DOM names and type def IDictionary <String, ConfigurationEventTypeXMLDOM> xmlDOMNames = configSnapshot.EventTypesXMLDOM; foreach (KeyValuePair <String, ConfigurationEventTypeXMLDOM> entry in xmlDOMNames) { SchemaModel schemaModel = null; if ((entry.Value.SchemaResource != null) || (entry.Value.SchemaText != null)) { try { schemaModel = XSDSchemaMapper.LoadAndMap(entry.Value.SchemaResource, entry.Value.SchemaText, 2); } catch (Exception ex) { throw new ConfigurationException(ex.Message, ex); } } // Add XML DOM type try { eventAdapterService.AddXMLDOMType(entry.Key, entry.Value, schemaModel, true); } catch (EventAdapterException ex) { throw new ConfigurationException("Error configuring engine: " + ex.Message, ex); } } // Add maps in dependency order such that supertypes are added before subtypes ICollection <String> dependentMapOrder; try { var typesReferences = ToTypesReferences(configSnapshot.MapTypeConfigurations); dependentMapOrder = GraphUtil.GetTopDownOrder(typesReferences); } catch (GraphCircularDependencyException e) { throw new ConfigurationException("Error configuring engine, dependency graph between map type names is circular: " + e.Message, e); } IDictionary <String, Properties> mapNames = configSnapshot.EventTypesMapEvents; IDictionary <String, IDictionary <String, Object> > nestableMapNames = configSnapshot.EventTypesNestableMapEvents; dependentMapOrder.AddAll(mapNames.Keys); dependentMapOrder.AddAll(nestableMapNames.Keys); try { foreach (String mapName in dependentMapOrder) { ConfigurationEventTypeMap mapConfig = configSnapshot.MapTypeConfigurations.Get(mapName); Properties propertiesUnnested = mapNames.Get(mapName); if (propertiesUnnested != null) { IDictionary <String, Object> propertyTypes = CreatePropertyTypes(propertiesUnnested); IDictionary <String, Object> propertyTypesCompiled = EventTypeUtility.CompileMapTypeProperties(propertyTypes, eventAdapterService); eventAdapterService.AddNestableMapType(mapName, propertyTypesCompiled, mapConfig, true, true, true, false, false); } IDictionary <String, Object> propertiesNestable = nestableMapNames.Get(mapName); if (propertiesNestable != null) { IDictionary <String, Object> propertiesNestableCompiled = EventTypeUtility.CompileMapTypeProperties(propertiesNestable, eventAdapterService); eventAdapterService.AddNestableMapType(mapName, propertiesNestableCompiled, mapConfig, true, true, true, false, false); } } } catch (EventAdapterException ex) { throw new ConfigurationException("Error configuring engine: " + ex.Message, ex); } // Add object-array in dependency order such that supertypes are added before subtypes ICollection <string> dependentObjectArrayOrder; try { var typesReferences = ToTypesReferences(configSnapshot.ObjectArrayTypeConfigurations); dependentObjectArrayOrder = GraphUtil.GetTopDownOrder(typesReferences); } catch (GraphCircularDependencyException e) { throw new ConfigurationException( "Error configuring engine, dependency graph between object array type names is circular: " + e.Message, e); } var nestableObjectArrayNames = configSnapshot.EventTypesNestableObjectArrayEvents; dependentObjectArrayOrder.AddAll(nestableObjectArrayNames.Keys); try { foreach (string objectArrayName in dependentObjectArrayOrder) { var objectArrayConfig = configSnapshot.ObjectArrayTypeConfigurations.Get(objectArrayName); var propertyTypes = nestableObjectArrayNames.Get(objectArrayName); propertyTypes = ResolveClassesForStringPropertyTypes(propertyTypes); var propertyTypesCompiled = EventTypeUtility.CompileMapTypeProperties(propertyTypes, eventAdapterService); eventAdapterService.AddNestableObjectArrayType(objectArrayName, propertyTypesCompiled, objectArrayConfig, true, true, true, false, false, false, null); } } catch (EventAdapterException ex) { throw new ConfigurationException("Error configuring engine: " + ex.Message, ex); } // Add plug-in event representations var plugInReps = configSnapshot.PlugInEventRepresentation; foreach (var entry in plugInReps) { String className = entry.Value.EventRepresentationTypeName; Type eventRepClass; try { eventRepClass = TypeHelper.ResolveType(className); } catch (TypeLoadException ex) { throw new ConfigurationException("Failed to load plug-in event representation class '" + className + "'", ex); } Object pluginEventRepObj; try { pluginEventRepObj = Activator.CreateInstance(eventRepClass); } catch (TypeInstantiationException ex) { throw new ConfigurationException("Failed to instantiate plug-in event representation class '" + className + "' via default constructor", ex); } catch (TargetInvocationException ex) { throw new ConfigurationException("Failed to instantiate plug-in event representation class '" + className + "' via default constructor", ex); } catch (MethodAccessException ex) { throw new ConfigurationException("Illegal access to instantiate plug-in event representation class '" + className + "' via default constructor", ex); } catch (MemberAccessException ex) { throw new ConfigurationException("Illegal access to instantiate plug-in event representation class '" + className + "' via default constructor", ex); } if (!(pluginEventRepObj is PlugInEventRepresentation)) { throw new ConfigurationException("Plug-in event representation class '" + className + "' does not implement the required interface " + typeof(PlugInEventRepresentation).FullName); } var eventRepURI = entry.Key; var pluginEventRep = (PlugInEventRepresentation)pluginEventRepObj; var initializer = entry.Value.Initializer; var context = new PlugInEventRepresentationContext(eventAdapterService, eventRepURI, initializer); try { pluginEventRep.Init(context); eventAdapterService.AddEventRepresentation(eventRepURI, pluginEventRep); } catch (Exception e) { throw new ConfigurationException("Plug-in event representation class '" + className + "' and URI '" + eventRepURI + "' did not initialize correctly : " + e.Message, e); } } // Add plug-in event type names IDictionary <String, ConfigurationPlugInEventType> plugInNames = configSnapshot.PlugInEventTypes; foreach (KeyValuePair <String, ConfigurationPlugInEventType> entry in plugInNames) { String name = entry.Key; ConfigurationPlugInEventType config = entry.Value; eventAdapterService.AddPlugInEventType(name, config.EventRepresentationResolutionURIs, config.Initializer); } }
/// <summary> /// Creates a method-invocation polling view for use as a stream that calls a method, or pulls results from cache. /// </summary> /// <param name="streamNumber">the stream number</param> /// <param name="methodStreamSpec">defines the class and method to call</param> /// <param name="eventAdapterService">for creating event types and events</param> /// <param name="epStatementAgentInstanceHandle">for time-based callbacks</param> /// <param name="methodResolutionService">for resolving classes and imports</param> /// <param name="engineImportService">for resolving configurations</param> /// <param name="schedulingService">for scheduling callbacks in expiry-time based caches</param> /// <param name="scheduleBucket">for schedules within the statement</param> /// <param name="exprEvaluatorContext">expression evaluation context</param> /// <returns>pollable view</returns> /// <throws>ExprValidationException if the expressions cannot be validated or the method descriptorhas incorrect class and method names, or parameter number and types don't match /// </throws> public static HistoricalEventViewable CreatePollMethodView( int streamNumber, MethodStreamSpec methodStreamSpec, EventAdapterService eventAdapterService, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, MethodResolutionService methodResolutionService, EngineImportService engineImportService, SchedulingService schedulingService, ScheduleBucket scheduleBucket, ExprEvaluatorContext exprEvaluatorContext, VariableService variableService, String contextName) { VariableMetaData variableMetaData = variableService.GetVariableMetaData(methodStreamSpec.ClassName); MethodPollingExecStrategyEnum strategy; VariableReader variableReader; String variableName; // Try to resolve the method MethodInfo methodReflection; FastMethod methodFastClass; Type declaringClass; Object invocationTarget; try { if (variableMetaData != null) { variableName = variableMetaData.VariableName; if (variableMetaData.ContextPartitionName != null) { if (contextName == null || !contextName.Equals(variableMetaData.ContextPartitionName)) { throw new ExprValidationException("Variable by name '" + variableMetaData.VariableName + "' has been declared for context '" + variableMetaData.ContextPartitionName + "' and can only be used within the same context"); } strategy = MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT; variableReader = null; invocationTarget = null; } else { variableReader = variableService.GetReader(methodStreamSpec.ClassName, VariableServiceConstants.NOCONTEXT_AGENTINSTANCEID); if (variableMetaData.IsConstant) { invocationTarget = variableReader.Value; if (invocationTarget is EventBean) { invocationTarget = ((EventBean)invocationTarget).Underlying; } strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } else { invocationTarget = null; strategy = MethodPollingExecStrategyEnum.TARGET_VAR; } } methodReflection = methodResolutionService.ResolveNonStaticMethod(variableMetaData.VariableType, methodStreamSpec.MethodName); } else { methodReflection = methodResolutionService.ResolveMethod(methodStreamSpec.ClassName, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } declaringClass = methodReflection.DeclaringType; methodFastClass = FastClass.CreateMethod(methodReflection); } catch (ExprValidationException e) { throw; } catch (Exception e) { throw new ExprValidationException(e.Message, e); } // Determine object type returned by method var beanClass = methodFastClass.ReturnType; if ((beanClass == typeof(void)) || (beanClass.IsBuiltinDataType())) { throw new ExprValidationException("Invalid return type for static method '" + methodFastClass.Name + "' of class '" + methodStreamSpec.ClassName + "', expecting a class"); } bool isCollection = false; bool isIterator = false; Type collectionClass = null; Type iteratorClass = null; if (methodFastClass.ReturnType.IsArray) { beanClass = methodFastClass.ReturnType.GetElementType(); } else if (!methodFastClass.ReturnType.IsGenericStringDictionary()) { isCollection = methodFastClass.ReturnType.IsGenericCollection(); if (isCollection) { collectionClass = beanClass.GetGenericType(0); beanClass = collectionClass; } var beanEnumerable = methodFastClass.ReturnType.FindGenericInterface(typeof(IEnumerable <>)); if (beanEnumerable != null) { isIterator = true; iteratorClass = beanEnumerable.GetGenericType(0); beanClass = iteratorClass; } else { var beanEnumerator = methodFastClass.ReturnType.FindGenericInterface(typeof(IEnumerator <>)); if (beanEnumerator != null) { isIterator = true; iteratorClass = beanEnumerator.GetGenericType(0); beanClass = iteratorClass; } } } // If the method returns a Map, look up the map type IDictionary <string, object> mapType = null; String mapTypeName = null; if ((methodFastClass.ReturnType.IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsArray && methodFastClass.ReturnType.GetElementType().IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericCollection() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericEnumerator() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericEnumerable() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary())) { var metadata = GetCheckMetadata(methodStreamSpec.MethodName, methodStreamSpec.ClassName, methodResolutionService, typeof(IDictionary <string, object>)); mapTypeName = metadata.TypeName; mapType = (IDictionary <string, object>)metadata.TypeMetadata; } // If the method returns an Object[] or Object[][], look up the type information IDictionary <string, object> oaType = null; String oaTypeName = null; if ((methodFastClass.ReturnType == typeof(object[])) || (methodFastClass.ReturnType == typeof(object[][])) || (methodFastClass.ReturnType.IsGenericCollection() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[])) || (methodFastClass.ReturnType.IsGenericEnumerator() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[])) || (methodFastClass.ReturnType.IsGenericEnumerable() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[]))) { var metadata = GetCheckMetadata(methodStreamSpec.MethodName, methodStreamSpec.ClassName, methodResolutionService, typeof(IDictionary <string, object>)); oaTypeName = metadata.TypeName; oaType = (IDictionary <String, Object>)metadata.TypeMetadata; } // Determine event type from class and method name EventType eventType; if (mapType != null) { eventType = eventAdapterService.AddNestableMapType(mapTypeName, mapType, null, false, true, true, false, false); } else if (oaType != null) { eventType = eventAdapterService.AddNestableObjectArrayType(oaTypeName, oaType, null, false, true, true, false, false, false, null); } else { eventType = eventAdapterService.AddBeanType(beanClass.FullName, beanClass, false, true, true); } // Construct polling strategy as a method invocation var configCache = engineImportService.GetConfigurationMethodRef(declaringClass.FullName); if (configCache == null) { configCache = engineImportService.GetConfigurationMethodRef(declaringClass.FullName); } var dataCacheDesc = configCache != null ? configCache.DataCacheDesc : null; var dataCache = DataCacheFactory.GetDataCache(dataCacheDesc, epStatementAgentInstanceHandle, schedulingService, scheduleBucket); PollExecStrategy methodPollStrategy; if (mapType != null) { if (methodFastClass.ReturnType.IsArray) { methodPollStrategy = new MethodPollingExecStrategyMapArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyMapCollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyMapIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyMapPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } else if (oaType != null) { if (methodFastClass.ReturnType == typeof(object[][])) { methodPollStrategy = new MethodPollingExecStrategyOAArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyOACollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyOAIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyOAPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } else { if (methodFastClass.ReturnType.IsArray) { methodPollStrategy = new MethodPollingExecStrategyPOCOArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyPOCOCollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyPOCOIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyPOCOPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } return(new MethodPollingViewable(variableMetaData == null, methodReflection.DeclaringType, methodStreamSpec, streamNumber, methodStreamSpec.Expressions, methodPollStrategy, dataCache, eventType, exprEvaluatorContext)); }
/// <summary> /// Creates a method-invocation polling view for use as a stream that calls a method, or pulls results from cache. /// </summary> /// <param name="streamNumber">the stream number</param> /// <param name="methodStreamSpec">defines the class and method to call</param> /// <param name="eventAdapterService">for creating event types and events</param> /// <param name="epStatementAgentInstanceHandle">for time-based callbacks</param> /// <param name="engineImportService">for resolving configurations</param> /// <param name="schedulingService">for scheduling callbacks in expiry-time based caches</param> /// <param name="scheduleBucket">for schedules within the statement</param> /// <param name="exprEvaluatorContext">expression evaluation context</param> /// <param name="variableService">variable service</param> /// <param name="statementContext">statement context</param> /// <param name="contextName">context name</param> /// <param name="dataCacheFactory">factory for cache</param> /// <exception cref="ExprValidationException"> /// if the expressions cannot be validated or the method descriptor /// has incorrect class and method names, or parameter number and types don't match /// </exception> /// <returns>pollable view</returns> public static HistoricalEventViewable CreatePollMethodView( int streamNumber, MethodStreamSpec methodStreamSpec, EventAdapterService eventAdapterService, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, EngineImportService engineImportService, SchedulingService schedulingService, ScheduleBucket scheduleBucket, ExprEvaluatorContext exprEvaluatorContext, VariableService variableService, string contextName, DataCacheFactory dataCacheFactory, StatementContext statementContext) { VariableMetaData variableMetaData = variableService.GetVariableMetaData(methodStreamSpec.ClassName); MethodPollingExecStrategyEnum strategy; VariableReader variableReader = null; string variableName = null; MethodInfo methodReflection = null; object invocationTarget = null; string eventTypeNameProvidedUDFOrScript = null; // see if this is a script in the from-clause ExprNodeScript scriptExpression = null; if (methodStreamSpec.ClassName == null && methodStreamSpec.MethodName != null) { var scriptsByName = statementContext.ExprDeclaredService.GetScriptsByName(methodStreamSpec.MethodName); if (scriptsByName != null) { scriptExpression = ExprDeclaredHelper.GetExistsScript( statementContext.ConfigSnapshot.EngineDefaults.Scripts.DefaultDialect, methodStreamSpec.MethodName, methodStreamSpec.Expressions, scriptsByName, statementContext.ExprDeclaredService); } } try { if (scriptExpression != null) { eventTypeNameProvidedUDFOrScript = scriptExpression.EventTypeNameAnnotation; strategy = MethodPollingExecStrategyEnum.TARGET_SCRIPT; ExprNodeUtility.ValidateSimpleGetSubtree( ExprNodeOrigin.METHODINVJOIN, scriptExpression, statementContext, null, false); } else if (variableMetaData != null) { variableName = variableMetaData.VariableName; if (variableMetaData.ContextPartitionName != null) { if (contextName == null || !contextName.Equals(variableMetaData.ContextPartitionName)) { throw new ExprValidationException( "Variable by name '" + variableMetaData.VariableName + "' has been declared for context '" + variableMetaData.ContextPartitionName + "' and can only be used within the same context"); } strategy = MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT; variableReader = null; invocationTarget = null; } else { variableReader = variableService.GetReader( methodStreamSpec.ClassName, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID); if (variableMetaData.IsConstant) { invocationTarget = variableReader.Value; if (invocationTarget is EventBean) { invocationTarget = ((EventBean)invocationTarget).Underlying; } strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } else { invocationTarget = null; strategy = MethodPollingExecStrategyEnum.TARGET_VAR; } } methodReflection = engineImportService.ResolveNonStaticMethodOverloadChecked( variableMetaData.VariableType, methodStreamSpec.MethodName); } else if (methodStreamSpec.ClassName == null) { // must be either UDF or script Pair <Type, EngineImportSingleRowDesc> udf = null; try { udf = engineImportService.ResolveSingleRow(methodStreamSpec.MethodName); } catch (EngineImportException ex) { throw new ExprValidationException( "Failed to find user-defined function '" + methodStreamSpec.MethodName + "': " + ex.Message, ex); } methodReflection = engineImportService.ResolveMethodOverloadChecked(udf.First, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; eventTypeNameProvidedUDFOrScript = udf.Second.OptionalEventTypeName; } else { methodReflection = engineImportService.ResolveMethodOverloadChecked(methodStreamSpec.ClassName, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } } catch (ExprValidationException) { throw; } catch (Exception e) { throw new ExprValidationException(e.Message, e); } Type methodProviderClass = null; Type beanClass; IDictionary <string, object> oaType = null; IDictionary <string, object> mapType = null; bool isCollection = false; bool isIterator = false; EventType eventType; EventType eventTypeWhenMethodReturnsEventBeans = null; bool isStaticMethod = false; if (methodReflection != null) { methodProviderClass = methodReflection.DeclaringType; isStaticMethod = variableMetaData == null; // Determine object type returned by method beanClass = methodReflection.ReturnType; if ((beanClass == typeof(void)) || (beanClass.IsBuiltinDataType())) { throw new ExprValidationException( "Invalid return type for static method '" + methodReflection.Name + "' of class '" + methodStreamSpec.ClassName + "', expecting a class"); } if (methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType() != typeof(EventBean)) { beanClass = methodReflection.ReturnType.GetElementType(); } Type collectionClass = null; Type iteratorClass = null; if (!beanClass.IsGenericDictionary()) { isCollection = beanClass.IsGenericCollection(); if (isCollection) { collectionClass = TypeHelper.GetGenericReturnType(methodReflection, true); beanClass = collectionClass; } isIterator = beanClass.IsGenericEnumerator() && !beanClass.IsGenericDictionary(); if (isIterator) { iteratorClass = TypeHelper.GetGenericReturnType(methodReflection, true); beanClass = iteratorClass; } } // If the method returns a Map, look up the map type string mapTypeName = null; if ((methodReflection.ReturnType.IsGenericStringDictionary()) || (methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType().IsGenericStringDictionary()) || (isCollection && collectionClass.IsImplementsInterface(typeof(Map))) || (isIterator && iteratorClass.IsImplementsInterface(typeof(Map)))) { MethodMetadataDesc metadata; if (variableMetaData != null) { metadata = GetCheckMetadataVariable( methodStreamSpec.MethodName, variableMetaData, variableReader, engineImportService, typeof(Map)); } else { metadata = GetCheckMetadataNonVariable( methodStreamSpec.MethodName, methodStreamSpec.ClassName, engineImportService, typeof(Map)); } mapTypeName = metadata.TypeName; mapType = (IDictionary <string, object>)metadata.TypeMetadata; } // If the method returns an object[] or object[][], look up the type information string oaTypeName = null; if (methodReflection.ReturnType == typeof(object[]) || methodReflection.ReturnType == typeof(object[][]) || (isCollection && collectionClass == typeof(object[])) || (isIterator && iteratorClass == typeof(object[]))) { MethodMetadataDesc metadata; if (variableMetaData != null) { metadata = GetCheckMetadataVariable( methodStreamSpec.MethodName, variableMetaData, variableReader, engineImportService, typeof(IDictionary <string, object>)); } else { metadata = GetCheckMetadataNonVariable( methodStreamSpec.MethodName, methodStreamSpec.ClassName, engineImportService, typeof(IDictionary <string, object>)); } oaTypeName = metadata.TypeName; oaType = (IDictionary <string, object>)metadata.TypeMetadata; } // Determine event type from class and method name // If the method returns EventBean[], require the event type if ((methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType() == typeof(EventBean)) || (isCollection && collectionClass == typeof(EventBean)) || (isIterator && iteratorClass == typeof(EventBean))) { string typeName = methodStreamSpec.EventTypeName == null ? eventTypeNameProvidedUDFOrScript : methodStreamSpec.EventTypeName; eventType = EventTypeUtility.RequireEventType( "Method", methodReflection.Name, eventAdapterService, typeName); eventTypeWhenMethodReturnsEventBeans = eventType; } else if (mapType != null) { eventType = eventAdapterService.AddNestableMapType( mapTypeName, mapType, null, false, true, true, false, false); } else if (oaType != null) { eventType = eventAdapterService.AddNestableObjectArrayType( oaTypeName, oaType, null, false, true, true, false, false, false, null); } else { eventType = eventAdapterService.AddBeanType(beanClass.GetDefaultTypeName(), beanClass, false, true, true); } // the @type is only allowed in conjunction with EventBean return types if (methodStreamSpec.EventTypeName != null && eventTypeWhenMethodReturnsEventBeans == null) { throw new ExprValidationException(EventTypeUtility.DisallowedAtTypeMessage()); } } else { string eventTypeName = methodStreamSpec.EventTypeName == null ? scriptExpression.EventTypeNameAnnotation : methodStreamSpec.EventTypeName; eventType = EventTypeUtility.RequireEventType( "Script", scriptExpression.Script.Name, eventAdapterService, eventTypeName); } // get configuration for cache string configName = methodProviderClass != null ? methodProviderClass.FullName : methodStreamSpec.MethodName; ConfigurationMethodRef configCache = engineImportService.GetConfigurationMethodRef(configName); if (configCache == null) { configCache = engineImportService.GetConfigurationMethodRef(configName); } ConfigurationDataCache dataCacheDesc = (configCache != null) ? configCache.DataCacheDesc : null; DataCache dataCache = dataCacheFactory.GetDataCache( dataCacheDesc, statementContext, epStatementAgentInstanceHandle, schedulingService, scheduleBucket, streamNumber); // metadata var meta = new MethodPollingViewableMeta( methodProviderClass, isStaticMethod, mapType, oaType, invocationTarget, strategy, isCollection, isIterator, variableReader, variableName, eventTypeWhenMethodReturnsEventBeans, scriptExpression); return(new MethodPollingViewable(methodStreamSpec, dataCache, eventType, exprEvaluatorContext, meta, statementContext.ThreadLocalManager)); }