Пример #1
0
        /// <summary>
        /// Binds a DottedIdentifierToken and it's parent node (if needed).
        /// </summary>
        /// <param name="dottedIdentifierToken">Token to bind to metadata.</param>
        /// <param name="state">State of the Binding.</param>
        /// <returns>A bound node representing the cast.</returns>
        internal QueryNode BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken, BindingState state)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(dottedIdentifierToken, "castToken");
            ExceptionUtils.CheckArgumentNotNull(state, "state");

            QueryNode parent;
            IEdmType  parentType;

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

            SingleEntityNode parentAsSingleValue = parent as SingleEntityNode;

            IEdmSchemaType childType       = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier);
            IEdmEntityType childEntityType = childType as IEdmEntityType;

            if (childEntityType == null)
            {
                FunctionCallBinder functionCallBinder = new FunctionCallBinder(bindMethod);
                QueryNode          functionCallNode;
                if (functionCallBinder.TryBindDottedIdentifierAsFunctionCall(dottedIdentifierToken, parentAsSingleValue, state, out functionCallNode))
                {
                    return(functionCallNode);
                }
                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);

            EntityCollectionNode parentAsCollection = parent as EntityCollectionNode;

            if (parentAsCollection != null)
            {
                return(new EntityCollectionCastNode(parentAsCollection, childEntityType));
            }

            // parent can be null for casts on the implicit parameter; this is OK
            if (parent == null)
            {
                return(new SingleEntityCastNode(null, childEntityType));
            }

            Debug.Assert(parentAsSingleValue != null, "If parent of the cast node was not collection, it should be a single value.");
            return(new SingleEntityCastNode(parentAsSingleValue, childEntityType));
        }
Пример #2
0
        /// <summary>
        /// Follow any type segments on the path, stopping at the first segment that isn't a type token.
        /// </summary>
        /// <param name="firstTypeToken">the first type segment</param>
        /// <param name="model">the model these types are contained in.</param>
        /// <param name="maxDepth">the maximum recursive depth</param>
        /// <param name="currentLevelEntityType">the top level entity type, will be overwritten with the last entity type in the chain</param>
        /// <param name="firstNonTypeToken">the first non type token in the path</param>
        /// <returns>A path with type segments added to it.</returns>
        public static IEnumerable <ODataPathSegment> FollowTypeSegments(PathSegmentToken firstTypeToken, IEdmModel model, int maxDepth, ref IEdmEntityType currentLevelEntityType, out PathSegmentToken firstNonTypeToken)
        {
            ExceptionUtils.CheckArgumentNotNull(firstTypeToken, "firstTypeToken");
            ExceptionUtils.CheckArgumentNotNull(model, "model");

            if (!firstTypeToken.IsNamespaceOrContainerQualified())
            {
                throw new ODataException(ODataErrorStrings.SelectExpandPathBinder_FollowNonTypeSegment(firstTypeToken.Identifier));
            }

            int index = 0;
            List <ODataPathSegment> pathToReturn = new List <ODataPathSegment>();
            PathSegmentToken        currentToken = firstTypeToken;

            while (currentToken.IsNamespaceOrContainerQualified() && currentToken.NextToken != null)
            {
                IEdmEntityType previousLevelEntityType = currentLevelEntityType;
                currentLevelEntityType = UriEdmHelpers.FindTypeFromModel(model, currentToken.Identifier) as IEdmEntityType;
                if (currentLevelEntityType == null)
                {
                    // TODO: fix this error message?
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_CannotFindType(currentToken.Identifier));
                }

                UriEdmHelpers.CheckRelatedTo(previousLevelEntityType, currentLevelEntityType);
                pathToReturn.Add(new TypeSegment(currentLevelEntityType, /*entitySet*/ null));

                index++;
                currentToken = currentToken.NextToken;

                if (index >= maxDepth)
                {
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_PathTooDeep);
                }
            }

            firstNonTypeToken = currentToken;

            return(pathToReturn);
        }
Пример #3
0
        /// <summary>
        /// Binds a DottedIdentifierToken and it's parent node (if needed).
        /// </summary>
        /// <param name="dottedIdentifierToken">Token to bind to metadata.</param>
        /// <param name="state">State of the Binding.</param>
        /// <returns>A bound node representing the cast.</returns>
        internal QueryNode BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken, BindingState state)
        {
            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();
                }
            }

            SingleEntityNode   parentAsSingleValue = parent as SingleEntityNode;
            IEdmSchemaType     childType           = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier);
            IEdmStructuredType childStructuredType = childType as IEdmStructuredType;

            if (childStructuredType == null)
            {
                FunctionCallBinder functionCallBinder = new FunctionCallBinder(bindMethod);
                QueryNode          functionCallNode;
                if (functionCallBinder.TryBindDottedIdentifierAsFunctionCall(dottedIdentifierToken, parentAsSingleValue, state, out functionCallNode))
                {
                    return(functionCallNode);
                }
                else if ((!string.IsNullOrEmpty(dottedIdentifierToken.Identifier)) &&
                         (dottedIdentifierToken.Identifier[dottedIdentifierToken.Identifier.Length - 1] == '\''))
                {
                    // check if it is enum or not
                    EnumBinder enumBinder = new EnumBinder(this.bindMethod);
                    QueryNode  enumNode;
                    if (enumBinder.TryBindDottedIdentifierAsEnum(dottedIdentifierToken, parentAsSingleValue, state, out enumNode))
                    {
                        return(enumNode);
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.Binder_IsNotValidEnumConstant(dottedIdentifierToken.Identifier));
                    }
                }
                else
                {
                    IEdmTypeReference edmTypeReference = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier).ToTypeReference();
                    if (edmTypeReference is IEdmPrimitiveTypeReference || edmTypeReference is IEdmEnumTypeReference)
                    {
                        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);

            IEdmEntityType childEntityType = childStructuredType as IEdmEntityType;

            if (childEntityType != null)
            {
                EntityCollectionNode parentAsCollection = parent as EntityCollectionNode;
                if (parentAsCollection != null)
                {
                    return(new EntityCollectionCastNode(parentAsCollection, childEntityType));
                }

                // parent can be null for casts on the implicit parameter; this is OK
                if (parent == null)
                {
                    return(new SingleEntityCastNode(null, childEntityType));
                }

                Debug.Assert(parentAsSingleValue != null, "If parent of the cast node was not collection, it should be a single value.");
                return(new SingleEntityCastNode(parentAsSingleValue, childEntityType));
            }
            else
            {
                IEdmComplexType childComplexType = childStructuredType as IEdmComplexType;
                Debug.Assert(childComplexType != null, "If it is not entity type, it should be complex type");

                CollectionPropertyAccessNode parentAsCollectionProperty = parent as CollectionPropertyAccessNode;
                if (parentAsCollectionProperty != null)
                {
                    return(new CollectionPropertyCastNode(parentAsCollectionProperty, childComplexType));
                }

                // parent can be null for casts on the implicit parameter; this is OK
                if (parent == null)
                {
                    return(new SingleValueCastNode(null, childComplexType));
                }

                SingleValueNode parentAsSingleValueNode = parent as SingleValueNode;
                Debug.Assert(parentAsSingleValueNode != null, "If parent of the cast node was not collection, it should be a single value.");
                return(new SingleValueCastNode(parentAsSingleValueNode, childComplexType));
            }
        }