Esempio n. 1
0
        internal static bool TryCastPathAsType(this IEdmPathExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors)
        {
            IEdmStructuredType structuredContext = context as IEdmStructuredType;

            if (structuredContext != null)
            {
                IEdmType result = context;

                // [EdmLib] Need to handle paths that bind to things other than properties.
                foreach (string segment in expression.PathSegments)
                {
                    IEdmStructuredType structuredResult = result as IEdmStructuredType;
                    if (structuredResult == null)
                    {
                        discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PathIsNotValidForTheGivenContext, Edm.Strings.EdmModel_Validator_Semantic_PathIsNotValidForTheGivenContext(segment)) };
                        return(false);
                    }

                    IEdmProperty resultProperty = structuredResult.FindProperty(segment);
                    result = (resultProperty != null) ? resultProperty.Type.Definition : null;

                    // If the path is not resolved, it could refer to an open type, and we cannot make an assertion about its type.
                    if (result == null)
                    {
                        discoveredErrors = Enumerable.Empty <EdmError>();
                        return(true);
                    }
                }

                return(TestTypeMatch(result, type.Definition, expression.Location(), matchExactly, out discoveredErrors));
            }

            discoveredErrors = Enumerable.Empty <EdmError>();
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Resolve property from property name
        /// </summary>
        /// <param name="type">The declaring type.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The resolved <see cref="IEdmProperty"/></returns>
        public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName)
        {
            IEdmProperty property = type.FindProperty(propertyName);

            if (property != null || !EnableCaseInsensitive)
            {
                return(property);
            }

            var result = type.Properties()
                         .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase));

            IEdmProperty resolvedProperty = null;

            foreach (IEdmProperty candidate in result)
            {
                if (resolvedProperty == null)
                {
                    resolvedProperty = candidate;
                }
                else
                {
                    throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName()));
                }
            }

            return(resolvedProperty);
        }
Esempio n. 3
0
            /// <summary>
            /// Returns the structural property for the given payload element (only for properties).
            /// </summary>
            /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
            /// <param name="model">The model to get the structural property from.</param>
            /// <returns>The expected structural property for the specified payload element.</returns>
            private static IEdmStructuralProperty GetExpectedStructuralProperty(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model)
            {
                ExceptionUtilities.Assert(model != null, "model != null");

                if (expectedTypeAnnotation != null)
                {
                    if (expectedTypeAnnotation.EdmProperty != null)
                    {
                        return(expectedTypeAnnotation.EdmProperty as IEdmStructuralProperty);
                    }
                    MemberProperty expectedStructuralProperty = expectedTypeAnnotation.MemberProperty;
                    if (expectedStructuralProperty != null)
                    {
                        NamedStructuralType expectedOwningType = expectedTypeAnnotation.OwningType;
                        ExceptionUtilities.Assert(expectedOwningType != null, "Need an owning type if a structural property is specified.");

                        IEdmStructuredType owningType = model.FindType(expectedOwningType.FullName) as IEdmStructuredType;
                        ExceptionUtilities.Assert(owningType != null, "Did not find expected structured type in the model.");

                        IEdmStructuralProperty structuralProperty = owningType.FindProperty(expectedStructuralProperty.Name) as IEdmStructuralProperty;
                        ExceptionUtilities.Assert(structuralProperty != null, "Did not find expected structural property in the model.");

                        return(structuralProperty);
                    }
                }

                return(null);
            }
        /// <summary>
        /// Sets the expected property for the top-level property instance.
        /// </summary>
        /// <param name="property">The property instance to set the expected property for.</param>
        /// <param name="owningType">The type owning the expected property.</param>
        /// <param name="expectedPropertyName">The name of the property to set as the expected property.</param>
        /// <returns>The <paramref name="property"/> after its expected property was set.</returns>
        public static PropertyInstance ExpectedProperty(
            this PropertyInstance property,
            IEdmStructuredType owningType,
            string expectedPropertyName)
        {
            ExceptionUtilities.CheckArgumentNotNull(property, "property");
            ExceptionUtilities.CheckArgumentNotNull(owningType, "owningType");
            ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(expectedPropertyName, "expectedPropertyName");

            ExpectedTypeODataPayloadElementAnnotation annotation = ODataPayloadElementExtensions.AddExpectedTypeAnnotation(property);

            annotation.EdmOwningType = owningType;
            var memberProperty = owningType.FindProperty(expectedPropertyName);

            if (memberProperty != null)
            {
                annotation.EdmProperty     = memberProperty;
                annotation.EdmExpectedType = memberProperty.Type;
            }
            else
            {
                ExceptionUtilities.Assert(owningType.IsOpen, "For non-declared properties the owning type must be open.");
                annotation.OpenMemberPropertyName = expectedPropertyName;
            }

            return(property);
        }
 public PropertyMetadataTypeInfo(string name, IEdmStructuredType owningType)
 {
     this.PropertyName         = name;
     this.OwningType           = owningType;
     this.EdmProperty          = owningType == null ? null : owningType.FindProperty(name);
     this.IsUndeclaredProperty = this.EdmProperty == null;
     this.IsOpenProperty       = (owningType != null && owningType.IsOpen && this.IsUndeclaredProperty);
     this.TypeReference        = this.IsUndeclaredProperty ? null : this.EdmProperty.Type;
     this.FullName             = this.TypeReference == null ? null : this.TypeReference.Definition.AsActualType().FullTypeName();
 }
