Ejemplo n.º 1
0
        public static object ToFieldValue(this Java.Lang.Object fieldValue, Type type)
        {
            if (fieldValue == null)
            {
                return(null);
            }

            switch (fieldValue)
            {
            case Java.Lang.Boolean @bool:
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    type = type.GenericTypeArguments[0];
                }
                return(Convert.ChangeType((bool)@bool, type));

            case Java.Lang.Long @long:
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    type = type.GenericTypeArguments[0];
                }
                return(Convert.ChangeType((long)@long, type));

            case Java.Lang.Double @double:
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    type = type.GenericTypeArguments[0];
                }
                return(Convert.ChangeType((double)@double, type));

            case Java.Lang.String @string:
                return(fieldValue.ToString());

            case Firebase.Timestamp timestamp:
            {
                var time = new Timestamp(timestamp);
                if (type == typeof(DateTime) || type == typeof(DateTime?))
                {
                    return(time.ToDateTime());
                }
                if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
                {
                    return(time.ToDateTimeOffset());
                }
                return(time);
            }

            case Java.Util.Date date:
            {
                var time = new Timestamp(date);
                if (type == typeof(DateTime) || type == typeof(DateTime?))
                {
                    return(time.ToDateTime());
                }
                if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
                {
                    return(time.ToDateTimeOffset());
                }
                return(time);
            }

            case JavaList javaList:
            {
                IList list;
                if (type.GetInterfaces().Contains(typeof(IList)))
                {
                    list = (IList)Activator.CreateInstance(type);
                }
                else if (type.IsGenericType)
                {
                    var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]);
                    list = (IList)Activator.CreateInstance(listType);
                }
                else
                {
                    list = new List <object>();
                }

                var genericType = typeof(object);
                if (type.IsGenericType)
                {
                    genericType = type.GenericTypeArguments[0];
                }

                foreach (var data in javaList)
                {
                    var value = data;
                    if (value is Java.Lang.Object javaObject)
                    {
                        value = javaObject.ToFieldValue(genericType);
                    }
                    else if (value != null && genericType != typeof(object))
                    {
                        if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            genericType = genericType.GenericTypeArguments[0];
                        }
                        value = Convert.ChangeType(value, genericType);
                    }
                    list.Add(value);
                }
                return(list);
            }

            case Java.Util.AbstractList javaList:
            {
                IList list;
                if (type.GetInterfaces().Contains(typeof(IList)))
                {
                    list = (IList)Activator.CreateInstance(type);
                }
                else if (type.IsGenericType)
                {
                    var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]);
                    list = (IList)Activator.CreateInstance(listType);
                }
                else
                {
                    list = new List <object>();
                }

                var genericType = typeof(object);
                if (type.IsGenericType)
                {
                    genericType = type.GenericTypeArguments[0];
                }

                var iterator = javaList.Iterator();
                while (iterator.HasNext)
                {
                    object value = iterator.Next();
                    if (value is Java.Lang.Object javaObject)
                    {
                        value = javaObject.ToFieldValue(genericType);
                    }
                    else if (value != null && genericType != typeof(object))
                    {
                        if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            genericType = genericType.GenericTypeArguments[0];
                        }
                        value = Convert.ChangeType(value, genericType);
                    }
                    list.Add(value);
                }
                return(list);
            }

            case JavaDictionary dictionary:
            {
                object @object;
                if (type == typeof(object))
                {
                    @object = new Dictionary <string, object>();
                }
                else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>))
                {
                    var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]);
                    @object = Activator.CreateInstance(dictionaryType);
                }
                else
                {
                    @object = Activator.CreateInstance(type);
                }

                if (@object is IDictionary dict)
                {
                    var genericType = typeof(object);
                    if (type.IsGenericType)
                    {
                        genericType = type.GenericTypeArguments[1];
                    }

                    foreach (var key in dictionary.Keys)
                    {
                        var value = dictionary[key];
                        if (value is Java.Lang.Object javaObject)
                        {
                            value = javaObject.ToFieldValue(genericType);
                        }
                        else if (value != null && genericType != typeof(object))
                        {
                            if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>))
                            {
                                genericType = genericType.GenericTypeArguments[0];
                            }
                            value = Convert.ChangeType(value, genericType);
                        }
                        dict.Add(key.ToString(), value);
                    }
                }
                else
                {
                    var properties       = type.GetProperties();
                    var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute))
                                           .Where(t => t.Attribute != null)
                                           .ToDictionary(t => t.Attribute.Mapping, t => t.Property);
                    var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null);

                    foreach (var key in dictionary.Keys)
                    {
                        PropertyInfo property;
                        if (mappedProperties.ContainsKey(key.ToString()))
                        {
                            property = mappedProperties[key.ToString()];
                        }
                        else
                        {
                            property = type.GetProperty(key.ToString());
                        }

                        if (property != null && !igonoredProperties.Contains(property))
                        {
                            var value = dictionary[key];
                            if (value is Java.Lang.Object javaObject)
                            {
                                value = javaObject.ToFieldValue(property.PropertyType);
                            }
                            else if (value != null)
                            {
                                var propertyType = property.PropertyType;
                                if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                                {
                                    propertyType = propertyType.GenericTypeArguments[0];
                                }
                                value = Convert.ChangeType(value, propertyType);
                            }
                            property.SetValue(@object, value);
                        }
                    }
                }
                return(@object);
            }

            case Java.Util.AbstractMap map:
            {
                object @object;
                if (type == typeof(object))
                {
                    @object = new Dictionary <string, object>();
                }
                else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>))
                {
                    var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]);
                    @object = Activator.CreateInstance(dictionaryType);
                }
                else
                {
                    @object = Activator.CreateInstance(type);
                }

                if (@object is IDictionary dict)
                {
                    var genericType = typeof(object);
                    if (type.IsGenericType)
                    {
                        genericType = type.GenericTypeArguments[1];
                    }

                    foreach (var key in map.KeySet())
                    {
                        object value = map.Get(key.ToString());
                        if (value is Java.Lang.Object javaObject)
                        {
                            value = javaObject.ToFieldValue(genericType);
                        }
                        else if (value != null && genericType != typeof(object))
                        {
                            if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>))
                            {
                                genericType = genericType.GenericTypeArguments[0];
                            }
                            value = Convert.ChangeType(value, genericType);
                        }
                        dict.Add(key.ToString(), value);
                    }
                }
                else
                {
                    var properties       = type.GetProperties();
                    var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute))
                                           .Where(t => t.Attribute != null)
                                           .ToDictionary(t => t.Attribute.Mapping, t => t.Property);
                    var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null);

                    foreach (var key in map.KeySet())
                    {
                        PropertyInfo property;
                        if (mappedProperties.ContainsKey(key.ToString()))
                        {
                            property = mappedProperties[key.ToString()];
                        }
                        else
                        {
                            property = type.GetProperty(key.ToString());
                        }

                        if (property != null && !igonoredProperties.Contains(property))
                        {
                            object value = map.Get(key.ToString());
                            if (value is Java.Lang.Object javaObject)
                            {
                                value = javaObject.ToFieldValue(property.PropertyType);
                            }
                            else if (value != null)
                            {
                                var propertyType = property.PropertyType;
                                if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                                {
                                    propertyType = propertyType.GenericTypeArguments[0];
                                }
                                value = Convert.ChangeType(value, propertyType);
                            }
                            property.SetValue(@object, value);
                        }
                    }
                }
                return(@object);
            }

            case Firebase.Firestore.Blob blob:
                if (type == typeof(byte[]))
                {
                    return(blob.ToBytes());
                }
                return(new MemoryStream(blob.ToBytes()));

            case Firebase.Firestore.GeoPoint geoPoint:
                return(new GeoPoint(geoPoint));

            case Firebase.Firestore.DocumentReference documentReference:
                return(new DocumentReferenceWrapper(documentReference));

            default:
                throw new ArgumentOutOfRangeException($"{fieldValue.GetType().FullName} is not supported");
            }
        }
