public void SingleExpandResultsInSingleExpandTree()
 {
     SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor();
     NonSystemToken path = new NonSystemToken("NavProp", null, null);
     path.IsStructuralProperty = false;
     path.Accept(visitor).Should().Be("NavProp");
 }
예제 #2
0
 public void IsNamespaceOrContainerQualifiedIsCorrect()
 {
     NonSystemToken token1 = new NonSystemToken("Fully.Qualified.Namespace", null, null);
     token1.IsNamespaceOrContainerQualified().Should().BeTrue();
     NonSystemToken token2 = new NonSystemToken("namespace", null, null);
     token2.IsNamespaceOrContainerQualified().Should().BeFalse();
 }
 public void MaxRecursiveDepthIsRespected()
 {
     NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("Fully.Qualified.Namespace.Manager", null, new NonSystemToken("NumberOfReports", null, null)));
     PathSegmentToken firstNonTypeToken;
     IEdmStructuredType entityType = HardCodedTestModel.GetPersonType();
     Action followLongChain = () => SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 1, ODataUriResolver.Default, ref entityType, out firstNonTypeToken);
     followLongChain.ShouldThrow<ODataException>().WithMessage(ODataErrorStrings.ExpandItemBinder_PathTooDeep);
 }
 public void InvalidTypeSegmentThrowsException()
 {
     NonSystemToken typeSegment = new NonSystemToken("Stuff", null, new NonSystemToken("stuff", null, null));
     PathSegmentToken firstNonTypeToken;
     IEdmStructuredType entityType = HardCodedTestModel.GetPersonType();
     Action followInvalidTypeSegment = () => SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken);
     followInvalidTypeSegment.ShouldThrow<ODataException>().WithMessage(ODataErrorStrings.SelectExpandPathBinder_FollowNonTypeSegment("Stuff"));
 }
 public void PathWithoutWildcardIsInvariant()
 {
     RemoveWildcardVisitor visitor = new RemoveWildcardVisitor();
     NonSystemToken token = new NonSystemToken("stuff", null, null);
     token.Accept(visitor);
     token.Identifier.Should().Be("stuff");
     token.NextToken.Should().BeNull();
 }
예제 #6
0
        public void NamedValuesSetCorrectly()
        {
            List<NamedValue> namedValues = new List<NamedValue>();
            namedValues.Add(new NamedValue("name", new LiteralToken("value")));

            NonSystemToken token = new NonSystemToken("stuff", namedValues, null);
            token.NamedValues.Should().OnlyContain(x => x.Name == "name" && x.Value.Value.As<string>() == "value");
        }
예제 #7
0
 public void ReversePathWorksWithStarToken()
 {
     // $expand=1/*
     PathReverser pathReverser = new PathReverser();
     PathSegmentToken nonReversedPath = new NonSystemToken("*", null, new NonSystemToken("1", null, null));
     PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser);
     reversedPath.ShouldBeNonSystemToken("1").And.NextToken.ShouldBeNonSystemToken("*");
 }
 public void ExpandOnlyPathResultsInExpandOnlyTree()
 {
     SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor();
     NonSystemToken path = new NonSystemToken("NavProp", null, new NonSystemToken("NavProp1", null, null));
     path.IsStructuralProperty = false;
     path.NextToken.IsStructuralProperty = false;
     path.Accept(visitor).Should().Be("NavProp($expand=NavProp1)");
 }
 public void SelectAtTheEndOfPathResultsInSelectQueryOption()
 {
     SelectExpandPathToStringVisitor visitor = new SelectExpandPathToStringVisitor();
     NonSystemToken path = new NonSystemToken("NavProp", null, new NonSystemToken("StructuralProp", null, null));
     path.IsStructuralProperty = false;
     path.NextToken.IsStructuralProperty = true;
     path.Accept(visitor).Should().Be("NavProp($select=StructuralProp)");
 }
예제 #10
0
 public void ReversePathWorksWithSingleSegment()
 {
     // $expand=1
     PathReverser pathReverser = new PathReverser();
     PathSegmentToken nonReversedPath = new NonSystemToken("1", null, null);
     PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser);
     reversedPath.ShouldBeNonSystemToken("1").And.NextToken.Should().BeNull();
 }
