Пример #1
0
 /// <summary>
 /// Visit a SingleComplexNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>true, indicating that the node has been visited.</returns>
 public override bool Visit(SingleComplexNode nodeIn)
 {
     validate(nodeIn);
     validate(nodeIn.Property);
     validate(nodeIn.TypeReference.Definition);
     return(true);
 }
        public override SingleValueNode Visit(SingleValuePropertyAccessNode nodeIn)
        {
            if (nodeIn.Source != null)
            {
                if (nodeIn.Source.Kind == QueryNodeKind.SingleNavigationNode)
                {
                    SingleNavigationNode singleNavigationNode = nodeIn.Source as SingleNavigationNode;
                    if (EdmLibHelpers.IsNotSortable(nodeIn.Property, singleNavigationNode.NavigationProperty,
                                                    singleNavigationNode.NavigationProperty.ToEntityType(), _model, _enableOrderBy))
                    {
                        return(nodeIn);
                    }
                }
                else if (nodeIn.Source.Kind == QueryNodeKind.SingleComplexNode)
                {
                    SingleComplexNode singleComplexNode = nodeIn.Source as SingleComplexNode;
                    if (EdmLibHelpers.IsNotSortable(nodeIn.Property, singleComplexNode.Property,
                                                    nodeIn.Property.DeclaringType, _model, _enableOrderBy))
                    {
                        return(nodeIn);
                    }
                }
                else if (EdmLibHelpers.IsNotSortable(nodeIn.Property, _property, _structuredType, _model, _enableOrderBy))
                {
                    return(nodeIn);
                }
            }

            if (nodeIn.Source != null)
            {
                return(nodeIn.Source.Accept(this));
            }

            return(null);
        }
        private static string GetNavigationPath(SingleComplexNode nodeIn)
        {
            if (nodeIn.NavigationSource == null)
            {
                return(nodeIn.Property.Name);
            }

            string[] pathSegments;
            if (nodeIn.Source.Kind == QueryNodeKind.SingleComplexNode)
            {
                var paths = GetPathFromSource(nodeIn.Source as SingleComplexNode);
                paths.Add(nodeIn.Property.Name);
                pathSegments = paths.ToArray();
            }
            else
            {
                if (nodeIn.NavigationSource.Path.PathSegments.ToArray().Length > 1)
                {
                    pathSegments = nodeIn.NavigationSource.Path.PathSegments.Skip(1).ToArray();
                }
                else
                {
                    pathSegments = new[] { nodeIn.Property.Name }
                };
            }

            var path = string.Join(Constants.SymbolDot, pathSegments);

            return(string.IsNullOrWhiteSpace(path) ? string.Empty : path);
        }
Пример #4
0
        /// <summary>
        /// We return the <see cref="ResourceRangeVariableReferenceNode"/> within a <see cref="QueryNode"/>
        /// </summary>
        /// <param name="node">The node to extract the ResourceRangeVariableReferenceNode.</param>
        /// <returns>The extracted ResourceRangeVariableReferenceNode.</returns>
        private ResourceRangeVariableReferenceNode GetResourceRangeVariableReferenceNode(QueryNode node)
        {
            if (node == null)
            {
                return(null);
            }

            switch (node.Kind)
            {
            case QueryNodeKind.SingleValuePropertyAccess:
                SingleValuePropertyAccessNode singleValuePropertyAccessNode = node as SingleValuePropertyAccessNode;
                return(GetResourceRangeVariableReferenceNode(singleValuePropertyAccessNode.Source));

            case QueryNodeKind.Convert:
                ConvertNode convertNode = node as ConvertNode;
                return(GetResourceRangeVariableReferenceNode(convertNode.Source));

            case QueryNodeKind.Any:
                AnyNode anyNode = node as AnyNode;
                return(GetResourceRangeVariableReferenceNode(anyNode.Source));

            case QueryNodeKind.SingleValueFunctionCall:
                SingleValueFunctionCallNode singleValueFunctionCallNode = node as SingleValueFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(singleValueFunctionCallNode.Parameters.First()));

            case QueryNodeKind.ResourceRangeVariableReference:
                return(node as ResourceRangeVariableReferenceNode);

            case QueryNodeKind.SingleValueOpenPropertyAccess:
                SingleValueOpenPropertyAccessNode singleValueOpenPropertyAccessNode = node as SingleValueOpenPropertyAccessNode;
                return(GetResourceRangeVariableReferenceNode(singleValueOpenPropertyAccessNode.Source));

            case QueryNodeKind.SingleComplexNode:
                SingleComplexNode singleComplexNode = node as SingleComplexNode;
                return(GetResourceRangeVariableReferenceNode(singleComplexNode.Source));

            case QueryNodeKind.CollectionComplexNode:
                CollectionComplexNode collectionComplexNode = node as CollectionComplexNode;
                return(GetResourceRangeVariableReferenceNode(collectionComplexNode.Source));

            case QueryNodeKind.CollectionNavigationNode:
                CollectionNavigationNode collectionNavigationNode = node as CollectionNavigationNode;
                return(GetResourceRangeVariableReferenceNode(collectionNavigationNode.Source));

            case QueryNodeKind.SingleNavigationNode:
                SingleNavigationNode singleNavigationNode = node as SingleNavigationNode;
                return(GetResourceRangeVariableReferenceNode(singleNavigationNode.Source));

            case QueryNodeKind.CollectionResourceFunctionCall:
                CollectionResourceFunctionCallNode collectionResourceFunctionCallNode = node as CollectionResourceFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(collectionResourceFunctionCallNode.Source));

            case QueryNodeKind.SingleResourceFunctionCall:
                SingleResourceFunctionCallNode singleResourceFunctionCallNode = node as SingleResourceFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(singleResourceFunctionCallNode.Source));
            }

            return(null);
        }
