Beispiel #1
0
        private static void toRow(Row row, JSONDataMap jsonMap, ref string field, bool fromUI)
        {
            var amorph = row as IAmorphousData;

            foreach (var mfld in jsonMap)
            {
                var fv = mfld.Value;

                var rfd = row.Schema[mfld.Key];
                field = mfld.Key;

                if (rfd == null)
                {
                    if (amorph != null)
                    {
                        if (amorph.AmorphousDataEnabled)
                        {
                            amorph.AmorphousData[mfld.Key] = fv;
                        }
                    }
                    continue;
                }

                if (fromUI && rfd.NonUI)
                {
                    continue;                         //skip NonUI fields
                }
                if (fv == null)
                {
                    row.SetFieldValue(rfd, null);
                }
                else
                if (fv is JSONDataMap)
                {
                    if (typeof(TypedRow).IsAssignableFrom(rfd.Type))
                    {
                        row.SetFieldValue(rfd, ToRow(rfd.Type, (JSONDataMap)fv));
                    }
                    else
                    {
                        row.SetFieldValue(rfd, fv);   //try to set row's field to MAP directly
                    }
                }
                else if (rfd.NonNullableType == typeof(TimeSpan) && (fv is ulong || fv is long || fv is int || fv is uint))
                {
                    var lt = Convert.ToInt64(fv);
                    row.SetFieldValue(rfd, TimeSpan.FromTicks(lt));
                }
                else if (fv is int || fv is long || fv is ulong || fv is double || fv is bool)
                {
                    row.SetFieldValue(rfd, fv);
                }
                else if (fv is byte[] && rfd.Type == typeof(byte[]))  //optimization byte array assignment without copies
                {
                    var passed = (byte[])fv;
                    var arr    = new byte[passed.Length];
                    Array.Copy(passed, arr, passed.Length);
                    row.SetFieldValue(rfd, arr);
                }
                else if (fv is JSONDataArray || fv.GetType().IsArray)
                {
                    JSONDataArray arr;
                    if (fv is JSONDataArray)
                    {
                        arr = (JSONDataArray)fv;
                    }
                    else
                    {
                        arr = new JSONDataArray(((Array)fv).Length);
                        foreach (var elm in (System.Collections.IEnumerable)fv)
                        {
                            arr.Add(elm);
                        }
                    }

                    if (rfd.Type.IsArray)
                    {
                        var raet = rfd.Type.GetElementType();        //row array element type
                        if (typeof(TypedRow).IsAssignableFrom(raet))
                        {
                            var narr = Array.CreateInstance(raet, arr.Count);
                            for (var i = 0; i < narr.Length; i++)
                            {
                                narr.SetValue(ToRow(raet, arr[i] as JSONDataMap), i);
                            }
                            row.SetFieldValue(rfd, narr);
                        }        //else primitives
                        else
                        {
                            var narr = Array.CreateInstance(raet, arr.Count);
                            for (var i = 0; i < narr.Length; i++)
                            {
                                if (arr[i] != null)
                                {
                                    narr.SetValue(StringValueConversion.AsType(arr[i].ToString(), raet, false), i);
                                }
                            }

                            row.SetFieldValue(rfd, narr);
                        }
                    }
                    else if (rfd.Type.IsGenericType && rfd.Type.GetGenericTypeDefinition() == typeof(List <>))     //List
                    {
                        var gat = rfd.Type.GetGenericArguments()[0];

                        var lst = Activator.CreateInstance(rfd.Type) as System.Collections.IList;

                        if (typeof(TypedRow).IsAssignableFrom(gat))
                        {
                            for (var i = 0; i < arr.Count; i++)
                            {
                                if (arr[i] is JSONDataMap)
                                {
                                    lst.Add(ToRow(gat, arr[i] as JSONDataMap));
                                }
                                else
                                {
                                    lst.Add(null);
                                }
                            }
                        }
                        else if (gat == typeof(object))
                        {
                            for (var i = 0; i < arr.Count; i++)
                            {
                                lst.Add(arr[i]);
                            }
                        }
                        else if (gat == typeof(string))
                        {
                            for (var i = 0; i < arr.Count; i++)
                            {
                                if (arr[i] != null)
                                {
                                    lst.Add(arr[i].ToString());
                                }
                                else
                                {
                                    lst.Add(null);
                                }
                            }
                        }
                        else if (gat.IsPrimitive ||
                                 gat == typeof(NFX.DataAccess.Distributed.GDID) ||
                                 gat == typeof(Guid) ||
                                 gat == typeof(DateTime))
                        {
                            for (var i = 0; i < arr.Count; i++)
                            {
                                if (arr[i] != null)
                                {
                                    lst.Add(StringValueConversion.AsType(arr[i].ToString(), gat, false));
                                }
                            }
                        }
                        else if (gat.IsGenericType && gat.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            var nt = gat.GetGenericArguments()[0];
                            if (nt.IsPrimitive ||
                                nt == typeof(NFX.DataAccess.Distributed.GDID) ||
                                nt == typeof(Guid) ||
                                nt == typeof(DateTime))
                            {
                                for (var i = 0; i < arr.Count; i++)
                                {
                                    if (arr[i] != null)
                                    {
                                        lst.Add(StringValueConversion.AsType(arr[i].ToString(), gat, false));
                                    }
                                    else
                                    {
                                        lst.Add(null);
                                    }
                                }
                            }
                        }

                        row.SetFieldValue(rfd, lst);
                    }
                }
                else
                {
                    //Try to get String containing JSON
                    if (fv is string)
                    {
                        var sfv = (string)fv;
                        if (rfd.Type == typeof(string))
                        {
                            row.SetFieldValue(rfd, sfv);
                            continue;
                        }

                        if (typeof(TypedRow).IsAssignableFrom(rfd.Type))
                        {
                            if (sfv.IsNotNullOrWhiteSpace())
                            {
                                row.SetFieldValue(rfd, ToRow(rfd.Type, (JSONDataMap)deserializeObject(read(sfv))));
                            }
                            continue;
                        }
                        if (typeof(IJSONDataObject).IsAssignableFrom(rfd.Type))
                        {
                            if (sfv.IsNotNullOrWhiteSpace())
                            {
                                row.SetFieldValue(rfd, deserializeObject(read(sfv))); //try to set row's field to MAP directly
                            }
                            continue;
                        }
                    }

                    row.SetFieldValue(rfd, StringValueConversion.AsType(fv.ToString(), rfd.Type, false));      //<--Type conversion
                }
            }  //foreach

            //20140914 DKh
            var form = row as FormModel;

            if (form != null)
            {
                form.FormMode  = jsonMap[FormModel.JSON_MODE_PROPERTY].AsEnum <FormMode>(FormMode.Unspecified);
                form.CSRFToken = jsonMap[FormModel.JSON_CSRF_PROPERTY].AsString();
                var roundtrip = jsonMap[FormModel.JSON_ROUNDTRIP_PROPERTY].AsString();
                if (roundtrip.IsNotNullOrWhiteSpace())
                {
                    form.SetRoundtripBagFromJSONString(roundtrip);
                }
            }

            if (amorph != null && amorph.AmorphousDataEnabled)
            {
                amorph.AfterLoad("json");
            }
        }
