Exemplo n.º 1
0
 /// <summary>
 /// Constructs a KeyLookupNode.
 /// </summary>
 /// <param name="source">The collection that this key is referring to.</param>
 /// <param name="keyPropertyValues">List of the properties and their values that we use to look up our return value.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input source is null.</exception>
 public KeyLookupNode(CollectionResourceNode source, IEnumerable <KeyPropertyValue> keyPropertyValues)
 {
     ExceptionUtils.CheckArgumentNotNull(source, "source");
     this.source              = source;
     this.navigationSource    = source.NavigationSource;
     this.entityTypeReference = source.ItemStructuredType as IEdmEntityTypeReference;
     this.keyPropertyValues   = keyPropertyValues;
 }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a <see cref="ResourceRangeVariable"/>.
 /// </summary>
 /// <param name="name"> The name of the associated any/all parameter (null if none)</param>
 /// <param name="structuredType">The structured type of each item in the collection that this range variable iterates over.</param>
 /// <param name="navigationSource">The navigation source of the collection this node iterates over.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input name or entityType is null.</exception>
 public ResourceRangeVariable(string name, IEdmStructuredTypeReference structuredType, IEdmNavigationSource navigationSource)
 {
     ExceptionUtils.CheckArgumentNotNull(name, "name");
     ExceptionUtils.CheckArgumentNotNull(structuredType, "structuredType");
     this.name = name;
     this.structuredTypeReference = structuredType;
     this.collectionResourceNode  = null;
     this.navigationSource        = navigationSource;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Tries to bind key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToDeclaredKey(CollectionResourceNode collectionNode, IEnumerable <NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, out QueryNode keyLookupNode)
        {
            Dictionary <string, IEdmProperty> keys = new Dictionary <string, IEdmProperty>(StringComparer.Ordinal);

            foreach (IEdmStructuralProperty property in collectionItemEntityType.Key())
            {
                keys[property.Name] = property;
            }

            return(TryBindToKeys(collectionNode, namedValues, model, collectionItemEntityType, keys, out keyLookupNode));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create a CollectionCastNode with the given source node and the given target type.
        /// </summary>
        /// <param name="source">Parent <see cref="CollectionNode"/> that is being cast.</param>
        /// <param name="structuredType">Type to cast to.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input source or structuredType are null.</exception>
        public CollectionResourceCastNode(CollectionResourceNode source, IEdmStructuredType structuredType)
        {
            ExceptionUtils.CheckArgumentNotNull(source, "source");
            ExceptionUtils.CheckArgumentNotNull(structuredType, "structuredType");
            this.source           = source;
            this.edmTypeReference = structuredType.GetTypeReference();
            this.navigationSource = source.NavigationSource;

            // creating a new collection type here because the type in the request is just the item type, there is no user-provided collection type.
            this.collectionTypeReference = EdmCoreModel.GetCollection(this.edmTypeReference);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Tries to bind key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToDeclaredAlternateKey(CollectionResourceNode collectionNode, IEnumerable <NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, out QueryNode keyLookupNode)
        {
            IEnumerable <IDictionary <string, IEdmProperty> > alternateKeys = model.GetAlternateKeysAnnotation(collectionItemEntityType);

            foreach (IDictionary <string, IEdmProperty> keys in alternateKeys)
            {
                if (TryBindToKeys(collectionNode, namedValues, model, collectionItemEntityType, keys, out keyLookupNode))
                {
                    return(true);
                }
            }

            keyLookupNode = null;
            return(false);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keys">Dictionary of aliases to structural property names for the key.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToKeys(CollectionResourceNode collectionNode, IEnumerable <NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, IDictionary <string, IEdmProperty> keys, out QueryNode keyLookupNode)
        {
            List <KeyPropertyValue> keyPropertyValues = new List <KeyPropertyValue>();
            HashSet <string>        keyPropertyNames  = new HashSet <string>(StringComparer.Ordinal);

            foreach (NamedValue namedValue in namedValues)
            {
                KeyPropertyValue keyPropertyValue;

                if (!this.TryBindKeyPropertyValue(namedValue, collectionItemEntityType, keys, out keyPropertyValue))
                {
                    keyLookupNode = null;
                    return(false);
                }

                Debug.Assert(keyPropertyValue != null, "keyPropertyValue != null");
                Debug.Assert(keyPropertyValue.KeyProperty != null, "keyPropertyValue.KeyProperty != null");

                if (!keyPropertyNames.Add(keyPropertyValue.KeyProperty.Name))
                {
                    throw new ODataException(ODataErrorStrings.MetadataBinder_DuplicitKeyPropertyInKeyValues(keyPropertyValue.KeyProperty.Name));
                }

                keyPropertyValues.Add(keyPropertyValue);
            }

            if (keyPropertyValues.Count == 0)
            {
                // No key values specified, for example '/Customers()', do not include the key lookup at all
                keyLookupNode = collectionNode;
                return(true);
            }
            else if (keyPropertyValues.Count != collectionItemEntityType.Key().Count())
            {
                keyLookupNode = null;
                return(false);
            }
            else
            {
                keyLookupNode = new KeyLookupNode(collectionNode, new ReadOnlyCollection <KeyPropertyValue>(keyPropertyValues));
                return(true);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <returns>The bound key lookup.</returns>
        internal QueryNode BindKeyValues(CollectionResourceNode collectionNode, IEnumerable <NamedValue> namedValues, IEdmModel model)
        {
            Debug.Assert(namedValues != null, "namedValues != null");
            Debug.Assert(collectionNode != null, "CollectionNode != null");
            Debug.Assert(model != null, "model != null");

            IEdmEntityTypeReference collectionItemType = collectionNode.ItemStructuredType as IEdmEntityTypeReference;

            IEdmEntityType collectionItemEntityType = collectionItemType.EntityDefinition();
            QueryNode      keyLookupNode;

            if (TryBindToDeclaredKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return(keyLookupNode);
            }
            else if (TryBindToDeclaredAlternateKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return(keyLookupNode);
            }
            else
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_NotAllKeyPropertiesSpecifiedInKeyValues(collectionNode.ItemStructuredType.FullName()));
            }
        }
        /// <summary>
        /// Binds a DottedIdentifierToken and it's parent node (if needed).
        /// </summary>
        /// <param name="dottedIdentifierToken">Token to bind to metadata.</param>
        /// <returns>A bound node representing the cast.</returns>
        internal QueryNode BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken)
        {
            ExceptionUtils.CheckArgumentNotNull(dottedIdentifierToken, "castToken");
            ExceptionUtils.CheckArgumentNotNull(state, "state");

            QueryNode parent     = null;
            IEdmType  parentType = null;

            if (state.ImplicitRangeVariable != null)
            {
                if (dottedIdentifierToken.NextToken == null)
                {
                    parent     = NodeFactory.CreateRangeVariableReferenceNode(state.ImplicitRangeVariable);
                    parentType = state.ImplicitRangeVariable.TypeReference.Definition;
                }
                else
                {
                    parent     = this.bindMethod(dottedIdentifierToken.NextToken);
                    parentType = parent.GetEdmType();
                }
            }

            SingleResourceNode parentAsSingleResource = parent as SingleResourceNode;
            IEdmSchemaType     childType           = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier, this.Resolver);
            IEdmStructuredType childStructuredType = childType as IEdmStructuredType;

            if (childStructuredType == null)
            {
                SingleValueNode    singleValueNode    = parent as SingleValueNode;
                FunctionCallBinder functionCallBinder = new FunctionCallBinder(bindMethod, state);
                QueryNode          functionCallNode;
                if (functionCallBinder.TryBindDottedIdentifierAsFunctionCall(dottedIdentifierToken, singleValueNode, out functionCallNode))
                {
                    return(functionCallNode);
                }
                else if ((!string.IsNullOrEmpty(dottedIdentifierToken.Identifier)) &&
                         (dottedIdentifierToken.Identifier[dottedIdentifierToken.Identifier.Length - 1] == '\''))
                {
                    // check if it is enum or not
                    QueryNode enumNode;
                    if (EnumBinder.TryBindDottedIdentifierAsEnum(dottedIdentifierToken, parentAsSingleResource, state, this.Resolver, out enumNode))
                    {
                        return(enumNode);
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.Binder_IsNotValidEnumConstant(dottedIdentifierToken.Identifier));
                    }
                }
                else
                {
                    IEdmTypeReference edmTypeReference = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier, this.Resolver).ToTypeReference();
                    if (edmTypeReference is IEdmPrimitiveTypeReference || edmTypeReference is IEdmEnumTypeReference)
                    {
                        IEdmPrimitiveType childPrimitiveType = childType as IEdmPrimitiveType;
                        if (childPrimitiveType != null && dottedIdentifierToken.NextToken != null)
                        {
                            return(new SingleValueCastNode(singleValueNode, childPrimitiveType));
                        }
                        else
                        {
                            return(new ConstantNode(dottedIdentifierToken.Identifier, dottedIdentifierToken.Identifier));
                        }
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.CastBinder_ChildTypeIsNotEntity(dottedIdentifierToken.Identifier));
                    }
                }
            }

            // Check whether childType is a derived type of the type of its parent node
            UriEdmHelpers.CheckRelatedTo(parentType, childType);

            this.state.ParsedSegments.Add(new TypeSegment(childType, parentType, null));

            CollectionResourceNode parentAsCollection = parent as CollectionResourceNode;

            if (parentAsCollection != null)
            {
                return(new CollectionResourceCastNode(parentAsCollection, childStructuredType));
            }

            return(new SingleResourceCastNode(parentAsSingleResource, childStructuredType));
        }