Esempio n. 6
0
        /// <summary>
        /// Translates a V3 SingleNavigationNode to V4 SingleNavigationNode
        /// </summary>
        /// <param name="nodeIn">V3 SingleNavigationNode</param>
        /// <returns>V4 SingleNavigationNode</returns>
        public override QueryNode Visit(Data.OData.Query.SemanticAst.SingleNavigationNode nodeIn)
        {
            IEdmStructuredType v4Type = v4model.GetV4Definition(nodeIn.TypeReference.Definition) as IEdmStructuredType;
            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 type " + nodeIn.TypeReference.Definition.GetFullTypeName());

            IEdmNavigationProperty v4navProperty = v4Type.FindProperty(nodeIn.NavigationProperty.Name) as IEdmNavigationProperty;
            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 navigation property " + nodeIn.NavigationProperty.Name);

            return new SingleNavigationNode((SingleResourceNode)nodeIn.Source.Accept(this), v4navProperty, null);
        }
        /// <summary>
        /// Determines whether or not the given operation is selected and takes type-segments into account.
        /// </summary>
        /// <param name="structuredType">The current resource type.</param>
        /// <param name="operation">The operation.</param>
        /// <param name="mustBeNamespaceQualified">Whether or not the operation name must be container qualified in the $select string.</param>
        /// <returns>
        ///   <c>true</c> if the operation is selected; otherwise, <c>false</c>.
        /// </returns>
        internal bool IsOperationSelected(IEdmStructuredType structuredType, IEdmOperation operation, bool mustBeNamespaceQualified)
        {
            Debug.Assert(structuredType != null, "structuredType != null");
            Debug.Assert(operation != null, "operation != null");

            // If the operation name conflicts with a property name then it must be namespace qualified
            mustBeNamespaceQualified = mustBeNamespaceQualified || structuredType.FindProperty(operation.Name) != null;

            return(this.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified) || this.GetMatchingTypeSegments(structuredType).Any(typeSegment => typeSegment.IsOperationSelectedAtThisLevel(operation, mustBeNamespaceQualified)));
        }
        /// <summary>
        /// Gets resource path from service root, and request Uri.
        /// </summary>
        /// <param name="baseUri">The service root Uri.</param>
        /// <param name="odataUri">The request Uri.</param>
        /// <returns>The resource path.</returns>
        private Uri GetContainingEntitySetUri(Uri baseUri, ODataUri odataUri)
        {
            ODataPath path = odataUri.Path;
            List <ODataPathSegment> segments    = path.ToList();
            ODataPathSegment        lastSegment = segments.Last();

            while (!(lastSegment is NavigationPropertySegment) && !(lastSegment is OperationSegment))
            {
                segments.Remove(lastSegment);
                lastSegment = segments.Last();
            }

            // also removed the last navigation property segment
            segments.Remove(lastSegment);

            // Remove the unnecessary type cast segment.
            ODataPathSegment nextToLastSegment = segments.Last();

            while (nextToLastSegment is TypeSegment)
            {
                ODataPathSegment   previousSegment = segments[segments.Count - 2];
                IEdmStructuredType owningType      = previousSegment.TargetEdmType as IEdmStructuredType;
                if (owningType != null && owningType.FindProperty(lastSegment.Identifier) != null)
                {
                    segments.Remove(nextToLastSegment);
                    nextToLastSegment = segments.Last();
                }
                else
                {
                    break;
                }
            }

            // append each segment to base uri
            Uri uri = baseUri;

            foreach (ODataPathSegment segment in segments)
            {
                var keySegment = segment as KeySegment;
                if (keySegment == null)
                {
                    uri = this.UriBuilder.BuildEntitySetUri(uri, segment.Identifier);
                }
                else
                {
                    uri = this.UriBuilder.BuildEntityInstanceUri(
                        uri,
                        keySegment.Keys.ToList(),
                        keySegment.EdmType.FullTypeName());
                }
            }

            return(uri);
        }
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        public IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnMissingProperty = true)
        {
            if (owningStructuredType == null)
            {
                return null;
            }

            return owningStructuredType.FindProperty(propertyName);
        }
Esempio n. 10
0
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</param>
        /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        public IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnMissingProperty = true)
        {
            if (owningStructuredType == null)
            {
                return(null);
            }

            return(owningStructuredType.FindProperty(propertyName));
        }
Esempio n. 11
0
        public PropertyMetadataTypeInfo(IEdmModel model, string name, IEdmStructuredType owningType)
        {
            this.PropertyName         = name;
            this.OwningType           = owningType;
            this.EdmProperty          = owningType == null ? null : owningType.FindProperty(name);
            this.IsUndeclaredProperty = this.EdmProperty == null;
            this.IsOpenProperty       = (owningType != null && owningType.IsOpen && this.IsUndeclaredProperty);
            this.TypeReference        = this.IsUndeclaredProperty ? null : this.EdmProperty.Type;
            this.FullName             = this.TypeReference == null ? null : this.TypeReference.Definition.AsActualType().FullTypeName();

            this.model = model;
            derivedTypeConstraintsLoaded = false;
        }
Esempio n. 12
0
 internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings)
 {
     if (owningStructuredType == null)
     {
         return null;
     }
     IEdmProperty property = owningStructuredType.FindProperty(propertyName);
     if (((property == null) && owningStructuredType.IsOpen) && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName()));
     }
     return property;
 }
