Example #1
0
        /// <summary>
        /// Converts JSONMap into supplied row instance.
        /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise.
        /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e.
        ///  it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries
        /// </summary>
        /// <param name="doc">Data document instance to convert into</param>
        /// <param name="jsonMap">JSON data to convert into row</param>
        /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param>
        /// <param name="options">Used for backend name matching or null (any target)</param>
        public static void ToDoc(Doc doc, JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null)
        {
            if (doc == null || jsonMap == null)
            {
                throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(doc|jsonMap=null)");
            }

            var field = "";

            try
            {
                var tDoc          = doc.GetType();
                var customHandler = JsonHandlerAttribute.TryFind(tDoc);
                if (customHandler != null)
                {
                    var castResult = customHandler.TypeCastOnRead(jsonMap, tDoc, fromUI, options ?? DocReadOptions.BindByCode);

                    //only reacts to ChangeSource because this method works on pre-allocated doc
                    if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.ChangedSourceValue)
                    {
                        jsonMap = (castResult.Value as JsonDataMap).NonNull("Changed source value must be of JsonDataMap type for root data documents");
                    }
                }

                toDoc(doc, options.HasValue ? options.Value : DocReadOptions.BindByCode, jsonMap, ref field, fromUI);
            }
            catch (Exception error)
            {
                throw new JSONDeserializationException("JSONReader.ToDoc(doc, jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error);
            }
        }
Example #2
0
        private static TypedDoc toTypedDoc(Type type, DocReadOptions?options, JsonDataMap jsonMap, ref string field, bool fromUI)
        {
            var toAllocate = type;

            var customHandler = JsonHandlerAttribute.TryFind(type);

            if (customHandler != null)
            {
                var castResult = customHandler.TypeCastOnRead(jsonMap, type, fromUI, options ?? DocReadOptions.BindByCode);

                if (castResult.Outcome >= JsonHandlerAttribute.TypeCastOutcome.ChangedTargetType)
                {
                    toAllocate = castResult.ToType.IsOfType(type, "Changed type must be a subtype of specific document type");
                }

                if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.ChangedSourceValue)
                {
                    jsonMap = (castResult.Value as JsonDataMap).NonNull("Changed source value must be of JsonDataMap type for root data documents");
                }
                else if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.HandledCast)
                {
                    return(castResult.Value.ValueIsOfType(type, "HandledCast must return TypedDoc for root data documents") as TypedDoc);
                }
            }

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

            var doc = (TypedDoc)SerializationUtils.MakeNewObjectInstance(toAllocate);

            toDoc(doc, options.HasValue ? options.Value : DocReadOptions.BindByCode, jsonMap, ref field, fromUI);
            return(doc);
        }
Example #3
0
        /// <summary>
        /// If there is error, converts its details to JSONDataMap
        /// </summary>
        public static Azos.Serialization.JSON.JsonDataMap ToJSONDataMap(this Exception error, bool recurse = true, bool stackTrace = false)
        {
            if (error == null)
            {
                return(null);
            }
            var result = new Azos.Serialization.JSON.JsonDataMap(false);

            result["Type"] = error.GetType().FullName;
            result["Msg"]  = error.Message;
            result["Data"] = error.Data;
            result["Src"]  = error.Source;
            if (stackTrace)
            {
                result["STrace"] = error.StackTrace;
            }

            if (recurse)
            {
                result["Inner"] = error.InnerException.ToJSONDataMap(recurse);
            }
            else
            {
                result["Inner.Type"] = error.InnerException != null?error.InnerException.GetType().FullName : null;

                result["Inner.Msg"] = error.InnerException != null ? error.InnerException.Message : null;
                if (stackTrace)
                {
                    result["Inner.STrace"] = error.InnerException != null ? error.InnerException.StackTrace : null;
                }
            }

            return(result);
        }