예제 #11
0
 public void ReversePathWorksWithATypeToken()
 {
     // $expand=Fully.Qualified.Namespace/1
     PathReverser pathReverser = new PathReverser();
     PathSegmentToken nonReversedPath = new NonSystemToken("1", null, new NonSystemToken("Fully.Qualified.Namespace", null, null));
     PathSegmentToken reversedPath = nonReversedPath.Accept(pathReverser);
     reversedPath.ShouldBeNonSystemToken("Fully.Qualified.Namespace").And.NextToken.ShouldBeNonSystemToken("1");
 }
 public void IfNewTokenIsNullInputIsInvariant()
 {
     AddNewEndingTokenVisitor visitor = new AddNewEndingTokenVisitor(null);
     NonSystemToken token = new NonSystemToken("stuff", null, null);
     token.Accept(visitor);
     token.Identifier.Should().Be("stuff");
     token.NextToken.Should().BeNull();
 }
 public void WildcardIsRemoved()
 {
     RemoveWildcardVisitor visitor = new RemoveWildcardVisitor();
     NonSystemToken token = new NonSystemToken("stuff", null, new NonSystemToken("*", null, null));
     token.Accept(visitor);
     token.Identifier.Should().Be("stuff");
     token.NextToken.Should().BeNull();
 }
예제 #14
0
        public void ExpandTermTokenPathIsSet()
        {
            PathSegmentToken pathToken = new NonSystemToken("SomeNavProp", null, null);

            ExpandOptionParser optionParser = new ExpandOptionParser(5);
            var termToken = optionParser.BuildExpandTermToken(pathToken, "");

            termToken.PathToNavProp.Should().Be(pathToken);
        }
 public void IfNewTokenIsPresentItIsAddedToEndOfPath()
 {
     AddNewEndingTokenVisitor visitor = new AddNewEndingTokenVisitor(new NonSystemToken("moreStuff", null, null));
     NonSystemToken token = new NonSystemToken("stuff", null, null);
     token.Accept(visitor);
     token.Identifier.Should().Be("stuff");
     token.NextToken.Identifier.Should().Be("moreStuff");
     token.NextToken.NextToken.Should().BeNull();
 }
예제 #16
0
 public void BindingOnTreeWithWithMultipleNavPropPathsThrows()
 {
     NonSystemToken topLevelSegment = new NonSystemToken("MyDog", null, null);
     NonSystemToken navProp = new NonSystemToken("MyPeople", null, topLevelSegment);
     ExpandTermToken expandTerm = new ExpandTermToken(navProp);
     ExpandToken expandToken = new ExpandToken(new ExpandTermToken[] {expandTerm});
     Action bindTreeWithMultipleNavPropPaths = () => this.binderForPerson.Bind(BuildUnifiedSelectExpandToken(expandToken));
     bindTreeWithMultipleNavPropPaths.ShouldThrow<ODataException>()
                         .WithMessage(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
 }
 public void SingleLevelTypeSegmentWorks()
 {
     NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("WorkEmail", null, null));
     PathSegmentToken firstNonTypeToken;
     IEdmStructuredType entityType = HardCodedTestModel.GetPersonType();
     var result = SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken);
     result.Should().OnlyContain(x => x.Equals(new TypeSegment(HardCodedTestModel.GetEmployeeType(), null)));
     entityType.Should().Be(HardCodedTestModel.GetEmployeeType());
     firstNonTypeToken.ShouldBeNonSystemToken("WorkEmail");
 }
