Exemple #1
0
        /// <summary>
        /// Process a <see cref="SelectTermToken"/> to identify whether it's a Wildcard path.
        /// </summary>
        /// <param name="selectToken">the select token to process.</param>
        /// <param name="newSelectItem">the built select item to out.</param>
        private bool ProcessWildcardTokenPath(SelectTermToken selectToken, out SelectItem newSelectItem)
        {
            newSelectItem = null;
            if (selectToken == null || selectToken.PathToProperty == null)
            {
                return(false);
            }

            PathSegmentToken pathToken = selectToken.PathToProperty;

            if (SelectPathSegmentTokenBinder.TryBindAsWildcard(pathToken, this.Model, out newSelectItem))
            {
                // * or Namespace.*
                if (pathToken.NextToken != null)
                {
                    throw new ODataException(ODataErrorStrings.SelectExpandBinder_InvalidIdentifierAfterWildcard(pathToken.NextToken.Identifier));
                }

                VerifyNoQueryOptionsNested(selectToken, pathToken.Identifier);

                return(true);
            }

            return(false);
        }
Exemple #2
0
        private static void VerifySelectedPath(SelectTermToken selectedToken)
        {
            PathSegmentToken current = selectedToken.PathToProperty;

            while (current != null)
            {
                if (current is SystemToken)
                {
                    // It's not allowed to set a system token in a select clause.
                    throw new ODataException(ODataErrorStrings.SelectExpandBinder_SystemTokenInSelect(current.Identifier));
                }

                current = current.NextToken;
            }
        }
Exemple #3
0
 private static void VerifyNoQueryOptionsNested(SelectTermToken selectToken, string identifier)
 {
     if (selectToken != null)
     {
         if (selectToken.ComputeOption != null ||
             selectToken.FilterOption != null ||
             selectToken.OrderByOptions != null ||
             selectToken.SearchOption != null ||
             selectToken.CountQueryOption != null ||
             selectToken.SelectOption != null ||
             selectToken.TopOption != null ||
             selectToken.SkipOption != null)
         {
             throw new ODataException(ODataErrorStrings.SelectExpandBinder_InvalidQueryOptionNestedSelection(identifier));
         }
     }
 }
Exemple #4
0
        private static bool VerifySelectedNavigationProperty(IList <ODataPathSegment> selectedPath, SelectTermToken tokenIn)
        {
            NavigationPropertySegment navPropSegment = selectedPath.LastOrDefault() as NavigationPropertySegment;

            if (navPropSegment != null)
            {
                // After navigation property, it's not allowed to nest query options
                VerifyNoQueryOptionsNested(tokenIn, navPropSegment.Identifier);

                return(true);
            }

            return(false);
        }
Exemple #5
0
        /// <summary>
        /// Generate a select item <see cref="SelectItem"/> based on a <see cref="SelectTermToken"/>.
        /// for example:  abc/efg($count=true;$filter=....;$top=1)
        /// </summary>
        /// <param name="tokenIn">the select term token to visit</param>
        /// <returns>the select item for this select term token.</returns>
        private SelectItem GenerateSelectItem(SelectTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");
            ExceptionUtils.CheckArgumentNotNull(tokenIn.PathToProperty, "pathToProperty");

            VerifySelectedPath(tokenIn);

            SelectItem newSelectItem;

            if (ProcessWildcardTokenPath(tokenIn, out newSelectItem))
            {
                return(newSelectItem);
            }

            IList <ODataPathSegment> selectedPath = ProcessSelectTokenPath(tokenIn.PathToProperty);

            Debug.Assert(selectedPath.Count > 0);

            // Navigation property should be the last segment in select path.
            if (VerifySelectedNavigationProperty(selectedPath, tokenIn))
            {
                return(new PathSelectItem(new ODataSelectPath(selectedPath)));
            }

            // We should use the "NavigationSource" at this level for the next level binding.
            IEdmNavigationSource targetNavigationSource = this.NavigationSource;
            ODataPathSegment     lastSegment            = selectedPath.Last();
            IEdmType             targetElementType      = lastSegment.TargetEdmType;
            IEdmCollectionType   collection             = targetElementType as IEdmCollectionType;

            if (collection != null)
            {
                targetElementType = collection.ElementType.Definition;
            }
            IEdmTypeReference elementTypeReference = targetElementType.ToTypeReference();

            // $compute
            ComputeClause          compute             = BindCompute(tokenIn.ComputeOption, targetNavigationSource, elementTypeReference);
            HashSet <EndPathToken> generatedProperties = GetGeneratedProperties(compute, null);

            // $filter
            FilterClause filter = BindFilter(tokenIn.FilterOption, targetNavigationSource, elementTypeReference, generatedProperties);

            // $orderby
            OrderByClause orderBy = BindOrderby(tokenIn.OrderByOptions, targetNavigationSource, elementTypeReference, generatedProperties);

            // $search
            SearchClause search = BindSearch(tokenIn.SearchOption, targetNavigationSource, elementTypeReference);

            // $select
            List <ODataPathSegment> parsedPath = new List <ODataPathSegment>(this.parsedSegments);

            parsedPath.AddRange(selectedPath);
            SelectExpandClause selectExpand = BindSelectExpand(null, tokenIn.SelectOption, parsedPath, targetNavigationSource, elementTypeReference, generatedProperties);

            return(new PathSelectItem(new ODataSelectPath(selectedPath),
                                      targetNavigationSource,
                                      selectExpand,
                                      filter,
                                      orderBy,
                                      tokenIn.TopOption,
                                      tokenIn.SkipOption,
                                      tokenIn.CountQueryOption,
                                      search,
                                      compute));
        }