/// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem = eventMonitoredItems[ii];

                #region  Filter out audit events in case the Server_Auditing values is false or the channel is not encrypted

                if (e is AuditEventState)
                {
                    // check Server.Auditing flag and skip if false
                    if (!NodeManager.Server.Auditing)
                    {
                        continue;
                    }
                    else
                    {
                        // check if channel is not encrypted and skip if so
                        if (monitoredItem?.Session?.EndpointDescription?.SecurityMode != MessageSecurityMode.SignAndEncrypt &&
                            monitoredItem?.Session?.EndpointDescription?.TransportProfileUri != Profiles.HttpsBinaryTransport)
                        {
                            continue;
                        }
                    }
                }
                #endregion

                // validate if the monitored item has the required role permissions to receive the event
                ServiceResult validationResult = NodeManager.ValidateEventRolePermissions(monitoredItem, e);

                if (ServiceResult.IsBad(validationResult))
                {
                    // skip event reporting for EventType without permissions
                    continue;
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
 /// <summary>
 /// Called by any component to report a global event.
 /// </summary>
 /// <param name="e">The event.</param>
 public void ReportEvent(IFilterTarget e)
 {
     if (m_serverObject != null)
     {
         m_serverObject.ReportEvent(this.DefaultSystemContext, e);
     }
 }
 /// <summary>
 /// Called by any component to report a global event.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="e">The event.</param>
 public void ReportEvent(ISystemContext context, IFilterTarget e)
 {
     if (m_serverObject != null)
     {
         m_serverObject.ReportEvent(context, e);
     }
 }
        /// <summary>
        /// Sets the flag which indicates whether event are being monitored for the instance and its children.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="e">The event to report.</param>
        public override void ReportEvent(ISystemContext context, IFilterTarget e)
        {
            base.ReportEvent(context, e);

            // recusively notify the parent.
            if (m_parent != null)
            {
                m_parent.ReportEvent(context, e);
            }
        }
Example #5
0
        /// <summary>
        /// Called by any component to report a global event.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="e">The event.</param>
        public void ReportEvent(ISystemContext context, IFilterTarget e)
        {
            if ((Auditing == false) && (e is AuditEventState))
            {
                // do not report auditing events if server Auditing flag is false
                return;
            }

            m_serverObject?.ReportEvent(context, e);
        }
Example #6
0
 /// <summary>
 /// Handles events reported by the node.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="state">The node that raised the event.</param>
 /// <param name="e">The event to report.</param>
 public void OnReportEvent(ISystemContext context, NodeState state, IFilterTarget e)
 {
     if (m_eventSubscriptions != null)
     {
         for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
         {
             m_eventSubscriptions[ii].QueueEvent(e);
         }
     }
 }
 /// <summary>
 /// Called when a Node produces an event.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="node">The affected node.</param>
 /// <param name="e">The event.</param>
 public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
 {
     lock (NodeManager.Lock)
     {
         for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
         {
             IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
             monitoredItem.QueueEvent(e);
         }
     }
 }
Example #8
0
        /// <summary>
        /// Reports an event.
        /// </summary>
        public static void ReportEvent(IFilterTarget e, IList <IEventMonitoredItem> monitoredItems)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            foreach (IEventMonitoredItem monitoredItem in monitoredItems)
            {
                monitoredItem.QueueEvent(e);
            }
        }