예제 #18
0
 public void ReversePathWorksWithDeepPath()
 {
     // $expand=1/2/3/4
     PathReverser pathReverser = new PathReverser();
     NonSystemToken endPath = new NonSystemToken("4", null, new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null))));
     PathSegmentToken reversedPath = endPath.Accept(pathReverser);
     reversedPath.ShouldBeNonSystemToken("1")
         .And.NextToken.ShouldBeNonSystemToken("2")
         .And.NextToken.ShouldBeNonSystemToken("3")
         .And.NextToken.ShouldBeNonSystemToken("4");
 }
 public void NormalizeTreeResultsInReversedPath()
 {
     // $select=1/2/3
     NonSystemToken endPath = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null)));
     SelectToken selectToken = new SelectToken(new NonSystemToken[]{endPath});
     SelectTreeNormalizer selectTreeNormalizer = new SelectTreeNormalizer();
     SelectToken normalizedToken = selectTreeNormalizer.NormalizeSelectTree(selectToken);
     normalizedToken.Properties.Single().ShouldBeNonSystemToken("1")
                    .And.NextToken.ShouldBeNonSystemToken("2")
                    .And.NextToken.ShouldBeNonSystemToken("3");
 }
 public void DeepPath()
 {
     NonSystemToken typeSegment = new NonSystemToken("Fully.Qualified.Namespace.Employee", null, new NonSystemToken("Fully.Qualified.Namespace.Manager", null, new NonSystemToken("NumberOfReports", null, null)));
     PathSegmentToken firstNonTypeToken;
     IEdmStructuredType entityType = HardCodedTestModel.GetPersonType();
     var result = SelectExpandPathBinder.FollowTypeSegments(typeSegment, HardCodedTestModel.TestModel, 800, ODataUriResolver.Default, ref entityType, out firstNonTypeToken);
     result.Should().Contain(x => x.As<TypeSegment>().EdmType == HardCodedTestModel.GetEmployeeType())
         .And.Contain(x => x.As<TypeSegment>().EdmType == HardCodedTestModel.GetManagerType());
     entityType.Should().Be(HardCodedTestModel.GetManagerType());
     firstNonTypeToken.ShouldBeNonSystemToken("NumberOfReports");
 }
예제 #21
0
 /// <summary>
 /// Traverse a NonSystemToken. 
 /// </summary>
 /// <param name="tokenIn">The NonSystemToken to traverse.</param>
 public void Visit(NonSystemToken tokenIn)
 {
     if (tokenIn.NextToken == null)
     {
         if (newTokenToAdd != null)
         {
             tokenIn.SetNextToken(newTokenToAdd);
         }
     }
     else
     {
         tokenIn.NextToken.Accept(this);
     }
 }
 public void CombineTermsWorksForMultipleTerms()
 {
     // $expand=1($expand=2), 1($expand=3)
     List<ExpandTermToken> expandTerms = new List<ExpandTermToken>();
     var token2 = new NonSystemToken("2", null, null);
     var token3 = new NonSystemToken("3", null, null);
     expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/null, /*nextToken*/null), /*SelectToken*/null, new ExpandToken(new List<ExpandTermToken>() { new ExpandTermToken(token2) })));
     expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/null, /*nextToken*/null), /*SelectToken*/null, new ExpandToken(new List<ExpandTermToken>() { new ExpandTermToken(token3) })));
     ExpandToken expand = new ExpandToken(expandTerms);
     ExpandTreeNormalizer expandTreeNormalizer = new ExpandTreeNormalizer();
     ExpandToken combinedExpand = expandTreeNormalizer.CombineTerms(expand);
     combinedExpand.ExpandTerms.Single().ShouldBeExpandTermToken("1", true);
     combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavProp == token2);
     combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavProp == token3);
 }