Пример #5
0
        /// <summary>
        /// Translate a SingleComplexNode.
        /// </summary>
        /// <param name="nodeIn">The node to be translated.</param>
        /// <returns>The translated node.</returns>
        public override QueryNode Visit(SingleComplexNode nodeIn)
        {
            Contract.Assert(nodeIn != null);

            return(new SingleComplexNode(
                       (SingleResourceNode)nodeIn.Source.Accept(this),
                       nodeIn.Property));
        }
Пример #6
0
        private GroupByTransformationNode BindGroupByToken(GroupByToken token)
        {
            List <GroupByPropertyNode> properties = new List <GroupByPropertyNode>();

            foreach (EndPathToken propertyToken in token.Properties)
            {
                QueryNode bindResult = this.bindMethod(propertyToken);
                SingleValuePropertyAccessNode property        = bindResult as SingleValuePropertyAccessNode;
                SingleComplexNode             complexProperty = bindResult as SingleComplexNode;

                if (property != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(property));
                }
                else if (complexProperty != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(complexProperty));
                }
                else
                {
                    SingleValueOpenPropertyAccessNode openProperty = bindResult as SingleValueOpenPropertyAccessNode;
                    if (openProperty != null)
                    {
                        IEdmTypeReference type = GetTypeReferenceByPropertyName(openProperty.Name);
                        properties.Add(new GroupByPropertyNode(openProperty.Name, openProperty, type));
                    }
                    else
                    {
                        throw new ODataException(
                                  ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(propertyToken.Identifier));
                    }
                }
            }

            var newProperties = new HashSet <EndPathToken>(((GroupByToken)token).Properties);

            TransformationNode aggregate = null;

            if (token.Child != null)
            {
                if (token.Child.Kind == QueryTokenKind.Aggregate)
                {
                    aggregate = BindAggregateToken((AggregateToken)token.Child);
                    aggregateExpressionsCache = ((AggregateTransformationNode)aggregate).AggregateExpressions;
                    newProperties.UnionWith(aggregateExpressionsCache.Select(statement => new EndPathToken(statement.Alias, null)));
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ApplyBinder_UnsupportedGroupByChild(token.Child.Kind));
                }
            }

            state.AggregatedPropertyNames = newProperties;

            // TODO: Determine source
            return(new GroupByTransformationNode(properties, aggregate, null));
        }
Пример #7
0
 /// <summary>
 /// Writes single complex property node to string.
 /// </summary>
 /// <param name="node">Node to write to string</param>
 /// <returns>String representation of node.</returns>
 private static string ToString(SingleComplexNode node)
 {
     return(tabHelper.Prefix + "SingleComplexNode" +
            tabHelper.Indent(() =>
                             tabHelper.Prefix + "Property = " + node.Property.Name +
                             tabHelper.Prefix + "TypeReference = " + node.TypeReference +
                             tabHelper.Prefix + "Source = " + ToString(node.Source)
                             ));
 }
Пример #8
0
        /// <summary>
        /// Binds a <see cref="SingleComplexNode"/> to create a LINQ <see cref="Expression"/> that
        /// represents the semantics of the <see cref="SingleComplexNode"/>.
        /// </summary>
        /// <param name="singleComplexNode">The node to bind.</param>
        /// <returns>The LINQ <see cref="Expression"/> created.</returns>
        public virtual Expression BindSingleComplexNode(SingleComplexNode singleComplexNode)
        {
            if (singleComplexNode == null)
            {
                throw Error.ArgumentNull(nameof(singleComplexNode));
            }

            Expression source = Bind(singleComplexNode.Source);

            return(CreatePropertyAccessExpression(source, singleComplexNode.Property, GetFullPropertyPath(singleComplexNode)));
        }
