public void ValueTerm_Path_OnProperty()
        {
            this.SetupModelsAndValues();

            const string applicationCsdl =
                @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""foo.Person/ContactInfo"">
        <Annotation Term=""bar.Int16Value"" Qualifier=""WorkPhoneLocal"" Path=""WorkPhone/Local"" />
    </Annotations>
</Schema>";
            IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel);
            EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup);

            IEdmEntityType    person               = this.baseModel.FindEntityType("foo.Person");
            IEdmProperty      property             = person.FindProperty("ContactInfo");
            IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("ContactInfo");

            IEdmValueTerm termInt16Value = this.vocabularyDefinitionModel.FindValueTerm("bar.Int16Value");
            // ?? Assumes Entity always??
            // IEdmValue annotationHotIndex = applicationModel.GetTermValue(contextPropertyValue.Value, termInt16Value, evaluator);
            IEdmValueAnnotation annotation = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt16Value) as IEdmValueAnnotation;
            IEdmExpression      expression = annotation.Value;
            IEdmValue           annotationWorkphoneLocal = expressionEvaluator.Evaluate(expression, (IEdmStructuredValue)contextPropertyValue.Value);

            Assert.AreEqual(9991234, ((IEdmIntegerValue)annotationWorkphoneLocal).Value, "Term annotation value");
        }
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);
        }
        public void ValueTerm_OperationApplication_OnNavigationProperty()
        {
            this.SetupModelsAndValues();

            const string applicationCsdl =
                @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""foo.Person/Address"">
        <Annotation Term=""bar.StringValue"">
            <Apply Function=""Functions.StringConcat"">
                <Path>Zip/Main</Path>
                <Apply Function=""Functions.StringConcat"">
                    <String>-</String>
                    <Path>Zip/Extension</Path>
                </Apply>
            </Apply>
        </Annotation>
    </Annotations>
</Schema>";
            IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel, this.operationsModel);
            EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup);

            IEdmEntityType    person               = this.baseModel.FindEntityType("foo.Person");
            IEdmProperty      property             = person.FindProperty("Address");
            IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("Address");

            IEdmValueTerm       termStringValue       = this.vocabularyDefinitionModel.FindValueTerm("bar.StringValue");
            IEdmValueAnnotation annotationString      = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termStringValue) as IEdmValueAnnotation;
            IEdmValue           annotationStringValue = expressionEvaluator.Evaluate(annotationString.Value, (IEdmStructuredValue)contextPropertyValue.Value);

            Assert.AreEqual("98052-0000", ((IEdmStringValue)annotationStringValue).Value, "Term annotation value");
        }
