Esempio n. 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);
        }
Esempio n. 2
0
        /// <summary>
        /// Add a select item to the current list of selection items
        /// </summary>
        /// <param name="itemToAdd">The item to add</param>
        internal void AddToSelectedItems(SelectItem itemToAdd)
        {
            ExceptionUtils.CheckArgumentNotNull(itemToAdd, "itemToAdd");

            if (this.selectedItems.Any(x => x is WildcardSelectItem) && IsStructuralOrNavigationPropertySelectionItem(itemToAdd))
            {
                return;
            }

            bool isWildcard = itemToAdd is WildcardSelectItem;

            List <SelectItem> newSelectedItems = new List <SelectItem>();

            foreach (SelectItem selectedItem in this.selectedItems)
            {
                if (isWildcard)
                {
                    if (!IsStructuralSelectionItem(selectedItem))
                    {
                        newSelectedItems.Add(selectedItem);
                    }
                }
                else
                {
                    newSelectedItems.Add(selectedItem);
                }
            }

            newSelectedItems.Add(itemToAdd);
            this.selectedItems = new ReadOnlyCollection <SelectItem>(newSelectedItems);
        }
Esempio n. 3
0
        /// <summary>
        /// Bind the $expand <see cref="ExpandToken"/> and $select <see cref="SelectToken"/> at this level.
        /// </summary>
        /// <param name="expandToken">the expand token to visit.</param>
        /// <param name="selectToken">the select token to visit.</param>
        /// <returns>a SelectExpand clause based on <see cref="ExpandToken"/> and <see cref="SelectToken"/>.</returns>
        public SelectExpandClause Bind(ExpandToken expandToken, SelectToken selectToken)
        {
            List <SelectItem> selectExpandItems = new List <SelectItem>();

            // $expand=
            if (expandToken != null && expandToken.ExpandTerms.Any())
            {
                selectExpandItems.AddRange(expandToken.ExpandTerms.Select(this.GenerateExpandItem).Where(s => s != null));
            }

            // $select=
            bool isAllSelected = true;

            if (selectToken != null && selectToken.SelectTerms.Any())
            {
                // if there are any select items at this level then allSelected is false, otherwise it's true.
                isAllSelected = false;

                foreach (SelectTermToken selectTermToken in selectToken.SelectTerms)
                {
                    SelectItem     selectItem     = GenerateSelectItem(selectTermToken);
                    PathSelectItem selectPathItem = selectItem as PathSelectItem;
                    bool           duplicate      = false;

                    if (selectPathItem != null)
                    {
                        // It's not allowed to have multiple select clause with the same path.
                        // For example: $select=abc($top=2),abc($skip=2) is not allowed by design.
                        // Customer should combine them together, for example: $select=abc($top=2;$skip=2).
                        // The logic is different with ExpandTreeNormalizer. We should change the logic in ExpandTreeNormalizer
                        // in next breaking change version.
                        // For backward compatibility with previous versions of OData Library, we only validate
                        // if one of the select items has options.
                        foreach (PathSelectItem existingItem in selectExpandItems.OfType <PathSelectItem>())
                        {
                            if ((selectPathItem.HasOptions && overLaps(selectPathItem, existingItem)) || (existingItem.HasOptions && overLaps(existingItem, selectPathItem)))
                            {
                                throw new ODataException(ODataErrorStrings.SelectTreeNormalizer_MultipleSelecTermWithSamePathFound(ToPathString(selectTermToken.PathToProperty)));
                            }

                            // two items without options are identical -- for backward compat just ignore the new one
                            if (selectPathItem.SelectedPath.Equals(existingItem.SelectedPath))
                            {
                                duplicate = true;
                            }
                        }
                    }

                    if (!duplicate)
                    {
                        AddToSelectedItems(selectItem, selectExpandItems);
                    }
                }
            }

            // It's better to return "null" if both expand and select are null.
            // However, in order to be consistent, we returns empty "SelectExpandClause" with AllSelected = true.
            return(new SelectExpandClause(selectExpandItems, isAllSelected));
        }