Example #4
0
        private static TypedDoc toTypedDoc(Type type, NameBinding?nameBinding, JsonDataMap jsonMap, ref string field, bool fromUI)
        {
            var doc = (TypedDoc)SerializationUtils.MakeNewObjectInstance(type);

            toDoc(doc, nameBinding.HasValue ? nameBinding.Value : NameBinding.ByCode, jsonMap, ref field, fromUI);
            return(doc);
        }
Example #5
0
 private void buildNode(ConfigSectionNode node, JsonDataMap map)
 {
     foreach (var kvp in map)
     {
         var cmap = kvp.Value as JsonDataMap;
         if (cmap != null)
         {
             buildNode(node.AddChildNode(kvp.Key), cmap);
         }
         else
         {
             node.AddAttributeNode(kvp.Key, kvp.Value);
         }
     }
 }
Example #6
0
        /// <summary>
        /// Converts JSONMap into typed data document of the requested type.
        /// The requested type must be derived from Azos.Data.TypedDoc.
        /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise.
        /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e.
        ///  it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries
        /// </summary>
        /// <param name="type">TypedDoc subtype to convert into</param>
        /// <param name="jsonMap">JSON data to convert into data doc</param>
        /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param>
        /// <param name="options">Used for backend name matching or null (any target)</param>
        public static TypedDoc ToDoc(Type type, JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null)
        {
            if (!typeof(TypedDoc).IsAssignableFrom(type) || jsonMap == null)
            {
                throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(type|jsonMap=null)");
            }
            var field = "";

            try
            {
                return(toTypedDoc(type, options, jsonMap, ref field, fromUI));
            }
            catch (Exception error)
            {
                throw new JSONDeserializationException("JSONReader.ToDoc(jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error);
            }
        }
Example #7
0
        /// <summary>
        /// Turns URL encoded content into JSONDataMap
        /// </summary>
        public static JsonDataMap FromURLEncodedString(string content, bool caseSensitive = false)
        {
            var result = new JsonDataMap(caseSensitive);

            if (content.IsNullOrWhiteSpace())
            {
                return(result);
            }

            int queryLen = content.Length;
            int idx      = 0;

            while (idx < queryLen)
            {
                int ampIdx = content.IndexOf('&', idx);
                int kvLen  = (ampIdx != -1) ? ampIdx - idx : queryLen - idx;

                if (kvLen < 1)
                {
                    idx = ampIdx + 1;
                    continue;
                }

                int eqIdx = content.IndexOf('=', idx, kvLen);
                if (eqIdx == -1)
                {
                    var key = Uri.UnescapeDataString(content.Substring(idx, kvLen).Replace('+', ' '));
                    result.Add(key, null);
                }
                else
                {
                    int keyLen = eqIdx - idx;
                    if (keyLen > 0)
                    {
                        var key = Uri.UnescapeDataString(content.Substring(idx, keyLen).Replace('+', ' '));
                        var val = Uri.UnescapeDataString(content.Substring(eqIdx + 1, kvLen - keyLen - 1).Replace('+', ' '));

                        result.Add(key, val);
                    }
                }

                idx += kvLen + 1;
            }

            return(result);
        }
Example #8
0
        /// <summary>
        /// Converts JSONMap into supplied row instance.
        /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise.
        /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e.
        ///  it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries
        /// </summary>
        /// <param name="doc">Data document instance to convert into</param>
        /// <param name="jsonMap">JSON data to convert into row</param>
        /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param>
        /// <param name="nameBinding">Used for backend name matching or null (any target)</param>
        public static void ToDoc(Doc doc, JsonDataMap jsonMap, bool fromUI = true, NameBinding?nameBinding = null)
        {
            if (doc == null || jsonMap == null)
            {
                throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(doc|jsonMap=null)");
            }
            var field = "";

            try
            {
                toDoc(doc, nameBinding.HasValue ? nameBinding.Value : NameBinding.ByCode, jsonMap, ref field, fromUI);
            }
            catch (Exception error)
            {
                throw new JSONDeserializationException("JSONReader.ToDoc(doc, jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error);
            }
        }
Example #9
0
        private static IJsonDataObject deserializeObject(object root)
        {
            if (root == null)
            {
                return(null);
            }

            var data = root as IJsonDataObject;

            if (data == null)
            {
                data = new JsonDataMap {
                    { "value", root }
                }
            }
            ;

            return(data);
        }
Example #10
0
        /// <summary>
        /// Appends contents of another JSONDataMap for keys that do not exist in this one or null.
        /// Only appends references, does not provide deep reference copy
        /// </summary>
        public JsonDataMap Append(JsonDataMap other, bool deep = false)
        {
            if (other == null)
            {
                return(this);
            }

            foreach (var kvp in other)
            {
                var here = this[kvp.Key];
                if (here == null)
                {
                    this[kvp.Key] = kvp.Value;
                }
                else
                if (deep && here is JsonDataMap)
                {
                    ((JsonDataMap)here).Append(kvp.Value as JsonDataMap, deep);
                }
            }

            return(this);
        }
Example #11
0
        private static void toDoc(Doc doc, DocReadOptions options, JsonDataMap jsonMap, ref string field, bool fromUI)
        {
            var amorph = doc as IAmorphousData;
            var schema = doc.Schema;

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

                //Multi-targeting for deserialization to TypedDoc from JSON
                Schema.FieldDef def;
                if (options.BindBy == DocReadOptions.By.CodeName)
                {
                    def = schema[field];
                }
                else
                {
                    def = schema.TryFindFieldByTargetedBackendName(options.TargetName, field);//what about case sensitive json name?
                }
                //No such field exists in a typed doc, try to put in amorphous data
                if (def == null)
                {
                    if (amorph != null)
                    {
                        if (amorph.AmorphousDataEnabled)
                        {
                            amorph.AmorphousData[mfld.Key] = fv;
                        }
                    }
                    continue;
                }

                if (fromUI && def.NonUI)
                {
                    continue;             //skip NonUI fields
                }
                //weed out NULLS here
                if (fv == null)
                {
                    doc.SetFieldValue(def, null);
                    continue;
                }

                //fv is NEVER NULL here
                var wasset = setOneField(doc, def, fv, fromUI, options); //<------------------- field assignment

                //try to put in amorphous data if could not be set in a field
                if (!wasset && amorph != null)
                {
                    if (amorph.AmorphousDataEnabled)
                    {
                        amorph.AmorphousData[mfld.Key] = fv;
                    }
                }
            }//foreach field in jsonMap

            //process FORM
            var form = doc as Form;

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

            if (amorph != null && amorph.AmorphousDataEnabled)
            {
                amorph.AfterLoad(options.TargetName ?? "json");
            }
        }
Example #12
0
 /// <summary>
 /// Generic version of ToDoc(Type...)/>
 /// </summary>
 /// <typeparam name="T">TypedDoc</typeparam>
 public static T ToDoc <T>(JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null) where T : TypedDoc
 {
     return(ToDoc(typeof(T), jsonMap, fromUI, options) as T);
 }
Example #13
0
 /// <summary>
 /// Deserializes into Rowset or Table from JSONDataMap, as serialized by RowsedBase.WriteAsJSON()
 /// </summary>
 public static RowsetBase ToRowset(JsonDataMap jsonMap, bool schemaOnly = false, bool readOnlySchema = false)
 {
     return(RowsetBase.FromJSON(jsonMap, schemaOnly, readOnlySchema));
 }
Example #14
0
 /// <summary>
 /// Generic version of ToDoc(Type, JSONDataMap, bool)/>
 /// </summary>
 /// <typeparam name="T">TypedDoc</typeparam>
 public static T ToDoc <T>(JsonDataMap jsonMap, bool fromUI = true, NameBinding?nameBinding = null) where T : TypedDoc
 {
     return(ToDoc(typeof(T), jsonMap, fromUI, nameBinding) as T);
 }