Esempio n. 13
0
        /// <summary>
        /// Translates a v3 NavigationPropertyLinkSegment (TODO: EXAMPLE) into v4 NavigationPropertyLinkSegment
        /// </summary>
        /// <param name="segment">OData V3 NavigationPropertyLinkSegment</param>
        /// <returns>OData V4 NavigationPropertyLinkSegment</returns>
        public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.NavigationPropertyLinkSegment segment)
        {
            ExceptionUtil.IfArgumentNullThrowException(segment.EntitySet, "segment.EntitySet", "V3 entity set not found");
            IEdmStructuredType     v4Type = v4model.GetV4Definition(segment.NavigationProperty.DeclaringType) as IEdmStructuredType;
            IEdmNavigationProperty v4navigationProperty = v4Type.FindProperty(segment.NavigationProperty.Name) as IEdmNavigationProperty;

            ExceptionUtil.IfNullThrowException(v4Type, "Unable to find equivalent V4 property of V3 property: " + segment.NavigationProperty.Name);

            IEdmNavigationSource v4navigationSource = v4model.FindDeclaredNavigationSource(segment.EntitySet.Name);

            ExceptionUtil.IfNullThrowException(v4navigationSource, "Unable to find equivalent V4 entity set of V3 Entity set " + segment.EntitySet.Name);
            return(new NavigationPropertyLinkSegment(v4navigationProperty, v4navigationSource));
        }
Esempio n. 14
0
        internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings)
        {
            if (owningStructuredType == null)
            {
                return(null);
            }
            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            if (((property == null) && owningStructuredType.IsOpen) && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None))
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName()));
            }
            return(property);
        }
Esempio n. 15
0
        /// <summary>
        /// Translates at V3 PropertySegment (e.g. "/Boxes(1)/Name") into a V4 PropertySegment
        /// </summary>
        /// <param name="segment">OData V3 PropertySegment</param>
        /// <returns>OData V4 PropertySegment</returns>
        public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.PropertySegment segment)
        {
            // Look up equivalent declaring type in V4 model
            IEdmStructuredType v4Type = v4model.GetV4Definition(segment.Property.DeclaringType) as IEdmStructuredType;

            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate equivalent v4 type for " + segment.Property.DeclaringType.GetFullTypeName());

            // Look up corresponding Property in V4 Type by name
            IEdmStructuralProperty v4Property = v4Type.FindProperty(segment.Property.Name) as IEdmStructuralProperty;

            ExceptionUtil.IfNullThrowException(v4Property, "Unable to locate equivalent v4 property for " + segment.Property.Name);

            return(new PropertySegment(v4Property));
        }
Esempio n. 16
0
        /// <summary>
        /// Gets resource path from service root, and request Uri.
        /// </summary>
        /// <param name="baseUri">The service root Uri.</param>
        /// <param name="odataUri">The request Uri.</param>
        /// <returns>The resource path.</returns>
        private Uri GetContainingEntitySetUri(Uri baseUri, ODataUri odataUri)
        {
            ODataPath path = odataUri.Path;
            List <ODataPathSegment> segments = path.ToList();
            int lastIndex = segments.Count - 1;
            ODataPathSegment lastSegment = segments[lastIndex];

            while (!(lastSegment is NavigationPropertySegment) && !(lastSegment is OperationSegment))
            {
                lastSegment = segments[--lastIndex];
            }

            while (lastSegment is TypeSegment)
            {
                ODataPathSegment   previousSegment = segments[lastIndex - 1];
                IEdmStructuredType owningType      = previousSegment.TargetEdmType as IEdmStructuredType;
                if (owningType != null && owningType.FindProperty(lastSegment.Identifier) != null)
                {
                    lastSegment = segments[--lastIndex];
                }
                else
                {
                    break;
                }
            }

            // trim all the un-needed segments
            segments = segments.GetRange(0, lastIndex);

            // append each segment to base uri
            Uri uri = baseUri;

            foreach (ODataPathSegment segment in segments)
            {
                var keySegment = segment as KeySegment;
                if (keySegment == null)
                {
                    uri = this.UriBuilder.BuildEntitySetUri(uri, segment.Identifier);
                }
                else
                {
                    uri = this.UriBuilder.BuildEntityInstanceUri(
                        uri,
                        keySegment.Keys.ToList(),
                        keySegment.EdmType.FullTypeName());
                }
            }

            return(uri);
        }
Esempio n. 17
0
        internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType)
        {
            if (owningStructuredType == null)
            {
                return(null);
            }
            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            if (!owningStructuredType.IsOpen && (property == null))
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName()));
            }
            return(property);
        }
Esempio n. 18
0
        public static IEdmProperty ResolveProperty(this IEdmStructuredType type, string propertyName, bool enableCaseInsensitive = false)
        {
            IEdmProperty property = type.FindProperty(propertyName);

            if (property != null || !enableCaseInsensitive)
            {
                return(property);
            }

            var result = type.Properties()
                         .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase))
                         .ToList();

            return(result.SingleOrDefault());
        }