Example #9
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem  = eventMonitoredItems[ii];
                BaseEventState      baseEventState = e as BaseEventState;

                if (baseEventState != null)
                {
                    ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                         baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for EventType without permissions
                        continue;
                    }

                    validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                           baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for SourceNode without permissions
                        continue;
                    }
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
        /// <summary>
        /// Evaluates the first element in the ContentFilter. If the first or any 
        /// subsequent element has dependent elements, the dependent elements are 
        /// evaluated before the root element (recursive descent). Elements which 
        /// are not linked (directly or indirectly) to the first element will not 
        /// be evaluated (they have no influence on the result). 
        /// </summary>
        /// <param name="context">The context to use when evaluating the filter.</param>
        /// <param name="target">The target to use when evaluating elements that reference the type model.</param>
        /// <returns>Returns true, false or null.</returns>
        public bool Evaluate(FilterContext context, IFilterTarget target)
        {
            // check if nothing to do.
            if (this.Elements.Count == 0)
            {
                return true;
            }

            bool? result = Evaluate(context, target, 0) as bool?;

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

            return result.Value;
        }
        /// <summary>
        /// Fetches the requested event fields from the event.
        /// </summary>
        private HistoryEventFieldList GetEventFields(HistoryReadRequest request, IFilterTarget instance)
        {
            // fetch the event fields.
            HistoryEventFieldList fields = new HistoryEventFieldList();

            foreach (SimpleAttributeOperand clause in request.Filter.SelectClauses)
            {
                // get the value of the attribute (apply localization).
                object value = instance.GetAttributeValue(
                    request.FilterContext,
                    clause.TypeDefinitionId,
                    clause.BrowsePath,
                    clause.AttributeId,
                    clause.ParsedIndexRange);

                // add the value to the list of event fields.
                if (value != null)
                {
                    // translate any localized text.
                    LocalizedText text = value as LocalizedText;

                    if (text != null)
                    {
                        value = Server.ResourceManager.Translate(request.FilterContext.PreferredLocales, text);
                    }

                    // add value.
                    fields.EventFields.Add(new Variant(value));
                }

                // add a dummy entry for missing values.
                else
                {
                    fields.EventFields.Add(Variant.Null);
                }
            }

            return(fields);
        }
Example #12
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem  = EventMonitoredItems[ii];
                    BaseEventState      baseEventState = e as BaseEventState;
                    if (baseEventState != null)
                    {
                        ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                             baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);
                        if (ServiceResult.IsBad(validationResult))
                        {
                            // ignore invalid permission type events
                            continue;
                        }

                        validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                               baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);
                        if (ServiceResult.IsBad(validationResult))
                        {
                            // ignore invalid permission type events
                            continue;
                        }

                        // enque event
                        monitoredItem.QueueEvent(e);
                    }
                }
            }
        }
        /// <summary>
        /// Equals FilterOperator
        /// </summary>
        private bool Equals(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            object lhs = GetValue(context, operands[0], target);
            object rhs = GetValue(context, operands[1], target);

            DoImplicitConversion(ref lhs, ref rhs);

            return IsEqual(lhs, rhs);
        }
