Exemplo n.º 1
0
        internal static bool TryAssertCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors)
        {
            IEnumerable <EdmError> edmErrors = null;
            bool flag;

            if (type.IsCollection())
            {
                IEdmTypeReference edmTypeReference = type.AsCollection().ElementType();
                bool            flag1      = true;
                List <EdmError> edmErrors1 = new List <EdmError>();
                foreach (IEdmExpression element in expression.Elements)
                {
                    if (!element.TryAssertType(edmTypeReference, out edmErrors))
                    {
                        flag = false;
                    }
                    else
                    {
                        flag = flag1;
                    }
                    flag1 = flag;
                    edmErrors1.AddRange(edmErrors);
                }
                discoveredErrors = edmErrors1;
                return(flag1);
            }
            else
            {
                EdmError[] edmError = new EdmError[1];
                edmError[0]      = new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType);
                discoveredErrors = edmError;
                return(false);
            }
        }
Exemplo n.º 2
0
        public void EnumPropertyWithConcurrencyToken_SetsVocabuaryAnnotaion()
        {
            // Arrange
            var builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>().Add_Color_EnumType();
            var entityTypeConfiguration = builder.EntityType <EntityTypeWithEnumTypePropertyTestModel>();

            entityTypeConfiguration.EnumProperty(c => c.RequiredColor).IsOptional().IsConcurrencyToken();
            builder.EntitySet <EntityTypeWithEnumTypePropertyTestModel>("EnumEntities");

            // Act
            var model = builder.GetEdmModel();

            // Assert
            var entityset = model.FindDeclaredEntitySet("EnumEntities");

            Assert.NotNull(entityset);

            var annotations = model.FindVocabularyAnnotations <IEdmValueAnnotation>(entityset, CoreVocabularyModel.ConcurrencyTerm);
            IEdmValueAnnotation concurrencyAnnotation = Assert.Single(annotations);

            IEdmCollectionExpression properties = concurrencyAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(properties);

            Assert.Equal(1, properties.Elements.Count());
            var element = properties.Elements.First() as IEdmPathExpression;

            Assert.NotNull(element);

            string path = Assert.Single(element.Path);

            Assert.Equal("RequiredColor", path);
        }
Exemplo n.º 3
0
        public void GetEdmModel_PropertyWithETag_IsConcurrencyToken_HasVocabularyAnnotation()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.Id);
            customer.Property(c => c.Id);
            customer.Property(c => c.Name).IsConcurrencyToken();
            builder.EntitySet <Customer>("Customers");

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            var customers = model.FindDeclaredEntitySet("Customers");

            Assert.NotNull(customers);

            var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(customers, CoreVocabularyModel.ConcurrencyTerm);
            IEdmVocabularyAnnotation concurrencyAnnotation = Assert.Single(annotations);

            IEdmCollectionExpression properties = concurrencyAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(properties);

            Assert.Single(properties.Elements);
            var element = properties.Elements.First() as IEdmPathExpression;

            Assert.NotNull(element);

            string path = Assert.Single(element.PathSegments);

            Assert.Equal("Name", path);
        }
        private static IList <NavigationPropertyRestriction> GetRestrictedProperties(IEdmRecordExpression record)
        {
            if (record != null && record.Properties != null)
            {
                IEdmPropertyConstructor property = record.Properties.FirstOrDefault(p => p.Name == "RestrictedProperties");
                if (property != null)
                {
                    IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
                    if (value != null && value.Elements != null)
                    {
                        IList <NavigationPropertyRestriction> restrictedProperties = new List <NavigationPropertyRestriction>();
                        foreach (var item in value.Elements.OfType <IEdmRecordExpression>())
                        {
                            NavigationPropertyRestriction restriction = new NavigationPropertyRestriction();
                            restriction.Navigability       = item.GetEnum <NavigationType>("Navigability");
                            restriction.NavigationProperty = item.GetPropertyPath("NavigationProperty");
                            restrictedProperties.Add(restriction);
                        }

                        if (restrictedProperties.Any())
                        {
                            return(restrictedProperties);
                        }
                    }
                }
            }

            return(null);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Create the corresponding Authorization object.
        /// </summary>
        /// <param name="record">The input record.</param>
        /// <returns>The created <see cref="Authorization"/> object.</returns>
        public static IEnumerable <Authorization> GetAuthorizations(this IEdmModel model, IEdmVocabularyAnnotatable target)
        {
            Utils.CheckArgumentNull(model, nameof(model));
            Utils.CheckArgumentNull(target, nameof(target));

            return(GetOrAddCached(model, target, AuthorizationConstants.Authorizations, () =>
            {
                IEdmTerm term = model.FindTerm(AuthorizationConstants.Authorizations);
                if (term != null)
                {
                    IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
                    if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.Collection)
                    {
                        IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
                        if (collection.Elements != null)
                        {
                            return collection.Elements.Select(e =>
                            {
                                Debug.Assert(e.ExpressionKind == EdmExpressionKind.Record);

                                IEdmRecordExpression recordExpression = (IEdmRecordExpression)e;
                                Authorization auth = Authorization.CreateAuthorization(recordExpression);
                                return auth;
                            });
                        }
                    }
                }

                return null;
            }));
        }
        /// <summary>
        /// Get the collection of property path from the record using the given property name.
        /// </summary>
        /// <param name="record">The record expression.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The collection of property path or null.</returns>
        public static IList <string> GetCollectionPropertyPath(this IEdmRecordExpression record, string propertyName)
        {
            Utils.CheckArgumentNull(record, nameof(record));
            Utils.CheckArgumentNull(propertyName, nameof(propertyName));

            if (record.Properties != null)
            {
                IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
                if (property != null)
                {
                    IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
                    if (value != null && value.Elements != null)
                    {
                        IList <string> properties = new List <string>();
                        foreach (var a in value.Elements.Select(e => e as IEdmPathExpression))
                        {
                            properties.Add(a.Path);
                        }

                        if (properties.Any())
                        {
                            return(properties);
                        }
                    }
                }
            }

            return(null);
        }