Exemplo n.º 4
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 <IEdmValueAnnotation>(customers, 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("Name", path);
        }
        public void ValueTerm_TypeTerm_If_OnEntityContainer()
        {
            this.SetupModelsAndValues();

            const string applicationCsdl =
                @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""foo.fooContainer"">
        <Annotation Term=""bar.Int32Value"">
            <If>
                <Apply Function=""Functions.True"" />
                <Int>999</Int>
                <Int>30</Int>
            </If>                
        </Annotation>
    </Annotations>
</Schema>";
            IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel, this.operationsModel);
            EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup);

            IEdmEntityContainer container = this.baseModel.FindEntityContainer("fooContainer");

            IEdmValueTerm       termInt32Value  = this.vocabularyDefinitionModel.FindValueTerm("bar.Int32Value");
            IEdmValueAnnotation valueAnnotation = applicationModel.FindVocabularyAnnotations <IEdmValueAnnotation>(container, termInt32Value).SingleOrDefault();

            // ?? why do I need a context here?
            IEdmValue valueOfValueAnnotation = expressionEvaluator.Evaluate(valueAnnotation.Value, this.personValue);

            Assert.AreEqual(999, ((IEdmIntegerValue)valueOfValueAnnotation).Value, "Value annotation evaluated value.");
        }
        public void ValueTerm_OperationApplication_WithOverloads_OnEntitySet()
        {
            this.SetupModelsAndValues();

            const string applicationCsdl =
                @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""foo.fooContainer/PersonSet"">
        <Annotation Term=""bar.StringValue"">
            <If>
                <Apply Function=""Functions.True"" />
                <Apply Function=""Functions.StringConcat"">
                    <String>1</String>
                    <String>2</String>
                    <String>3</String>
                </Apply>
                <String>foo</String>
            </If>                
        </Annotation>
    </Annotations>
</Schema>";
            IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel, this.operationsModel);
            EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup);

            IEdmEntitySet personSet = this.baseModel.FindEntityContainer("fooContainer").FindEntitySet("PersonSet");

            IEdmValueTerm       term            = this.vocabularyDefinitionModel.FindValueTerm("bar.StringValue");
            IEdmValueAnnotation valueAnnotation = applicationModel.FindVocabularyAnnotations <IEdmValueAnnotation>(personSet, term).SingleOrDefault();

            IEdmValue valueOfAnnotation = expressionEvaluator.Evaluate(valueAnnotation.Value, this.personValue);

            Assert.AreEqual("123", ((IEdmStringValue)valueOfAnnotation).Value, "Annotation evaluated value.");
        }
        public void EvaluateUnboundTerms()
        {
            const string applicationCsdl =
                @"<Schema Namespace=""bar"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""bar.Person"">
        <Annotation Term=""bar.RandomTerm"" Path=""Extra"" />
    </Annotations>
    <EntityType Name=""Person"">
        <Key>
            <PropertyRef Name=""Name"" />
        </Key>
        <Property Name=""Name"" Type=""String"" Nullable=""false"" />
        <Property Name=""Decoration"" Type=""bar.Decoration"">
            <Annotation Term=""bar.DecorationTerm"" Qualifier=""Goodness"" String=""Excellent"" />
        </Property>
    </EntityType>
    <ComplexType Name=""Decoration"">
        <Property Name=""One"" Type=""Int32"" />
        <Property Name=""Two"" Type=""Int32"" />
    </ComplexType>
</Schema>";
            IEdmModel      applicationModel = this.Parse(applicationCsdl);
            IEdmEntityType person           = (IEdmEntityType)applicationModel.FindType("bar.Person");
            IEdmProperty   personDecoration = person.FindProperty("Decoration");

            EdmToClrEvaluator evaluator = new EdmToClrEvaluator(null);

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

            decorationPropertyValues.Add(new EdmPropertyValue("One", new EdmIntegerConstant(1)));
            decorationPropertyValues.Add(new EdmPropertyValue("Two", new EdmIntegerConstant(2)));

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

            propertyValues.Add(new EdmPropertyValue("Name", new EdmStringConstant("Goober")));
            propertyValues.Add(new EdmPropertyValue("Decoration", new EdmStructuredValue(null, decorationPropertyValues)));
            propertyValues.Add(new EdmPropertyValue("Extra", new EdmStringConstant("Extra value!")));
            IEdmStructuredValue context = new EdmStructuredValue(new EdmEntityTypeReference(person, false), propertyValues);

            string random = applicationModel.GetTermValue <string>(context, "bar.RandomTerm", evaluator);

            Assert.AreEqual("Extra value!", random, "Annotation evaluated value.");

            IEdmValue randomValue = applicationModel.GetTermValue(context, "bar.RandomTerm", evaluator);

            Assert.AreEqual("Extra value!", ((IEdmStringValue)randomValue).Value, "Annotation evaluated value.");

            string goodness = applicationModel.GetTermValue <string>(personDecoration, "bar.DecorationTerm", "Goodness", evaluator);

            Assert.AreEqual("Excellent", goodness, "Annotation evaluated value.");

            IEdmValue goodnessValue = applicationModel.GetTermValue(personDecoration, "bar.DecorationTerm", "Goodness", evaluator);

            Assert.AreEqual("Excellent", ((IEdmStringValue)goodnessValue).Value, "Annotation evaluated value.");

            IEdmValueAnnotation randomTermAnnotation = applicationModel.FindVocabularyAnnotations <IEdmValueAnnotation>(person, "bar.RandomTerm").Single();

            random = evaluator.EvaluateToClrValue <string>(randomTermAnnotation.Value, context);
            Assert.AreEqual("Extra value!", random, "Annotation evaluated value.");
        }