Esempio n. 19
0
        /// <summary>
        /// Translates V3 CollectionNavigationNode to V4 CollectionNavigationNode
        /// </summary>
        /// <param name="nodeIn">V3 CollectionNavigationNode</param>
        /// <returns>V4 CollectionNavigationNode</returns>
        public override QueryNode Visit(Data.OData.Query.SemanticAst.CollectionNavigationNode nodeIn)
        {
            IEdmPathExpression pathExpr = null;
            if (nodeIn.EntitySet != null)
            {
                IEdmNavigationSource navigationSource = v4model.FindDeclaredNavigationSource(nodeIn.EntitySet.Name);
                pathExpr = navigationSource.Path;
            }

            IEdmStructuredType v4Type = v4model.GetV4Definition(nodeIn.NavigationProperty.DeclaringType) as IEdmStructuredType;
            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 structured type " + nodeIn.NavigationProperty.DeclaringType.GetFullTypeName());

            IEdmNavigationProperty v4navProperty = v4Type.FindProperty(nodeIn.NavigationProperty.Name) as IEdmNavigationProperty;
            ExceptionUtil.IfNullThrowException(v4navProperty, "Unable to locate property " + nodeIn.NavigationProperty.Name);
            return new CollectionNavigationNode((SingleResourceNode)nodeIn.Source.Accept(this), v4navProperty, pathExpr);
        }
        internal static IEdmNavigationProperty ResolvePartnerPath(IEdmEntityType type, IEdmPathExpression path, IEdmModel model)
        {
            Debug.Assert(type != null);
            Debug.Assert(path != null);
            Debug.Assert(model != null);

            IEdmStructuredType currentType = type;
            IEdmProperty       property    = null;

            foreach (var segment in path.PathSegments)
            {
                if (currentType == null)
                {
                    return(null);
                }

                if (segment.IndexOf('.') < 0)
                {
                    property = currentType.FindProperty(segment);
                    if (property == null)
                    {
                        return(null);
                    }

                    currentType = property.Type.Definition.AsElementType() as IEdmStructuredType;
                }
                else
                {
                    var derivedType = model.FindDeclaredType(segment);
                    if (derivedType == null || !derivedType.IsOrInheritsFrom(currentType))
                    {
                        return(null);
                    }

                    currentType = derivedType as IEdmStructuredType;
                    property    = null;
                }
            }

            return(property != null
                   ? property as IEdmNavigationProperty
                   : null);
        }
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            if (owningStructuredType == null)
            {
                return(null);
            }

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            // verify that the property is declared if the type is not an open type.
            if (!owningStructuredType.IsOpen && property == null)
            {
                throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName()));
            }

            return(property);
        }
Esempio n. 22
0
        /// <summary>
        /// Translates a v3 NavigationPropertySegment (TODO: EXAMPLE) into v4 NavigationPropertySegment
        /// </summary>
        /// <param name="segment">OData V3 NavigationPropertySegment</param>
        /// <returns>OData V4 NavigationPropertySegment</returns>
        public override ODataPathSegment Translate(Data.OData.Query.SemanticAst.NavigationPropertySegment segment)
        {
            // Look up corresponding V4 type in model
            IEdmStructuredType v4Type = v4model.GetV4Definition(segment.NavigationProperty.DeclaringType) as IEdmStructuredType;

            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate equivalent v4 type for declaring type: " + segment.NavigationProperty.DeclaringType.GetFullTypeName());

            // Use corresponding V4 type to look up corresponding NavigationProperty
            IEdmNavigationProperty v4navigationProperty = v4Type.FindProperty(segment.NavigationProperty.Name) as IEdmNavigationProperty;

            ExceptionUtil.IfNullThrowException(v4navigationProperty, "Unable to locate equivalent v4 property for " + segment.NavigationProperty.Name);

            // Separately, look up navigation source (entity set)
            IEdmNavigationSource v4navigationSource = v4model.FindDeclaredNavigationSource(segment.EntitySet.Name);

            ExceptionUtil.IfNullThrowException(v4navigationSource, "Unable to locate navigation source for entity set: " + segment.EntitySet.Name);

            return(new NavigationPropertySegment(v4navigationProperty, v4navigationSource));
        }
Esempio n. 23
0
        /// <summary>
        /// Resolve property from property name
        /// </summary>
        /// <param name="type">The declaring type.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The resolved <see cref="IEdmProperty"/></returns>
        public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName)
        {
            if (EnableCaseInsensitive)
            {
                var result = type.Properties()
                             .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase))
                             .ToList();

                if (result.Count == 1)
                {
                    return(result.Single());
                }
                else if (result.Count > 1)
                {
                    throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName()));
                }
            }

            return(type.FindProperty(propertyName));
        }
Esempio n. 24
0
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</param>
        /// <param name="throwOnUndeclaredProperty">Flag indicating whether undeclared property on non open type should be prohibited.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnUndeclaredProperty)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            if (owningStructuredType == null)
            {
                return(null);
            }

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            if (throwOnUndeclaredProperty && !owningStructuredType.IsOpen && property == null)
            {
                throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.FullTypeName()));
            }

            return(property);
        }
