Provides context information to used when searching the address space.
Inheritance: IOperationContext
Esempio n. 1
0
        /// <summary>
        /// Validates the ContentFilter.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>The result of validation.</returns>
        public Result Validate(FilterContext context)
        {
            Result result = new Result(null);
            
            // check for empty filter.
            if (m_elements == null || m_elements.Count == 0)
            {
                return result;
            }            

            bool error = false;

            for (int ii = 0; ii < m_elements.Count; ii++)
            {
                ContentFilterElement element = m_elements[ii];
                
                // check for null.
                if (element == null)
                {
                    ServiceResult nullResult = ServiceResult.Create(
                        StatusCodes.BadStructureMissing, 
                        "ContentFilterElement is null (Index={0}).",
                        ii);

                    result.ElementResults.Add(new ElementResult(nullResult));
                    error = true;
                    continue;
                }
                
                element.Parent = this;

                // validate element.
                ElementResult elementResult = element.Validate(context, ii);

                if (ServiceResult.IsBad(elementResult.Status))
                {
                    result.ElementResults.Add(elementResult);
                    error = true;
                    continue;
                }

                result.ElementResults.Add(null);
            }
            
            // ensure the global error code.
            if (error)
            {
                result.Status = StatusCodes.BadContentFilterInvalid;
            }
            else
            {
                result.ElementResults.Clear();
            }

            return result;
        }
        /// <summary>
        /// Returns true if the snapshort is an instance of the specified type.
        /// </summary>
        /// <param name="context">The context to use when checking the type definition.</param>
        /// <param name="typeDefinitionId">The type of the instance.</param>
        /// <returns>
        /// True if the object is an instance of the specified type.
        /// </returns>
        public bool IsTypeOf(FilterContext context, NodeId typeDefinitionId)
        {
            if (!NodeId.IsNull(typeDefinitionId))
            {
                if (!context.TypeTree.IsTypeOf(m_typeDefinitionId, typeDefinitionId))
                {
                    return false;
                }
            }

            return true;
        }
        /// <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>
        /// 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>
        /// 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);
        }
        /// <summary>
        /// Creates a new history request.
        /// </summary>
        private HistoryReadRequest CreateHistoryReadRequest(
            ServerSystemContext context,
            ReadEventDetails details,
            NodeHandle handle,
            HistoryReadValueId nodeToRead)
        {
            FilterContext filterContext = new FilterContext(context.NamespaceUris, context.TypeTable, context.PreferredLocales);
            LinkedList<BaseEventState> events = new LinkedList<BaseEventState>();

            for (ReportType ii = ReportType.FluidLevelTest; ii <= ReportType.InjectionTest; ii++)
            {
                DataView view = null;

                if (handle.Node is WellState)
                {
                    view = m_generator.ReadHistoryForWellId(
                        ii,
                        (string)handle.Node.NodeId.Identifier,
                        details.StartTime,
                        details.EndTime);
                }
                else
                {
                    view = m_generator.ReadHistoryForArea(
                        ii,
                        handle.Node.NodeId.Identifier as string,
                        details.StartTime,
                        details.EndTime);
                }

                LinkedListNode<BaseEventState> pos = events.First;
                bool sizeLimited = (details.StartTime == DateTime.MinValue || details.EndTime == DateTime.MinValue);

                foreach (DataRowView row in view)
                {
                    // check if reached max results.
                    if (sizeLimited)
                    {
                        if (events.Count >= details.NumValuesPerNode)
                        {
                            break;
                        }
                    }

                    BaseEventState e = m_generator.GetReport(context, NamespaceIndex, ii, row.Row);

                    if (details.Filter.WhereClause != null && details.Filter.WhereClause.Elements.Count > 0)
                    {
                        if (!details.Filter.WhereClause.Evaluate(filterContext, e))
                        {
                            continue;
                        }
                    }

                    bool inserted = false;

                    for (LinkedListNode<BaseEventState> jj = pos; jj != null; jj = jj.Next)
                    {
                        if (jj.Value.Time.Value > e.Time.Value)
                        {
                            events.AddBefore(jj, e);
                            pos = jj;
                            inserted = true;
                            break;
                        }
                    }

                    if (!inserted)
                    {
                        events.AddLast(e);
                        pos = null;
                    }
                }
            }

            HistoryReadRequest request = new HistoryReadRequest();
            request.Events = events;
            request.TimeFlowsBackward = details.StartTime == DateTime.MinValue || (details.EndTime != DateTime.MinValue && details.EndTime < details.StartTime);
            request.NumValuesPerNode = details.NumValuesPerNode;
            request.Filter = details.Filter;
            request.FilterContext = filterContext;
            return request;
        }
 /// <summary>
 /// RelatedTo FilterOperator
 /// </summary>
 private bool RelatedTo(FilterContext context, IFilterTarget target, ContentFilterElement element)
 {
     return RelatedTo(context, target, element, null);
 }