Exemplo n.º 8
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);
        }
 internal void WriteValueAnnotationElementHeader(IEdmValueAnnotation annotation, bool isInline)
 {
     this.xmlWriter.WriteStartElement(CsdlConstants.Element_Annotation);
     this.WriteRequiredAttribute(CsdlConstants.Attribute_Term, annotation.Term, this.TermAsXml);
     this.WriteOptionalAttribute(CsdlConstants.Attribute_Qualifier, annotation.Qualifier, EdmValueWriter.StringAsXml);
     if (isInline)
     {
         this.WriteInlineExpression(annotation.Value);
     }
 }
Exemplo n.º 10
0
 internal void WriteValueAnnotationElementHeader(IEdmValueAnnotation annotation, bool isInline)
 {
     this.xmlWriter.WriteStartElement("ValueAnnotation");
     this.WriteRequiredAttribute <IEdmTerm>("Term", annotation.Term, new Func <IEdmTerm, string>(this.TermAsXml));
     this.WriteOptionalAttribute <string>("Qualifier", annotation.Qualifier, new Func <string, string>(EdmValueWriter.StringAsXml));
     if (isInline)
     {
         this.WriteInlineExpression(annotation.Value);
     }
 }
Exemplo n.º 11
0
        public void ValueTerm_Constant_OnProperty()
        {
            this.SetupModelsAndValues();

            const string applicationCsdl =
                @"<Schema Namespace=""Annotations"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
    <Annotations Target=""foo.Person/CoolnessIndex"">
        <Annotation Term=""bar.Int32Value"" Qualifier=""HotIndex"" Int=""-1"" />
        <Annotation Term=""bar.StringValue"" String=""Goofy"" />
    </Annotations>
</Schema>";
            IEdmModel applicationModel = this.Parse(applicationCsdl, this.baseModel, this.vocabularyDefinitionModel);
            EdmExpressionEvaluator expressionEvaluator = new EdmExpressionEvaluator(this.operationsLookup);
            EdmToClrEvaluator      clrEvaluator        = new EdmToClrEvaluator(this.operationsLookup);

            IEdmEntityType    person               = this.baseModel.FindEntityType("foo.Person");
            IEdmProperty      property             = person.FindProperty("CoolnessIndex");
            IEdmPropertyValue contextPropertyValue = ((IEdmStructuredValue)this.personValue).FindPropertyValue("CoolnessIndex");

            IEdmValueTerm termInt32Value  = this.vocabularyDefinitionModel.FindValueTerm("bar.Int32Value");
            IEdmValueTerm termStringValue = this.vocabularyDefinitionModel.FindValueTerm("bar.StringValue");

            IEdmValueAnnotation annotation         = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt32Value) as IEdmValueAnnotation;
            IEdmExpression      expression         = annotation.Value;
            IEdmValue           annotationHotIndex = expressionEvaluator.Evaluate(expression);

            Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value");

            annotationHotIndex = applicationModel.GetTermValue(property, termInt32Value, "HotIndex", expressionEvaluator);
            Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value");

            annotationHotIndex = applicationModel.GetTermValue(property, "bar.Int32Value", "HotIndex", expressionEvaluator);
            Assert.AreEqual(-1, ((IEdmIntegerValue)annotationHotIndex).Value, "Term annotation value");

            int hotIndex = applicationModel.GetTermValue <int>(property, termInt32Value, "HotIndex", clrEvaluator);

            Assert.AreEqual(-1, hotIndex, "Term annotation value");

            hotIndex = applicationModel.GetTermValue <int>(property, "bar.Int32Value", "HotIndex", clrEvaluator);
            Assert.AreEqual(-1, hotIndex, "Term annotation value");

            IEdmValue annotationString = applicationModel.GetTermValue(property, termStringValue, expressionEvaluator);

            Assert.AreEqual("Goofy", ((IEdmStringValue)annotationString).Value, "Term annotation value");

            annotationString = applicationModel.GetTermValue(property, "bar.StringValue", expressionEvaluator);
            Assert.AreEqual("Goofy", ((IEdmStringValue)annotationString).Value, "Term annotation value");

            string stringValue = applicationModel.GetTermValue <string>(property, termStringValue, clrEvaluator);

            Assert.AreEqual("Goofy", stringValue, "Term annotation value");

            stringValue = applicationModel.GetTermValue <string>(property, "bar.StringValue", clrEvaluator);
            Assert.AreEqual("Goofy", stringValue, "Term annotation value");
        }