Esempio n. 25
0
        /// <summary>
        /// Compares two sets of structural properties (expected value in CSDL, actual as IEdmStructuredType).
        /// This can apply to both entity types and complex types.
        /// </summary>
        /// <param name="propertyElements">The CSDL element representing the properties.</param>
        /// <param name="modelType">The EDM model type to compare against.</param>
        private static void CompareStructuralProperties(IEnumerable <XElement> propertyElements, IEdmStructuredType modelType)
        {
            ExceptionUtilities.Assert(propertyElements.Count() == modelType.StructuralProperties().Count(), "Unexpected number of properties on type " + modelType.TestFullName());
            foreach (var propertyElement in propertyElements)
            {
                var propertyName    = propertyElement.GetAttributeValue("Name");
                var propertyOnModel = modelType.FindProperty(propertyName) as IEdmStructuralProperty;
                ExceptionUtilities.Assert(propertyOnModel != null, "Failed to find structural property " + propertyName + " on type " + modelType.TestFullName());
                CompareType(propertyElement, propertyOnModel.Type);
                // TODO: Enable this.
                // CompareTypeFacets(propertyElement, propertyOnModel.Type);

                string defaultValueString;
                if (propertyElement.TryGetAttributeValue("DefaultValue", out defaultValueString))
                {
                    ExceptionUtilities.Assert(string.Compare(defaultValueString, propertyOnModel.DefaultValueString) == 0, "Unexpected value for DefaultValue");
                }
                else
                {
                    ExceptionUtilities.Assert(string.IsNullOrEmpty(propertyOnModel.DefaultValueString), "Did not expect a value for DefaultValue property");
                }
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</param>
        /// <param name="undeclaredPropertyBehaviorKinds">Value of UndeclaredPropertyBehaviorKinds in message settings.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType, ODataUndeclaredPropertyBehaviorKinds undeclaredPropertyBehaviorKinds)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            if (owningStructuredType == null)
            {
                return(null);
            }

            // .None / .LinkProperty
            bool throwErr = !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty) &&
                            !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty);

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            // verify that the property is declared if the type is not an open type.
            if (throwErr && !owningStructuredType.IsOpen && property == null)
            {
                throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName()));
            }

            return(property);
        }
        /// <summary>
        /// Generates a dictionary with property name and property values specified in the skiptoken value.
        /// </summary>
        /// <param name="value">The skiptoken string value.</param>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information</param>
        /// <returns>Dictionary with property name and property value in the skiptoken value.</returns>
        private static IDictionary <string, object> PopulatePropertyValuePairs(string value, ODataQueryContext context)
        {
            Contract.Assert(context != null);

            IDictionary <string, object> propertyValuePairs = new Dictionary <string, object>();
            IList <string> keyValuesPairs = ParseValue(value, CommaDelimiter);

            IEdmStructuredType type = context.ElementType as IEdmStructuredType;

            Debug.Assert(type != null);

            foreach (string pair in keyValuesPairs)
            {
                string[] pieces = pair.Split(new char[] { propertyDelimiter }, 2);
                if (pieces.Length > 1 && !String.IsNullOrWhiteSpace(pieces[0]))
                {
                    object propValue = null;

                    IEdmTypeReference propertyType = null;
                    IEdmProperty      property     = type.FindProperty(pieces[0]);
                    if (property != null)
                    {
                        propertyType = property.Type;
                    }

                    propValue = ODataUriUtils.ConvertFromUriLiteral(pieces[1], ODataVersion.V401, context.Model, propertyType);
                    propertyValuePairs.Add(pieces[0], propValue);
                }
                else
                {
                    throw Error.InvalidOperation(SRResources.SkipTokenParseError);
                }
            }

            return(propertyValuePairs);
        }
        private static bool TryBindAsDeclaredProperty(PathSegmentToken tokenIn, IEdmStructuredType edmType, out ODataPathSegment segment)
        {
            IEdmProperty prop = edmType.FindProperty(tokenIn.Identifier);

            if (prop == null)
            {
                segment = null;
                return(false);
            }

            if (prop.PropertyKind == EdmPropertyKind.Structural)
            {
                segment = new PropertySegment((IEdmStructuralProperty)prop);
                return(true);
            }

            if (prop.PropertyKind == EdmPropertyKind.Navigation)
            {
                segment = new NavigationPropertySegment((IEdmNavigationProperty)prop, null /*TODO set*/);
                return(true);
            }

            throw new ODataException(ODataErrorStrings.SelectExpandBinder_UnknownPropertyType(prop.Name));
        }
Esempio n. 29
0
 internal static IEdmProperty ValidatePropertyDefined(string propertyName, IEdmStructuredType owningStructuredType)
 {
     if (owningStructuredType == null)
     {
         return null;
     }
     IEdmProperty property = owningStructuredType.FindProperty(propertyName);
     if (!owningStructuredType.IsOpen && (property == null))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName()));
     }
     return property;
 }
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return(this.targetContext);
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string              target              = this.annotationsContext.Annotations.Target;
                string[]            targetSegments      = target.Split('/');
                int                 targetSegmentsCount = targetSegments.Count();
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string         elementName = targetSegments[0];
                    IEdmSchemaType type        = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return(type);
                    }

                    IEdmValueTerm term = this.schema.FindValueTerm(elementName);
                    if (term != null)
                    {
                        return(term);
                    }

                    IEdmFunction function = this.FindParameterizedFunction(elementName, this.Schema.FindFunctions, this.CreateAmbiguousFunction);
                    if (function != null)
                    {
                        return(function);
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return(container);
                    }

                    return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location));
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmEntityContainerElement containerElement = container.FindEntitySet(targetSegments[1]);
                        if (containerElement != null)
                        {
                            return(containerElement);
                        }

                        IEdmFunctionImport functionImport = this.FindParameterizedFunction(targetSegments[1], container.FindFunctionImports, this.CreateAmbiguousFunctionImport);
                        if (functionImport != null)
                        {
                            return(functionImport);
                        }

                        return(new UnresolvedEntitySet(targetSegments[1], container, this.Location));
                    }

                    IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType;
                    if (type != null)
                    {
                        IEdmProperty property = type.FindProperty(targetSegments[1]);
                        if (property != null)
                        {
                            return(property);
                        }

                        return(new UnresolvedProperty(type, targetSegments[1], this.Location));
                    }

                    IEdmFunction function = this.FindParameterizedFunction(targetSegments[0], this.Schema.FindFunctions, this.CreateAmbiguousFunction);
                    if (function != null)
                    {
                        IEdmFunctionParameter parameter = function.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return(parameter);
                        }

                        return(new UnresolvedParameter(function, targetSegments[1], this.Location));
                    }

                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location));
                }

                if (targetSegmentsCount == 3)
                {
                    container = this.Model.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmFunctionImport functionImport = this.FindParameterizedFunction(targetSegments[1], container.FindFunctionImports, this.CreateAmbiguousFunctionImport);
                        if (functionImport != null)
                        {
                            IEdmFunctionParameter parameter = functionImport.FindParameter(targetSegments[2]);
                            if (parameter != null)
                            {
                                return(parameter);
                            }

                            return(new UnresolvedParameter(functionImport, targetSegments[1], this.Location));
                        }
                    }
                }

                return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) }));
            }
        }