Esempio n. 4
0
        private static bool IsStructuralOrNavigationPropertySelectionItem(SelectItem selectItem)
        {
            PathSelectItem pathSelectItem = selectItem as PathSelectItem;

            return(pathSelectItem != null &&
                   (pathSelectItem.SelectedPath.LastSegment is NavigationPropertySegment ||
                    pathSelectItem.SelectedPath.LastSegment is PropertySegment));
        }
Esempio n. 5
0
        /// <summary>
        /// Add a select item to the current list of selection items
        /// </summary>
        /// <param name="itemToAdd">The item to add</param>
        /// <param name="getOnlySubset">A boolean value indicating whether to get subset only</param>
        internal void AddToSelectedItems(SelectItem itemToAdd, bool getOnlySubset = false)
        {
            ExceptionUtils.CheckArgumentNotNull(itemToAdd, "itemToAdd");

            WildcardSelectItem wildcardSelectItem = this.selectedItems.OfType <WildcardSelectItem>().FirstOrDefault();

            if (wildcardSelectItem != null && IsStructuralOrNavigationPropertySelectionItem(itemToAdd))
            {
                wildcardSelectItem.AddSubsumed(itemToAdd);
                return;
            }

            wildcardSelectItem = itemToAdd as WildcardSelectItem;
            if (wildcardSelectItem != null)
            {
                List <SelectItem> newSelectedItems = new List <SelectItem>();

                foreach (SelectItem selectedItem in this.selectedItems)
                {
                    if (!IsStructuralSelectionItem(selectedItem))
                    {
                        newSelectedItems.Add(selectedItem);
                    }
                    else if (getOnlySubset)
                    {
                        var pathItem = selectedItem as PathSelectItem;
                        if (pathItem != null && pathItem.SelectAndExpand != null)
                        {
                            newSelectedItems.Add(selectedItem);
                        }
                        else
                        {
                            wildcardSelectItem.AddSubsumed(selectedItem);
                        }
                    }
                    else
                    {
                        wildcardSelectItem.AddSubsumed(selectedItem);
                    }
                }

                this.selectedItems = newSelectedItems;
            }

            this.selectedItems.Add(itemToAdd);
        }
Esempio n. 6
0
        private static void AddToSelectedItems(SelectItem itemToAdd, List <SelectItem> selectItems)
        {
            if (itemToAdd == null)
            {
                return;
            }

            // ignore all property selection if there's a wildcard select item.
            WildcardSelectItem wildcardSelectItem = selectItems.OfType <WildcardSelectItem>().FirstOrDefault();

            if (wildcardSelectItem != null && IsStructuralOrNavigationPropertySelectionItem(itemToAdd))
            {
                wildcardSelectItem.AddSubsumed(itemToAdd);
                return;
            }

            // if the selected item is a nav prop, then see if its already there before we add it.
            PathSelectItem pathSelectItem = itemToAdd as PathSelectItem;

            if (pathSelectItem != null)
            {
                NavigationPropertySegment trailingNavPropSegment = pathSelectItem.SelectedPath.LastSegment as NavigationPropertySegment;
                if (trailingNavPropSegment != null)
                {
                    if (selectItems.OfType <PathSelectItem>().Any(i => i.SelectedPath.Equals(pathSelectItem.SelectedPath)))
                    {
                        return;
                    }
                }
            }

            // if the selected item is "*", filter the existing property selection.
            wildcardSelectItem = itemToAdd as WildcardSelectItem;
            if (wildcardSelectItem != null)
            {
                List <SelectItem> shouldFilter = selectItems.Where(s => IsStructuralSelectionItem(s)).ToList();
                wildcardSelectItem.AddSubsumed(shouldFilter);
                foreach (var filterItem in shouldFilter)
                {
                    selectItems.Remove(filterItem);
                }
            }

            selectItems.Add(itemToAdd);
        }