Esempio n. 8
0
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 public SimpleAttributeOperand(
     FilterContext        context, 
     ExpandedNodeId       typeId,
     IList<QualifiedName> browsePath)
 {
     m_typeDefinitionId = ExpandedNodeId.ToNodeId(typeId, context.NamespaceUris);
     m_browsePath       = new QualifiedNameCollection(browsePath);
     m_attributeId      = Attributes.Value;
     m_indexRange       = null;
 }
        /// <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;
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Validates the content filter element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="index">The index.</param>
        /// <returns>The results of the validation.</returns>
        public virtual ContentFilter.ElementResult Validate(FilterContext context, int index)
        {
            ContentFilter.ElementResult result = new ContentFilter.ElementResult(null);

            // check the number of operands.
            int operandCount = -1;

            switch (m_filterOperator)
            {
                case FilterOperator.Not:
                case FilterOperator.IsNull:
                case FilterOperator.InView:
                case FilterOperator.OfType:
                {
                    operandCount = 1;
                    break;
                }

                case FilterOperator.And:
                case FilterOperator.Or:
                case FilterOperator.Equals:
                case FilterOperator.GreaterThan:
                case FilterOperator.GreaterThanOrEqual:
                case FilterOperator.LessThan:
                case FilterOperator.LessThanOrEqual:
                case FilterOperator.Like:
                case FilterOperator.Cast:
                {
                    operandCount = 2;
                    break;
                }

                case FilterOperator.Between:
                {
                    operandCount = 3;
                    break;
                }

                case FilterOperator.RelatedTo:
                {
                    operandCount = 6;
                    break;
                }

                case FilterOperator.InList:
                {
                    operandCount = -1;
                    break;
                }

                default:
                {
                    break;
                }
            }

            if (operandCount != -1)
            {
                if (operandCount != m_filterOperands.Count)
                {                    
                    result.Status = ServiceResult.Create(
                        StatusCodes.BadEventFilterInvalid, 
                        "ContentFilterElement does not have the correct number of operands (Operator={0} OperandCount={1}).", 
                        m_filterOperator,
                        operandCount);

                    return result;
                }
            }
            else
            {
                if (m_filterOperands.Count < 2)
                {                    
                    result.Status = ServiceResult.Create(
                        StatusCodes.BadEventFilterInvalid, 
                        "ContentFilterElement does not have the correct number of operands (Operator={0} OperandCount={1}).", 
                        m_filterOperator,
                        m_filterOperands.Count);

                    return result;
                }
            }

            // validate the operands.
            bool error = false;

            for (int ii = 0; ii < m_filterOperands.Count; ii++)
            {
                ServiceResult operandResult = null;

                ExtensionObject operand = m_filterOperands[ii];
                
                // check for null.
                if (ExtensionObject.IsNull(operand))
                {
                    operandResult = ServiceResult.Create(
                        StatusCodes.BadEventFilterInvalid,
                        "The FilterOperand cannot be Null.");
                
                    result.OperandResults.Add(operandResult);
                    error = true;
                    continue;
                }            
                
                // check that the extension object contains a filter operand.
                FilterOperand filterOperand = operand.Body  as FilterOperand;

                if (filterOperand == null)
                {
                    operandResult = ServiceResult.Create(
                        StatusCodes.BadEventFilterInvalid,
                        "The FilterOperand is not a supported type ({0}).", 
                        filterOperand.GetType());

                    result.OperandResults.Add(operandResult);
                    error = true;
                    continue;
                }

                // validate the operand.
                filterOperand.Parent = this;
                operandResult = filterOperand.Validate(context, index);

                if (ServiceResult.IsBad(operandResult))
                {
                    result.OperandResults.Add(operandResult);
                    error = true;
                    continue;
                }

                result.OperandResults.Add(null);
            }
            
            // ensure the global error code.
            if (error)
            {
                result.Status = StatusCodes.BadContentFilterInvalid;
            }
            else
            {
                result.OperandResults.Clear();
            }

            return result;
        }
        /// <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);
        }