Esempio n. 31
0
        /// <summary>
        /// Resolve property from property name
        /// </summary>
        /// <param name="type">The declaring type.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The resolved <see cref="IEdmProperty"/></returns>
        public virtual IEdmProperty ResolveProperty(IEdmStructuredType type, string propertyName)
        {
            if (EnableCaseInsensitive)
            {
                var result = type.Properties()
                .Where(_ => string.Equals(propertyName, _.Name, StringComparison.OrdinalIgnoreCase))
                .ToList();

                if (result.Count == 1)
                {
                    return result.Single();
                }
                else if (result.Count > 1)
                {
                    throw new ODataException(Strings.UriParserMetadata_MultipleMatchingPropertiesFound(propertyName, type.FullTypeName()));
                }
            }

            return type.FindProperty(propertyName);
        }
Esempio n. 32
0
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            IEdmEntityContainer edmEntityContainer;

            if (this.targetContext == null)
            {
                string target   = this.annotationsContext.Annotations.Target;
                char[] chrArray = new char[1];
                chrArray[0] = '/';
                string[] strArrays = target.Split(chrArray);
                int      num       = strArrays.Count <string>();
                if (num != 1)
                {
                    if (num != 2)
                    {
                        if (num == 3)
                        {
                            edmEntityContainer = this.Model.FindEntityContainer(strArrays[0]);
                            if (edmEntityContainer != null)
                            {
                                IEdmEntityContainer edmEntityContainer1 = edmEntityContainer;
                                IEdmFunctionImport  edmFunctionImport   = this.FindParameterizedFunction <IEdmFunctionImport>(strArrays[1], new Func <string, IEnumerable <IEdmFunctionImport> >(edmEntityContainer1.FindFunctionImports), new Func <IEnumerable <IEdmFunctionImport>, IEdmFunctionImport>(this.CreateAmbiguousFunctionImport));
                                if (edmFunctionImport != null)
                                {
                                    IEdmFunctionParameter edmFunctionParameter = edmFunctionImport.FindParameter(strArrays[2]);
                                    if (edmFunctionParameter == null)
                                    {
                                        return(new UnresolvedParameter(edmFunctionImport, strArrays[1], base.Location));
                                    }
                                    else
                                    {
                                        return(edmFunctionParameter);
                                    }
                                }
                            }
                        }
                        EdmError[] edmError = new EdmError[1];
                        edmError[0] = new EdmError(base.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target));
                        return(new BadElement(edmError));
                    }
                    else
                    {
                        edmEntityContainer = this.schema.FindEntityContainer(strArrays[0]);
                        if (edmEntityContainer == null)
                        {
                            IEdmStructuredType edmStructuredType = this.schema.FindType(strArrays[0]) as IEdmStructuredType;
                            if (edmStructuredType == null)
                            {
                                IEdmFunction edmFunction = this.FindParameterizedFunction <IEdmFunction>(strArrays[0], new Func <string, IEnumerable <IEdmFunction> >(this.Schema.FindFunctions), new Func <IEnumerable <IEdmFunction>, IEdmFunction>(this.CreateAmbiguousFunction));
                                if (edmFunction == null)
                                {
                                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(strArrays[0]), base.Location), strArrays[1], base.Location));
                                }
                                else
                                {
                                    IEdmFunctionParameter edmFunctionParameter1 = edmFunction.FindParameter(strArrays[1]);
                                    if (edmFunctionParameter1 == null)
                                    {
                                        return(new UnresolvedParameter(edmFunction, strArrays[1], base.Location));
                                    }
                                    else
                                    {
                                        return(edmFunctionParameter1);
                                    }
                                }
                            }
                            else
                            {
                                IEdmProperty edmProperty = edmStructuredType.FindProperty(strArrays[1]);
                                if (edmProperty == null)
                                {
                                    return(new UnresolvedProperty(edmStructuredType, strArrays[1], base.Location));
                                }
                                else
                                {
                                    return(edmProperty);
                                }
                            }
                        }
                        else
                        {
                            IEdmEntityContainerElement edmEntityContainerElement = edmEntityContainer.FindEntitySet(strArrays[1]);
                            if (edmEntityContainerElement == null)
                            {
                                IEdmEntityContainer edmEntityContainer2 = edmEntityContainer;
                                IEdmFunctionImport  edmFunctionImport1  = this.FindParameterizedFunction <IEdmFunctionImport>(strArrays[1], new Func <string, IEnumerable <IEdmFunctionImport> >(edmEntityContainer2.FindFunctionImports), new Func <IEnumerable <IEdmFunctionImport>, IEdmFunctionImport>(this.CreateAmbiguousFunctionImport));
                                if (edmFunctionImport1 == null)
                                {
                                    return(new UnresolvedEntitySet(strArrays[1], edmEntityContainer, base.Location));
                                }
                                else
                                {
                                    return(edmFunctionImport1);
                                }
                            }
                            else
                            {
                                return(edmEntityContainerElement);
                            }
                        }
                    }
                }
                else
                {
                    string         str           = strArrays[0];
                    IEdmSchemaType edmSchemaType = this.schema.FindType(str);
                    if (edmSchemaType == null)
                    {
                        IEdmValueTerm edmValueTerm = this.schema.FindValueTerm(str);
                        if (edmValueTerm == null)
                        {
                            IEdmFunction edmFunction1 = this.FindParameterizedFunction <IEdmFunction>(str, new Func <string, IEnumerable <IEdmFunction> >(this.Schema.FindFunctions), new Func <IEnumerable <IEdmFunction>, IEdmFunction>(this.CreateAmbiguousFunction));
                            if (edmFunction1 == null)
                            {
                                edmEntityContainer = this.schema.FindEntityContainer(str);
                                if (edmEntityContainer == null)
                                {
                                    return(new UnresolvedType(this.Schema.UnresolvedName(strArrays[0]), base.Location));
                                }
                                else
                                {
                                    return(edmEntityContainer);
                                }
                            }
                            else
                            {
                                return(edmFunction1);
                            }
                        }
                        else
                        {
                            return(edmValueTerm);
                        }
                    }
                    else
                    {
                        return(edmSchemaType);
                    }
                }
            }
            else
            {
                return(this.targetContext);
            }
        }