Example #14
0
 /// <summary>
 /// Called by any component to report a global event.
 /// </summary>
 /// <param name="e">The event.</param>
 public void ReportEvent(IFilterTarget e)
 {
     ReportEvent(DefaultSystemContext, e);
 }
        /// <summary>
        /// RelatedTo FilterOperator
        /// </summary>
        private bool RelatedTo(FilterContext context, IFilterTarget target, ContentFilterElement element, NodeId intermediateNodeId)
        {
            // RelatedTo only supported in advanced filter targets.
            IAdvancedFilterTarget advancedTarget = target as IAdvancedFilterTarget;

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

            FilterOperand[] operands = GetOperands(element, 6);
            
            // get the type of the source.
            NodeId sourceTypeId = GetValue(context, operands[0], target) as NodeId;

            if (sourceTypeId == null)
            {
                return false;
            }
                        
            // get the type of reference to follow.
            NodeId referenceTypeId = GetValue(context, operands[2], target) as NodeId;

            if (referenceTypeId == null)
            {
                return false;
            }
            
            // get the number of hops
            int? hops = 1;

            object hopsValue = GetValue(context, operands[3], target);

            if (hopsValue != null)
            {
                hops = Cast(hopsValue, BuiltInType.Int32) as int?;

                if (hops == null)
                {
                    hops = 1;
                }
            }

            // get whether to include type definition subtypes.
            bool? includeTypeDefinitionSubtypes = true;

            object includeValue = GetValue(context, operands[4], target);

            if (includeValue != null)
            {
                includeTypeDefinitionSubtypes = Cast(includeValue, BuiltInType.Boolean) as bool?;

                if (includeTypeDefinitionSubtypes == null)
                {
                    includeTypeDefinitionSubtypes = true;
                }
            }

            // get whether to include reference type subtypes.
            bool? includeReferenceTypeSubtypes = true;

            includeValue = GetValue(context, operands[5], target);

            if (includeValue != null)
            {
                includeReferenceTypeSubtypes = Cast(includeValue, BuiltInType.Boolean) as bool?;

                if (includeReferenceTypeSubtypes == null)
                {
                    includeReferenceTypeSubtypes = true;
                }
            }

            NodeId targetTypeId = null;

            // check if elements are chained.
            ElementOperand chainedOperand = operands[1] as ElementOperand;

            if (chainedOperand != null)
            {
                if (chainedOperand.Index < 0 || chainedOperand.Index >= Elements.Count)
                {
                    return false;
                }

                ContentFilterElement chainedElement = Elements[(int)chainedOperand.Index];

                // get the target type from the first operand of the chained element.
                if (chainedElement.FilterOperator == FilterOperator.RelatedTo)
                {
                    FilterOperand nestedType = ExtensionObject.ToEncodeable(chainedElement.FilterOperands[0]) as FilterOperand;

                    targetTypeId = GetValue(context, nestedType, target) as NodeId;

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

                    // find the nodes that meet the criteria in the first link of the chain.
                    IList<NodeId> nodeIds = advancedTarget.GetRelatedNodes(
                        context,
                        intermediateNodeId,
                        sourceTypeId,
                        targetTypeId,
                        referenceTypeId,
                        hops.Value,
                        includeTypeDefinitionSubtypes.Value,
                        includeReferenceTypeSubtypes.Value);

                    if (nodeIds == null || nodeIds.Count == 0)
                    {
                        return false;
                    }
                    
                    // recursively follow the chain.
                    for (int ii = 0; ii < nodeIds.Count; ii++)
                    {
                        // one match is all that is required.
                        if (RelatedTo(context, target, chainedElement, nodeIds[ii]))
                        {
                            return true;
                        }
                    }

                    // no matches.
                    return false;
                }
            }
            
            // get the type of the target.
            if (targetTypeId == null)
            {
                targetTypeId = GetValue(context, operands[1], target) as NodeId;

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

            // check the target.            
            try
            {
                bool relatedTo = advancedTarget.IsRelatedTo(
                    context,
                    intermediateNodeId,
                    sourceTypeId,
                    targetTypeId,
                    referenceTypeId,
                    hops.Value,
                    includeTypeDefinitionSubtypes.Value,
                    includeReferenceTypeSubtypes.Value);

                return relatedTo;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// InView FilterOperator
        /// </summary>
        private bool InView(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            // views only supported in advanced filter targets.
            IAdvancedFilterTarget advancedFilter = target as IAdvancedFilterTarget;

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

            FilterOperand[] operands = GetOperands(element, 1);
            
            // get the desired type.
            NodeId viewId = GetValue(context, operands[0], target) as NodeId;

            if (viewId == null || target == null)
            {
                return false;
            }

            // check the target.
            try
            {
                return advancedFilter.IsInView(context, viewId);
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Returns the value for the element.
        /// </summary>
        private object GetValue(FilterContext context, FilterOperand operand, IFilterTarget target)
        {
            // return the contained value for literal operands.
            LiteralOperand literal = operand as LiteralOperand;

            if (literal != null)
            {
                return literal.Value.Value;
            }

            // must query the filter target for simple attribute operands.
            SimpleAttributeOperand simpleAttribute = operand as SimpleAttributeOperand;

            if (simpleAttribute != null)
            {
                return target.GetAttributeValue(
                    context,
                    simpleAttribute.TypeDefinitionId,
                    simpleAttribute.BrowsePath,
                    simpleAttribute.AttributeId,
                    simpleAttribute.ParsedIndexRange);
            }

            // must query the filter target for attribute operands.
            AttributeOperand attribute = operand as AttributeOperand;

            if (attribute != null)
            {
                // AttributeOperands only supported in advanced filter targets.
                IAdvancedFilterTarget advancedTarget = target as IAdvancedFilterTarget;

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

                return advancedTarget.GetRelatedAttributeValue(
                    context,
                    attribute.NodeId,
                    attribute.BrowsePath,
                    attribute.AttributeId,
                    attribute.ParsedIndexRange);
            }
            
            // recursively evaluate element operands.
            ElementOperand element = operand as ElementOperand;

            if (element != null)
            {
                return Evaluate(context, target, (int)element.Index);
            }
                    
            // oops - Validate() was not called.
            throw new ServiceResultException(StatusCodes.BadUnexpectedError, "FilterOperand is not supported.");
        }
        /// <summary>
        /// IsNull FilterOperator
        /// </summary>
        private bool IsNull(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 1);

            object rhs = GetValue(context, operands[0], target);
            
            if (rhs == null)
            {
                return true;
            }
            
            return false;
        }
        /// <summary>
        /// InList FilterOperator
        /// </summary>
        private bool? InList(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 0);

            object value = GetValue(context, operands[0], target);

            // check for a match.
            for (int ii = 1; ii < operands.Length; ii++)
            {                
                object lhs = value;
                object rhs = GetValue(context, operands[ii], target);

                DoImplicitConversion(ref lhs, ref rhs);

                if (IsEqual(lhs, rhs))
                {
                    return true;
                }
            }

            // no match.
            return false;
        }
Example #20
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem  = eventMonitoredItems[ii];
                BaseEventState      baseEventState = e as BaseEventState;

                if (baseEventState != null)
                {
                    #region  Filter out audit events in case the Server_Auditing values is false or the channel is not encrypted

                    if (e is AuditEventState)
                    {
                        // check Server.Auditing flag and skip if false
                        if (!NodeManager.Server.EventManager.ServerAuditing)
                        {
                            continue;
                        }
                        else
                        {
                            // check if channel is not encrypted and skip if so
                            OperationContext operationContext = (context as SystemContext)?.OperationContext as OperationContext;
                            if (operationContext != null &&
                                operationContext.ChannelContext.EndpointDescription.SecurityMode != MessageSecurityMode.SignAndEncrypt &&
                                operationContext.ChannelContext.EndpointDescription.TransportProfileUri != Profiles.HttpsBinaryTransport)
                            {
                                continue;
                            }
                        }
                    }
                    #endregion

                    ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                         baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);


                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for EventType without permissions
                        continue;
                    }

                    validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                           baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for SourceNode without permissions
                        continue;
                    }
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
Example #21
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    monitoredItem.QueueEvent(e);
                }
            }
        }
 /// <summary>
 /// Handles events reported by the node.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="state">The node that raised the event.</param>
 /// <param name="e">The event to report.</param>
 public void OnReportEvent(ISystemContext context, NodeState state, IFilterTarget e)
 {
     if (m_eventSubscriptions != null)
     {
         for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
         {
             m_eventSubscriptions[ii].QueueEvent(e);
         }
     }
 }
 /// <summary>
 /// Reports an event for a root notifier.
 /// </summary>
 protected virtual void OnReportEvent(
     ISystemContext context,
     NodeState node,
     IFilterTarget e)
 {
     Server.ReportEvent(context, e);
 }