Exemplo n.º 7
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource)
        {
            Contract.Assert(model != null);
            Contract.Assert(navigationSource != null);

            IEnumerable <IEdmStructuralProperty> cachedProperties;

            if (_concurrencyProperties != null && _concurrencyProperties.TryGetValue(navigationSource, out cachedProperties))
            {
                return(cachedProperties);
            }

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType            entityType   = navigationSource.EntityType();
            IEdmVocabularyAnnotatable annotatable  = navigationSource as IEdmVocabularyAnnotatable;

            IEdmContainedEntitySet navigationSourceAsEntitySet = navigationSource as IEdmContainedEntitySet;

            if (navigationSourceAsEntitySet != null)
            {
                annotatable = navigationSourceAsEntitySet.NavigationProperty as EdmNavigationProperty;
            }

            if (annotatable != null)
            {
                IEdmValueAnnotation annotation = model.FindVocabularyAnnotations <IEdmValueAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm).FirstOrDefault();
                if (annotation != null)
                {
                    IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                    if (properties != null)
                    {
                        foreach (var property in properties.Elements)
                        {
                            IEdmPathExpression pathExpression = property as IEdmPathExpression;
                            if (pathExpression != null)
                            {
                                // So far, we only consider the single path, because only the direct properties from declaring type are used.
                                // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                                string                 propertyName       = pathExpression.Path.Single();
                                IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                                IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                                if (structuralProperty != null)
                                {
                                    results.Add(structuralProperty);
                                }
                            }
                        }
                    }
                }
            }

            if (_concurrencyProperties == null)
            {
                _concurrencyProperties = new ConcurrentDictionary <IEdmNavigationSource, IEnumerable <IEdmStructuralProperty> >();
            }

            _concurrencyProperties[navigationSource] = results;
            return(results);
        }
Exemplo n.º 8
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource)
        {
            Contract.Assert(model != null);
            Contract.Assert(navigationSource != null);

            // Ensure that concurrency properties cache is attached to model as an annotation to avoid expensive calculations each time
            ConcurrencyPropertiesAnnotation concurrencyProperties = model.GetAnnotationValue <ConcurrencyPropertiesAnnotation>(model);

            if (concurrencyProperties == null)
            {
                concurrencyProperties = new ConcurrencyPropertiesAnnotation();
                model.SetAnnotationValue(model, concurrencyProperties);
            }

            IEnumerable <IEdmStructuralProperty> cachedProperties;

            if (concurrencyProperties.TryGetValue(navigationSource, out cachedProperties))
            {
                return(cachedProperties);
            }

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType            entityType   = navigationSource.EntityType();
            IEdmVocabularyAnnotatable annotatable  = navigationSource as IEdmVocabularyAnnotatable;

            if (annotatable != null)
            {
                var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm);
                IEdmVocabularyAnnotation annotation = annotations.FirstOrDefault();
                if (annotation != null)
                {
                    IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                    if (properties != null)
                    {
                        foreach (var property in properties.Elements)
                        {
                            IEdmPathExpression pathExpression = property as IEdmPathExpression;
                            if (pathExpression != null)
                            {
                                // So far, we only consider the single path, because only the direct properties from declaring type are used.
                                // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                                string                 propertyName       = pathExpression.PathSegments.First();
                                IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                                IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                                if (structuralProperty != null)
                                {
                                    results.Add(structuralProperty);
                                }
                            }
                        }
                    }
                }
            }

            concurrencyProperties[navigationSource] = results;
            return(results);
        }
Exemplo n.º 9
0
        public async Task ModelBuilderTest()
        {
            // Arrange
            string expectMetadata =
                "<EntitySet Name=\"ETagUntypedCustomers\" EntityType=\"NS.Customer\">\r\n" +
                "          <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" +
                "            <Collection>\r\n" +
                "              <PropertyPath>Name</PropertyPath>\r\n" +
                "            </Collection>\r\n" +
                "          </Annotation>\r\n" +
                "        </EntitySet>";

            // Remove indentation
            expectMetadata = Regex.Replace(expectMetadata, @"\r\n\s*<", @"<");
            HttpClient client     = CreateClient();
            string     requestUri = "odata/$metadata";

            // Act
            HttpResponseMessage response = await client.GetAsync(requestUri);

            // Assert
            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains(expectMetadata, content);

            var stream = await response.Content.ReadAsStreamAsync();

            IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers);
            var reader   = new ODataMessageReader(message);
            var edmModel = reader.ReadMetadataDocument();

            Assert.NotNull(edmModel);

            var etagCustomers = edmModel.FindDeclaredEntitySet("ETagUntypedCustomers");

            Assert.NotNull(etagCustomers);

            var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers);
            IEdmVocabularyAnnotation annotation = Assert.Single(annotations);

            Assert.NotNull(annotation);

            Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term);
            Assert.Same(etagCustomers, annotation.Target);

            IEdmVocabularyAnnotation valueAnnotation = annotation as IEdmVocabularyAnnotation;

            Assert.NotNull(valueAnnotation);
            Assert.NotNull(valueAnnotation.Value);

            IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(collection);
            Assert.Equal(new[] { "Name" }, collection.Elements.Select(e => ((IEdmPathExpression)e).PathSegments.Single()));
        }
Exemplo n.º 10
0
        private IEnumerable <object> ParseRecordCollection(IEdmCollectionExpression collectionExpression)
        {
            var records = new List <ExpandoObject>();

            foreach (IEdmRecordExpression recordExpression in collectionExpression.Elements)
            {
                records.Add(ParseRecordProperties(recordExpression));
            }

            return(records);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets the collection of Org.OData.Core.V1.HttpRequest for a given <see cref="IEdmVocabularyAnnotatable"/>.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns>The collection of Org.OData.Core.V1.HttpRequest</returns>
        public IEnumerable <HttpRequest> GetHttpRequests(IEdmVocabularyAnnotatable target)
        {
            Utils.CheckArgumentNull(target, nameof(target));

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

            // Search the cache.
            if (_requests.TryGetValue(target, out IList <HttpRequest> value))
            {
                return(value);
            }

            IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(target, Term);

            if (annotation == null)
            {
                IEdmNavigationSource navigationSource = target as IEdmNavigationSource;

                // if not, search the entity type.
                if (navigationSource != null)
                {
                    IEdmEntityType entityType = navigationSource.EntityType();
                    annotation = Model.GetVocabularyAnnotation(entityType, Term);
                }
            }

            if (annotation == null ||
                annotation.Value == null ||
                annotation.Value.ExpressionKind != EdmExpressionKind.Collection)
            {
                _requests[target] = null;
                return(null);
            }

            IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
            var httpRequests = new List <HttpRequest>();

            foreach (var item in collection.Elements)
            {
                IEdmRecordExpression record     = (IEdmRecordExpression)item;
                HttpRequest          newRequest = new HttpRequest();
                newRequest.Init(record);
                httpRequests.Add(newRequest);
            }

            _requests[target] = httpRequests;
            return(httpRequests);
        }
Exemplo n.º 12
0
        public void ModelBuilderTest()
        {
            const string expectMetadata =
                "        <EntitySet Name=\"ETagUntypedCustomers\" EntityType=\"NS.Customer\">\r\n" +
                "          <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" +
                "            <Collection>\r\n" +
                "              <PropertyPath>Name</PropertyPath>\r\n" +
                "            </Collection>\r\n" +
                "          </Annotation>\r\n" +
                "        </EntitySet>";

            string requestUri = string.Format("{0}/odata/$metadata", this.BaseAddress);

            HttpResponseMessage response = this.Client.GetAsync(requestUri).Result;

            var content = response.Content.ReadAsStringAsync().Result;

            Assert.Contains(expectMetadata, content);

            var stream = response.Content.ReadAsStreamAsync().Result;
            IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers);
            var reader   = new ODataMessageReader(message);
            var edmModel = reader.ReadMetadataDocument();

            Assert.NotNull(edmModel);

            var etagCustomers = edmModel.FindDeclaredEntitySet("ETagUntypedCustomers");

            Assert.NotNull(etagCustomers);

            var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers);
            IEdmVocabularyAnnotation annotation = Assert.Single(annotations);

            Assert.NotNull(annotation);

            Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term);
            Assert.Same(etagCustomers, annotation.Target);

            IEdmValueAnnotation valueAnnotation = annotation as IEdmValueAnnotation;

            Assert.NotNull(valueAnnotation);
            Assert.NotNull(valueAnnotation.Value);

            IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(collection);
            Assert.Equal(new[] { "Name" }, collection.Elements.Select(e => ((IEdmPathExpression)e).Path.Single()));
        }
