public void Term_FunctionApplication_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"); IEdmTerm termStringValue = this.vocabularyDefinitionModel.FindTerm("bar.StringValue"); IEdmVocabularyAnnotation annotationString = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termStringValue); IEdmValue annotationStringValue = expressionEvaluator.Evaluate(annotationString.Value, (IEdmStructuredValue)contextPropertyValue.Value); Assert.AreEqual("98052-0000", ((IEdmStringValue)annotationStringValue).Value, "Term annotation value"); }
protected override bool Initialize(IEdmVocabularyAnnotation annotation) { if (annotation == null || annotation.Value == null || annotation.Value.ExpressionKind != EdmExpressionKind.Record) { return(false); } IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value; // Filterable Filterable = record.GetBoolean("Filterable"); // RequiresFilter RequiresFilter = record.GetBoolean("RequiresFilter"); // RequiredProperties RequiredProperties = record.GetCollectionPropertyPath("RequiredProperties"); // NonFilterableProperties NonFilterableProperties = record.GetCollectionPropertyPath("NonFilterableProperties"); return(true); }
/// <summary> /// Compute ETag from Annotation Org.OData.Core.V1.OptimisticConcurrency on EntitySet /// </summary> /// <returns>Enumerable of IEdmStructuralProperty</returns> private IEnumerable <IEdmStructuralProperty> ComputeETagPropertiesFromAnnotation() { IEdmModel model = this.metadataContext.Model; IEdmEntitySet entitySet = model.FindDeclaredEntitySet(this.typeContext.NavigationSourceName); if (entitySet != null) { IEdmVocabularyAnnotation annotation = model.FindDeclaredVocabularyAnnotations(entitySet) .SingleOrDefault(t => t.Term.FullName().Equals(CoreVocabularyConstants.OptimisticConcurrency, StringComparison.Ordinal)); if (annotation != null) { IEdmExpression collectionExpression = annotation.Value; if (collectionExpression is IEdmCollectionExpression) { IEnumerable <IEdmExpression> pathExpressions = (collectionExpression as IEdmCollectionExpression).Elements.Where(p => p is IEdmPathExpression); foreach (IEdmPathExpression pathExpression in pathExpressions) { // TODO: // 1. Add support for Complex type // 2. Add new exception when collectionExpression is not IEdmCollectionExpression: CoreOptimisticConcurrency must be followed by collection expression IEdmStructuralProperty property = this.actualResourceType.StructuralProperties().FirstOrDefault(p => p.Name == pathExpression.PathSegments.LastOrDefault()); if (property == null) { throw new ODataException(Strings.EdmValueUtils_PropertyDoesntExist(this.ActualResourceTypeName, pathExpression.PathSegments.LastOrDefault())); } yield return(property); } } } } }
/// <summary> /// Searches for vocabulary annotations specified by this model. /// </summary> /// <param name="element">The annotated element.</param> /// <returns>The vocabulary annotations for the element.</returns> public override IEnumerable <IEdmVocabularyAnnotation> FindDeclaredVocabularyAnnotations(IEdmVocabularyAnnotatable element) { // Include the inline annotations only if this model is the one that defined them. CsdlSemanticsElement semanticsElement = element as CsdlSemanticsElement; IEnumerable <IEdmVocabularyAnnotation> inlineAnnotations = semanticsElement != null && semanticsElement.Model == this ? semanticsElement.InlineVocabularyAnnotations : Enumerable.Empty <IEdmVocabularyAnnotation>(); List <CsdlSemanticsAnnotations> elementAnnotations; string fullName = EdmUtil.FullyQualifiedName(element); if (fullName != null && this.outOfLineAnnotations.TryGetValue(fullName, out elementAnnotations)) { List <IEdmVocabularyAnnotation> result = new List <IEdmVocabularyAnnotation>(); foreach (CsdlSemanticsAnnotations annotations in elementAnnotations) { foreach (CsdlAnnotation annotation in annotations.Annotations.Annotations) { IEdmVocabularyAnnotation vocabAnnotation = this.WrapVocabularyAnnotation(annotation, annotations.Context, null, annotations, annotations.Annotations.Qualifier); vocabAnnotation.SetSerializationLocation(this, EdmVocabularyAnnotationSerializationLocation.OutOfLine); result.Add(vocabAnnotation); } } return(inlineAnnotations.Concat(result)); } return(inlineAnnotations); // TODO: REF // find annotation in referenced models }
public void VisitVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { if (annotation.Term != null) { switch (annotation.Term.TermKind) { case EdmTermKind.Type: this.ProcessTypeAnnotation((IEdmTypeAnnotation)annotation); break; case EdmTermKind.Value: this.ProcessValueAnnotation((IEdmValueAnnotation)annotation); break; case EdmTermKind.None: this.ProcessVocabularyAnnotation(annotation); break; default: throw new InvalidOperationException(Edm.Strings.UnknownEnumVal_TermKind(annotation.Term.TermKind)); } } else { this.ProcessVocabularyAnnotation(annotation); } }
public void Term_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"); IEdmTerm termInt32Value = this.vocabularyDefinitionModel.FindTerm("bar.Int32Value"); IEdmVocabularyAnnotation valueAnnotation = applicationModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(container, termInt32Value).SingleOrDefault(); // ?? why do I need a context here? IEdmValue valueOfValueAnnotation = expressionEvaluator.Evaluate(valueAnnotation.Value, this.personValue); Assert.AreEqual(999, ((IEdmIntegerValue)valueOfValueAnnotation).Value, "Annotation evaluated value."); }
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.Equal(1, properties.Elements.Count()); var element = properties.Elements.First() as IEdmPathExpression; Assert.NotNull(element); string path = Assert.Single(element.PathSegments); Assert.Equal("Name", path); }
protected override bool Initialize(IEdmVocabularyAnnotation annotation) { if (annotation == null || annotation.Value == null || annotation.Value.ExpressionKind != EdmExpressionKind.Record) { return(false); } IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value; // Sortable Sortable = record.GetBoolean("Sortable"); // AscendingOnlyProperties AscendingOnlyProperties = record.GetCollectionPropertyPath("AscendingOnlyProperties"); // DescendingOnlyProperties DescendingOnlyProperties = record.GetCollectionPropertyPath("DescendingOnlyProperties"); // NonSortablePropeties NonSortableProperties = record.GetCollectionPropertyPath("NonSortableProperties"); return(true); }
public void Term_FunctionApplication_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"); IEdmTerm term = this.vocabularyDefinitionModel.FindTerm("bar.StringValue"); IEdmVocabularyAnnotation valueAnnotation = applicationModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(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."); IEdmVocabularyAnnotation randomTermAnnotation = applicationModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(person, "bar.RandomTerm").Single(); random = evaluator.EvaluateToClrValue <string>(randomTermAnnotation.Value, context); Assert.AreEqual("Extra value!", random, "Annotation evaluated value."); }
/// <summary> /// Sets the location an annotation should be serialized in. /// </summary> /// <param name="annotation">The annotation the location is being specified for.</param> /// <param name="model">Model containing the annotation.</param> /// <param name="location">The location the annotation should appear.</param> public static void SetSerializationLocation(this IEdmVocabularyAnnotation annotation, IEdmModel model, EdmVocabularyAnnotationSerializationLocation?location) { EdmUtil.CheckArgumentNull(annotation, "annotation"); EdmUtil.CheckArgumentNull(model, "model"); model.SetAnnotationValue(annotation, EdmConstants.InternalUri, CsdlConstants.AnnotationSerializationLocationAnnotation, (object)location); }
/// <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> /// Determines whether the specified function is UrlEscape function or not. /// </summary> /// <param name="model">The Edm model.</param> /// <param name="function">The specified function</param> /// <returns><c>true</c> if the specified operation is UrlEscape function; otherwise, <c>false</c>.</returns> public static bool IsUrlEscapeFunction(this IEdmModel model, IEdmFunction function) { Utils.CheckArgumentNull(model, nameof(model)); Utils.CheckArgumentNull(function, nameof(function)); IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(function, CommunityVocabularyModel.UrlEscapeFunctionTerm).FirstOrDefault(); if (annotation != null) { if (annotation.Value == null) { // If the annotation is applied but a value is not specified then the value is assumed to be true. return(true); } IEdmBooleanConstantExpression tagConstant = annotation.Value as IEdmBooleanConstantExpression; if (tagConstant != null) { return(tagConstant.Value); } } return(false); }
public void VisitVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { if (annotation.Term == null) { this.ProcessVocabularyAnnotation(annotation); return; } else { EdmTermKind termKind = annotation.Term.TermKind; switch (termKind) { case EdmTermKind.None: { this.ProcessVocabularyAnnotation(annotation); return; } case EdmTermKind.Type: { this.ProcessTypeAnnotation((IEdmTypeAnnotation)annotation); return; } case EdmTermKind.Value: { this.ProcessValueAnnotation((IEdmValueAnnotation)annotation); return; } } throw new InvalidOperationException(Strings.UnknownEnumVal_TermKind(annotation.Term.TermKind)); } }
protected override void ProcessVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { EdmSchema edmSchema = null; if (!annotation.IsInline(this.Model)) { string schemaNamespace = annotation.GetSchemaNamespace(this.Model); string empty = schemaNamespace; if (schemaNamespace == null) { Dictionary <string, EdmSchema> strs = this.modelSchemas; string str = strs.Select <KeyValuePair <string, EdmSchema>, string>((KeyValuePair <string, EdmSchema> s) => s.Key).FirstOrDefault <string>(); empty = str; if (str == null) { empty = string.Empty; } } string str1 = empty; if (!this.modelSchemas.TryGetValue(str1, out edmSchema)) { edmSchema = new EdmSchema(str1); this.modelSchemas.Add(edmSchema.Namespace, edmSchema); } edmSchema.AddVocabularyAnnotation(annotation); this.activeSchema = edmSchema; } if (annotation.Term != null) { this.CheckSchemaElementReference(annotation.Term); } base.ProcessVocabularyAnnotation(annotation); }
public void Term_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"); IEdmTerm termInt16Value = this.vocabularyDefinitionModel.FindTerm("bar.Int16Value"); // ?? Assumes Entity always?? // IEdmValue annotationHotIndex = applicationModel.GetTermValue(contextPropertyValue.Value, termInt16Value, evaluator); IEdmVocabularyAnnotation annotation = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt16Value); IEdmExpression expression = annotation.Value; IEdmValue annotationWorkphoneLocal = expressionEvaluator.Evaluate(expression, (IEdmStructuredValue)contextPropertyValue.Value); Assert.AreEqual(9991234, ((IEdmIntegerValue)annotationWorkphoneLocal).Value, "Term annotation value"); }
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); }
internal override void WriteVocabularyAnnotationElementHeader(IEdmVocabularyAnnotation 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); } }
public void Term_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"); IEdmTerm termInt32Value = this.vocabularyDefinitionModel.FindTerm("bar.Int32Value"); IEdmTerm termStringValue = this.vocabularyDefinitionModel.FindTerm("bar.StringValue"); IEdmVocabularyAnnotation annotation = property.VocabularyAnnotations(applicationModel).SingleOrDefault(a => a.Term == termInt32Value); 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"); }
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())); }
public void VisitVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { if (annotation.Term != null) { this.ProcessAnnotation(annotation); } else { this.ProcessVocabularyAnnotation(annotation); } }
public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { List <IEdmVocabularyAnnotation> edmVocabularyAnnotations = null; if (!this.annotations.TryGetValue(annotation.TargetString(), out edmVocabularyAnnotations)) { edmVocabularyAnnotations = new List <IEdmVocabularyAnnotation>(); this.annotations[annotation.TargetString()] = edmVocabularyAnnotations; } edmVocabularyAnnotations.Add(annotation); }
/// <summary> /// Adds the specified annotation. /// </summary> /// <param name="annotation">The annotation to add.</param> internal void Add(IEdmVocabularyAnnotation annotation) { Debug.Assert(annotation != null, "annotation != null"); IEdmVocabularyAnnotatable target = annotation.Target; if (target != null && IsModelMember(target, this.primaryModel)) { this.uniqueAnnotationsStorage.Add(annotation); } }
private void ValidateClrObjectConverter <T>(IEdmVocabularyAnnotation 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; } }
public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { List<IEdmVocabularyAnnotation> annotationList; if (!this.annotations.TryGetValue(annotation.TargetString(), out annotationList)) { annotationList = new List<IEdmVocabularyAnnotation>(); this.annotations[annotation.TargetString()] = annotationList; } annotationList.Add(annotation); }
internal override void WriteVocabularyAnnotationElementHeader(IEdmVocabularyAnnotation 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 && !IsUsingDefaultValue(annotation)) { // in xml format, we can (should) skip writing the expression value if it matches the term default value. this.WriteInlineExpression(annotation.Value); } }
protected override void ProcessAnnotation(IEdmVocabularyAnnotation annotation) { bool isInline = IsInlineExpression(annotation.Value); this.BeginElement(annotation, t => this.schemaWriter.WriteVocabularyAnnotationElementHeader(t, isInline)); if (!isInline) { base.ProcessAnnotation(annotation); } this.EndElement(annotation, t => this.schemaWriter.WriteVocabularyAnnotationElementEnd(annotation, isInline)); }
public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { List <IEdmVocabularyAnnotation> annotationList; if (!this.annotations.TryGetValue(annotation.TargetString(), out annotationList)) { annotationList = new List <IEdmVocabularyAnnotation>(); this.annotations[annotation.TargetString()] = annotationList; } annotationList.Add(annotation); }
public void AmbiguousOperationTest() { string csdl = @" <Schema Namespace=""DefaultNamespace"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> <Term Name=""Annotation"" Type=""Edm.Int32"" /> <EntityType Name=""Entity"" > <Key> <PropertyRef Name=""ID"" /> </Key> <Property Name=""ID"" Type=""Edm.Int32"" Nullable=""False"" /> </EntityType> <Function Name=""Function""> <Parameter Name=""Parameter"" Type=""Edm.String"" /> <Parameter Name=""Parameter2"" Type=""Ref(DefaultNamespace.Entity)"" /> <ReturnType Type=""Edm.Int32"" /> </Function> <Function Name=""Function""> <Parameter Name=""Parameter"" Type=""Edm.String"" /> <Parameter Name=""Parameter2"" Type=""Ref(DefaultNamespace.Entity)"" /> <ReturnType Type=""Edm.Int32"" /> </Function> <Function Name=""Function""> <Parameter Name=""Parameter"" Type=""Edm.String"" /> <Parameter Name=""Parameter2"" Type=""Ref(DefaultNamespace.Entity)"" /> <ReturnType Type=""Edm.Int32"" /> </Function> <Annotations Target=""DefaultNamespace.Function(Edm.String, Ref(DefaultNamespace.Entity))""> <Annotation Term=""AnnotationNamespace.Annotation""> <Int>42</Int> </Annotation> </Annotations> </Schema>"; IEdmModel model; IEnumerable <EdmError> errors; bool parsed = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(csdl)) }, out model, out errors); Assert.IsTrue(parsed, "parsed"); Assert.IsTrue(errors.Count() == 0, "No errors"); IEdmVocabularyAnnotation annotation = model.VocabularyAnnotations.First(); IEdmOperation firstOperation = model.FindOperations("DefaultNamespace.Function").First(); IEdmOperation ambiguousOperation = annotation.Target as IEdmOperation; Assert.IsNotNull(ambiguousOperation, "Function not null"); Assert.AreEqual(EdmSchemaElementKind.Function, ambiguousOperation.SchemaElementKind, "Correct schema element kind"); Assert.IsNull(ambiguousOperation.ReturnType, "Null return type"); Assert.AreEqual("DefaultNamespace", ambiguousOperation.Namespace, "Correct namespace"); Assert.AreEqual(firstOperation.Parameters.First(), ambiguousOperation.Parameters.First(), "Function gets parameters from first function"); Assert.AreEqual(firstOperation.FindParameter("Parameter"), ambiguousOperation.FindParameter("Parameter"), "Find parameter defers to first function"); }
/// <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 vocabulary annotation that binds to a term and a qualifier for the specified annotated type.</returns> private static IEdmVocabularyAnnotation GetOrInsertCachedMetadataAnnotationForType(DataServiceContext context, Type type, string term, string qualifier) { var serviceModel = context.Format.ServiceModel; if (serviceModel == null) { return(null); } IEdmVocabularyAnnotation 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 <IEdmVocabularyAnnotation>(edmVocabularyAnnotatable, term, qualifier) .Where(a => a.Qualifier == qualifier && a.Target == edmVocabularyAnnotatable); if (!edmValueAnnotations.Any()) { edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForType(context, type.GetBaseType(), term, qualifier); } else if (edmValueAnnotations.Count() == 1) { edmValueAnnotation = edmValueAnnotations.Single(); } InsertMetadataAnnotation(context, type, edmValueAnnotation); return(edmValueAnnotation); }
/// <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 vocabulary annotation that binds to a term and a qualifier for the specified annotated methodInfo.</returns> private static IEdmVocabularyAnnotation GetOrInsertCachedMetadataAnnotationForMethodInfo(DataServiceContext context, MethodInfo methodInfo, string term, string qualifier) { IEdmModel serviceModel = context.Format.ServiceModel; if (serviceModel == null) { return(null); } IEdmVocabularyAnnotation 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 <IEdmVocabularyAnnotation> edmValueAnnotations = null; if (edmOperationImport != null) { edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(edmOperationImport, term, qualifier) .Where(a => a.Qualifier == qualifier); if (!edmValueAnnotations.Any()) { edmVocabularyAnnotatable = edmOperationImport.Operation; } } if (edmValueAnnotations == null || !edmValueAnnotations.Any()) { edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(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); }
public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { List<IEdmVocabularyAnnotation> edmVocabularyAnnotations = null; EdmUtil.CheckArgumentNull<IEdmVocabularyAnnotation>(annotation, "annotation"); if (annotation.Target != null) { if (!this.vocabularyAnnotationsDictionary.TryGetValue(annotation.Target, out edmVocabularyAnnotations)) { edmVocabularyAnnotations = new List<IEdmVocabularyAnnotation>(); this.vocabularyAnnotationsDictionary.Add(annotation.Target, edmVocabularyAnnotations); } edmVocabularyAnnotations.Add(annotation); return; } else { throw new InvalidOperationException(Strings.Constructable_VocabularyAnnotationMustHaveTarget); } }
protected override void ProcessVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { if (!annotation.IsInline(this.Model)) { var annotationSchemaNamespace = annotation.GetSchemaNamespace(this.Model) ?? this.modelSchemas.Select(s => s.Key).FirstOrDefault() ?? string.Empty; EdmSchema annotationSchema; if (!this.modelSchemas.TryGetValue(annotationSchemaNamespace, out annotationSchema)) { annotationSchema = new EdmSchema(annotationSchemaNamespace); this.modelSchemas.Add(annotationSchema.Namespace, annotationSchema); } annotationSchema.AddVocabularyAnnotation(annotation); this.activeSchema = annotationSchema; } if (annotation.Term != null) { this.CheckSchemaElementReference(annotation.Term); } base.ProcessVocabularyAnnotation(annotation); }
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); } }
public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { List<IEdmVocabularyAnnotation> edmVocabularyAnnotations = null; if (!this.annotations.TryGetValue(annotation.TargetString(), out edmVocabularyAnnotations)) { edmVocabularyAnnotations = new List<IEdmVocabularyAnnotation>(); this.annotations[annotation.TargetString()] = edmVocabularyAnnotations; } edmVocabularyAnnotations.Add(annotation); }
protected override void ProcessVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { EdmSchema edmSchema = null; if (!annotation.IsInline(this.Model)) { string schemaNamespace = annotation.GetSchemaNamespace(this.Model); string empty = schemaNamespace; if (schemaNamespace == null) { Dictionary<string, EdmSchema> strs = this.modelSchemas; string str = strs.Select<KeyValuePair<string, EdmSchema>, string>((KeyValuePair<string, EdmSchema> s) => s.Key).FirstOrDefault<string>(); empty = str; if (str == null) { empty = string.Empty; } } string str1 = empty; if (!this.modelSchemas.TryGetValue(str1, out edmSchema)) { edmSchema = new EdmSchema(str1); this.modelSchemas.Add(edmSchema.Namespace, edmSchema); } edmSchema.AddVocabularyAnnotation(annotation); this.activeSchema = edmSchema; } if (annotation.Term != null) { this.CheckSchemaElementReference(annotation.Term); } base.ProcessVocabularyAnnotation(annotation); }
/// <summary> /// Set a vocabulary annotation to this model. /// </summary> /// <param name="annotation">The annotation to be set.</param> public void SetVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { EdmUtil.CheckArgumentNull(annotation, "annotation"); if (annotation.Target == null) { throw new InvalidOperationException(Strings.Constructable_VocabularyAnnotationMustHaveTarget); } List<IEdmVocabularyAnnotation> elementAnnotations; if (!this.vocabularyAnnotationsDictionary.TryGetValue(annotation.Target, out elementAnnotations)) { elementAnnotations = new List<IEdmVocabularyAnnotation>(); this.vocabularyAnnotationsDictionary.Add(annotation.Target, elementAnnotations); } elementAnnotations.RemoveAll(p => p.Term.FullName() == annotation.Term.FullName()); elementAnnotations.Add(annotation); }
/// <summary> /// Add an vocabulary annotation /// </summary> /// <param name="annotation">the annotation</param> public void AddVocabularyAnnotation(IEdmVocabularyAnnotation annotation) { // question: how do you get the annotation? Namespace.Name, or qualifier.NamespaceUri.Name? this.vocabularyAnnotations.Add(annotation); }