Beispiel #2
0
        }//setOneField

        //Returns non null on success; may return null for collection sub-element in which case null=null and does not indicate failure
        private static object cast(object v, Type toType, bool fromUI, DocReadOptions options, JsonHandlerAttribute fieldCustomHandler = null)
        {
            //See #264 - the collection inability to cast has no amorphous data so it MUST throw
            //used only for collections inner calls
            if (v == null)
            {
                return(null);
            }

            var customHandler = fieldCustomHandler ?? JsonHandlerAttribute.TryFind(toType);

            if (customHandler != null)
            {
                var castResult = customHandler.TypeCastOnRead(v, toType, fromUI, options);

                if (castResult.Outcome >= JsonHandlerAttribute.TypeCastOutcome.ChangedTargetType)
                {
                    toType = castResult.ToType;
                }

                if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.ChangedSourceValue)
                {
                    v = castResult.Value;
                }
                else if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.HandledCast)
                {
                    return(castResult.Value);
                }
            }

            //object goes as is
            if (toType == typeof(object))
            {
                return(v);
            }

            //IJSONDataObject
            if (toType == typeof(IJsonDataObject))
            {
                if (v is IJsonDataObject)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject();
                    return(jo);
                }
            }

            //IJSONDataMap
            if (toType == typeof(JsonDataMap))
            {
                if (v is JsonDataMap)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject() as JsonDataMap;
                    return(jo);
                }
            }

            //IJSONDataArray
            if (toType == typeof(JsonDataArray))
            {
                if (v is JsonDataArray)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject() as JsonDataArray;
                    return(jo);
                }
            }

            var nntp = toType;

            if (nntp.IsGenericType && nntp.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                nntp = toType.GetGenericArguments()[0];
            }

            //20191217 DKh
            if (nntp == typeof(DateTime))
            {
                if (options.LocalDates)
                {
                    var d = v.AsDateTime(System.Globalization.DateTimeStyles.AssumeLocal);
                    return(d);
                }
                else //UTC (the default)
                {
                    var d = v.AsDateTime(System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AdjustToUniversal);
                    return(d);
                }
            }
            //20191217 DKh


            //Custom JSON Readable (including config)
            if (typeof(IJsonReadable).IsAssignableFrom(nntp) || typeof(IConfigSectionNode).IsAssignableFrom(nntp))
            {
                var toAllocate = nntp;

                //Configuration requires special handling because nodes do not exist as independent entities and there
                //is master/detail relationship between them
                if (toAllocate == typeof(Configuration) ||
                    toAllocate == typeof(ConfigSectionNode) ||
                    toAllocate == typeof(IConfigSectionNode))
                {
                    toAllocate = typeof(MemoryConfiguration);
                }

                if (toAllocate.IsAbstract)
                {
                    throw new JSONDeserializationException(StringConsts.JSON_DESERIALIZATION_ABSTRACT_TYPE_ERROR.Args(toAllocate.Name, nameof(JsonHandlerAttribute)));
                }

                var newval = SerializationUtils.MakeNewObjectInstance(toAllocate) as IJsonReadable;
                var got    = newval.ReadAsJson(v, fromUI, options);//this may re-allocate the result based of newval

                if (!got.match)
                {
                    return(null);
                }

                if (typeof(IConfigSectionNode).IsAssignableFrom(nntp))
                {
                    return((got.self as Configuration)?.Root);
                }

                return(got.self);
            }

            //byte[] direct assignment w/o copies
            if (nntp == typeof(byte[]) && v is byte[] passed)
            {
                return(passed);
            }


            //field def = []
            if (toType.IsArray)
            {
                var fvseq = v as IEnumerable;
                if (fvseq == null)
                {
                    return(null);      //can not set non enumerable into array
                }
                var arr    = fvseq.Cast <object>().Select(e => cast(e, toType.GetElementType(), fromUI, options, fieldCustomHandler)).ToArray();
                var newval = Array.CreateInstance(toType.GetElementType(), arr.Length);
                for (var i = 0; i < newval.Length; i++)
                {
                    newval.SetValue(arr[i], i);
                }

                return(newval);
            }

            //field def = List<t>
            if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(List <>))
            {
                var fvseq = v as IEnumerable;
                if (fvseq == null)
                {
                    return(false);      //can not set non enumerable into List<t>
                }
                var arr    = fvseq.Cast <object>().Select(e => cast(e, toType.GetGenericArguments()[0], fromUI, options, fieldCustomHandler)).ToArray();
                var newval = SerializationUtils.MakeNewObjectInstance(toType) as IList;
                for (var i = 0; i < arr.Length; i++)
                {
                    newval.Add(arr[i]);
                }

                return(newval);
            }

            //last resort
            try
            {
                return(StringValueConversion.AsType(v.ToString(), toType, false));
            }
            catch
            {
                return(null);//the value could not be converted, and is going to go into amorphous bag if it is enabled
            }
        }