Exemplo n.º 13
0
        private void ParsePropertyCollection(OdcmObject odcmObject, IEdmCollectionExpression collectionExpression, string annotationTerm)
        {
            foreach (IEdmRecordExpression recordExpression in collectionExpression.Elements)
            {
                var pathExpression = (IEdmPathExpression)recordExpression.Properties
                                     .First(p => p.Value is IEdmPathExpression)
                                     .Value;

                var odcmProperty = SetPathCapability(odcmObject, pathExpression, annotationTerm);

                foreach (var propertyConstructor in recordExpression.Properties.Where(p => !(p.Value is IEdmPathExpression)))
                {
                    TryParseCapability(odcmProperty, propertyConstructor.Value, annotationTerm + "/" + propertyConstructor.Name);
                }
            }
        }
        /// <summary>
        /// Get the collection of <typeparamref name="T"/> from the record using the given property name.
        /// </summary>
        /// <param name="record">The record expression.</param>
        /// <param name="propertyName">The property name.</param>
        /// <param name="elementFunc">The element func.</param>
        /// <returns>The collection of string or null.</returns>
        public static IEnumerable <T> GetCollection <T>(this IEdmRecordExpression record, string propertyName, Func <IEdmExpression, T> elementFunc)
        {
            Utils.CheckArgumentNull(record, nameof(record));
            Utils.CheckArgumentNull(propertyName, nameof(propertyName));

            IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);

            if (property != null)
            {
                IEdmCollectionExpression collection = property.Value as IEdmCollectionExpression;
                if (collection != null && collection.Elements != null)
                {
                    return(collection.Elements.Select(e => elementFunc(e)));
                }
            }

            return(null);
        }
        /// <summary>
        /// Gets the collection of string for a target annotatable.
        /// </summary>
        /// <param name="model">The model referenced to.</param>
        /// <param name="target">The target annotatable to find annotation.</param>
        /// <param name="term">The target annotatable to find annotation.</param>
        /// <returns>Null or a collection string of qualified type name.</returns>
        public static IEnumerable <string> GetVocabularyStringCollection(this IEdmModel model, IEdmVocabularyAnnotatable target, IEdmTerm term)
        {
            EdmUtil.CheckArgumentNull(model, "model");
            EdmUtil.CheckArgumentNull(target, "target");
            EdmUtil.CheckArgumentNull(target, "term");

            IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, term).FirstOrDefault();

            if (annotation != null)
            {
                IEdmCollectionExpression collectionExpression = annotation.Value as IEdmCollectionExpression;
                if (collectionExpression != null && collectionExpression.Elements != null)
                {
                    return(collectionExpression.Elements.OfType <IEdmStringConstantExpression>().Select(e => e.Value));
                }
            }

            return(Enumerable.Empty <string>());
        }