Ejemplo n.º 2
0
        public static object ToFieldValue(this NSObject fieldValue, Type type)
        {
            if (fieldValue == null)
            {
                return(null);
            }

            switch (fieldValue)
            {
            case NSNumber number:
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    type = type.GenericTypeArguments[0];
                }

                if (type == typeof(bool))
                {
                    return(number.BoolValue);
                }
                if (type == typeof(byte))
                {
                    return(number.ByteValue);
                }
                if (type == typeof(double))
                {
                    return(number.DoubleValue);
                }
                if (type == typeof(float))
                {
                    return(number.FloatValue);
                }
                if (type == typeof(int))
                {
                    return(number.Int32Value);
                }
                if (type == typeof(long))
                {
                    return(number.Int64Value);
                }
                if (type == typeof(sbyte))
                {
                    return(number.SByteValue);
                }
                if (type == typeof(short))
                {
                    return(number.Int16Value);
                }
                if (type == typeof(uint))
                {
                    return(number.UInt32Value);
                }
                if (type == typeof(ulong))
                {
                    return(number.UInt64Value);
                }
                if (type == typeof(ushort))
                {
                    return(number.UInt16Value);
                }
                return(Convert.ChangeType(number.DoubleValue, type));

            case NSString @string:
                return(@string.ToString());

            case Firebase.CloudFirestore.Timestamp timestamp:
            {
                var time = new Timestamp(timestamp);
                if (type == typeof(DateTime) || type == typeof(DateTime?))
                {
                    return(time.ToDateTime());
                }
                if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
                {
                    return(time.ToDateTimeOffset());
                }
                return(time);
            }

            case NSDate date:
            {
                var time = new Timestamp(date);
                if (type == typeof(DateTime) || type == typeof(DateTime?))
                {
                    return(time.ToDateTime());
                }
                if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
                {
                    return(time.ToDateTimeOffset());
                }
                return(time);
            }

            case NSArray array:
            {
                IList list;
                if (type.GetInterfaces().Contains(typeof(IList)))
                {
                    list = (IList)Activator.CreateInstance(type);
                }
                else if (type.IsGenericType)
                {
                    var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]);
                    list = (IList)Activator.CreateInstance(listType);
                }
                else
                {
                    list = new List <object>();
                }

                var genericType = typeof(object);
                if (type.IsGenericType)
                {
                    genericType = type.GenericTypeArguments[0];
                }

                for (nuint i = 0; i < array.Count; i++)
                {
                    list.Add(array.GetItem <NSObject>(i).ToFieldValue(genericType));
                }
                return(list);
            }

            case NSDictionary dictionary:
            {
                object @object;
                if (type == typeof(object))
                {
                    @object = new Dictionary <string, object>();
                }
                else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>))
                {
                    var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]);
                    @object = Activator.CreateInstance(dictionaryType);
                }
                else
                {
                    @object = Activator.CreateInstance(type);
                }

                if (@object is IDictionary dict)
                {
                    var genericType = typeof(object);
                    if (type.IsGenericType)
                    {
                        genericType = type.GenericTypeArguments[1];
                    }

                    foreach (var(key, value) in dictionary)
                    {
                        dict.Add(key.ToString(), value.ToFieldValue(genericType));
                    }
                }
                else
                {
                    var properties       = type.GetProperties();
                    var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute))
                                           .Where(t => t.Attribute != null)
                                           .ToDictionary(t => t.Attribute.Mapping, t => t.Property);
                    var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null);

                    foreach (var(key, value) in dictionary)
                    {
                        PropertyInfo property;
                        if (mappedProperties.ContainsKey(key.ToString()))
                        {
                            property = mappedProperties[key.ToString()];
                        }
                        else
                        {
                            property = type.GetProperty(key.ToString());
                        }

                        if (property != null && !igonoredProperties.Contains(property))
                        {
                            property.SetValue(@object, value.ToFieldValue(property.PropertyType));
                        }
                    }
                }
                return(@object);
            }

            case NSData data:
                if (type == typeof(byte[]))
                {
                    return(data.ToArray());
                }
                return(new MemoryStream(data.ToArray()));

            case Firebase.CloudFirestore.GeoPoint geoPoint:
                return(new GeoPoint(geoPoint));

            case Firebase.CloudFirestore.DocumentReference documentReference:
                return(new DocumentReferenceWrapper(documentReference));

            case NSNull @null:
                return(null);

            default:
                throw new ArgumentOutOfRangeException($"{fieldValue.GetType().FullName} is not supported");
            }
        }