示例#1
0
 private void ReadCompare(String[] variables, Object value)
 {
     _service.SetLocalVersion();
     for (int i = 0; i < variables.Length; i++)
     {
         Assert.AreEqual(value, _service.GetReader(variables[i], 0).Value);
     }
 }
示例#2
0
        public void TestRollover()
        {
            _service = new VariableServiceImpl(
                VariableServiceImpl.ROLLOVER_READER_BOUNDARY - 100,
                10000,
                new SchedulingServiceImpl(new TimeSourceServiceImpl()),
                SupportEventAdapterService.Service,
                null);

            String[] variables = "a,b,c,d".Split(',');

            var readers = new VariableReader[variables.Length];

            for (int i = 0; i < variables.Length; i++)
            {
                _service.CreateNewVariable <long>(null, variables[i], false, 100L, null);
                _service.AllocateVariableState(variables[i], EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID, null, false);
                readers[i] = _service.GetReader(variables[i], EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);
            }

            for (int i = 0; i < 1000; i++)
            {
                for (int j = 0; j < variables.Length; j++)
                {
                    _service.Write(readers[j].VariableMetaData.VariableNumber, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID, 100L + i);
                    _service.Commit();
                }
                ReadCompare(variables, 100L + i);
            }
        }
示例#3
0
 /// <summary>
 /// Ctor.
 /// </summary>
 /// <param name="statementId">The statement id.</param>
 /// <param name="eventAdapterService">for creating events</param>
 /// <param name="variableService">for looking up variables</param>
 /// <param name="variableName">is the name of the variable to create</param>
 /// <param name="statementResultService">for coordinating on whether insert and remove stream events should be posted</param>
 /// <param name="agentInstanceId"></param>
 public CreateVariableView(int statementId, EventAdapterService eventAdapterService, VariableService variableService, string variableName, StatementResultService statementResultService, int agentInstanceId)
 {
     _eventAdapterService    = eventAdapterService;
     _variableName           = variableName;
     _statementResultService = statementResultService;
     _reader    = variableService.GetReader(variableName, agentInstanceId);
     _eventType = GetEventType(statementId, eventAdapterService, _reader.VariableMetaData);
 }
示例#4
0
 /// <summary>
 /// Ctor.
 /// </summary>
 /// <param name="statementId">The statement id.</param>
 /// <param name="eventAdapterService">for creating events</param>
 /// <param name="variableService">for looking up variables</param>
 /// <param name="variableName">is the name of the variable to create</param>
 /// <param name="statementResultService">for coordinating on whether insert and remove stream events should be posted</param>
 public CreateVariableView(String statementId, EventAdapterService eventAdapterService, VariableService variableService, String variableName, StatementResultService statementResultService)
 {
     _eventAdapterService    = eventAdapterService;
     _variableName           = variableName;
     _statementResultService = statementResultService;
     _reader    = variableService.GetReader(variableName, VariableServiceConstants.NOCONTEXT_AGENTINSTANCEID);
     _eventType = GetEventType(statementId, eventAdapterService, _reader.VariableMetaData);
 }
        private AggSvcGroupByReclaimAgedEvalFuncFactory GetEvaluationFunction(VariableService variableService, String hintValue, String optionalContextName)
        {
            VariableMetaData variableMetaData = variableService.GetVariableMetaData(hintValue);

            if (variableMetaData != null)
            {
                if (!variableMetaData.VariableType.IsNumeric())
                {
                    throw new ExprValidationException("Variable type of variable '" + variableMetaData.VariableName + "' is not numeric");
                }
                String message = VariableServiceUtil.CheckVariableContextName(optionalContextName, variableMetaData);
                if (message != null)
                {
                    throw new ExprValidationException(message);
                }
                return(new ProxyAggSvcGroupByReclaimAgedEvalFuncFactory
                {
                    ProcMake = agentInstanceContext =>
                    {
                        VariableReader reader = variableService.GetReader(
                            variableMetaData.VariableName, agentInstanceContext.AgentInstanceId);
                        return new AggSvcGroupByReclaimAgedEvalFuncVariable(reader);
                    }
                });
            }
            else
            {
                double valueDouble;
                try {
                    valueDouble = DoubleValue.ParseString(hintValue);
                }
                catch (Exception) {
                    throw new ExprValidationException("Failed to parse hint parameter value '" + hintValue + "' as a double-typed seconds value or variable name");
                }
                if (valueDouble <= 0)
                {
                    throw new ExprValidationException("Hint parameter value '" + hintValue + "' is an invalid value, expecting a double-typed seconds value or variable name");
                }
                return(new ProxyAggSvcGroupByReclaimAgedEvalFuncFactory
                {
                    ProcMake = agentInstanceContext => new AggSvcGroupByReclaimAgedEvalFuncConstant(valueDouble)
                });
            }
        }