Exemplo n.º 16
0
        private void ParseCollection(OdcmObject odcmObject, IEdmCollectionExpression collectionExpression, string annotationTerm)
        {
            if (!collectionExpression.Elements.Any())
            {
                return;
            }

            var elementExpression = collectionExpression.Elements.First();
            var recordExpression  = elementExpression as IEdmRecordExpression;

            if (recordExpression != null)
            {
                if (recordExpression.Properties.Count(p => p.Value is IEdmPathExpression) == 1)
                {
                    // We assume that if a collection element is a record with a single path expression, the rest
                    // of record properties should be associated with this path expression
                    // (e.g. NavigationRestrictions/RestrictedProperties).
                    ParsePropertyCollection(odcmObject, collectionExpression, annotationTerm);
                }
                else
                {
                    var records = ParseRecordCollection(collectionExpression);
                    SetListCapability(odcmObject, records, annotationTerm);
                }
            }
            else if (elementExpression is IEdmStringConstantExpression)
            {
                var strings = collectionExpression.Elements.Select(e => (e as IEdmStringConstantExpression).Value);
                SetListCapability(odcmObject, strings, annotationTerm);
            }
            else if (elementExpression is IEdmPathExpression)
            {
                foreach (IEdmPathExpression expression in collectionExpression.Elements)
                {
                    SetPathCapability(odcmObject, expression, annotationTerm);
                }
            }
            else
            {
                Logger.Warn($"Unsupported collection of kind {elementExpression.ExpressionKind.ToString()} for Term \"{annotationTerm}\"");
            }
        }
        private XObject GenerateCollectionExpression(XNamespace ns, IEdmCollectionExpression collection)
        {
            var collectionElements = new XElement(ns.GetName("Collection"));

            foreach (var element in collection.Elements)
            {
                var elementValue = GenerateValueExpression(ns, element);

                if (elementValue is XAttribute)
                {
                    var collectionElement = new XElement(ns.GetName(((XAttribute)elementValue).Name.ToString()));
                    collectionElement.Add(((XAttribute)elementValue).Value);
                    collectionElements.Add(collectionElement);
                }
                else
                {
                    collectionElements.Add(elementValue);
                }
            }
            return(collectionElements);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Gets the Org.OData.Core.V1.AcceptableMediaTypes
        /// </summary>
        /// <param name="model">The Edm model.</param>
        /// <param name="target">The vocabulary annotatable target.</param>
        /// <returns>null or the collection of media type.</returns>
        internal static IList <string> GetAcceptableMediaTypes(this IEdmModel model, IEdmVocabularyAnnotatable target)
        {
            if (model == null)
            {
                throw Error.ArgumentNull(nameof(model));
            }

            if (target == null)
            {
                throw Error.ArgumentNull(nameof(target));
            }

            IList <string>           mediaTypes  = null;
            var                      annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(target, CoreVocabularyModel.AcceptableMediaTypesTerm);
            IEdmVocabularyAnnotation annotation  = annotations.FirstOrDefault();

            if (annotation != null)
            {
                IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                if (properties != null)
                {
                    mediaTypes = new List <string>();
                    foreach (var element in properties.Elements)
                    {
                        IEdmStringConstantExpression elementValue = element as IEdmStringConstantExpression;
                        if (elementValue != null)
                        {
                            mediaTypes.Add(elementValue.Value);
                        }
                    }
                }
            }

            if (mediaTypes == null || mediaTypes.Count == 0)
            {
                return(null);
            }

            return(mediaTypes);
        }
Exemplo n.º 19
0
        private static IEnumerable <IDictionary <string, IEdmPathExpression> > GetDeclaredAlternateKeysForType(IEdmModel model, IEdmEntityType type, IEdmTerm term)
        {
            IEdmVocabularyAnnotation annotationValue = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(type, term).FirstOrDefault();

            if (annotationValue != null)
            {
                List <IDictionary <string, IEdmPathExpression> > declaredAlternateKeys = new List <IDictionary <string, IEdmPathExpression> >();

                IEdmCollectionExpression keys = annotationValue.Value as IEdmCollectionExpression;

                foreach (IEdmRecordExpression key in keys.Elements.OfType <IEdmRecordExpression>())
                {
                    var edmPropertyConstructor = key.Properties.FirstOrDefault(e => e.Name == "Key");
                    if (edmPropertyConstructor != null)
                    {
                        IEdmCollectionExpression collectionExpression = edmPropertyConstructor.Value as IEdmCollectionExpression;

                        IDictionary <string, IEdmPathExpression> alternateKey = new Dictionary <string, IEdmPathExpression>();
                        foreach (IEdmRecordExpression propertyRef in collectionExpression.Elements.OfType <IEdmRecordExpression>())
                        {
                            var    aliasProp = propertyRef.Properties.FirstOrDefault(e => e.Name == "Alias");
                            string alias     = ((IEdmStringConstantExpression)aliasProp.Value).Value;

                            var nameProp = propertyRef.Properties.FirstOrDefault(e => e.Name == "Name");
                            alternateKey[alias] = (IEdmPathExpression)nameProp.Value;
                        }

                        if (alternateKey.Any())
                        {
                            declaredAlternateKeys.Add(alternateKey);
                        }
                    }
                }

                return(declaredAlternateKeys);
            }

            return(null);
        }
Exemplo n.º 20
0
        internal static bool TryAssertCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors)
        {
            if (!type.IsCollection())
            {
                discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Edm.Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType) };
                return(false);
            }

            IEdmTypeReference collectionElementType = type.AsCollection().ElementType();
            bool                   success          = true;
            List <EdmError>        errors           = new List <EdmError>();
            IEnumerable <EdmError> recursiveErrors;

            foreach (IEdmExpression element in expression.Elements)
            {
                success = TryAssertType(element, collectionElementType, context, matchExactly, out recursiveErrors) && success;
                errors.AddRange(recursiveErrors);
            }

            discoveredErrors = errors;
            return(success);
        }
        /// <summary>
        /// Create the corresponding Authorization object.
        /// </summary>
        /// <param name="record">The input record.</param>
        /// <returns>The created <see cref="Authorization"/> object.</returns>
        private IEnumerable <Authorization> RetrieveAuthorizations(IEdmVocabularyAnnotatable target)
        {
            IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(target, Term);

            if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.Collection)
            {
                IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
                foreach (var item in collection.Elements)
                {
                    IEdmRecordExpression record = item as IEdmRecordExpression;
                    if (record == null || record.DeclaredType == null)
                    {
                        continue;
                    }

                    Authorization auth = Authorization.CreateAuthorization(record);
                    if (auth != null)
                    {
                        yield return(auth);
                    }
                }
            }
        }
Exemplo n.º 22
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmEntitySet entitySet)
        {
            Contract.Assert(model != null);
            Contract.Assert(entitySet != null);

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType      entityType         = entitySet.EntityType();
            var                 annotations        = model.FindVocabularyAnnotations <IEdmValueAnnotation>(entitySet, CoreVocabularyModel.ConcurrencyTerm);
            IEdmValueAnnotation annotation         = annotations.FirstOrDefault();

            if (annotation != null)
            {
                IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                if (properties != null)
                {
                    foreach (var property in properties.Elements)
                    {
                        IEdmPathExpression pathExpression = property as IEdmPathExpression;
                        if (pathExpression != null)
                        {
                            // So far, we only consider the single path, because only the direct properties from declaring type are used.
                            // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                            string                 propertyName       = pathExpression.Path.Single();
                            IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                            IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                            if (structuralProperty != null)
                            {
                                results.Add(structuralProperty);
                            }
                        }
                    }
                }
            }

            return(results);
        }
Exemplo n.º 23
0
 protected override void ProcessCollectionExpression(IEdmCollectionExpression expression)
 {
     this.BeginElement(expression, this.schemaWriter.WriteCollectionExpressionElementHeader);
     this.VisitExpressions(expression.Elements);
     this.EndElement(expression, this.schemaWriter.WriteCollectionExpressionElementEnd);
 }
Exemplo n.º 24
0
 internal void WriteCollectionExpressionElementHeader(IEdmCollectionExpression expression)
 {
     this.xmlWriter.WriteStartElement(CsdlConstants.Element_Collection);
 }
Exemplo n.º 25
0
 internal override void WriteCollectionExpressionElementEnd(IEdmCollectionExpression expression)
 {
     this.WriteEndElement();
 }