Esempio n. 12
0
        /// <summary>
        /// Validates the operand.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="index">The index.</param>
        /// <returns>The result of the validation</returns>
        public override ServiceResult Validate(FilterContext context, int index)
        {
            if (m_index < 0)
            {
                return ServiceResult.Create(
                    StatusCodes.BadFilterOperandInvalid, 
                    "ElementOperand specifies an Index that is less than zero ({0}).", 
                    m_index);
            }

            if (m_index <= index)
            {
                return ServiceResult.Create(
                    StatusCodes.BadFilterOperandInvalid, 
                    "ElementOperand references an element that precedes it in the ContentFilter.", 
                    m_index);
            }

            if (m_index >= Parent.Parent.Elements.Count)
            {
                return ServiceResult.Create(
                    StatusCodes.BadFilterOperandInvalid, 
                    "ElementOperand references an element that does not exist.", 
                    m_index);
            }

            return ServiceResult.Good;
        }
Esempio n. 13
0
        /// <summary>
        /// Validates the operand.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="index">The index.</param>
        /// <returns>The result of the validation</returns>
        public override ServiceResult Validate(FilterContext context, int index)
        {
            if (m_value.Value == null)
            {
                return ServiceResult.Create(
                    StatusCodes.BadEventFilterInvalid, 
                    "LiteralOperand specifies a null Value.");
            }

            return ServiceResult.Good;
        }
Esempio n. 14
0
        /// <summary>
        /// Validates the operand (sets the ParsedBrowsePath and ParsedIndexRange properties).
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="index">The index.</param>
        /// <returns>The result of the validation.</returns>
        public override ServiceResult Validate(FilterContext context, int index)
        {
            m_validated = false;

            // verify that the operand refers to a node in the type model.
            if (!context.TypeTree.IsKnown(m_nodeId))
            {                
                return ServiceResult.Create(
                    StatusCodes.BadTypeDefinitionInvalid, 
                    "AttributeOperand does not have a known TypeDefinitionId ({0}).", 
                    m_nodeId);
            }

            // verify attribute id.
            if (!Attributes.IsValid(m_attributeId))
            {
                return ServiceResult.Create(
                    StatusCodes.BadAttributeIdInvalid, 
                    "AttributeOperand does not specify a valid AttributeId ({0}).", 
                    m_attributeId);
            }

            // initialize as empty.
            m_parsedIndexRange = NumericRange.Empty;

            // parse the index range.
            if (!String.IsNullOrEmpty(m_indexRange))
            {
                try
                {
                    m_parsedIndexRange = NumericRange.Parse(m_indexRange);
                }
                catch (Exception e)
                {
                    return ServiceResult.Create(
                        e,
                        StatusCodes.BadIndexRangeInvalid, 
                        "AttributeOperand does not specify a valid BrowsePath ({0}).", 
                        m_indexRange);
                }

                if (m_attributeId != Attributes.Value)
                {
                    return ServiceResult.Create(
                        StatusCodes.BadIndexRangeInvalid, 
                        "AttributeOperand specifies an IndexRange for an Attribute other than Value ({0}).", 
                        m_attributeId);
                }
            }

            m_validated = true;

            return ServiceResult.Good;
        }
        /// <summary cref="IFilterTarget.GetAttributeValue" />
        public virtual object GetAttributeValue(
            FilterContext context, 
            NodeId typeDefinitionId, 
            IList<QualifiedName> relativePath, 
            uint attributeId, 
            NumericRange indexRange)
        {
            // check the type definition.
            if (!NodeId.IsNull(typeDefinitionId) && typeDefinitionId != ObjectTypes.BaseEventType)
            {
                if (!context.TypeTree.IsTypeOf(TypeDefinitionId, typeDefinitionId))
                {
                    return null;
                }
            }

            // read the child attribute.
            DataValue dataValue = new DataValue();   

            ServiceResult result = ReadChildAttribute(
                null,
                relativePath,
                0,
                attributeId,
                dataValue);
            
            if (ServiceResult.IsBad(result))
            {
                return null;
            }

            // apply any index range.
            object value = dataValue.Value;

            if (value != null)
            {
                result = indexRange.ApplyRange(ref value);
                
                if (ServiceResult.IsBad(result))
                {
                    return null;
                }
            }

            // return the result.
            return value;
        }
