예제 #1
0
        /// <summary>
        /// Returns the operands for the element.
        /// </summary>
        /// <returns>The list of operands for the element.</returns>
        public List <FilterOperand> GetOperands()
        {
            List <FilterOperand> operands = new List <FilterOperand>(FilterOperands.Count);

            foreach (ExtensionObject extension in FilterOperands)
            {
                if (ExtensionObject.IsNull(extension))
                {
                    continue;
                }

                FilterOperand operand = extension.Body as FilterOperand;

                if (operand == null)
                {
                    continue;
                }

                operands.Add(operand);
            }

            return(operands);
        }
        /// <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>
        /// Returns the operands for the element.
        /// </summary>
        private FilterOperand[] GetOperands(ContentFilterElement element, int expectedCount)
        {
            FilterOperand[] operands = new FilterOperand[element.FilterOperands.Count]; 

            int ii = 0;

            foreach (ExtensionObject extension in element.FilterOperands)
            {
                if (ExtensionObject.IsNull(extension))
                {
                    throw new ServiceResultException(StatusCodes.BadUnexpectedError, "FilterOperand is null.");
                }

                FilterOperand operand = extension.Body as FilterOperand;

                if (operand == null)
                {
                    throw new ServiceResultException(StatusCodes.BadUnexpectedError, "FilterOperand is not supported.");
                }
               
                operands[ii++] = operand;
            }

            if (expectedCount > 0 && expectedCount != operands.Length)
            {
                throw new ServiceResultException(StatusCodes.BadUnexpectedError, "ContentFilterElement does not have the correct number of operands.");
            }

            return operands;
        }
예제 #4
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 = 4;
                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);
        }
예제 #5
0
        /// <summary>
        /// Pushes a new element onto the stack.
        /// </summary>
        /// <param name="op">The filter operator.</param>
        /// <param name="operands">The operands.</param>
        /// <returns></returns>
        public ContentFilterElement Push(FilterOperator op, params object[] operands)
        {
            // check if nothing more to do.
            if (operands == null || operands.Length == 0)
            {
                throw ServiceResultException.Create(StatusCodes.BadInvalidArgument, "ContentFilterElement does not have an operands.");
            }

            // create the element and set the operator.
            ContentFilterElement element = new ContentFilterElement();

            element.FilterOperator = op;

            for (int ii = 0; ii < operands.Length; ii++)
            {
                // check if a FilterOperand was provided.
                FilterOperand filterOperand = operands[ii] as FilterOperand;

                if (filterOperand != null)
                {
                    element.FilterOperands.Add(new ExtensionObject(filterOperand));
                    continue;
                }

                // check for reference to another ContentFilterElement.
                ContentFilterElement existingElement = operands[ii] as ContentFilterElement;

                if (existingElement != null)
                {
                    int index = FindElementIndex(existingElement);

                    if (index == -1)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadInvalidArgument, "ContentFilterElement is not part of the ContentFilter.");
                    }

                    ElementOperand operand = new ElementOperand();
                    operand.Index = (uint)index;

                    element.FilterOperands.Add(new ExtensionObject(operand));
                    continue;
                }

                // assume a literal operand.
                LiteralOperand literalOperand = new LiteralOperand();
                literalOperand.Value = new Variant(operands[ii]);
                element.FilterOperands.Add(new ExtensionObject(literalOperand));
            }

            // insert the new element at the begining of the list.
            m_elements.Insert(0, element);

            // re-number ElementOperands since all element were shifted up.
            for (int ii = 0; ii < m_elements.Count; ii++)
            {
                foreach (ExtensionObject extension in m_elements[ii].FilterOperands)
                {
                    if (extension != null)
                    {
                        ElementOperand operand = extension.Body as ElementOperand;

                        if (operand != null)
                        {
                            operand.Index++;
                        }
                    }
                }
            }

            // return new element.
            return(element);
        }