Exemplo n.º 26
0
        private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context)
        {
            switch (expression.ExpressionKind)
            {
            case EdmExpressionKind.IntegerConstant:
                return((IEdmIntegerConstantExpression)expression);

            case EdmExpressionKind.StringConstant:
                return((IEdmStringConstantExpression)expression);

            case EdmExpressionKind.BinaryConstant:
                return((IEdmBinaryConstantExpression)expression);

            case EdmExpressionKind.BooleanConstant:
                return((IEdmBooleanConstantExpression)expression);

            case EdmExpressionKind.DateTimeOffsetConstant:
                return((IEdmDateTimeOffsetConstantExpression)expression);

            case EdmExpressionKind.DecimalConstant:
                return((IEdmDecimalConstantExpression)expression);

            case EdmExpressionKind.FloatingConstant:
                return((IEdmFloatingConstantExpression)expression);

            case EdmExpressionKind.GuidConstant:
                return((IEdmGuidConstantExpression)expression);

            case EdmExpressionKind.DurationConstant:
                return((IEdmDurationConstantExpression)expression);

            case EdmExpressionKind.DateConstant:
                return((IEdmDateConstantExpression)expression);

            case EdmExpressionKind.TimeOfDayConstant:
                return((IEdmTimeOfDayConstantExpression)expression);

            case EdmExpressionKind.Null:
                return((IEdmNullExpression)expression);

            case EdmExpressionKind.Path:
            {
                if (context == null)
                {
                    throw new InvalidOperationException(Strings.Edm_Evaluator_NoContextPath);
                }

                IEdmPathExpression pathExpression = (IEdmPathExpression)expression;
                IEdmValue          result         = context;
#if NET35
                // [EdmLib] Need to handle paths that bind to things other than properties.
                foreach (string hop in pathExpression.PathSegments)
                {
                    result = FindProperty(hop, result);

                    if (result == null)
                    {
                        throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop));
                    }
                }
#else
                // Only Support Annotation in EntityType or ComplexType or Property or NavigationProperty.
                // Empty Path is not supported.
                foreach (string hop in pathExpression.PathSegments)
                {
                    if (hop.Contains("@"))
                    {
                        var            currentPathSegementInfos = hop.Split('@');
                        var            propertyName             = currentPathSegementInfos[0];
                        var            termInfo           = currentPathSegementInfos[1];
                        IEdmExpression termCastExpression = null;

                        if (!Utils.StringIsNullOrWhitespace(termInfo))
                        {
                            var termInfos = termInfo.Split('#');
                            if (termInfos.Length <= 2)
                            {
                                string termName  = termInfos[0];
                                string qualifier = termInfos.Length == 2 ? termInfos[1] : null;

                                if (Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForType != null)
                                {
                                    termCastExpression = this.getAnnotationExpressionForType(this.edmModel, context.Type.Definition, termName, qualifier);
                                }
                                else if (!Utils.StringIsNullOrWhitespace(propertyName) && this.getAnnotationExpressionForProperty != null)
                                {
                                    termCastExpression = this.getAnnotationExpressionForProperty(this.edmModel, context.Type.Definition, propertyName, termName, qualifier);
                                }
                            }
                        }

                        if (termCastExpression == null)
                        {
                            result = null;
                            break;
                        }

                        result = this.Eval(termCastExpression, context);
                    }
                    else if (hop == "$count")
                    {
                        var edmCollectionValue = result as IEdmCollectionValue;
                        if (edmCollectionValue != null)
                        {
                            result = new EdmIntegerConstant(edmCollectionValue.Elements.Count());
                        }
                        else
                        {
                            result = null;
                            break;
                        }
                    }
                    else if (hop.Contains("."))
                    {
                        if (this.edmModel == null)
                        {
                            throw new InvalidOperationException(Strings.Edm_Evaluator_TypeCastNeedsEdmModel);
                        }

                        IEdmType typeSegmentClientType = this.resolveTypeFromName(hop, this.edmModel);
                        if (typeSegmentClientType == null)
                        {
                            result = null;
                            break;
                        }

                        IEdmTypeReference operandType = result.Type;
                        EdmValueKind      operandKind = result.ValueKind;

                        if (operandKind == EdmValueKind.Collection)
                        {
                            List <IEdmDelayedValue> elementValues = new List <IEdmDelayedValue>();
                            var collection = result as IEdmCollectionValue;
                            foreach (IEdmDelayedValue element in collection.Elements)
                            {
                                if (element.Value.Type.Definition.IsOrInheritsFrom(typeSegmentClientType))
                                {
                                    elementValues.Add(element);
                                }
                            }

                            result = new EdmCollectionValue(
                                new EdmCollectionTypeReference(new EdmCollectionType(typeSegmentClientType.GetTypeReference(false))),
                                elementValues);
                        }
                        else if (operandKind != EdmValueKind.Structured ||
                                 (operandKind == EdmValueKind.Structured &&
                                  !operandType.Definition.IsOrInheritsFrom(typeSegmentClientType)))
                        {
                            result = null;
                            break;
                        }
                    }
                    else
                    {
                        result = FindProperty(hop, result);
                        if (result == null)
                        {
                            throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop));
                        }
                    }
                }