示例#6
0
        public VariableServiceCallable(String[] variables, VariableService variableService, VariableVersionCoord variableVersionCoord, int numLoops)
        {
            _random               = new Random();
            _variables            = variables;
            _variableService      = variableService;
            _variableVersionCoord = variableVersionCoord;
            _numLoops             = numLoops;

            _results = new int[numLoops][];
            for (int ii = 0; ii < numLoops; ii++)
            {
                _results[ii] = new int[variables.Length];
            }

            _marks = new int[numLoops];

            _readers = new VariableReader[variables.Length];
            for (int i = 0; i < variables.Length; i++)
            {
                _readers[i] = variableService.GetReader(variables[i], EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);
            }
        }
示例#7
0
        public IList <EventBean> Poll(Object[] lookupValues, ExprEvaluatorContext exprEvaluatorContext)
        {
            switch (Strategy)
            {
            case MethodPollingExecStrategyEnum.TARGET_CONST:
                return(InvokeInternal(lookupValues, InvocationTarget));

            case MethodPollingExecStrategyEnum.TARGET_VAR:
                return(InvokeInternalVariable(lookupValues, VariableReader));

            case MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT:
                var reader = VariableService.GetReader(VariableName, exprEvaluatorContext.AgentInstanceId);
                if (reader == null)
                {
                    return(null);
                }
                return(InvokeInternalVariable(lookupValues, reader));

            default:
                throw new NotSupportedException("unrecognized strategy " + Strategy);
            }
        }
        public VariableServiceCallable(String[] variables, VariableService variableService, VariableVersionCoord variableVersionCoord, int numLoops)
        {
            _random               = new Random();
            _variables            = variables;
            _variableService      = variableService;
            _variableVersionCoord = variableVersionCoord;
            _numLoops             = numLoops;

            _results = new int[numLoops][];
            for (int ii = 0; ii < numLoops; ii++)
            {
                _results[ii] = new int[variables.Length];
            }

            _marks = new int[numLoops];

            _readers = new VariableReader[variables.Length];
            for (int i = 0; i < variables.Length; i++)
            {
                _readers[i] = variableService.GetReader(variables[i], 0);
            }
        }
        public bool RemoveVariable(String name, bool force)
        {
            if (!force)
            {
                ICollection <String> statements = _statementVariableRef.GetStatementNamesForVar(name);
                if ((statements != null) && (statements.IsNotEmpty()))
                {
                    throw new ConfigurationException("Variable '" + name + "' is in use by one or more statements");
                }
            }

            var reader = _variableService.GetReader(name, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);

            if (reader == null)
            {
                return(false);
            }

            _variableService.RemoveVariableIfFound(name);
            _statementVariableRef.RemoveReferencesVariable(name);
            _statementVariableRef.RemoveConfiguredVariable(name);
            return(true);
        }
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="assignments">the list of variable assignments</param>
        /// <param name="variableService">variable service</param>
        /// <param name="eventAdapterService">event adapters</param>
        /// <throws><seealso cref="ExprValidationException" /> when variables cannot be found</throws>
        public VariableReadWritePackage(IList <OnTriggerSetAssignment> assignments, VariableService variableService, EventAdapterService eventAdapterService)

        {
            _metaData             = new VariableMetaData[assignments.Count];
            _readersForGlobalVars = new VariableReader[assignments.Count];
            _mustCoerce           = new bool[assignments.Count];
            _writers = new WriteDesc[assignments.Count];

            _variableTypes       = new Dictionary <String, Object>();
            _eventAdapterService = eventAdapterService;
            _variableService     = variableService;

            IDictionary <EventTypeSPI, CopyMethodDesc> eventTypeWrittenProps = new Dictionary <EventTypeSPI, CopyMethodDesc>();
            var count = 0;
            IList <VariableTriggerSetDesc> assignmentList = new List <VariableTriggerSetDesc>();

            foreach (var expressionWithAssignments in assignments)
            {
                var possibleVariableAssignment = ExprNodeUtility.CheckGetAssignmentToVariableOrProp(expressionWithAssignments.Expression);
                if (possibleVariableAssignment == null)
                {
                    throw new ExprValidationException("Missing variable assignment expression in assignment number " + count);
                }
                assignmentList.Add(new VariableTriggerSetDesc(possibleVariableAssignment.First, possibleVariableAssignment.Second.ExprEvaluator));

                var    fullVariableName = possibleVariableAssignment.First;
                var    variableName     = fullVariableName;
                String subPropertyName  = null;

                var indexOfDot = variableName.IndexOf('.');
                if (indexOfDot != -1)
                {
                    subPropertyName = variableName.Substring(indexOfDot + 1);
                    variableName    = variableName.Substring(0, indexOfDot);
                }

                VariableMetaData variableMetadata = variableService.GetVariableMetaData(variableName);
                _metaData[count] = variableMetadata;
                if (variableMetadata == null)
                {
                    throw new ExprValidationException("Variable by name '" + variableName + "' has not been created or configured");
                }
                if (variableMetadata.IsConstant)
                {
                    throw new ExprValidationException("Variable by name '" + variableName + "' is declared constant and may not be set");
                }
                if (variableMetadata.ContextPartitionName == null)
                {
                    _readersForGlobalVars[count] = variableService.GetReader(variableName, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);
                }

                if (subPropertyName != null)
                {
                    if (variableMetadata.EventType == null)
                    {
                        throw new ExprValidationException("Variable by name '" + variableName + "' does not have a property named '" + subPropertyName + "'");
                    }
                    var type = variableMetadata.EventType;
                    if (!(type is EventTypeSPI))
                    {
                        throw new ExprValidationException("Variable by name '" + variableName + "' event type '" + type.Name + "' not writable");
                    }
                    var spi    = (EventTypeSPI)type;
                    var writer = spi.GetWriter(subPropertyName);
                    var getter = spi.GetGetter(subPropertyName);
                    if (writer == null)
                    {
                        throw new ExprValidationException("Variable by name '" + variableName + "' the property '" + subPropertyName + "' is not writable");
                    }

                    _variableTypes.Put(fullVariableName, spi.GetPropertyType(subPropertyName));
                    var writtenProps = eventTypeWrittenProps.Get(spi);
                    if (writtenProps == null)
                    {
                        writtenProps = new CopyMethodDesc(variableName, new List <String>());
                        eventTypeWrittenProps.Put(spi, writtenProps);
                    }
                    writtenProps.PropertiesCopied.Add(subPropertyName);

                    _writers[count] = new WriteDesc(spi, variableName, writer, getter);
                }
                else
                {
                    // determine types
                    var expressionType = possibleVariableAssignment.Second.ExprEvaluator.ReturnType;

                    if (variableMetadata.EventType != null)
                    {
                        if ((expressionType != null) && (!TypeHelper.IsSubclassOrImplementsInterface(expressionType, variableMetadata.EventType.UnderlyingType)))
                        {
                            throw new VariableValueException("Variable '" + variableName
                                                             + "' of declared event type '" + variableMetadata.EventType.Name + "' underlying type '" + variableMetadata.EventType.UnderlyingType.FullName +
                                                             "' cannot be assigned a value of type '" + expressionType.FullName + "'");
                        }
                        _variableTypes.Put(variableName, variableMetadata.EventType.UnderlyingType);
                    }
                    else
                    {
                        var variableType = variableMetadata.VariableType;
                        _variableTypes.Put(variableName, variableType);

                        // determine if the expression type can be assigned
                        if (variableType != typeof(object))
                        {
                            if ((TypeHelper.GetBoxedType(expressionType) != variableType) &&
                                (expressionType != null))
                            {
                                if ((!TypeHelper.IsNumeric(variableType)) ||
                                    (!TypeHelper.IsNumeric(expressionType)))
                                {
                                    throw new ExprValidationException(VariableServiceUtil.GetAssigmentExMessage(variableName, variableType, expressionType));
                                }

                                if (!(TypeHelper.CanCoerce(expressionType, variableType)))
                                {
                                    throw new ExprValidationException(VariableServiceUtil.GetAssigmentExMessage(variableName, variableType, expressionType));
                                }

                                _mustCoerce[count] = true;
                            }
                        }
                    }
                }

                count++;
            }

            _assignments = assignmentList.ToArray();

            if (eventTypeWrittenProps.IsEmpty())
            {
                _copyMethods = new Dictionary <EventTypeSPI, EventBeanCopyMethod>();
                return;
            }

            _copyMethods = new Dictionary <EventTypeSPI, EventBeanCopyMethod>();
            foreach (var entry in eventTypeWrittenProps)
            {
                var propsWritten = entry.Value.PropertiesCopied;
                var props        = propsWritten.ToArray();
                var copyMethod   = entry.Key.GetCopyMethod(props);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Variable '" + entry.Value.VariableName
                                                      + "' of declared type " + entry.Key.UnderlyingType.GetTypeNameFullyQualPretty() +
                                                      "' cannot be assigned to");
                }
                _copyMethods.Put(entry.Key, copyMethod);
            }
        }
        /// <summary>
        /// Write new variable values and commit, evaluating assignment expressions using the given
        /// events per stream.
        /// <para />Populates an optional map of new values if a non-null map is passed.
        /// </summary>
        /// <param name="variableService">variable service</param>
        /// <param name="eventsPerStream">events per stream</param>
        /// <param name="valuesWritten">null or an empty map to populate with written values</param>
        /// <param name="exprEvaluatorContext">expression evaluation context</param>
        public void WriteVariables(VariableService variableService,
                                   EventBean[] eventsPerStream,
                                   IDictionary <String, Object> valuesWritten,
                                   ExprEvaluatorContext exprEvaluatorContext)
        {
            ISet <String> variablesBeansCopied = null;

            if (!_copyMethods.IsEmpty())
            {
                variablesBeansCopied = new HashSet <String>();
            }

            // We obtain a write lock global to the variable space
            // Since expressions can contain variables themselves, these need to be unchangeable for the duration
            // as there could be multiple statements that do "var1 = var1 + 1".
            using (variableService.ReadWriteLock.AcquireWriteLock())
            {
                try
                {
                    variableService.SetLocalVersion();

                    var count = 0;
                    foreach (var assignment in _assignments)
                    {
                        var variableMetaData = _metaData[count];
                        int agentInstanceId  = variableMetaData.ContextPartitionName == null ? EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID : exprEvaluatorContext.AgentInstanceId;
                        var value            = assignment.Evaluator.Evaluate(
                            new EvaluateParams(eventsPerStream, true, exprEvaluatorContext));

                        if (_writers[count] != null)
                        {
                            var reader = variableService.GetReader(
                                variableMetaData.VariableName, exprEvaluatorContext.AgentInstanceId);
                            var current = (EventBean)reader.Value;
                            if (current == null)
                            {
                                value = null;
                            }
                            else
                            {
                                var writeDesc = _writers[count];
                                var copy      = variablesBeansCopied.Add(writeDesc.VariableName);
                                if (copy)
                                {
                                    var copied = _copyMethods.Get(writeDesc.Type).Copy(current);
                                    current = copied;
                                }
                                variableService.Write(variableMetaData.VariableNumber, agentInstanceId, current);
                                writeDesc.Writer.Write(value, current);
                            }
                        }
                        else if (variableMetaData.EventType != null)
                        {
                            var eventBean = _eventAdapterService.AdapterForType(value, variableMetaData.EventType);
                            variableService.Write(variableMetaData.VariableNumber, agentInstanceId, eventBean);
                        }
                        else
                        {
                            if ((value != null) && (_mustCoerce[count]))
                            {
                                value = CoercerFactory.CoerceBoxed(value, variableMetaData.VariableType);
                            }
                            variableService.Write(variableMetaData.VariableNumber, agentInstanceId, value);
                        }

                        count++;

                        if (valuesWritten != null)
                        {
                            valuesWritten.Put(assignment.VariableName, value);
                        }
                    }

                    variableService.Commit();
                }
                catch (Exception ex)
                {
                    Log.Error("Error evaluating on-set variable expressions: " + ex.Message, ex);
                    variableService.Rollback();
                }
            }
        }
        /// <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));
        }