/// <summary> /// Writes all the instance annotations specified in <paramref name="instanceAnnotations"/>. /// </summary> /// <param name="instanceAnnotations">Collection of instance annotations to write.</param> /// <param name="tracker">The tracker to track if instance annotations are written.</param> /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param> /// <param name="propertyName">The name of the property this instance annotation applies to</param> internal void WriteInstanceAnnotations( IEnumerable <ODataInstanceAnnotation> instanceAnnotations, InstanceAnnotationWriteTracker tracker, bool ignoreFilter = false, string propertyName = null) { Debug.Assert(instanceAnnotations != null, "instanceAnnotations should not be null if we called this"); Debug.Assert(tracker != null, "tracker should not be null if we called this"); HashSet <string> instanceAnnotationNames = new HashSet <string>(StringComparer.Ordinal); foreach (var annotation in instanceAnnotations) { if (!instanceAnnotationNames.Add(annotation.Name)) { throw new ODataException(ODataErrorStrings.JsonLightInstanceAnnotationWriter_DuplicateAnnotationNameInCollection(annotation.Name)); } if (!tracker.IsAnnotationWritten(annotation.Name) && (!ODataAnnotationNames.IsODataAnnotationName(annotation.Name) || ODataAnnotationNames.IsUnknownODataAnnotationName(annotation.Name))) { this.WriteInstanceAnnotation(annotation, ignoreFilter, propertyName); tracker.MarkAnnotationWritten(annotation.Name); } } }
public void IsUnknownODataAnnotationNameShouldReturnFalseOnReservedODataAnnotationName() { foreach (string annotationName in ReservedODataAnnotationNames) { ODataAnnotationNames.IsUnknownODataAnnotationName(annotationName).Should().BeFalse(); } }
public void IsODataAnnotationNameShouldReturnFalseForAnnotationNamesNotUnderODataNamespace() { ODataAnnotationNames.IsODataAnnotationName("odataa.unknown").Should().BeFalse(); ODataAnnotationNames.IsODataAnnotationName("oodata.unknown").Should().BeFalse(); ODataAnnotationNames.IsODataAnnotationName("custom.unknown").Should().BeFalse(); ODataAnnotationNames.IsODataAnnotationName("OData.unknown").Should().BeFalse(); }
public void ValidateCustomAnnotationNameShouldThrowOnReservedODataAnnotationName() { foreach (string annotationName in ReservedODataAnnotationNames) { Action test = () => ODataAnnotationNames.ValidateIsCustomAnnotationName(annotationName); test.ShouldThrow <ODataException>().WithMessage(Strings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties(annotationName)); } }
public void IsUnknownODataAnnotationNameShouldReturnFalseOnCustomAnnotationName() { ODataAnnotationNames.IsUnknownODataAnnotationName("custom.annotation").Should().BeFalse(); foreach (string annotationName in ReservedODataAnnotationNames) { // We match the "odata." namespace case sensitive. ODataAnnotationNames.IsUnknownODataAnnotationName(annotationName.ToUpperInvariant()).Should().BeFalse(); } }
public void ReservedODataAnnotationNamesHashSetShouldContainAllODataAnnotationNamesSpecialToODataLib() { Assert.Equal(ReservedODataAnnotationNames.Length, ODataAnnotationNames.KnownODataAnnotationNames.Count); foreach (string annotationName in ReservedODataAnnotationNames) { ODataAnnotationNames.IsODataAnnotationName(annotationName).Should().BeTrue(); ODataAnnotationNames.KnownODataAnnotationNames.Contains(annotationName).Should().BeTrue(); ODataAnnotationNames.KnownODataAnnotationNames.Contains(annotationName.ToUpperInvariant()).Should().BeFalse(); } }
public void ReservedODataAnnotationNamesHashSetShouldContainAllODataAnnotationNamesSpecialToODataLib() { Assert.Equal(ReservedODataAnnotationNames.Length, ODataAnnotationNames.KnownODataAnnotationNames.Count); foreach (string annotationName in ReservedODataAnnotationNames) { Assert.True(ODataAnnotationNames.IsODataAnnotationName(annotationName)); Assert.Contains(annotationName, ODataAnnotationNames.KnownODataAnnotationNames); Assert.DoesNotContain(annotationName.ToUpperInvariant(), ODataAnnotationNames.KnownODataAnnotationNames); } }
/// <summary> /// Reads the json object value from the jsonReader /// </summary> /// <param name="jsonReader">Json reader to read payload from the wire.</param> /// <param name="insideJsonObjectValue">true if the reader is positioned on the first property of the value which is a JSON Object /// (or the second property if the first one was odata.type).</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="recursionDepth">The recursion depth to start with.</param> /// <returns>an instance of IDictionary containing the spatial value.</returns> private static IDictionary <string, object> ReadObjectValue(IJsonReader jsonReader, bool insideJsonObjectValue, ODataInputContext inputContext, int recursionDepth) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject, "insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject"); Debug.Assert( !insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.Property || jsonReader.NodeType == JsonNodeType.EndObject, "!insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.Property || jsonReader.NodeType == JsonNodeType.EndObject"); Debug.Assert(inputContext != null, "inputContext != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, inputContext.MessageReaderSettings.MessageQuotas.MaxNestingDepth); IDictionary <string, object> jsonValue = new Dictionary <string, object>(StringComparer.Ordinal); if (!insideJsonObjectValue) { // Note that if the insideJsonObjectValue is true we will ignore the odata.type instance annotation // which might have been there. This is OK since for spatial we only need the normal properties anyway. jsonReader.ReadNext(); } while (jsonReader.NodeType != JsonNodeType.EndObject) { // read the property name string propertyName = jsonReader.ReadPropertyName(); // read the property value object propertyValue = null; switch (jsonReader.NodeType) { case JsonNodeType.PrimitiveValue: propertyValue = jsonReader.ReadPrimitiveValue(); break; case JsonNodeType.StartArray: propertyValue = ReadArrayValue(jsonReader, inputContext, recursionDepth); break; case JsonNodeType.StartObject: propertyValue = ReadObjectValue(jsonReader, /*insideJsonObjectValue*/ false, inputContext, recursionDepth); break; default: Debug.Assert(false, "We should never reach here - There should be matching end element"); return(null); } jsonValue.Add(ODataAnnotationNames.RemoveAnnotationPrefix(propertyName), propertyValue); } jsonReader.ReadEndObject(); return(jsonValue); }
/// <summary> /// Constructs a new <see cref="ODataInstanceAnnotation"/> instance. /// </summary> /// <param name="annotationName">The name of the instance annotation.</param> /// <param name="annotationValue">The value of the instance annotation.</param> /// <param name="isCustomAnnotation">If the name is not for built-in OData annotation.</param> internal ODataInstanceAnnotation(string annotationName, ODataValue annotationValue, bool isCustomAnnotation) { ExceptionUtils.CheckArgumentStringNotNullOrEmpty(annotationName, "annotationName"); if (!isCustomAnnotation && ODataAnnotationNames.IsODataAnnotationName(annotationName)) { // isCustomAnnotation==true includes '@odata.<unknown name>', which won't cause the below exception. throw new ArgumentException(Strings.ODataInstanceAnnotation_ReservedNamesNotAllowed(annotationName, JsonLightConstants.ODataAnnotationNamespacePrefix)); } ValidateName(annotationName); ValidateValue(annotationValue); this.Name = annotationName; this.Value = annotationValue; }
/// <summary> /// Write instance annotation if not already written. /// </summary> /// <param name="annotation">The instance annotation to write.</param> /// <param name="tracker">The tracker to track if instance annotations are written.</param> /// <param name="instanceAnnotationNames">Set used to detect a duplicate annotation.</param> /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param> /// <param name="propertyName">The name of the property this instance annotation applies to.</param> private void WriteAndTrackInstanceAnnotation( ODataInstanceAnnotation annotation, InstanceAnnotationWriteTracker tracker, HashSet <string> instanceAnnotationNames, bool ignoreFilter = false, string propertyName = null) { if (!instanceAnnotationNames.Add(annotation.Name)) { throw new ODataException(ODataErrorStrings.JsonLightInstanceAnnotationWriter_DuplicateAnnotationNameInCollection(annotation.Name)); } if (!tracker.IsAnnotationWritten(annotation.Name) && (!ODataAnnotationNames.IsODataAnnotationName(annotation.Name) || ODataAnnotationNames.IsUnknownODataAnnotationName(annotation.Name))) { this.WriteInstanceAnnotation(annotation, ignoreFilter, propertyName); tracker.MarkAnnotationWritten(annotation.Name); } }
/// <summary> /// Validates that the given <paramref name="name"/> is a valid instance annotation name. /// </summary> /// <param name="name">Name to validate.</param> internal static void ValidateName(string name) { ExceptionUtils.CheckArgumentStringNotNullOrEmpty(name, "name"); if (name.IndexOf('.') < 0 || name[0] == '.' || name[name.Length - 1] == '.') { throw new ArgumentException(Strings.ODataInstanceAnnotation_NeedPeriodInName(name)); } if (ODataAnnotationNames.IsODataAnnotationName(name)) { throw new ArgumentException(Strings.ODataInstanceAnnotation_ReservedNamesNotAllowed(name, JsonLightConstants.ODataAnnotationNamespacePrefix)); } try { XmlConvert.VerifyNCName(name); } catch (XmlException e) { throw new ArgumentException(Strings.ODataInstanceAnnotation_BadTermName(name), e); } }
public void IsODataAnnotationNameShouldReturnTrueForAnnotationNamesUnderODataNamespace() { ODataAnnotationNames.IsODataAnnotationName("odata.unknown").Should().BeTrue(); }
public void IsODataAnnotationNameShouldReturnFalseForAnnotationNamesNotUnderODataNamespace(string annotationName) { Assert.False(ODataAnnotationNames.IsODataAnnotationName(annotationName)); }
public void IsUnknownODataAnnotationNameShouldReturnFalseOnPropertyName() { Assert.False(ODataAnnotationNames.IsUnknownODataAnnotationName("odataPropertyName")); }
public void IsUnknownODataAnotationNameShouldReturnTrueOnUnknownODataAnnotationName() { ODataAnnotationNames.IsUnknownODataAnnotationName("odata.unknown").Should().BeTrue(); }
public void IsUnknownODataAnotationNameShouldReturnTrueOnUnknownODataAnnotationName() { Assert.True(ODataAnnotationNames.IsUnknownODataAnnotationName("odata.unknown")); }
/// <summary> /// Writes an instance annotation. /// </summary> /// <param name="instanceAnnotation">The instance annotation to write.</param> internal void WriteInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation) { DebugUtils.CheckNoExternalCallers(); string name = instanceAnnotation.Name; ODataValue value = instanceAnnotation.Value; Debug.Assert(!string.IsNullOrEmpty(name), "name should not be null or empty"); Debug.Assert(!ODataAnnotationNames.IsODataAnnotationName(name), "A reserved name cannot be used as instance annotation key"); Debug.Assert(value != null, "value should not be null because we use ODataNullValue for null instead"); Debug.Assert(!(value is ODataStreamReferenceValue), "!(value is ODataStreamReferenceValue) -- ODataInstanceAnnotation and InstanceAnnotationCollection will throw if the value is a stream value."); Debug.Assert(this.valueSerializer.Model != null, "this.valueSerializer.Model != null"); if (this.valueSerializer.Settings.ShouldSkipAnnotation(name)) { return; } IEdmTypeReference expectedType = MetadataUtils.LookupTypeOfValueTerm(name, this.valueSerializer.Model); if (value is ODataNullValue) { if (expectedType != null && !expectedType.IsNullable) { throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueSerializer_NullValueNotAllowedForInstanceAnnotation(instanceAnnotation.Name, expectedType.ODataFullName())); } this.JsonWriter.WriteName(name); this.valueSerializer.WriteNullValue(); return; } // If we didn't find an expected type from looking up the term in the model, treat this value the same way we would for open property values. // That is, write the type name (unless its a primitive value with a JSON-native type). If we did find an expected type, treat the annotation value like a // declared property with an expected type. This will still write out the type if the value type is more derived than the declared type, for example. bool treatLikeOpenProperty = expectedType == null; ODataComplexValue complexValue = value as ODataComplexValue; if (complexValue != null) { this.JsonWriter.WriteName(name); this.valueSerializer.WriteComplexValue(complexValue, expectedType, false /*isTopLevel*/, treatLikeOpenProperty, this.valueSerializer.CreateDuplicatePropertyNamesChecker()); return; } IEdmTypeReference typeFromValue = TypeNameOracle.ResolveAndValidateTypeNameForValue(this.valueSerializer.Model, expectedType, value, treatLikeOpenProperty); ODataCollectionValue collectionValue = value as ODataCollectionValue; if (collectionValue != null) { string collectionTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(collectionValue, expectedType, typeFromValue, treatLikeOpenProperty); if (collectionTypeNameToWrite != null) { ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, collectionTypeNameToWrite); } this.JsonWriter.WriteName(name); this.valueSerializer.WriteCollectionValue(collectionValue, expectedType, false /*isTopLevelProperty*/, false /*isInUri*/, treatLikeOpenProperty); return; } ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue; Debug.Assert(primitiveValue != null, "Did we add a new subclass of ODataValue?"); string primitiveTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(primitiveValue, expectedType, typeFromValue, treatLikeOpenProperty); if (primitiveTypeNameToWrite != null) { ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, primitiveTypeNameToWrite); } this.JsonWriter.WriteName(name); this.valueSerializer.WritePrimitiveValue(primitiveValue.Value, expectedType); }
public void IsUnknownODataAnnotationNameShouldReturnFalseOnPropertyName() { ODataAnnotationNames.IsUnknownODataAnnotationName("odataPropertyName").Should().BeFalse(); }
public void IsODataAnnotationNameShouldReturnTrueForAnnotationNamesUnderODataNamespace() { Assert.True(ODataAnnotationNames.IsODataAnnotationName("odata.unknown")); }