#endif
                return(result);
            }

            case EdmExpressionKind.PropertyPath:
            case EdmExpressionKind.NavigationPropertyPath:
            {
                EdmUtil.CheckArgumentNull(context, "context");

                IEdmPathExpression pathExpression = (IEdmPathExpression)expression;
                IEdmValue          result         = context;

                // [EdmLib] Need to handle paths that bind to things other than properties.
                foreach (string hop in pathExpression.PathSegments)
                {
                    result = FindProperty(hop, result);

                    if (result == null)
                    {
                        throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundPath(hop));
                    }
                }

                return(result);
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression apply  = (IEdmApplyExpression)expression;
                IEdmFunction        target = apply.AppliedFunction;
                if (target != null)
                {
                    IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList();
                    IEdmValue[]            arguments           = new IEdmValue[argumentExpressions.Count()];

                    {
                        int argumentIndex = 0;
                        foreach (IEdmExpression argument in argumentExpressions)
                        {
                            arguments[argumentIndex++] = this.Eval(argument, context);
                        }
                    }

                    //// Static validation will have checked that the number and types of arguments are correct,
                    //// so those checks are not performed dynamically.

                    Func <IEdmValue[], IEdmValue> operationEvaluator;
                    if (this.builtInFunctions.TryGetValue(target, out operationEvaluator))
                    {
                        return(operationEvaluator(arguments));
                    }

                    if (this.lastChanceOperationApplier != null)
                    {
                        return(this.lastChanceOperationApplier(target.FullName(), arguments));
                    }
                }

                throw new InvalidOperationException(Strings.Edm_Evaluator_UnboundFunction(target != null ? target.ToTraceString() : string.Empty));
            }

            case EdmExpressionKind.If:
            {
                IEdmIfExpression ifExpression = (IEdmIfExpression)expression;

                if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value)
                {
                    return(this.Eval(ifExpression.TrueExpression, context));
                }

                return(this.Eval(ifExpression.FalseExpression, context));
            }

            case EdmExpressionKind.IsType:
            {
                IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression;

                IEdmValue         operand    = this.Eval(isType.Operand, context);
                IEdmTypeReference targetType = isType.Type;

                return(new EdmBooleanConstant(MatchesType(targetType, operand)));
            }

            case EdmExpressionKind.Cast:
            {
                IEdmCastExpression castType = (IEdmCastExpression)expression;

                IEdmValue         operand    = this.Eval(castType.Operand, context);
                IEdmTypeReference targetType = castType.Type;

                return(Cast(targetType, operand));
            }

            case EdmExpressionKind.Record:
            {
                IEdmRecordExpression     record        = (IEdmRecordExpression)expression;
                DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context);

                List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>();

                //// Static validation will have checked that the set of supplied properties are appropriate
                //// for the supplied type and have no duplicates, so those checks are not performed dynamically.

                foreach (IEdmPropertyConstructor propertyConstructor in record.Properties)
                {
                    propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor));
                }

                EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues);
                return(result);
            }

            case EdmExpressionKind.Collection:
            {
                IEdmCollectionExpression collection        = (IEdmCollectionExpression)expression;
                DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context);
                List <IEdmDelayedValue>  elementValues     = new List <IEdmDelayedValue>();

                //// Static validation will have checked that the result types of the element expressions are
                //// appropriate and so these checks are not performed dynamically.

                foreach (IEdmExpression element in collection.Elements)
                {
                    elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context));
                }

                EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues);
                return(result);
            }

            case EdmExpressionKind.LabeledExpressionReference:
            {
                return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value);
            }

            case EdmExpressionKind.Labeled:
                return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value);

            case EdmExpressionKind.EnumMember:
                IEdmEnumMemberExpression enumMemberExpression = (IEdmEnumMemberExpression)expression;
                var                   enumMembers             = enumMemberExpression.EnumMembers.ToList();
                IEdmEnumType          enumType          = enumMembers.First().DeclaringType;
                IEdmEnumTypeReference enumTypeReference = new EdmEnumTypeReference(enumType, false);
                if (enumMembers.Count() == 1)
                {
                    return(new EdmEnumValue(enumTypeReference, enumMemberExpression.EnumMembers.Single()));
                }
                else
                {
                    if (!enumType.IsFlags || !EdmEnumValueParser.IsEnumIntegerType(enumType))
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type {0} cannot be assigned with multi-values.", enumType.FullName()));
                    }

                    long result = 0;
                    foreach (var enumMember in enumMembers)
                    {
                        long value = enumMember.Value.Value;
                        result |= value;
                    }

                    return(new EdmEnumValue(enumTypeReference, new EdmEnumMemberValue(result)));
                }

            default:
                throw new InvalidOperationException(Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture)));
            }
        }