예제 #23
0
        /// <summary>
        /// Visit a NonSystemToken
        /// </summary>
        /// <param name="tokenIn">the non sytem token to visit</param>
        public override void Visit(NonSystemToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            // before looking for type segments or paths, handle both of the wildcard cases.
            if (tokenIn.NextToken == null)
            {
                SelectItem newSelectItem;
                if (SelectPathSegmentTokenBinder.TryBindAsWildcard(tokenIn, this.model, out newSelectItem))
                {
                    this.expandClauseToDecorate.AddToSelectedItems(newSelectItem);
                    return;
                }
            }

            this.ProcessTokenAsPath(tokenIn);
        }
 public void NormalizeTreeWorksForMultipleTerms()
 {
     // $select=1/2/3,4/5/6
     NonSystemToken endPath = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null)));
     NonSystemToken endPath1 = new NonSystemToken("6", null, new NonSystemToken("5", null, new NonSystemToken("4", null, null)));
     SelectToken selectToken = new SelectToken(new NonSystemToken[]{endPath, endPath1});
     SelectTreeNormalizer selectTreeNormalizer = new SelectTreeNormalizer();
     SelectToken normalizedToken = selectTreeNormalizer.NormalizeSelectTree(selectToken);
     List<PathSegmentToken> tokens = normalizedToken.Properties.ToList();
     tokens.Should().HaveCount(2);
     tokens.ElementAt(0).ShouldBeNonSystemToken("1")
           .And.NextToken.ShouldBeNonSystemToken("2")
           .And.NextToken.ShouldBeNonSystemToken("3");
     tokens.ElementAt(1).ShouldBeNonSystemToken("4")
           .And.NextToken.ShouldBeNonSystemToken("5")
           .And.NextToken.ShouldBeNonSystemToken("6");
 }
예제 #25
0
        /// <summary>
        /// Translate a NonSystemToken.
        /// </summary>
        /// <param name="tokenIn">The NonSystemToken to translate.</param>
        public void Visit(NonSystemToken tokenIn)
        {
            if (tokenIn.Identifier != UriHelper.ASTERISK.ToString())
            {
                if (tokenIn.NextToken == null)
                {
                    return;
                }

                previous = tokenIn;
                tokenIn.NextToken.Accept(this);
            }
            else
            {
                previous.SetNextToken(null);
                return;
            }
        }
예제 #26
0
        public void NormalizeTreeWorksForMultipleTerms()
        {
            // $select=1/2/3,4/5/6
            NonSystemToken          endPath              = new NonSystemToken("3", null, new NonSystemToken("2", null, new NonSystemToken("1", null, null)));
            NonSystemToken          endPath1             = new NonSystemToken("6", null, new NonSystemToken("5", null, new NonSystemToken("4", null, null)));
            SelectToken             selectToken          = new SelectToken(new NonSystemToken[] { endPath, endPath1 });
            SelectTreeNormalizer    selectTreeNormalizer = new SelectTreeNormalizer();
            SelectToken             normalizedToken      = selectTreeNormalizer.NormalizeSelectTree(selectToken);
            List <PathSegmentToken> tokens = normalizedToken.Properties.ToList();

            tokens.Should().HaveCount(2);
            tokens.ElementAt(0).ShouldBeNonSystemToken("1")
            .And.NextToken.ShouldBeNonSystemToken("2")
            .And.NextToken.ShouldBeNonSystemToken("3");
            tokens.ElementAt(1).ShouldBeNonSystemToken("4")
            .And.NextToken.ShouldBeNonSystemToken("5")
            .And.NextToken.ShouldBeNonSystemToken("6");
        }
예제 #27
0
        /// <summary>
        /// Translate a NonSystemToken.
        /// </summary>
        /// <param name="tokenIn">The NonSystemToken to translate.</param>
        public void Visit(NonSystemToken tokenIn)
        {
            if (tokenIn.Identifier != UriHelper.ASTERISK.ToString())
            {
                if (tokenIn.NextToken == null)
                {
                    return;
                }

                previous = tokenIn;
                tokenIn.NextToken.Accept(this);
            }
            else
            {
                previous.SetNextToken(null);
                return;
            }
        }
예제 #28
0
        /// <summary>
        /// Appends a name of a property/link/type to the current expand path.
        /// </summary>
        /// <param name="name">name of the property/link/type which needs to be added to the expand path.</param>
        /// <param name="isStructural">is this a structural property.</param>
        private void AppendToExpandPath(string name, bool isStructural)
        {
            PathSegmentToken path     = this.expandPaths.LastOrDefault();
            NonSystemToken   newToken = new NonSystemToken(name, /*namedValues*/ null, /*nextToken*/ null);

            newToken.IsStructuralProperty = isStructural;
            if (path != null)
            {
                expandPaths.Remove(path);
                AddNewEndingTokenVisitor addNewEndingTokenVisitor = new AddNewEndingTokenVisitor(newToken);
                path.Accept(addNewEndingTokenVisitor);
                expandPaths.Add(path);
            }
            else
            {
                expandPaths.Add(newToken);
            }
        }