Esempio n. 33
0
        private void ValidateAnnotationWithFewerPropertyThanType(IEdmModel model, IEdmStructuredType actualType, IEnumerable<IEdmPropertyConstructor> annotationProperties)
        {
            foreach (var annotationProperty in annotationProperties)
            {
                var annotationName = annotationProperty.Name;
                var actualProperty = actualType.FindProperty(annotationName);
                Assert.IsNotNull(actualProperty, "Invalid property name.");

                Action<IEdmModel, IEdmStructuredType, IEnumerable<IEdmPropertyConstructor>> validateAnnotation = (m, t, l) => this.ValidateAnnotationWithFewerPropertyThanType(m, t, l);
                ValidateAnnotationProperty(model, actualProperty, annotationProperty, validateAnnotation);
            }
        }
Esempio n. 34
0
        private void ValidateAnnotationWithExactPropertyAsType(IEdmModel model, IEdmStructuredType actualType, IEnumerable<IEdmPropertyConstructor> annotationProperties)
        {
            Assert.AreEqual(actualType.Properties().Count(), annotationProperties.Count(), "Annotation does not have the same count of properties as it's declared type.");

            foreach (var annotationProperty in annotationProperties)
            {
                var annotationName = annotationProperty.Name;
                var actualProperty = actualType.FindProperty(annotationName);
                Assert.IsNotNull(actualProperty, "Invalid property name.");

                Action<IEdmModel, IEdmStructuredType, IEnumerable<IEdmPropertyConstructor>> validateAnnotation = (m, t, l) => this.ValidateAnnotationWithExactPropertyAsType(m, t, l);
                ValidateAnnotationProperty(model, actualProperty, annotationProperty, validateAnnotation);
            }
        }
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return(this.targetContext);
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string              target              = this.annotationsContext.Annotations.Target;
                string[]            targetSegments      = target.Split('/');
                int                 targetSegmentsCount = targetSegments.Count();
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string         elementName = targetSegments[0];
                    IEdmSchemaType type        = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return(type);
                    }

                    IEdmValueTerm term = this.schema.FindValueTerm(elementName);
                    if (term != null)
                    {
                        return(term);
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        return(operation);
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return(container);
                    }

                    return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location));
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1]);
                        if (containerElement != null)
                        {
                            return(containerElement);
                        }

                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            return(operationImport);
                        }

                        return(new UnresolvedEntitySet(targetSegments[1], container, this.Location));
                    }

                    IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType;
                    if (type != null)
                    {
                        IEdmProperty property = type.FindProperty(targetSegments[1]);
                        if (property != null)
                        {
                            return(property);
                        }

                        return(new UnresolvedProperty(type, targetSegments[1], this.Location));
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return(parameter);
                        }

                        return(new UnresolvedParameter(operation, targetSegments[1], this.Location));
                    }

                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location));
                }

                if (targetSegmentsCount == 3)
                {
                    // The only valid target with three segments is a function parameter.
                    string containerName = targetSegments[0];
                    string operationName = targetSegments[1];
                    string parameterName = targetSegments[2];

                    container = this.Model.FindEntityContainer(containerName);
                    if (container != null)
                    {
                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName);
                            if (parameter != null)
                            {
                                return(parameter);
                            }

                            return(new UnresolvedParameter(operationImport.Operation, parameterName, this.Location));
                        }
                    }

                    string qualifiedOperationName           = containerName + "/" + operationName;
                    UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location);
                    return(new UnresolvedParameter(unresolvedOperation, parameterName, this.Location));
                }

                return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) }));
            }
        }
