Example #1
0
        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);
                            }
                        }
                    }
                }
            }
Example #4
0
        /// <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
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }
Example #9
0
        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.");
        }
Example #10
0
        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);
        }
Example #12
0
        /// <summary>
        /// Create the corresponding Authorization object.
        /// </summary>
        /// <param name="record">The input record.</param>
        /// <returns>The created <see cref="Authorization"/> object.</returns>
        public static IEnumerable <Authorization> GetAuthorizations(this IEdmModel model, IEdmVocabularyAnnotatable target)
        {
            Utils.CheckArgumentNull(model, nameof(model));
            Utils.CheckArgumentNull(target, nameof(target));

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

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

                return null;
            }));
        }
Example #13
0
        /// <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);
        }
Example #14
0
        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);
        }
Example #16
0
        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");
        }
Example #17
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource)
        {
            Contract.Assert(model != null);
            Contract.Assert(navigationSource != null);

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

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

            IEnumerable <IEdmStructuralProperty> cachedProperties;

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

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

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

            concurrencyProperties[navigationSource] = results;
            return(results);
        }
 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);
     }
 }
Example #19
0
        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");
        }
Example #20
0
        public async Task ModelBuilderTest()
        {
            // Arrange
            string expectMetadata =
                "<EntitySet Name=\"ETagUntypedCustomers\" EntityType=\"NS.Customer\">\r\n" +
                "          <Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">\r\n" +
                "            <Collection>\r\n" +
                "              <PropertyPath>Name</PropertyPath>\r\n" +
                "            </Collection>\r\n" +
                "          </Annotation>\r\n" +
                "        </EntitySet>";

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

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

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

            Assert.Contains(expectMetadata, content);

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

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

            Assert.NotNull(edmModel);

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

            Assert.NotNull(etagCustomers);

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

            Assert.NotNull(annotation);

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

            IEdmVocabularyAnnotation valueAnnotation = annotation as IEdmVocabularyAnnotation;

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

            IEdmCollectionExpression collection = valueAnnotation.Value as IEdmCollectionExpression;

            Assert.NotNull(collection);
            Assert.Equal(new[] { "Name" }, collection.Elements.Select(e => ((IEdmPathExpression)e).PathSegments.Single()));
        }
Example #21
0
 public void VisitVocabularyAnnotation(IEdmVocabularyAnnotation annotation)
 {
     if (annotation.Term != null)
     {
         this.ProcessAnnotation(annotation);
     }
     else
     {
         this.ProcessVocabularyAnnotation(annotation);
     }
 }
Example #22
0
        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);
        }
Example #23
0
        /// <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);
            }
        }
Example #24
0
 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;
     }
 }
Example #25
0
        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);
            }
        }
Example #27
0
        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));
        }
Example #28
0
        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);
        }
Example #29
0
        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);
        }
Example #32
0
		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);
            }
        }
Example #35
0
		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);
		}
Example #37
0
        /// <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);
        }
Example #38
0
 /// <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);
 }