예제 #29
0
        /// <summary>
        /// Write out a PathSegmentToken
        /// </summary>
        /// <param name="segmentToken">the pathSegmentToken to write.</param>
        private void WritePathSegment(PathSegmentToken segmentToken)
        {
            NonSystemToken nonSystemToken = segmentToken as NonSystemToken;

            if (nonSystemToken != null)
            {
                // If this desriptor have no path, it is a service-document Url, so just quit
                if (string.IsNullOrEmpty(nonSystemToken.Identifier))
                {
                    return;
                }

                if (nonSystemToken.NextToken != null)
                {
                    this.WritePathSegment(nonSystemToken.NextToken);
                    this.builder.Append(ExpressionConstants.SymbolForwardSlash);
                }

                this.builder.Append(nonSystemToken.Identifier);

                if (nonSystemToken.NamedValues != null)
                {
                    this.builder.Append(ExpressionConstants.SymbolOpenParen);

                    bool needComma = false;
                    foreach (NamedValue nv in nonSystemToken.NamedValues)
                    {
                        if (needComma)
                        {
                            this.builder.Append(ExpressionConstants.SymbolComma);
                        }

                        this.builder.Append(nv.Name);
                        this.builder.Append(ExpressionConstants.SymbolEqual);
                        this.WriteLiteral(nv.Value);
                        needComma = true;
                    }

                    this.builder.Append(ExpressionConstants.SymbolClosedParen);
                }
            }
        }
예제 #30
0
        public void NormalizeTreeWorksWhenPathsHaveArguments()
        {
            // Arrange: $expand=1(name=value)
            ExpandToken expand = new ExpandToken(new ExpandTermToken[]
            {
                new ExpandTermToken(new NonSystemToken("1", new NamedValue[] { new NamedValue("name", new LiteralToken("value")) }, null))
            });

            // Act
            ExpandToken normalizedExpand = ExpandTreeNormalizer.NormalizeExpandTree(expand);

            // Assert
            Assert.NotNull(normalizedExpand);
            ExpandTermToken term  = Assert.Single(normalizedExpand.ExpandTerms).ShouldBeExpandTermToken("1", true);
            NonSystemToken  token = Assert.IsType <NonSystemToken>(term.PathToNavigationProp);

            Assert.Single(token.NamedValues).ShouldBeNamedValue("name", "value");

            Assert.Null(term.ExpandOption);
        }
예제 #31
0
        public void CombineTermsWorksForMultipleTerms()
        {
            // $expand=1($expand=2), 1($expand=3)
            List <ExpandTermToken> expandTerms = new List <ExpandTermToken>();
            var token2 = new NonSystemToken("2", null, null);
            var token3 = new NonSystemToken("3", null, null);

            expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/ null, /*nextToken*/ null), /*SelectToken*/ null, new ExpandToken(new List <ExpandTermToken>()
            {
                new ExpandTermToken(token2)
            })));
            expandTerms.Add(new ExpandTermToken(new NonSystemToken("1", /*namedValues*/ null, /*nextToken*/ null), /*SelectToken*/ null, new ExpandToken(new List <ExpandTermToken>()
            {
                new ExpandTermToken(token3)
            })));
            ExpandToken          expand = new ExpandToken(expandTerms);
            ExpandTreeNormalizer expandTreeNormalizer = new ExpandTreeNormalizer();
            ExpandToken          combinedExpand       = expandTreeNormalizer.CombineTerms(expand);

            combinedExpand.ExpandTerms.Single().ShouldBeExpandTermToken("1", true);
            combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavigationProp == token2);
            combinedExpand.ExpandTerms.ElementAt(0).ExpandOption.ExpandTerms.Should().Contain(t => t.PathToNavigationProp == token3);
        }
 public void NullPathSegmentTokensAreNotEquivalentToAnyNonNullToken()
 {
     var token = new NonSystemToken("foo", null, null);
     this.testSubject.Equals(null, token).Should().BeFalse();
     this.testSubject.Equals(token, null).Should().BeFalse();
 }