Пример #9
0
 public override ImmutableList <string> Visit(SingleComplexNode nodeIn)
 {
     if (nodeIn.Source is SingleComplexNode)
     {
         return(nodeIn.Source.Accept(this).Add(nodeIn.Property.Name));
     }
     else
     {
         return(ImmutableList.Create(nodeIn.Property.Name));
     }
 }
        /// <summary>
        /// Translate a SingleComplexNode.
        /// </summary>
        /// <param name="nodeIn">The node to be translated.</param>
        /// <returns>The translated node.</returns>
        public override QueryNode Visit(SingleComplexNode nodeIn)
        {
            if (nodeIn == null)
            {
                throw Error.ArgumentNull(nameof(nodeIn));
            }

            return(new SingleComplexNode(
                       (SingleResourceNode)nodeIn.Source.Accept(this),
                       nodeIn.Property));
        }
        private static List <string> GetPathFromSource(SingleComplexNode node)
        {
            if (!(node.Source is SingleComplexNode))
            {
                return(new List <string> {
                    node.Property.Name
                });
            }

            var sources = GetPathFromSource((SingleComplexNode)node.Source);

            sources.Add(node.Property.Name);
            return(sources);
        }
        public override SingleValueNode Visit(SingleComplexNode nodeIn)
        {
            if (EdmLibHelpers.IsNotSortable(nodeIn.Property, _property, _structuredType, _model, _enableOrderBy))
            {
                return(nodeIn);
            }

            if (nodeIn.Source != null)
            {
                return(nodeIn.Source.Accept(this));
            }

            return(null);
        }
Пример #13
0
        /// <summary>
        /// Override this method to validate single complex property accessor.
        /// </summary>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code.
        /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance.
        /// </remarks>
        /// <param name="singleComplexNode"></param>
        /// <param name="settings"></param>
        protected virtual void ValidateSingleComplexNode(SingleComplexNode singleComplexNode, ODataValidationSettings settings)
        {
            Contract.Assert(singleComplexNode != null);
            Contract.Assert(settings != null);

            // Check whether the property is filterable.
            IEdmProperty property = singleComplexNode.Property;

            if (EdmHelpers.IsNotFilterable(property, _property, _structuredType, _model,
                                           _defaultQuerySettings.EnableFilter))
            {
                throw new ODataException(Error.Format(SRResources.NotFilterablePropertyUsedInFilter, property.Name));
            }

            ValidateQueryNode(singleComplexNode.Source, settings);
        }
Пример #14
0
        /// <summary>
        /// Override this method to validate property accessor.
        /// </summary>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code.
        /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance.
        /// </remarks>
        /// <param name="propertyAccessNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
        {
            if (propertyAccessNode == null)
            {
                throw Error.ArgumentNull(nameof(propertyAccessNode));
            }

            if (settings == null)
            {
                throw Error.ArgumentNull(nameof(settings));
            }

            // Check whether the property is filterable.
            IEdmProperty property      = propertyAccessNode.Property;
            bool         notFilterable = false;

            if (propertyAccessNode.Source != null)
            {
                if (propertyAccessNode.Source.Kind == QueryNodeKind.SingleNavigationNode)
                {
                    SingleNavigationNode singleNavigationNode = propertyAccessNode.Source as SingleNavigationNode;
                    notFilterable = EdmHelpers.IsNotFilterable(property, singleNavigationNode.NavigationProperty,
                                                               singleNavigationNode.NavigationProperty.ToEntityType(), _model,
                                                               _defaultQuerySettings.EnableFilter);
                }
                else if (propertyAccessNode.Source.Kind == QueryNodeKind.SingleComplexNode)
                {
                    SingleComplexNode singleComplexNode = propertyAccessNode.Source as SingleComplexNode;
                    notFilterable = EdmHelpers.IsNotFilterable(property, singleComplexNode.Property,
                                                               property.DeclaringType, _model, _defaultQuerySettings.EnableFilter);
                }
                else
                {
                    notFilterable = EdmHelpers.IsNotFilterable(property, _property, _structuredType, _model,
                                                               _defaultQuerySettings.EnableFilter);
                }
            }

            if (notFilterable)
            {
                throw new ODataException(Error.Format(SRResources.NotFilterablePropertyUsedInFilter, property.Name));
            }

            ValidateQueryNode(propertyAccessNode.Source, settings);
        }