Beispiel #3
0
        }//setOneField

        //Returns non null on success; may return null for collection sub-element in which case null=null and does not indicate failure
        private static object cast(object v, Type toType, bool fromUI, NameBinding nameBinding)
        {
            //used only for collections inner calls
            if (v == null)
            {
                return(null);
            }

            //object goes as is
            if (toType == typeof(object))
            {
                return(v);
            }

            //IJSONDataObject
            if (toType == typeof(IJsonDataObject))
            {
                if (v is IJsonDataObject)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject();
                    return(jo);
                }
            }

            //IJSONDataMap
            if (toType == typeof(JsonDataMap))
            {
                if (v is JsonDataMap)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject() as JsonDataMap;
                    return(jo);
                }
            }

            //IJSONDataArray
            if (toType == typeof(JsonDataArray))
            {
                if (v is JsonDataArray)
                {
                    return(v);     //goes as is
                }
                if (v is string s) //string containing embedded JSON
                {
                    var jo = s.JsonToDataObject() as JsonDataArray;
                    return(jo);
                }
            }

            var nntp = toType;

            if (toType.IsGenericType && nntp.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                nntp = toType.GetGenericArguments()[0];
            }


            //Custom JSON Readable (including config)
            if (typeof(IJsonReadable).IsAssignableFrom(nntp) || typeof(IConfigSectionNode).IsAssignableFrom(nntp))
            {
                var toAllocate = nntp;

                //Configuration requires special handling because nodes do not exist as independent entities and there
                //is master/detail relationship between them
                if (toAllocate == typeof(Configuration) ||
                    toAllocate == typeof(ConfigSectionNode) ||
                    toAllocate == typeof(IConfigSectionNode))
                {
                    toAllocate = typeof(MemoryConfiguration);
                }

                var newval = SerializationUtils.MakeNewObjectInstance(toAllocate) as IJsonReadable;
                var got    = newval.ReadAsJson(v, fromUI, nameBinding);//this me re-allocate the result based of newval

                if (!got.match)
                {
                    return(null);
                }

                if (typeof(IConfigSectionNode).IsAssignableFrom(nntp))
                {
                    return((got.self as Configuration)?.Root);
                }

                return(got.self);
            }

            //byte[] direct assignment w/o copies
            if (nntp == typeof(byte[]) && v is byte[] passed)
            {
                return(passed);
            }


            //field def = []
            if (toType.IsArray)
            {
                var fvseq = v as IEnumerable <object>;
                if (fvseq == null)
                {
                    return(null);      //can not set non enumerable into array
                }
                var arr    = fvseq.Select(e => cast(e, toType.GetElementType(), fromUI, nameBinding)).ToArray();
                var newval = Array.CreateInstance(toType.GetElementType(), arr.Length);
                for (var i = 0; i < newval.Length; i++)
                {
                    newval.SetValue(arr[i], i);
                }

                return(newval);
            }

            //field def = List<t>
            if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(List <>))
            {
                var fvseq = v as IEnumerable <object>;
                if (fvseq == null)
                {
                    return(false);      //can not set non enumerable into List<t>
                }
                var arr    = fvseq.Select(e => cast(e, toType.GetGenericArguments()[0], fromUI, nameBinding)).ToArray();
                var newval = SerializationUtils.MakeNewObjectInstance(toType) as System.Collections.IList;
                for (var i = 0; i < arr.Length; i++)
                {
                    newval.Add(arr[i]);
                }

                return(newval);
            }

            //last resort
            try
            {
                return(StringValueConversion.AsType(v.ToString(), toType, false));
            }
            catch
            {
                return(null);//the value could not be converted, and is going to go into amorphous bag if it is enabled
            }
        }