예제 #33
0
        /// <summary>
        /// Building off of a PathSegmentToken whose value is star, only nested level options is allowed.
        /// </summary>
        /// <param name="pathToken">The PathSegmentToken representing the parsed expand path whose options we are now parsing.</param>
        /// <returns>An expand term token based on the path token, and all available expand options.</returns>
        private List <ExpandTermToken> BuildStarExpandTermToken(PathSegmentToken pathToken)
        {
            List <ExpandTermToken> expandTermTokenList = new List <ExpandTermToken>();
            long?levelsOption = null;
            bool isRefExpand  = (pathToken.Identifier == UriQueryConstants.RefSegment);

            // Based on the specification, 
            //   For star in expand, this will be supported,
            //   $expand=*
            //   $expand=EntitySet($expand=* )
            //   $expand=*/$ref
            //   $expand=*,EntitySet
            //   $expand=EntitySet, *
            //   $expand=*/$ref,EntitySet
            //   Parenthesized set of expand options for star expand option supported are $level per specification.
            //   And this will throw exception,
            //   $expand= * /$count
            //   Parenthesized set of expand options for star expand option which will also cause exception are $filter, $select, $orderby, $skip, $top, $count, $search, and $expand per specification.
            // And level is not supported with "*/$ref".

            // As 2016/1/8, the navigation property is only supported in entity type, and will support in ComplexType in future.
            if (this.lexer.CurrentToken.Kind == ExpressionTokenKind.OpenParen)
            {
                // advance past the '('
                this.lexer.NextToken();

                // Check for (), which is not allowed.
                if (this.lexer.CurrentToken.Kind == ExpressionTokenKind.CloseParen)
                {
                    throw new ODataException(ODataErrorStrings.UriParser_MissingExpandOption(pathToken.Identifier));
                }

                // Only level option is supported by expand.
                while (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen)
                {
                    string text = this.enableCaseInsensitiveBuiltinIdentifier
                        ? this.lexer.CurrentToken.Text.ToLowerInvariant()
                        : this.lexer.CurrentToken.Text;
                    switch (text)
                    {
                    case ExpressionConstants.QueryOptionLevels:
                    {
                        if (!isRefExpand)
                        {
                            levelsOption = ResolveLevelOption();
                        }
                        else
                        {
                            // no option is allowed when expand with star per specification
                            throw new ODataException(ODataErrorStrings.UriExpandParser_TermIsNotValidForStarRef(this.lexer.ExpressionText));
                        }

                        break;
                    }

                    default:
                    {
                        throw new ODataException(ODataErrorStrings.UriExpandParser_TermIsNotValidForStar(this.lexer.ExpressionText));
                    }
                    }
                }

                // Move past the ')'
                this.lexer.NextToken();
            }

            // Either there was no '(' at all or we just read past the ')' so we should be at the end
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.End)
            {
                throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(this.lexer.ExpressionText));
            }

            // As 2016/1/8, the navigation property is only supported in entity type, and will support in ComplexType in future.
            var entityType = parentEntityType as IEdmEntityType;

            if (entityType == null)
            {
                throw new ODataException(ODataErrorStrings.UriExpandParser_ParentEntityIsNull(this.lexer.ExpressionText));
            }

            foreach (var navigationProperty in entityType.NavigationProperties())
            {
                var tmpPathToken = default(PathSegmentToken);

                // create path token for each navigation properties.
                if (pathToken.Identifier.Equals(UriQueryConstants.RefSegment))
                {
                    tmpPathToken = new NonSystemToken(navigationProperty.Name, null, pathToken.NextToken.NextToken);
                    tmpPathToken = new NonSystemToken(UriQueryConstants.RefSegment, null, tmpPathToken);
                }
                else
                {
                    tmpPathToken = new NonSystemToken(navigationProperty.Name, null, pathToken.NextToken);
                }

                ExpandTermToken currentToken = new ExpandTermToken(tmpPathToken, null, null,
                                                                   null, null, null, levelsOption, null, null, null);
                expandTermTokenList.Add(currentToken);
            }

            return(expandTermTokenList);
        }
