/// <summary> /// Tries to convert the value if it is spatial. Preserves any OData-specific fields. /// </summary> /// <param name="jsonObject">The json object that might be spatial.</param> /// <param name="value">The converted spatial value.</param> /// <returns>Whether the object was spatial and could be converted</returns> public bool TryConvertIfSpatial(JsonObject jsonObject, out PrimitiveValue value) { ExceptionUtilities.CheckArgumentNotNull(jsonObject, "jsonObject"); string edmTypeName; SpatialTypeKind?expectedType = null; if (TryExtractMetadataTypeName(jsonObject, out edmTypeName)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); var clrType = this.PrimitiveDataTypeConverter.ToClrType(edmTypeName); if (clrType == null) { // must not be primitive, let alone spatial value = null; return(false); } SpatialUtilities.TryInferSpatialTypeKind(clrType, out expectedType); } var dictionary = this.DictionaryConverter.Convert(jsonObject); object spatialInstance; if (this.GeoJsonFormatter.TryParse(dictionary, expectedType, out spatialInstance)) { value = new PrimitiveValue(edmTypeName, spatialInstance); return(true); } value = null; return(false); }
/// <summary> /// Returns whether the given type is a primitive type /// </summary> /// <param name="type">The type to check</param> /// <returns>True if it is a primitive type, false otherwise</returns> public override bool IsPrimitiveType(Type type) { SpatialTypeKind?kind; if (SpatialUtilities.TryInferSpatialTypeKind(type, out kind)) { return(true); } return(base.IsPrimitiveType(type)); }
private static bool IsSpatialValue(PrimitiveValue primitiveValue) { // if the metadata is provided and is known to be spatial, expect an error var dataTypeAnnotation = primitiveValue.Annotations.OfType <DataTypeAnnotation>().SingleOrDefault(); if (dataTypeAnnotation != null && dataTypeAnnotation.DataType is SpatialDataType) { return(true); } // if the object is non-null and a spatial value, expect an error SpatialTypeKind?kind; if (primitiveValue.ClrValue.IfValid(false, o => SpatialUtilities.TryInferSpatialTypeKind(o.GetType(), out kind))) { return(true); } return(false); }
/// <summary> /// Determines whether the value is a geometry instanct that must be converted to geography. /// </summary> /// <param name="value">The value which might need to be converted.</param> /// <param name="expectedType">The expected type.</param> /// <returns>True if the value must be converted, otherwise false</returns> internal static bool MustConvertGeometryToGeography(object value, Type expectedType) { if (value == null) { return(false); } SpatialTypeKind?actualKind; if (!SpatialUtilities.TryInferSpatialTypeKind(value.GetType(), out actualKind)) { return(false); } SpatialTypeKind?expectedKind; if (!SpatialUtilities.TryInferSpatialTypeKind(expectedType, out expectedKind)) { return(false); } return(expectedKind == SpatialTypeKind.Geography && actualKind == SpatialTypeKind.Geometry); }
/// <summary> /// Deserializes the element as either a complex, a primitive, or a null property, based on the content /// </summary> /// <param name="property">The xml to deserialize</param> /// <param name="typeNameFallback">TypeName to use instead of the one from the XElement[type] attribute</param> /// <returns>A property representing the given xml</returns> private PropertyInstance DeserializeProperty(XElement property, string typeNameFallback) { string propertyName = property.Name.LocalName; // get the type name string typeNameFromPayload = null; XAttribute typeAttribute = property.Attribute(MetadataType); if (typeAttribute != null) { typeNameFromPayload = typeAttribute.Value; } // set type to be fallback when typeattribute does not exist var typeNameForClrTypeLookup = typeNameFromPayload; if (typeNameForClrTypeLookup == null && !string.IsNullOrEmpty(typeNameFallback)) { typeNameForClrTypeLookup = typeNameFallback; } // try to infer the clr type Type clrType = null; if (!string.IsNullOrEmpty(typeNameForClrTypeLookup)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); clrType = this.PrimitiveDataTypeConverter.ToClrType(typeNameForClrTypeLookup); } PropertyInstance result; if (property.HasElements) { // must be complex, a multivalue, or spatial ExceptionUtilities.CheckObjectNotNull(this.SpatialFormatter, "Cannot safely deserialize element with children without spatial formatter."); // try to infer which spatial type hierarchy it is from the type name in the payload SpatialTypeKind?kind = null; if (clrType != null) { SpatialUtilities.TryInferSpatialTypeKind(clrType, out kind); } object spatialInstance; if (this.SpatialFormatter.TryParse(property.Elements().First(), kind, out spatialInstance)) { ExceptionUtilities.Assert(property.Elements().Count() == 1, "Spatial property had more than 1 sub-element"); result = new PrimitiveProperty(propertyName, typeNameFromPayload, spatialInstance); } else if (property.Elements().All(e => e.Name == DataServicesElement)) { result = this.DeserializeCollectionProperty(property); } else { result = new ComplexProperty(propertyName, this.DeserializeComplexInstance(property)); } } else { // check for the null attribute bool isNull = false; XAttribute isNullAttribute = property.Attribute(MetadataNull); if (isNullAttribute != null) { isNull = bool.Parse(isNullAttribute.Value); } // If its null and we can't tell whether it is primitive or complex, then return a null marker if (isNull && clrType == null) { result = new NullPropertyInstance(propertyName, typeNameFromPayload); } else if (typeNameFromPayload != null && typeNameFromPayload.StartsWith(ODataConstants.BeginMultiValueTypeIdentifier, StringComparison.Ordinal)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); string elementTypeName = ParseBagElementTypeName(typeNameFromPayload); if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null) { result = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(typeNameFromPayload, isNull)); } else { result = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(typeNameFromPayload, isNull)); } } else { object value; if (isNull) { value = null; } else if (clrType != null) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveConverter, "PrimitiveConverter has not been set."); value = this.PrimitiveConverter.DeserializePrimitive(property.Value, clrType); } else { value = property.Value; } result = new PrimitiveProperty(propertyName, typeNameFromPayload, value); } } AddXmlBaseAnnotation(result, property); return(result); }