Exemplo n.º 12
0
 private void ValidateClrObjectConverter <T>(IEdmValueAnnotation valueAnnotation, T expected)
 {
     switch (valueAnnotation.Value.ExpressionKind)
     {
     case EdmExpressionKind.Record:
     case EdmExpressionKind.Collection:
         var actual = this.ConvertToClrObject <T>(valueAnnotation);
         Assert.IsTrue(CompareObjects(expected, actual), "The actual object content is different from the expected one.");
         break;
     }
 }
        protected override void ProcessValueAnnotation(IEdmValueAnnotation annotation)
        {
            bool isInline = IsInlineExpression(annotation.Value);

            this.BeginElement <IEdmValueAnnotation>(annotation, t => this.schemaWriter.WriteValueAnnotationElementHeader(t, isInline), new Action <IEdmValueAnnotation> [0]);
            if (!isInline)
            {
                base.ProcessValueAnnotation(annotation);
            }
            this.EndElement(annotation);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Gets vocabulary annotation that binds to a term and a qualifier from the metadata annotation dictionary in current data service context for a specified type.
        /// </summary>
        /// <param name="context">The data service context.</param>
        /// <param name="type">The specified annotated type.</param>
        /// <param name="term">The term name.</param>
        /// <param name="qualifier">The qualifier name.</param>
        /// <returns>The vacabulary annotation that binds to a term and a qualifier for the specified annotated type.</returns>
        private static IEdmValueAnnotation GetOrInsertCachedMetadataAnnotationForType(DataServiceContext context, Type type, string term, string qualifier)
        {
            var serviceModel = context.Format.ServiceModel;

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

            IEdmValueAnnotation edmValueAnnotation = GetCachedMetadataAnnotation(context, type, term, qualifier);

            if (edmValueAnnotation != null)
            {
                return(edmValueAnnotation);
            }

            IEdmVocabularyAnnotatable edmVocabularyAnnotatable = null;

            if (type.IsSubclassOf(typeof(DataServiceContext)))
            {
                edmVocabularyAnnotatable = serviceModel.EntityContainer;
            }
            else
            {
                var serversideName = context.ResolveName == null ? type.FullName : context.ResolveName(type);
                if (!string.IsNullOrWhiteSpace(serversideName))
                {
                    edmVocabularyAnnotatable = serviceModel.FindDeclaredType(serversideName);
                    if (edmVocabularyAnnotatable == null)
                    {
                        return(null);
                    }
                }
            }

            // Gets the annotations which exactly match the qualifier and target.
            var edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmValueAnnotation>(edmVocabularyAnnotatable, term, qualifier)
                                      .Where(a => a.Qualifier == qualifier && a.Target == edmVocabularyAnnotatable);

            if (edmValueAnnotations.Count() == 0)
            {
                edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForType(context, type.GetBaseType(), term, qualifier);
            }
            else if (edmValueAnnotations.Count() == 1)
            {
                edmValueAnnotation = edmValueAnnotations.Single();
            }

            InsertMetadataAnnotation(context, type, edmValueAnnotation);
            return(edmValueAnnotation);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Gets vocabulary annotation that binds to a term and a qualifier from the metadata annotation dictionary in current data service context for a specified methodInfo.
        /// </summary>
        /// <param name="context">The data service context.</param>
        /// <param name="methodInfo">The specified annotated methodInfo.</param>
        /// <param name="term">The term name.</param>
        /// <param name="qualifier">The qualifier name.</param>
        /// <returns>The vacabulary annotation that binds to a term and a qualifier for the specified annotated methodInfo.</returns>
        private static IEdmValueAnnotation GetOrInsertCachedMetadataAnnotationForMethodInfo(DataServiceContext context, MethodInfo methodInfo, string term, string qualifier)
        {
            IEdmModel serviceModel = context.Format.ServiceModel;

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

            IEdmValueAnnotation edmValueAnnotation = GetCachedMetadataAnnotation(context, methodInfo, term, qualifier);

            if (edmValueAnnotation != null)
            {
                return(edmValueAnnotation);
            }

            IEdmVocabularyAnnotatable edmVocabularyAnnotatable = context.GetEdmOperationOrOperationImport(methodInfo);

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

            var edmOperationImport = edmVocabularyAnnotatable as IEdmOperationImport;
            IEnumerable <IEdmValueAnnotation> edmValueAnnotations = null;

            if (edmOperationImport != null)
            {
                edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmValueAnnotation>(edmOperationImport, term, qualifier)
                                      .Where(a => a.Qualifier == qualifier);
                if (!edmValueAnnotations.Any())
                {
                    edmVocabularyAnnotatable = edmOperationImport.Operation;
                }
            }

            if (edmValueAnnotations == null || !edmValueAnnotations.Any())
            {
                edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmValueAnnotation>(edmVocabularyAnnotatable, term, qualifier)
                                      .Where(a => a.Qualifier == qualifier);
            }

            if (edmValueAnnotations != null && edmValueAnnotations.Count() == 1)
            {
                edmValueAnnotation = edmValueAnnotations.Single();
                InsertMetadataAnnotation(context, methodInfo, edmValueAnnotation);
                return(edmValueAnnotation);
            }

            return(null);
        }
Exemplo n.º 16
0
        private string GetStringAnnotationValue(IEdmVocabularyAnnotatable annotatable, string annotationNamespace,
                                                string annotationName)
        {
            // Find only direct annotation which have a string constant value
            IEdmValueAnnotation annotation = annotatable.VocabularyAnnotations(Model).
                                             OfType <IEdmValueAnnotation>().
                                             FirstOrDefault(
                a =>
                a.Term.Namespace.Equals(annotationNamespace) &&
                a.Term.Name.Equals(annotationName) &&
                a.Value.ExpressionKind == EdmExpressionKind.StringConstant &&
                a.Target.Equals(annotatable));

            return(annotation != null ? (annotation.Value as IEdmStringConstantExpression).Value : null);
        }
Exemplo n.º 17
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.º 18
0
        private T ConvertToClrObject <T>(IEdmValueAnnotation valueAnnotation)
        {
            var edmClrEvaluator = new EdmToClrEvaluator(this.operationDefinitions);
            var edmClrConverter = new EdmToClrConverter();

            var edmValue = edmClrEvaluator.Evaluate(valueAnnotation.Value);

            var object1 = edmClrEvaluator.EvaluateToClrValue <T>(valueAnnotation.Value);
            var object2 = (T)edmClrConverter.AsClrValue(edmValue, typeof(T));
            var object3 = edmClrEvaluator.EdmToClrConverter.AsClrValue <T>(edmValue);

            Assert.IsTrue(CompareObjects(object1, object2), "The results of EvaluateToClrValue and AsClrValue do not match.");
            Assert.IsTrue(CompareObjects(object2, object3), "The result of the generic version of AsClrValue does not match that of the non-generic version.");

            return(object1);
        }
        void GetAnnotation()
        {
            Uri             metadataUri = context.GetMetadataUri();
            HttpWebRequest  request     = (HttpWebRequest)WebRequest.Create(metadataUri);
            HttpWebResponse response    = (HttpWebResponse)request.GetResponse();
            Stream          stream      = response.GetResponseStream();
            StreamReader    sr          = new StreamReader(stream);

            stream.Flush();
            string metadata = sr.ReadToEnd();

            IEdmModel annotatedModel;
            IEnumerable <EdmError> errors;
            XmlReader xmlReader = XmlReader.Create(new StringReader(metadata));
            bool      parsed    = EdmxReader.TryParse(xmlReader, out annotatedModel, out errors);

            foreach (IEdmVocabularyAnnotation annotation in annotatedModel.VocabularyAnnotations)
            {
                if (annotation.Term.TermKind != EdmTermKind.Value)
                {
                    continue;
                }
                IEdmValueAnnotation valueAnnotation = (IEdmValueAnnotation)annotation;
                IEdmProperty        property        = (IEdmProperty)valueAnnotation.Target;
                IEdmTerm            term            = valueAnnotation.Term;
                string entityTypeName = ((IEdmSchemaType)property.DeclaringType).Name;
                if (!annotations.ContainsKey(entityTypeName))
                {
                    annotations.Add(entityTypeName, new Dictionary <string, XpoAnnotation>());
                }
                if (!annotations[entityTypeName].ContainsKey(property.Name))
                {
                    annotations[entityTypeName][property.Name] = new XpoAnnotation();
                }
                switch (term.Name)
                {
                case "Size":
                    annotations[entityTypeName][property.Name].Size = (int)((IEdmIntegerValue)valueAnnotation.Value).Value;
                    break;

                case "ReadOnly":
                    annotations[entityTypeName][property.Name].ReadOnly = ((IEdmBooleanValue)valueAnnotation.Value).Value;
                    break;
                }
            }
        }
Exemplo n.º 20
0
        private void CompareTermAnnotationContent(IEdmVocabularyAnnotation expectedTermAnnotation, IEdmVocabularyAnnotation actualTermAnnotation)
        {
            this.SatisfiesEquals(expectedTermAnnotation.Term.TermKind, actualTermAnnotation.Term.TermKind, "Term Kind mismatch at {0}.", this.scopeContext);

            if (expectedTermAnnotation.Term.TermKind == EdmTermKind.Value)
            {
                IEdmValueAnnotation expectedValueAnnotation = (IEdmValueAnnotation)expectedTermAnnotation;
                IEdmValueAnnotation actualValueAnnotation   = (IEdmValueAnnotation)actualTermAnnotation;

                // TODO: push Expression Equals() and ToString() to product?
                this.SatisfiesCondition(this.CompareIEdmExpression(expectedValueAnnotation.Value, actualValueAnnotation.Value), "Value expression mismatch at {0}.", this.scopeContext);
            }
            else
            {
                this.WriteErrorMessage("Unexpected TermKind {0} at {1}.", expectedTermAnnotation.Term.TermKind, this.scopeContext);
            }
        }
Exemplo n.º 21
0
        public static bool IsConcurrencyCheckEnabled(this IEdmModel model, IEdmEntitySet entitySet)
        {
            bool needCurrencyCheck;

            if (concurrencyCheckFlags.TryGetValue(entitySet, out needCurrencyCheck))
            {
                return(needCurrencyCheck);
            }

            needCurrencyCheck = false;
            var annotations = model.FindVocabularyAnnotations <IEdmValueAnnotation>(
                entitySet, CoreVocabularyModel.ConcurrencyTerm);
            IEdmValueAnnotation annotation = annotations.FirstOrDefault();

            if (annotation != null)
            {
                needCurrencyCheck = true;
            }

            concurrencyCheckFlags[entitySet] = needCurrencyCheck;
            return(needCurrencyCheck);
        }
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
 /// <summary>
 /// Determines whether or not the annotation indicates the 'KeyAsSegment' url-convention.
 /// </summary>
 /// <param name="annotation">The annotation to check.</param>
 /// <returns>True if the annotation indicates the 'KeyAsSegment' url convention; false otherwise.</returns>
 private static bool IsKeyAsSegmentUrlConventionAnnotation(IEdmValueAnnotation annotation)
 {
     return(annotation != null && IsUrlConventionTerm(annotation.Term) && IsKeyAsSegment(annotation.Value));
 }
Exemplo n.º 24
0
 /// <summary>
 /// Determines whether or not the annotation indicates the 'KeyAsSegment' url-convention.
 /// </summary>
 /// <param name="annotation">The annotation to check.</param>
 /// <returns>True if the annotation indicates the 'KeyAsSegment' url convention; false otherwise.</returns>
 private static bool IsKeyAsSegmentUrlConventionAnnotation(IEdmValueAnnotation annotation)
 {
     return annotation != null && IsUrlConventionTerm(annotation.Term) && IsKeyAsSegment(annotation.Value);
 }
Exemplo n.º 25
0
        /// <summary>
        /// Gets vocabulary annotation that binds to a term and a qualifier from the metadata annotation dictionary in current data service context for a specified propertyInfo.
        /// </summary>
        /// <param name="context">The data service context.</param>
        /// <param name="propertyInfo">The specified annotated propertyInfo.</param>
        /// <param name="term">The term name.</param>
        /// <param name="qualifier">The qualifier name.</param>
        /// <returns>The vacabulary annotation that binds to a term and a qualifier for the specified annotated propertyInfo.</returns>
        private static IEdmValueAnnotation GetOrInsertCachedMetadataAnnotationForPropertyInfo(DataServiceContext context, PropertyInfo propertyInfo, string term, string qualifier)
        {
            var serviceModel = context.Format.ServiceModel;

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

            IEdmValueAnnotation edmValueAnnotation = GetCachedMetadataAnnotation(context, propertyInfo, term, qualifier);

            if (edmValueAnnotation != null)
            {
                return(edmValueAnnotation);
            }

            var severSidePropertyName = ClientTypeUtil.GetServerDefinedName(propertyInfo);

            if (string.IsNullOrEmpty(severSidePropertyName))
            {
                return(null);
            }

            var declaringType = propertyInfo.DeclaringType;
            IEnumerable <IEdmValueAnnotation> edmValueAnnotations = null;

            if (declaringType.IsSubclassOf(typeof(DataServiceContext)))
            {
                var entityContainer            = serviceModel.EntityContainer;
                var edmEntityContainerElements = entityContainer.Elements.Where(e => e.Name == severSidePropertyName);
                if (edmEntityContainerElements != null && edmEntityContainerElements.Count() == 1)
                {
                    edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmValueAnnotation>(
                        edmEntityContainerElements.Single(), term, qualifier).Where(a => a.Qualifier == qualifier);
                }
            }
            else
            {
                var serversideTypeName = context.ResolveName == null ? declaringType.FullName : context.ResolveName(declaringType);
                var edmType            = serviceModel.FindDeclaredType(serversideTypeName);
                if (edmType != null)
                {
                    var edmStructuredType = edmType as IEdmStructuredType;
                    if (edmStructuredType != null)
                    {
                        var edmProperty = edmStructuredType.FindProperty(severSidePropertyName);
                        if (edmProperty != null)
                        {
                            edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmValueAnnotation>(
                                edmProperty, term, qualifier).Where(a => a.Qualifier == qualifier);
                        }
                    }
                }
            }

            if (edmValueAnnotations != null && edmValueAnnotations.Count() == 1)
            {
                edmValueAnnotation = edmValueAnnotations.Single();
                InsertMetadataAnnotation(context, propertyInfo, edmValueAnnotation);
                return(edmValueAnnotation);
            }

            return(null);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Gets the CLR value of a term that has been applied to the specified object
        /// </summary>
        /// <typeparam name="TResult">The CLR type of the annotation to be returned.</typeparam>
        /// <param name="context">The data service context.</param>
        /// <param name="source">The specified annotated object instance.</param>
        /// <param name="term">The term name.</param>
        /// <param name="qualifier">The qualifier name.</param>
        /// <param name="annotationValue">Value of the term evaluated.</param>
        /// <returns>True if the annotation value can be evaluated, else false.</returns>
        internal static bool TryGetMetadataAnnotation <TResult>(DataServiceContext context, object source, string term, string qualifier, out TResult annotationValue)
        {
            IEdmValueAnnotation      edmValueAnnotation = null;
            ClientEdmStructuredValue clientEdmValue     = null;
            PropertyInfo             propertyInfo       = null;
            MethodInfo methodInfo = null;

            var keyValue = source as Tuple <object, MemberInfo>;

            if (keyValue != null)
            {
                // Get metadata annotation defined on property or Navigation property or Operation or OperationImport
                var instance   = keyValue.Item1;
                var memberInfo = keyValue.Item2;
                propertyInfo = memberInfo as PropertyInfo;
                methodInfo   = memberInfo as MethodInfo;
                if (instance != null)
                {
                    IEdmType edmType = context.Model.GetOrCreateEdmType(instance.GetType());
                    if (edmType is IEdmStructuredType)
                    {
                        ClientTypeAnnotation clientTypeAnnotation = context.Model.GetClientTypeAnnotation(edmType);
                        clientEdmValue = new ClientEdmStructuredValue(instance, context.Model, clientTypeAnnotation);
                    }
                }
            }
            else
            {
                if (propertyInfo == null)
                {
                    propertyInfo = source as PropertyInfo;
                }

                if (methodInfo == null)
                {
                    methodInfo = source as MethodInfo;
                }
            }

            if (propertyInfo != null)
            {
                edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForPropertyInfo(context, propertyInfo, term, qualifier);
                return(TryEvaluateMetadataAnnotation(context, edmValueAnnotation, clientEdmValue, out annotationValue));
            }

            if (methodInfo != null)
            {
                edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForMethodInfo(context, methodInfo, term, qualifier);
                return(TryEvaluateMetadataAnnotation(context, edmValueAnnotation, clientEdmValue, out annotationValue));
            }

            var  type           = source as Type;
            Type underlyingType = type;

            if (type == null)
            {
                type           = source.GetType();
                underlyingType = Nullable.GetUnderlyingType(type) ?? type;

                // For complex type or entity type instance, try to convert the instance to ClientEdmStructuredValue for further evaluation.
                IEdmType edmType = context.Model.GetOrCreateEdmType(underlyingType);
                if (edmType is IEdmStructuredType)
                {
                    ClientTypeAnnotation clientTypeAnnotation = context.Model.GetClientTypeAnnotation(edmType);
                    clientEdmValue = new ClientEdmStructuredValue(source, context.Model, clientTypeAnnotation);
                }
            }

            edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForType(context, underlyingType, term, qualifier);
            return(TryEvaluateMetadataAnnotation(context, edmValueAnnotation, clientEdmValue, out annotationValue));
        }
Exemplo n.º 27
0
 public void  ParseCapabilityAnnotation(OdcmObject odcmObject, IEdmValueAnnotation annotation)
 {
     TryParseCapability(odcmObject, annotation.Value, annotation.Term.FullName());
 }
Exemplo n.º 28
0
        /// <summary>
        /// Insert an metadata annotation with the provided key to the metadata annotation dictionary.
        /// </summary>
        /// <param name="context">The data service context</param>
        /// <param name="key">The specified key</param>
        /// <param name="edmValueAnnotation">The metadata annotation to be inserted.</param>
        private static void InsertMetadataAnnotation(DataServiceContext context, object key, IEdmValueAnnotation edmValueAnnotation)
        {
            if (edmValueAnnotation != null)
            {
                IList <IEdmValueAnnotation> edmValueAnnotations;
                if (!context.MetadataAnnotationsDictionary.TryGetValue(key, out edmValueAnnotations))
                {
                    edmValueAnnotations = new List <IEdmValueAnnotation>();
                    context.MetadataAnnotationsDictionary.Add(key, edmValueAnnotations);
                }

                edmValueAnnotations.Add(edmValueAnnotation);
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Evaluate IEdmValueAnnotation to an CLR object
        /// </summary>
        /// <typeparam name="TResult">The CLR type of the annotation to be returned.</typeparam>
        /// <param name="context">The data service context.</param>
        /// <param name="edmValueAnnotation">IEdmValueAnnotation to be evaluated.</param>
        /// <param name="clientEdmValue">Value to use as context in evaluating the expression.</param>
        /// <param name="annotationValue">Value of the term evaluated.</param>
        /// <returns>True if the annotation value can be evaluated, else false.</returns>
        private static bool TryEvaluateMetadataAnnotation <TResult>(DataServiceContext context, IEdmValueAnnotation edmValueAnnotation, ClientEdmStructuredValue clientEdmValue, out TResult annotationValue)
        {
            if (edmValueAnnotation == null)
            {
                annotationValue = default(TResult);
                return(false);
            }

            EdmToClrEvaluator evaluator = CreateEdmToClrEvaluator(context);

            try
            {
                annotationValue = evaluator.EvaluateToClrValue <TResult>(edmValueAnnotation.Value, clientEdmValue);
            }
            catch (InvalidOperationException)
            {
                // When expression contains Path. if the clientEdmValue is null, or the related property is not valid property of the clientEdmValue.
                // TheEvaluateToClrValue might throw InvalidOperationException;
                annotationValue = default(TResult);
                return(false);
            }

            return(true);
        }
Exemplo n.º 30
0
 private List<PropertyValue> GetAnnotationValueList(EdmExpressionKind expressionKind, IEdmValueAnnotation valueAnnotation)
 {
     return this.GetAnnotationValueList(expressionKind, valueAnnotation.Value);
 }
Exemplo n.º 31
0
 protected virtual void ProcessValueAnnotation(IEdmValueAnnotation annotation)
 {
     this.ProcessVocabularyAnnotation(annotation);
     this.VisitExpression(annotation.Value);
 }
Exemplo n.º 32
0
        public void ModelBuilderTest()
        {
            const string expectMetadata =
                "        <EntitySet Name=\"ETagsCustomers\" EntityType=\"WebStack.QA.Test.OData.ETags.ETagsCustomer\">\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>";

            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("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);

            IEdmValueAnnotation valueAnnotation = annotation as IEdmValueAnnotation;

            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).Path.Single()));
        }