예제 #34
0
        public void IdentifierSetCorrectly()
        {
            NonSystemToken token = new NonSystemToken("stuff", null, null);

            Assert.Equal("stuff", token.Identifier);
        }
        internal static bool TryBindAsOperation(PathSegmentToken pathToken, IEdmModel model, IEdmStructuredType entityType, out ODataPathSegment segment)
        {
            Debug.Assert(pathToken != null, "pathToken != null");
            Debug.Assert(entityType != null, "bindingType != null");

            List <IEdmOperation> possibleFunctions = new List <IEdmOperation>();

            // Catch all catchable exceptions as FindDeclaredBoundOperations is implemented by anyone.
            // If an exception occurs it will be supressed and the possible functions will be empty and return false.
            try
            {
                int wildCardPos = pathToken.Identifier.IndexOf("*", StringComparison.Ordinal);
                if (wildCardPos > -1)
                {
                    string namespaceName = pathToken.Identifier.Substring(0, wildCardPos - 1);
                    possibleFunctions = model.FindBoundOperations(entityType).Where(o => o.Namespace == namespaceName).ToList();
                }
                else
                {
                    NonSystemToken nonSystemToken = pathToken as NonSystemToken;
                    IList <string> parameterNames = new List <string>();
                    if (nonSystemToken != null && nonSystemToken.NamedValues != null)
                    {
                        parameterNames = nonSystemToken.NamedValues.Select(s => s.Name).ToList();
                    }

                    if (parameterNames.Count > 0)
                    {
                        // Always force to use fully qualified name when select operation
                        possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).FilterOperationsByParameterNames(parameterNames, false).ToList();
                    }
                    else
                    {
                        possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).ToList();
                    }
                }
            }
            catch (Exception exc)
            {
                if (!ExceptionUtils.IsCatchableExceptionType(exc))
                {
                    throw;
                }
            }

            possibleFunctions = possibleFunctions.EnsureOperationsBoundWithBindingParameter().ToList();

            // Only filter if there is more than one and its needed.
            if (possibleFunctions.Count > 1)
            {
                possibleFunctions = possibleFunctions.FilterBoundOperationsWithSameTypeHierarchyToTypeClosestToBindingType(entityType).ToList();
            }

            if (possibleFunctions.Count <= 0)
            {
                segment = null;
                return(false);
            }

            segment = new OperationSegment(possibleFunctions, null /*entitySet*/);
            return(true);
        }