Example #24
0
 /// <summary>
 /// Reports an event.
 /// </summary>
 public static void ReportEvent(IFilterTarget e, IList<IEventMonitoredItem> monitoredItems)
 {
     if (e == null) throw new ArgumentNullException("e");
     
     foreach (IEventMonitoredItem monitoredItem in monitoredItems)
     {
         monitoredItem.QueueEvent(e);
     }
 }
        /// <summary>
        /// LessThanOrEqual FilterOperator
        /// </summary>
        private bool? LessThanOrEqual(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            object lhs = GetValue(context, operands[0], target);
            object rhs = GetValue(context, operands[1], target);

            DoImplicitConversion(ref lhs, ref rhs);

            if (lhs is IComparable && rhs is IComparable)
            {
                return ((IComparable)lhs).CompareTo(rhs) <= 0;
            }

            // return null if the types are not comparable.
            return null;
        }
        /// <summary>
        /// Between FilterOperator
        /// </summary>
        private bool? Between(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 3);

            object value = GetValue(context, operands[0], target);

            object min = GetValue(context, operands[1], target);
            object max = GetValue(context, operands[2], target);
            
            // the min and max could be different data types so the implicit conversion must be done twice.
            object lhs = value;
            DoImplicitConversion(ref lhs, ref min);

            bool? result = null;
            
            if (lhs is IComparable && min is IComparable)
            {
                // check if never in range no matter what happens with the upper bound.
                if (((IComparable)lhs).CompareTo(min) < 0)
                {
                    return false;
                }

                result = true;
            }
            
            lhs = value;
            DoImplicitConversion(ref lhs, ref max);
            
            if (lhs is IComparable && max is IComparable)
            {
                // check if never in range no matter what happens with the lower bound.
                if (((IComparable)lhs).CompareTo(max) > 0)
                {
                    return false;
                }

                // can't determine if in range if lower bound could not be resolved.
                return result != null;
            }
            
            // return null if the types are not comparable.
            return null;
        }
        /// <summary>
        /// Evaluates element at the specified index.
        /// </summary>
        private object Evaluate(FilterContext context, IFilterTarget target, int index)
        {
            // get the element to evaluate.
            ContentFilterElement element = Elements[index];

            switch (element.FilterOperator)
            {
                case FilterOperator.And: 
                {
                    return And(context, target, element);
                }
                    
                case FilterOperator.Or: 
                {
                    return Or(context, target, element);
                }

                case FilterOperator.Not: 
                {
                    return Not(context, target, element);
                }

                case FilterOperator.Equals: 
                {
                    return Equals(context, target, element);
                }

                case FilterOperator.GreaterThan: 
                {
                    return GreaterThan(context, target, element);
                }

                case FilterOperator.GreaterThanOrEqual: 
                {
                    return GreaterThanOrEqual(context, target, element);
                }

                case FilterOperator.LessThan: 
                {
                    return LessThan(context, target, element);
                }

                case FilterOperator.LessThanOrEqual: 
                {
                    return LessThanOrEqual(context, target, element);
                }

                case FilterOperator.Between: 
                {
                    return Between(context, target, element);
                }

                case FilterOperator.InList: 
                {
                    return InList(context, target, element);
                }

                case FilterOperator.Like: 
                {
                    return Like(context, target, element);
                }                    

                case FilterOperator.IsNull: 
                {
                    return IsNull(context, target, element);
                }             

                case FilterOperator.Cast: 
                {
                    return Cast(context, target, element);
                }

                case FilterOperator.OfType: 
                {
                    return OfType(context, target, element);
                }

                case FilterOperator.InView: 
                {
                    return InView(context, target, element);
                }

                case FilterOperator.RelatedTo: 
                {
                    return RelatedTo(context, target, element);
                }
            }
                        
            throw new ServiceResultException(StatusCodes.BadUnexpectedError, "FilterOperator is not recognized.");
        }
        /// <summary>
        /// Like FilterOperator
        /// </summary>
        private bool Like(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            object firstOperand = GetValue(context, operands[0], target);
            string lhs;
            LocalizedText firstOperandLocalizedText = firstOperand as LocalizedText;
            if (firstOperandLocalizedText != null)
            {
                lhs = firstOperandLocalizedText.Text;
            }
            else
            {
                lhs = firstOperand as string;
            }
            
            object secondOperand = GetValue(context, operands[1], target);
            string rhs;
            LocalizedText secondOperandLocalizedText = secondOperand as LocalizedText;
            if (secondOperandLocalizedText != null)
            {
                rhs = secondOperandLocalizedText.Text;
            }
            else
            {
                rhs = secondOperand as string;
            }

            // this operator requires strings.
            if (lhs == null || rhs == null)
            {
                return false;
            }
          
            return Match((string)lhs, (string)rhs);
        }
        /// <summary>
		/// Adds an event to the queue.
		/// </summary>
        public virtual void QueueEvent(IFilterTarget instance, bool bypassFilter)
        {
            if (instance == null) throw new ArgumentNullException("instance");
         
            lock (m_lock)
			{
                // this method should only be called for objects or views. 
                if ((m_typeMask & MonitoredItemTypeMask.Events) == 0)
                {
                    throw new ServiceResultException(StatusCodes.BadInternalError);
                }
                
                // can't do anything if queuing is disabled.
                if (m_events == null)
                {
                    return;
                }

                // check for duplicate instances being reported via multiple paths.
                for (int ii = 0; ii < m_events.Count; ii++)
                {
                    EventFieldList processedEvent = m_events[ii] as EventFieldList;

                    if (processedEvent != null)
                    {
                        if (Object.ReferenceEquals(instance, processedEvent.Handle))
                        {
                            return;
                        }
                    }
                }

                // check for space in the queue.
                if (m_events.Count >= m_queueSize)
                {
                    if (!m_discardOldest)
                    {
                        m_overflow = true;
                        return;
                    }
                }
                
                // construct the context to use for the event filter.
                FilterContext context = new FilterContext(m_server.NamespaceUris, m_server.TypeTree, m_session.PreferredLocales);

                // event filter must be specified.
                EventFilter filter = m_filterToUse as EventFilter;

                if (filter == null)
                {
                    throw new ServiceResultException(StatusCodes.BadInternalError);
                }
                
                // apply filter.
                if (!bypassFilter)
                {
                    if (!filter.WhereClause.Evaluate(context, instance))
                    {
                        return;
                    }
                }
                
                // fetch the event fields.
                EventFieldList fields = GetEventFields(context, filter, instance);
                QueueEvent(fields);
			}
        }
        /// <summary>
        /// Cast FilterOperator
        /// </summary>
        private object Cast(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);
            
            // get the value to cast.
            object value = GetValue(context, operands[0], target);

            if (value == null)
            {
                return null;
            }

            // get the datatype to cast to.
            NodeId datatype = GetValue(context, operands[1], target) as NodeId;

            if (datatype == null)
            {
                return null;
            }

            BuiltInType targetType = GetBuiltInType(datatype);
            
            // cast the value.
            return Cast(value, targetType);
        }
        /// <summary>
        /// Like FilterOperator
        /// </summary>
        private bool Like(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            object lhs = GetValue(context, operands[0], target) as string;
            object rhs = GetValue(context, operands[1], target) as string;

            // this operator requires strings.
            if (lhs == null || rhs == null)
            {
                return false;
            }
          
            return Match((string)lhs, (string)rhs);
        }
        /// <summary>
        /// OfType FilterOperator
        /// </summary>
        private bool OfType(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 1);
            
            // get the desired type.
            NodeId typeDefinitionId = GetValue(context, operands[0], target) as NodeId;

            if (typeDefinitionId == null || target == null)
            {
                return false;
            }

            // check the type.
            try
            {
                return target.IsTypeOf(context, typeDefinitionId);
            }
            catch
            {
                return false;
            }
        }
 /// <summary>
 /// Called by any component to report a global event.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="e">The event.</param>
 public void ReportEvent(ISystemContext context, IFilterTarget e)
 {
     m_serverObject.ReportEvent(context, e);
 }
 /// <summary>
 /// RelatedTo FilterOperator
 /// </summary>
 private bool RelatedTo(FilterContext context, IFilterTarget target, ContentFilterElement element)
 {
     return RelatedTo(context, target, element, null);
 }
        /// <summary>
        /// Or FilterOperator
        /// </summary>
        private bool? Or(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            bool? lhs = GetValue(context, operands[0], target) as bool?;

            // no need for further processing if first operand is true.
            if (lhs != null && lhs.Value)
            {
                return true;
            }

            bool? rhs = GetValue(context, operands[1], target) as bool?;
            
            if (lhs == null)
            {
                if (rhs == null || rhs == false)
            {
                return null;
            }
                else
                {
                    return true;
                }
            }

            if (rhs == null)
            {
                if (lhs == null || lhs == false)
                {
                    return null;
                }
                else
                {
                    return true;
                }
            }
            
            return lhs.Value || rhs.Value;
        }
        /// <summary>
        /// Sets the flag which indicates whether event are being monitored for the instance and its children.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="e">The event to report.</param>
        public override void ReportEvent(ISystemContext context, IFilterTarget e)
        {
            base.ReportEvent(context, e);

            // recusively notify the parent.
            if (m_parent != null)
            {
                m_parent.ReportEvent(context, e);
            }
        }
        /// <summary>
        /// Not FilterOperator
        /// </summary>
        private bool? Not(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 1);

            bool? rhs = GetValue(context, operands[0], target) as bool?;
            
            if (rhs == null)
            {
                return null;
            }
            
            return !rhs.Value;
        }
        /// <summary>
		/// Adds an event to the queue.
        /// </summary>
        public virtual void QueueEvent(IFilterTarget instance)
        {
            QueueEvent(instance, false);
        }
 /// <summary>
 /// Called by any component to report a global event.
 /// </summary>
 /// <param name="e">The event.</param>
 public void ReportEvent(IFilterTarget e)
 {
     m_serverObject.ReportEvent(this.DefaultSystemContext, e);
 }
        /// <summary>
        /// Fetches the event fields from the event.
        /// </summary>
        private EventFieldList GetEventFields(FilterContext context, EventFilter filter, IFilterTarget instance)
        {
            // fetch the event fields.
            EventFieldList fields = new EventFieldList();

            fields.ClientHandle = m_clientHandle;
            fields.Handle = instance;

            foreach (SimpleAttributeOperand clause in filter.SelectClauses)
            {
                // get the value of the attribute (apply localization).
                object value = instance.GetAttributeValue(
                    context, 
                    clause.TypeDefinitionId, 
                    clause.BrowsePath, 
                    clause.AttributeId, 
                    clause.ParsedIndexRange);

                // add the value to the list of event fields.
                if (value != null)
                {
                    // translate any localized text.
                    LocalizedText text = value as LocalizedText;

                    if (text != null)
                    {
                        value = m_server.ResourceManager.Translate(m_session.PreferredLocales, text);
                    }

                    // add value.
                    fields.EventFields.Add(new Variant(value));
                }

                // add a dummy entry for missing values.
                else
                {
                    fields.EventFields.Add(Variant.Null);
                }
            }

            return fields;
        }
        /// <summary>
        /// And FilterOperator
        /// </summary>
        private bool? And(FilterContext context, IFilterTarget target, ContentFilterElement element)
        {
            FilterOperand[] operands = GetOperands(element, 2);

            bool? lhs = GetValue(context, operands[0], target) as bool?;

            // no need for further processing if first operand is false.
            if (lhs != null && !lhs.Value)
            {
                return false;
            }

            bool? rhs = GetValue(context, operands[1], target) as bool?;
            
            if (lhs == null)
            {
                return (rhs == null)?null:(bool?)false;
            }
            
            if (rhs == null)
            {
                return (lhs == null)?null:(bool?)false;
            }

            return lhs.Value && rhs.Value;
        }