Esempio n. 36
0
        /// <summary>
        /// Generate an expand item (and a select item for the implicit nav prop if necessary) based on an ExpandTermToken
        /// </summary>
        /// <param name="tokenIn">the expandTerm token to visit</param>
        /// <returns>the expand item for this expand term token.</returns>
        private ExpandedNavigationSelectItem GenerateExpandItem(ExpandTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            // ensure that we're always dealing with proper V4 syntax
            if (tokenIn.PathToNavProp.NextToken != null && !tokenIn.PathToNavProp.IsNamespaceOrContainerQualified())
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
            }

            PathSegmentToken currentToken = tokenIn.PathToNavProp;

            IEdmStructuredType      currentLevelEntityType = this.EdmType;
            List <ODataPathSegment> pathSoFar         = new List <ODataPathSegment>();
            PathSegmentToken        firstNonTypeToken = currentToken;

            if (currentToken.IsNamespaceOrContainerQualified())
            {
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, ref currentLevelEntityType, out firstNonTypeToken));
            }

            IEdmProperty edmProperty = currentLevelEntityType.FindProperty(firstNonTypeToken.Identifier);

            if (edmProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.ODataFullName(), currentToken.Identifier));
            }

            IEdmNavigationProperty currentNavProp = edmProperty as IEdmNavigationProperty;

            if (currentNavProp == null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationProperty(currentToken.Identifier, currentLevelEntityType.ODataFullName()));
            }

            if (firstNonTypeToken.NextToken != null)
            {
                // lastly... make sure that, since we're on a NavProp, that the next token isn't null.
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
            }

            pathSoFar.Add(new NavigationPropertySegment(currentNavProp, /*entitySet*/ null));
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            SelectExpandClause subSelectExpand;

            if (tokenIn.ExpandOption != null)
            {
                subSelectExpand = this.GenerateSubExpand(currentNavProp, tokenIn);
            }
            else
            {
                subSelectExpand = BuildDefaultSubExpand();
            }

            subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption);

            IEdmNavigationSource targetNavigationSource = null;

            if (this.NavigationSource != null)
            {
                targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp);
            }

            // call MetadataBinder to build the filter clause
            FilterClause filterOption = null;

            if (tokenIn.FilterOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource);
                FilterBinder   filterBinder = new FilterBinder(binder.Bind, binder.BindingState);
                filterOption = filterBinder.BindFilter(tokenIn.FilterOption);
            }

            // call MetadataBinder again to build the orderby clause
            OrderByClause orderbyOption = null;

            if (tokenIn.OrderByOptions != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetNavigationSource);
                OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
                orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, tokenIn.OrderByOptions);
            }

            LevelsClause levelsOption = this.ParseLevels(tokenIn.LevelsOption, this.EdmType, currentNavProp);

            SearchClause searchOption = null;

            if (tokenIn.SearchOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource);
                SearchBinder   searchBinder = new SearchBinder(binder.Bind);
                searchOption = searchBinder.BindSearch(tokenIn.SearchOption);
            }

            return(new ExpandedNavigationSelectItem(pathToNavProp, targetNavigationSource, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, levelsOption, searchOption, subSelectExpand));
        }
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnMissingProperty = true)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            if (owningStructuredType == null)
            {
                return null;
            }

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            // verify that the property is declared if the type is not an open type.
            if (throwOnMissingProperty && !owningStructuredType.IsOpen && property == null)
            {
                throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.ODataFullName()));
            }

            return property;
        }
        /// <summary>
        /// Finds a defined property from the model if one is available.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to find.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            if (owningStructuredType == null)
            {
                return null;
            }

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);
            return property;
        }
Esempio n. 39
0
        private static void CompareMembers(IEdmStructuredType edmEdmType, IEdmStructuredType dataWebEdmType, bool isReflectionBasedProvider, out int totalNavProps)
        {
            // find the number of nav properties on this type (not the base type). This will help us to determine how many associations 
            // be generated
            totalNavProps = edmEdmType.DeclaredProperties.OfType<IEdmNavigationProperty>().Count();
            AstoriaTestLog.IsTrue(edmEdmType.DeclaredProperties.Count() == dataWebEdmType.DeclaredProperties.Count(), "Number of members must match");

            foreach (IEdmProperty member1 in edmEdmType.DeclaredProperties)
            {
                IEdmProperty member2 = dataWebEdmType.FindProperty(member1.Name);
                AstoriaTestLog.IsNotNull(member2);

                // WCF DS server will always write DateTimeOffset as the data type, if the backend model has DateTime as the data type
                string edmMemberTypeName = member1.Type.FullName();
                if (edmMemberTypeName == "Edm.DateTime")
                {
                    AstoriaTestLog.IsTrue(member2.Type.FullName() == "Edm.DateTimeOffset", "For DateTime properties in the model, we should generate");
                }
                else
                {
                    AstoriaTestLog.IsTrue(edmMemberTypeName == member2.Type.FullName(), "Type must match");
                }

                AstoriaTestLog.IsTrue(member1.Type.IsNullable == member2.Type.IsNullable, "nullability must match");

                // TODO: if its a navigation, compare referential constraint!
            }
        }
        /// <summary>
        /// Finds a defined property from the model if one is available.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to find.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <param name="messageReaderSettings">The message reader settings being used.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");
            Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null");

            if (owningStructuredType == null)
            {
                return null;
            }

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            if (property == null && owningStructuredType.IsOpen)
            {
                if (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None)
                {
                    throw new ODataException(Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName()));
                }
            }

            return property;
        }