Пример #15
0
        private static List <string> GetPathFromSource(SingleComplexNode node)
        {
            if (node.Source is ResourceRangeVariableReferenceNode referenceNode)
            {
                var path = GetPathFromSource(referenceNode);
                path.Add(node.Property.Name);
                return(path);
            }

            if (!(node.Source is SingleComplexNode))
            {
                return(new List <string> {
                    node.Property.Name
                });
            }

            var sources = GetPathFromSource((SingleComplexNode)node.Source);

            sources.Add(node.Property.Name);
            return(sources);
        }
Пример #16
0
        /// <summary>
        /// Override this method to validate single complex property accessor.
        /// </summary>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code.
        /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance.
        /// </remarks>
        /// <param name="singleComplexNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateSingleComplexNode(SingleComplexNode singleComplexNode, ODataValidationSettings settings)
        {
            if (singleComplexNode == null)
            {
                throw Error.ArgumentNull("singleComplexNode");
            }

            if (settings == null)
            {
                throw Error.ArgumentNull("settings");
            }

            // Check whether the property is filterable.
            IEdmProperty property = singleComplexNode.Property;

            if (EdmHelpers.IsNotFilterable(property, _property, _structuredType, _model,
                                           _defaultQuerySettings.EnableFilter))
            {
                throw new ODataException(Error.Format(SRResources.NotFilterablePropertyUsedInFilter, property.Name));
            }

            ValidateQueryNode(singleComplexNode.Source, settings);
        }
Пример #17
0
 /// <summary>
 /// Translates a <see cref="SingleComplexNode"/> into a corresponding <see cref="String"/>.
 /// </summary>
 /// <param name="node">The node to translate.</param>
 /// <returns>The translated String.</returns>
 public override String Visit(SingleComplexNode node)
 {
     ExceptionUtils.CheckArgumentNotNull(node, "node");
     return(this.TranslatePropertyAccess(node.Source, node.Property.Name));
 }
 public override T Visit(SingleComplexNode nodeIn) => DebuggerBreakVisited(nodeIn);
Пример #19
0
        public override QueryNode Visit(SingleComplexNode nodeIn)
        {
            SingleResourceNode?source = nodeIn.Source == null ? null : (SingleResourceNode)Visit(nodeIn.Source);

            return(new SingleComplexNode(source, nodeIn.Property));
        }
Пример #20
0
 private static void VerifySingleComplexNodeAreEqual(SingleComplexNode expected, SingleComplexNode actual, AssertionHandler assert)
 {
     VerifyQueryNodesAreEqual(expected.Source, actual.Source, assert);
     QueryTestUtils.VerifyPropertiesAreEqual(expected.Property, actual.Property, assert);
 }
Пример #21
0
 public override void ValidateSingleComplexNode(SingleComplexNode singleComplexNode, ODataValidationSettings settings)
 {
     IncrementCount("ValidateSingleComplexNode");
     base.ValidateSingleComplexNode(singleComplexNode, settings);
 }
Пример #22
0
 /// <summary>
 /// Translate a SingleComplexNode.
 /// </summary>
 /// <param name="nodeIn">The node to be translated.</param>
 /// <returns>The translated node.</returns>
 public override QueryNode Visit(SingleComplexNode nodeIn)
 {
     return(new SingleComplexNode(
                (SingleResourceNode)nodeIn.Source.Accept(this),
                nodeIn.Property));
 }
Пример #23
0
 /// <summary>
 /// Visit an SingleComplexNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>The translated expression</returns>
 public override Expression Visit(SingleComplexNode nodeIn)
 {
     this.CheckArgumentNull(nodeIn, "node");
     return(this.TranslatePropertyAccess(nodeIn.Source, nodeIn.Property));
 }
Пример #24
0
        /// <summary>
        /// Binds a <see cref="SingleComplexNode"/> to create a LINQ <see cref="Expression"/> that
        /// represents the semantics of the <see cref="SingleComplexNode"/>.
        /// </summary>
        /// <param name="singleComplexNode">The node to bind.</param>
        /// <returns>The LINQ <see cref="Expression"/> created.</returns>
        public virtual Expression BindSingleComplexNode(SingleComplexNode singleComplexNode)
        {
            Expression source = Bind(singleComplexNode.Source);

            return(CreatePropertyAccessExpression(source, singleComplexNode.Property, GetFullPropertyPath(singleComplexNode)));
        }
Пример #25
0
 /// <inheritdoc />
 public override string Visit(SingleComplexNode node)
 {
     return(GetNavigationPath(node));
 }
Пример #26
0
 public override string Visit(SingleComplexNode nodeIn) => $"{nodeIn.Property.Name}{nodeIn.Source.Accept(this)}";                    // return base.Visit(nodeIn);