Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <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);
            }
Esempio n. 4
0
        /// <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);
        }