Esempio n. 16
0
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 public SimpleAttributeOperand(
     FilterContext  context, 
     ExpandedNodeId typeDefinitionId,
     string         browsePath,
     uint           attributeId,
     string         indexRange)
 {
     m_typeDefinitionId = ExpandedNodeId.ToNodeId(typeDefinitionId, context.NamespaceUris);
     m_browsePath       = Parse(browsePath);
     m_attributeId      = attributeId;
     m_indexRange       = indexRange;                
 }
        /// <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>
        /// 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>
        /// 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;
        }
Esempio n. 20
0
        /// <summary>
        /// Validates the object.
        /// </summary>
        public Result Validate(FilterContext context)
        {
            Result result = new Result();

            // check for top level error.
            if (m_selectClauses == null || m_selectClauses.Count == 0)
            {
                result.Status = ServiceResult.Create(
                    StatusCodes.BadStructureMissing, 
                    "EventFilter does not specify any Select Clauses.");

                return result;
            }            

            if (m_whereClause == null)
            {
                result.Status = ServiceResult.Create(
                    StatusCodes.BadStructureMissing, 
                    "EventFilter does not specify any Where Clauses.");

                return result;
            }

            result.Status = ServiceResult.Good;

            // validate select clause.
            bool error = false;

            foreach (SimpleAttributeOperand clause in m_selectClauses)
            {
                ServiceResult clauseResult = null;

                // check for null.
                if (clause == null)
                {
                    clauseResult = ServiceResult.Create(
                        StatusCodes.BadStructureMissing, 
                        "EventFilterSelectClause cannot be null in EventFilter SelectClause.");

                    result.SelectClauseResults.Add(clauseResult);
                    error = true;
                    continue;
                }

                // validate clause.
                clauseResult = clause.Validate(context, 0);

                if (ServiceResult.IsBad(clauseResult))
                {
                    result.SelectClauseResults.Add(clauseResult);
                    error = true;
                    continue;
                }
                
                // clause ok.                    
                result.SelectClauseResults.Add(null);
            }

            if (error)
            {
                result.Status = StatusCodes.BadEventFilterInvalid;
            }
            else
            {
                result.SelectClauseResults.Clear();
            }
            
            // validate where clause.          
            result.WhereClauseResult = m_whereClause.Validate(context);

            if (ServiceResult.IsBad(result.WhereClauseResult.Status))
            {
                result.Status = StatusCodes.BadEventFilterInvalid;
            }

            return result;
        }
        /// <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;
        }
Esempio n. 22
0
 /// <summary>
 /// Validates the operand.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="index">The index.</param>
 /// <returns>the result of the validation</returns>
 public virtual ServiceResult Validate(FilterContext context, int index)
 {
     return ServiceResult.Create(StatusCodes.BadEventFilterInvalid, "A sub-class of FilterOperand must be specified.");
 }
        /// <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.");
        }
Esempio n. 24
0
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="nodeId">The node identifier.</param>
 /// <param name="relativePath">The relative path.</param>
 public AttributeOperand(
     FilterContext  context, 
     ExpandedNodeId nodeId,
     RelativePath   relativePath)
 {
     m_nodeId      = ExpandedNodeId.ToNodeId(nodeId, context.NamespaceUris);
     m_browsePath  = relativePath;
     m_attributeId = Attributes.Value;
     m_indexRange  = null;
     m_alias       = null;
 }
        /// <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;
            }
        }
Esempio n. 26
0
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeDefinitionId">The type definition identifier.</param>
 /// <param name="browsePath">The browse path.</param>
 /// <param name="attributeId">The attribute identifier.</param>
 /// <param name="indexRange">The index range.</param>
 public AttributeOperand(
     FilterContext  context, 
     ExpandedNodeId typeDefinitionId,
     string         browsePath,
     uint           attributeId,
     string         indexRange)
 {
     m_nodeId      = ExpandedNodeId.ToNodeId(typeDefinitionId, context.NamespaceUris);
     m_browsePath  = RelativePath.Parse(browsePath, context.TypeTree);
     m_attributeId = attributeId;
     m_indexRange  = indexRange;
     m_alias       = null;                        
 }
        /// <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>
        /// 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>
        /// 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>
        /// 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;
        }