Esempio n. 7
0
        /// <summary>
        /// Add a select item to the current list of selection items
        /// </summary>
        /// <param name="itemToAdd">The item to add</param>
        internal void AddToSelectedItems(SelectItem itemToAdd, bool getOnlySubset = false)
        {
            ExceptionUtils.CheckArgumentNotNull(itemToAdd, "itemToAdd");

            if (this.selectedItems.Any(x => x is WildcardSelectItem) && IsStructuralOrNavigationPropertySelectionItem(itemToAdd))
            {
                return;
            }

            bool isWildcard = itemToAdd is WildcardSelectItem;

            List <SelectItem> newSelectedItems = new List <SelectItem>();

            foreach (SelectItem selectedItem in this.selectedItems)
            {
                if (isWildcard)
                {
                    if (!IsStructuralSelectionItem(selectedItem))
                    {
                        newSelectedItems.Add(selectedItem);
                    }
                    else if (getOnlySubset)
                    {
                        var pathItem = selectedItem as PathSelectItem;
                        if (pathItem != null && pathItem.SelectAndExpand != null)
                        {
                            newSelectedItems.Add(selectedItem);
                        }
                    }
                }
                else
                {
                    newSelectedItems.Add(selectedItem);
                }
            }

            newSelectedItems.Add(itemToAdd);
            this.selectedItems = new ReadOnlyCollection <SelectItem>(newSelectedItems);
        }
        /// <summary>
        /// Get the string representation of a select item (that isn't an expandedNavPropSelectItem
        /// </summary>
        /// <param name="selectedItem">the select item to translate</param>
        /// <returns>the string representation of this select item, or null if the select item is an expandedNavPropSelectItem</returns>
        private static string GetSelectString(SelectItem selectedItem)
        {
            WildcardSelectItem wildcardSelect = selectedItem as WildcardSelectItem;
            NamespaceQualifiedWildcardSelectItem namespaceQualifiedWildcard = selectedItem as NamespaceQualifiedWildcardSelectItem;
            PathSelectItem pathSelectItem = selectedItem as PathSelectItem;

            if (wildcardSelect != null)
            {
                return("*");
            }
            else if (namespaceQualifiedWildcard != null)
            {
                return(namespaceQualifiedWildcard.Namespace + ".*");
            }
            else if (pathSelectItem != null)
            {
                return(String.Join("/", pathSelectItem.SelectedPath.WalkWith(PathSegmentToStringTranslator.Instance).ToArray()));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Build a wildcard selection item
        /// </summary>
        /// <param name="tokenIn">the token to bind to a wildcard</param>
        /// <param name="model">the model to search for this wildcard</param>
        /// <param name="item">the new wildcard selection item, if we found one</param>
        /// <returns>true if we successfully bound to a wildcard, false otherwise</returns>
        public static bool TryBindAsWildcard(PathSegmentToken tokenIn, IEdmModel model, out SelectItem item)
        {
            bool isTypeToken = tokenIn.IsNamespaceOrContainerQualified();
            bool wildcard    = tokenIn.Identifier.EndsWith("*", StringComparison.Ordinal);

            if (isTypeToken && wildcard)
            {
                string namespaceName = tokenIn.Identifier.Substring(0, tokenIn.Identifier.Length - 2);

                if (model.DeclaredNamespaces.Any(declaredNamespace => declaredNamespace.Equals(namespaceName, StringComparison.Ordinal)))
                {
                    item = new NamespaceQualifiedWildcardSelectItem(namespaceName);
                    return(true);
                }
            }

            if (tokenIn.Identifier == "*")
            {
                item = new WildcardSelectItem();
                return(true);
            }

            item = null;
            return(false);
        }
Esempio n. 10
0
 /// <summary>
 /// Adds the provided <see cref="SelectItem"/> to the set of items that are replaced by the wildcard.
 /// </summary>
 internal void AddSubsumed(SelectItem selectItem)
 {
     this.subsumedSelectItems.Add(selectItem);
 }