Exemplo n.º 27
0
        private IEdmValue Eval(IEdmExpression expression, IEdmStructuredValue context)
        {
            switch (expression.ExpressionKind)
            {
            case EdmExpressionKind.IntegerConstant:
                return((IEdmIntegerConstantExpression)expression);

            case EdmExpressionKind.StringConstant:
                return((IEdmStringConstantExpression)expression);

            case EdmExpressionKind.BinaryConstant:
                return((IEdmBinaryConstantExpression)expression);

            case EdmExpressionKind.BooleanConstant:
                return((IEdmBooleanConstantExpression)expression);

            case EdmExpressionKind.DateTimeConstant:
                return((IEdmDateTimeConstantExpression)expression);

            case EdmExpressionKind.DateTimeOffsetConstant:
                return((IEdmDateTimeOffsetConstantExpression)expression);

            case EdmExpressionKind.DecimalConstant:
                return((IEdmDecimalConstantExpression)expression);

            case EdmExpressionKind.FloatingConstant:
                return((IEdmFloatingConstantExpression)expression);

            case EdmExpressionKind.GuidConstant:
                return((IEdmGuidConstantExpression)expression);

            case EdmExpressionKind.TimeConstant:
                return((IEdmTimeConstantExpression)expression);

            case EdmExpressionKind.Null:
                return((IEdmNullExpression)expression);

            case EdmExpressionKind.Path:
            {
                EdmUtil.CheckArgumentNull(context, "context");

                IEdmPathExpression pathExpression = (IEdmPathExpression)expression;
                IEdmValue          result         = context;

                foreach (string hop in pathExpression.Path)
                {
                    result = this.FindProperty(hop, result);

                    if (result == null)
                    {
                        throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundPath(hop));
                    }
                }

                return(result);
            }

            case EdmExpressionKind.FunctionApplication:
            {
                IEdmApplyExpression             apply                   = (IEdmApplyExpression)expression;
                IEdmExpression                  targetReference         = apply.AppliedFunction;
                IEdmFunctionReferenceExpression targetFunctionReference = targetReference as IEdmFunctionReferenceExpression;
                if (targetFunctionReference != null)
                {
                    IList <IEdmExpression> argumentExpressions = apply.Arguments.ToList();
                    IEdmValue[]            arguments           = new IEdmValue[argumentExpressions.Count()];

                    {
                        int argumentIndex = 0;
                        foreach (IEdmExpression argument in argumentExpressions)
                        {
                            arguments[argumentIndex++] = this.Eval(argument, context);
                        }
                    }

                    IEdmFunction target = targetFunctionReference.ReferencedFunction;
                    if (!target.IsBad())
                    {
                        //// Static validation will have checked that the number and types of arguments are correct,
                        //// so those checks are not performed dynamically.

                        Func <IEdmValue[], IEdmValue> functionEvaluator;
                        if (this.builtInFunctions.TryGetValue(target, out functionEvaluator))
                        {
                            return(functionEvaluator(arguments));
                        }
                    }

                    if (this.lastChanceFunctionApplier != null)
                    {
                        return(this.lastChanceFunctionApplier(target.FullName(), arguments));
                    }
                }

                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnboundFunction(targetFunctionReference != null ? targetFunctionReference.ReferencedFunction.ToTraceString() : string.Empty));
            }

            case EdmExpressionKind.If:
            {
                IEdmIfExpression ifExpression = (IEdmIfExpression)expression;

                if (((IEdmBooleanValue)this.Eval(ifExpression.TestExpression, context)).Value)
                {
                    return(this.Eval(ifExpression.TrueExpression, context));
                }

                return(this.Eval(ifExpression.FalseExpression, context));
            }

            case EdmExpressionKind.IsType:
            {
                IEdmIsTypeExpression isType = (IEdmIsTypeExpression)expression;

                IEdmValue         operand    = this.Eval(isType.Operand, context);
                IEdmTypeReference targetType = isType.Type;

                return(new EdmBooleanConstant(MatchesType(targetType, operand)));
            }

            case EdmExpressionKind.AssertType:
            {
                IEdmAssertTypeExpression assertType = (IEdmAssertTypeExpression)expression;

                IEdmValue         operand    = this.Eval(assertType.Operand, context);
                IEdmTypeReference targetType = assertType.Type;

                return(AssertType(targetType, operand));
            }

            case EdmExpressionKind.Record:
            {
                IEdmRecordExpression     record        = (IEdmRecordExpression)expression;
                DelayedExpressionContext recordContext = new DelayedExpressionContext(this, context);

                List <IEdmPropertyValue> propertyValues = new List <IEdmPropertyValue>();

                //// Static validation will have checked that the set of supplied properties are appropriate
                //// for the supplied type and have no duplicates, so those checks are not performed dynamically.

                foreach (IEdmPropertyConstructor propertyConstructor in record.Properties)
                {
                    propertyValues.Add(new DelayedRecordProperty(recordContext, propertyConstructor));
                }

                EdmStructuredValue result = new EdmStructuredValue(record.DeclaredType != null ? record.DeclaredType.AsStructured() : null, propertyValues);
                return(result);
            }

            case EdmExpressionKind.Collection:
            {
                IEdmCollectionExpression collection        = (IEdmCollectionExpression)expression;
                DelayedExpressionContext collectionContext = new DelayedExpressionContext(this, context);
                List <IEdmDelayedValue>  elementValues     = new List <IEdmDelayedValue>();

                //// Static validation will have checked that the result types of the element expressions are
                //// appropriate and so these checks are not performed dynamically.

                foreach (IEdmExpression element in collection.Elements)
                {
                    elementValues.Add(this.MapLabeledExpressionToDelayedValue(element, collectionContext, context));
                }

                EdmCollectionValue result = new EdmCollectionValue(collection.DeclaredType != null ? collection.DeclaredType.AsCollection() : null, elementValues);
                return(result);
            }

            case EdmExpressionKind.LabeledExpressionReference:
            {
                return(this.MapLabeledExpressionToDelayedValue(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, null, context).Value);
            }

            case EdmExpressionKind.Labeled:
                return(this.MapLabeledExpressionToDelayedValue(expression, new DelayedExpressionContext(this, context), context).Value);

            case EdmExpressionKind.ParameterReference:
            case EdmExpressionKind.FunctionReference:
            case EdmExpressionKind.PropertyReference:
            case EdmExpressionKind.ValueTermReference:
            case EdmExpressionKind.EntitySetReference:
            case EdmExpressionKind.EnumMemberReference:
                throw new InvalidOperationException("Not yet implemented: evaluation of " + expression.ExpressionKind.ToString() + " expressions.");

            default:
                throw new InvalidOperationException(Edm.Strings.Edm_Evaluator_UnrecognizedExpressionKind(((int)expression.ExpressionKind).ToString(System.Globalization.CultureInfo.InvariantCulture)));
            }
        }
Exemplo n.º 28
0
        public async Task ModelBuilderTest()
        {
            string expectMetadata =
                "<EntitySet Name=\"ETagsCustomers\" EntityType=\"Microsoft.Test.E2E.AspNet.OData.ETags.ETagsCustomer\">\r\n" +
                "          <NavigationPropertyBinding Path=\"RelatedCustomer\" Target=\"ETagsCustomers\" />\r\n" +
                "          <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" +
                "            <Collection>\r\n" +
                "              <PropertyPath>Id</PropertyPath>\r\n" +
                "              <PropertyPath>Name</PropertyPath>\r\n" +
                "              <PropertyPath>BoolProperty</PropertyPath>\r\n" +
                "              <PropertyPath>ByteProperty</PropertyPath>\r\n" +
                "              <PropertyPath>CharProperty</PropertyPath>\r\n" +
                "              <PropertyPath>DecimalProperty</PropertyPath>\r\n" +
                "              <PropertyPath>DoubleProperty</PropertyPath>\r\n" +
                "              <PropertyPath>ShortProperty</PropertyPath>\r\n" +
                "              <PropertyPath>LongProperty</PropertyPath>\r\n" +
                "              <PropertyPath>SbyteProperty</PropertyPath>\r\n" +
                "              <PropertyPath>FloatProperty</PropertyPath>\r\n" +
                "              <PropertyPath>UshortProperty</PropertyPath>\r\n" +
                "              <PropertyPath>UintProperty</PropertyPath>\r\n" +
                "              <PropertyPath>UlongProperty</PropertyPath>\r\n" +
                "              <PropertyPath>GuidProperty</PropertyPath>\r\n" +
                "              <PropertyPath>DateTimeOffsetProperty</PropertyPath>\r\n" +
                "              <PropertyPath>StringWithConcurrencyCheckAttributeProperty</PropertyPath>\r\n" +
                "            </Collection>\r\n" +
                "          </Annotation>\r\n" +
                "        </EntitySet>";

            // Remove indentation
            expectMetadata = Regex.Replace(expectMetadata, @"\r\n\s*<", @"<");

            string requestUri = string.Format("{0}/odata/$metadata", this.BaseAddress);

            HttpResponseMessage response = await this.Client.GetAsync(requestUri);

            var content = await response.Content.ReadAsStringAsync();

            Assert.Contains(expectMetadata, content);

            var stream = await response.Content.ReadAsStreamAsync();

            IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers);
            var reader   = new ODataMessageReader(message);
            var edmModel = reader.ReadMetadataDocument();

            Assert.NotNull(edmModel);

            var etagCustomers = edmModel.FindDeclaredEntitySet("ETagsCustomers");

            Assert.NotNull(etagCustomers);

            var annotations = edmModel.FindDeclaredVocabularyAnnotations(etagCustomers);
            IEdmVocabularyAnnotation annotation = Assert.Single(annotations);

            Assert.NotNull(annotation);

            Assert.Same(CoreVocabularyModel.ConcurrencyTerm, annotation.Term);
            Assert.Same(etagCustomers, annotation.Target);

            IEdmVocabularyAnnotation valueAnnotation = annotation as IEdmVocabularyAnnotation;

            Assert.NotNull(valueAnnotation);
            Assert.NotNull(valueAnnotation.Value);

            IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(collection);
            Assert.Equal(new[]
            {
                "Id", "Name", "BoolProperty", "ByteProperty", "CharProperty", "DecimalProperty",
                "DoubleProperty", "ShortProperty", "LongProperty", "SbyteProperty",
                "FloatProperty", "UshortProperty", "UintProperty", "UlongProperty",
                "GuidProperty", "DateTimeOffsetProperty",
                "StringWithConcurrencyCheckAttributeProperty"
            },
                         collection.Elements.Select(e => ((IEdmPathExpression)e).PathSegments.Single()));
        }
        private XObject GenerateCollectionExpression(XNamespace ns, IEdmCollectionExpression collection)
        {
            var collectionElements = new XElement(ns.GetName("Collection"));
            foreach (var element in collection.Elements)
            {
                var elementValue = GenerateValueExpression(ns, element);

                if (elementValue is XAttribute)
                {
                    var collectionElement = new XElement(ns.GetName(((XAttribute)elementValue).Name.ToString()));
                    collectionElement.Add(((XAttribute)elementValue).Value);
                    collectionElements.Add(collectionElement);
                }
                else
                {
                    collectionElements.Add(elementValue);
                }
            }
            return collectionElements;
        }