예제 #36
0
        private void ProcessTokenAsPath(NonSystemToken tokenIn)
        {
            Debug.Assert(tokenIn != null, "tokenIn != null");

            List <ODataPathSegment> pathSoFar        = new List <ODataPathSegment>();
            IEdmStructuredType      currentLevelType = this.edmType;

            // first, walk through all type segments in a row, converting them from tokens into segments.
            if (tokenIn.IsNamespaceOrContainerQualified())
            {
                PathSegmentToken firstNonTypeToken;
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(tokenIn, this.model, this.maxDepth, this.resolver, ref currentLevelType, out firstNonTypeToken));
                Debug.Assert(firstNonTypeToken != null, "Did not get last token.");
                tokenIn = firstNonTypeToken as NonSystemToken;
                if (tokenIn == null)
                {
                    throw new ODataException(ODataErrorStrings.SelectPropertyVisitor_SystemTokenInSelect(firstNonTypeToken.Identifier));
                }
            }

            // next, create a segment for the first non-type segment in the path.
            ODataPathSegment lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(tokenIn, this.model, currentLevelType, resolver);

            // next, create an ODataPath and add the segments to it.
            if (lastSegment != null)
            {
                pathSoFar.Add(lastSegment);

                // try create a complex type property path.
                while (true)
                {
                    // no need to go on if the current property is not of complex type.
                    currentLevelType = lastSegment.EdmType as IEdmStructuredType;
                    if (currentLevelType == null || currentLevelType.TypeKind != EdmTypeKind.Complex)
                    {
                        break;
                    }

                    NonSystemToken nextToken = tokenIn.NextToken as NonSystemToken;
                    if (nextToken == null)
                    {
                        break;
                    }

                    // first try bind the segment as property.
                    lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.model, currentLevelType, resolver);

                    // then try bind the segment as type cast.
                    if (lastSegment == null)
                    {
                        IEdmStructuredType typeFromNextToken = UriEdmHelpers.FindTypeFromModel(this.model, nextToken.Identifier, this.resolver) as IEdmStructuredType;

                        if (typeFromNextToken.IsOrInheritsFrom(currentLevelType))
                        {
                            lastSegment = new TypeSegment(typeFromNextToken, /*entitySet*/ null);
                        }
                    }

                    // type cast failed too.
                    if (lastSegment == null)
                    {
                        break;
                    }

                    // try move to and add next path segment.
                    tokenIn = nextToken;
                    pathSoFar.Add(lastSegment);
                }
            }

            ODataSelectPath selectedPath = new ODataSelectPath(pathSoFar);

            var selectionItem = new PathSelectItem(selectedPath);

            // non-navigation cases do not allow further segments in $select.
            if (tokenIn.NextToken != null)
            {
                throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect);
            }

            // if the selected item is a nav prop, then see if its already there before we add it.
            NavigationPropertySegment trailingNavPropSegment = selectionItem.SelectedPath.LastSegment as NavigationPropertySegment;

            if (trailingNavPropSegment != null)
            {
                if (this.expandClauseToDecorate.SelectedItems.Any(x => x is PathSelectItem &&
                                                                  ((PathSelectItem)x).SelectedPath.Equals(selectedPath)))
                {
                    return;
                }
            }

            this.expandClauseToDecorate.AddToSelectedItems(selectionItem);
        }
예제 #37
0
        public void IdentifierSetCorrectly()
        {
            NonSystemToken token = new NonSystemToken("stuff", null, null);

            token.Identifier.Should().Be("stuff");
        }
 /// <summary>
 /// Visit an NonSystemToken
 /// </summary>
 /// <param name="tokenIn">The System token to visit</param>
 /// <returns>A user defined class</returns>
 public virtual T Visit(NonSystemToken tokenIn)
 {
     throw new NotImplementedException();
 }
 public void PathSegmentTokensAreNotEquivalentDueToLength()
 {
     var token1 = new NonSystemToken("foo", null, null);
     var token2 = new NonSystemToken("foo", null, new SystemToken("$batch", null));
     this.testSubject.Equals(token1, token2).Should().BeFalse();
 }
 public void PathSegmentTokensAreNotEquivalentAtSecondPosition()
 {
     var token1 = new NonSystemToken("foo", null, new SystemToken("$metadata", null));
     var token2 = new NonSystemToken("foo", null, new SystemToken("$batch", null));
     this.testSubject.Equals(token1, token2).Should().BeFalse();
 }
 public void PathSegmentTokenHashCodesShouldBeDifferent()
 {
     var token1 = new NonSystemToken("foo", null, null);
     var token2 = new NonSystemToken("bar", null, null);
     this.testSubject.GetHashCode(token1).Should().NotBe(this.testSubject.GetHashCode(token2));
 }
 public void PathSegmentTokenHashCodesShouldBeTheSame()
 {
     var token1 = new NonSystemToken("foo", null, new SystemToken("$metadata", null));
     var token2 = new NonSystemToken("foo", null, new SystemToken("$metadata", null));
     this.testSubject.GetHashCode(token1).Should().Be(this.testSubject.GetHashCode(token2));
 }
예제 #43
0
        // TODO: Probably missing more simple test cases
        // TODO: Write interesting, complex parsing cases

        private ExpandTermToken ParseExpandOptions(string optionsText, int maxDepth = 100)
        {
            PathSegmentToken pathToken = new NonSystemToken("NavProp", null, null);

            ExpandOptionParser optionParser = new ExpandOptionParser(maxDepth)
            {
                MaxFilterDepth = 9,
                MaxSearchDepth = 9,
                MaxOrderByDepth = 9
            };
            return optionParser.BuildExpandTermToken(pathToken, optionsText);
        }