Exemplo n.º 30
0
 protected virtual void ProcessCollectionExpression(IEdmCollectionExpression expression)
 {
     this.ProcessExpression(expression);
     this.VisitExpressions(expression.Elements);
 }
Exemplo n.º 31
0
        /// <summary>
        /// Determines if the type of an expression is compatible with the provided type
        /// </summary>
        /// <param name="expression">The expression to assert the type of.</param>
        /// <param name="type">The type to assert the expression as.</param>
        /// <param name="context">The context paths are to be evaluated in.</param>
        /// <param name="matchExactly">A value indicating whether the expression must match the asserted type exactly, or simply be compatible.</param>
        /// <param name="discoveredErrors">Errors produced if the expression does not match the specified type.</param>
        /// <returns>A value indicating whether the expression is valid for the given type or not.</returns>
        /// <remarks>If the expression has an associated type, this function will check that it matches the expected type and stop looking further.
        /// If an expression claims a type, it must be validated that the type is valid for the expression. If the expression does not claim a type
        /// this method will attempt to check the validity of the expression itself with the asserted type.</remarks>
        public static bool TryAssertType(this IEdmExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors)
        {
            EdmUtil.CheckArgumentNull(expression, "expression");

            // If we don't have a type to assert this passes vacuously.
            if (type == null || type.TypeKind() == EdmTypeKind.None)
            {
                discoveredErrors = Enumerable.Empty <EdmError>();
                return(true);
            }

            switch (expression.ExpressionKind)
            {
            case EdmExpressionKind.IntegerConstant:
            case EdmExpressionKind.StringConstant:
            case EdmExpressionKind.BinaryConstant:
            case EdmExpressionKind.BooleanConstant:
            case EdmExpressionKind.DateTimeConstant:
            case EdmExpressionKind.DateTimeOffsetConstant:
            case EdmExpressionKind.DecimalConstant:
            case EdmExpressionKind.FloatingConstant:
            case EdmExpressionKind.GuidConstant:
            case EdmExpressionKind.TimeConstant:
                IEdmPrimitiveValue primitiveValue = (IEdmPrimitiveValue)expression;
                if (primitiveValue.Type != null)
                {
                    return(TestTypeReferenceMatch(primitiveValue.Type, type, expression.Location(), matchExactly, out discoveredErrors));
                }

                return(TryAssertPrimitiveAsType(primitiveValue, type, out discoveredErrors));

            case EdmExpressionKind.Null:
                return(TryAssertNullAsType((IEdmNullExpression)expression, type, out discoveredErrors));

            case EdmExpressionKind.Path:
                return(TryAssertPathAsType((IEdmPathExpression)expression, type, context, matchExactly, out discoveredErrors));

            case EdmExpressionKind.FunctionApplication:
                IEdmApplyExpression applyExpression = (IEdmApplyExpression)expression;
                if (applyExpression.AppliedFunction != null)
                {
                    IEdmFunctionBase function = applyExpression.AppliedFunction as IEdmFunctionBase;
                    if (function != null)
                    {
                        return(TestTypeReferenceMatch(function.ReturnType, type, expression.Location(), matchExactly, out discoveredErrors));
                    }
                }

                // If we don't have the applied function we just assume that it will work.
                discoveredErrors = Enumerable.Empty <EdmError>();
                return(true);

            case EdmExpressionKind.If:
                return(TryAssertIfAsType((IEdmIfExpression)expression, type, context, matchExactly, out discoveredErrors));

            case EdmExpressionKind.IsType:
                return(TestTypeReferenceMatch(EdmCoreModel.Instance.GetBoolean(false), type, expression.Location(), matchExactly, out discoveredErrors));

            case EdmExpressionKind.Record:
                IEdmRecordExpression recordExpression = (IEdmRecordExpression)expression;
                if (recordExpression.DeclaredType != null)
                {
                    return(TestTypeReferenceMatch(recordExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors));
                }

                return(TryAssertRecordAsType(recordExpression, type, context, matchExactly, out discoveredErrors));

            case EdmExpressionKind.Collection:
                IEdmCollectionExpression collectionExpression = (IEdmCollectionExpression)expression;
                if (collectionExpression.DeclaredType != null)
                {
                    return(TestTypeReferenceMatch(collectionExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors));
                }

                return(TryAssertCollectionAsType(collectionExpression, type, context, matchExactly, out discoveredErrors));

            case EdmExpressionKind.Labeled:
                return(TryAssertType(((IEdmLabeledExpression)expression).Expression, type, context, matchExactly, out discoveredErrors));

            case EdmExpressionKind.AssertType:
                return(TestTypeReferenceMatch(((IEdmAssertTypeExpression)expression).Type, type, expression.Location(), matchExactly, out discoveredErrors));

            case EdmExpressionKind.LabeledExpressionReference:
                return(TryAssertType(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, type, out discoveredErrors));

            default:
                discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) };
                return(false);
            }
        }