From aed533e1ae6e851e41ccd60a1f161fbc4a9bf710 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 1 Mar 2023 09:29:59 -0700 Subject: [PATCH] refactor: rework config merge values --- .../Config/PortalConfigReader.cs | 146 ++++++++++++------ 1 file changed, 101 insertions(+), 45 deletions(-) diff --git a/Pepperdash Core/Pepperdash Core/Config/PortalConfigReader.cs b/Pepperdash Core/Pepperdash Core/Config/PortalConfigReader.cs index 0e6c6a9..ad3b20f 100644 --- a/Pepperdash Core/Pepperdash Core/Config/PortalConfigReader.cs +++ b/Pepperdash Core/Pepperdash Core/Config/PortalConfigReader.cs @@ -34,25 +34,30 @@ namespace PepperDash.Core.Config using (StreamReader fs = new StreamReader(filePath)) { var jsonObj = JObject.Parse(fs.ReadToEnd()); - if(jsonObj["template"] != null && jsonObj["system"] != null) + + if (jsonObj["template"] == null || jsonObj["system"] == null) + { + Debug.Console(2, "Template and/or System objects are null"); + return; + } + + // it's a double-config, merge it. + Debug.Console(2, "Merging template & system configurations"); + + var merged = MergeConfigs(jsonObj); + + if (jsonObj["system_url"] != null) { - // it's a double-config, merge it. - Debug.Console(2, "Merging template & system configurations"); - - var merged = MergeConfigs(jsonObj); - if (jsonObj["system_url"] != null) - { - merged["systemUrl"] = jsonObj["system_url"].Value(); - } - - if (jsonObj["template_url"] != null) - { - merged["templateUrl"] = jsonObj["template_url"].Value(); - } - - jsonObj = merged; + merged["systemUrl"] = jsonObj["system_url"].Value(); } + if (jsonObj["template_url"] != null) + { + merged["templateUrl"] = jsonObj["template_url"].Value(); + } + + jsonObj = merged; + using (StreamWriter fw = new StreamWriter(savePath)) { fw.Write(jsonObj.ToString(Formatting.Indented)); @@ -74,35 +79,60 @@ namespace PepperDash.Core.Config /// public static JObject MergeConfigs(JObject doubleConfig) { + Debug.Console(2, "Merging template & system configurations)"); + var system = JObject.FromObject(doubleConfig["system"]); var template = JObject.FromObject(doubleConfig["template"]); var merged = new JObject(); // Put together top-level objects - if (system["info"] != null) - merged.Add("info", Merge(template["info"], system["info"], "info")); - else - merged.Add("info", template["info"]); + if (system["info"] != null) + merged.Add("info", Merge(template["info"], system["info"], "info")); + else + { + merged.Add("info", template["info"]); + } + + Debug.Console(2, "Merging template & system devices"); merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray, system["devices"] as JArray, "uid", "devices")); - if (system["rooms"] == null) - merged.Add("rooms", template["rooms"]); - else - merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray, - system["rooms"] as JArray, "key", "rooms")); + if (system["rooms"] == null) + { + Debug.Console(2, "Using Template Rooms"); + merged.Add("rooms", template["rooms"]); + } + else + { + Debug.Console(2, "Merging template & system rooms"); + merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray, + system["rooms"] as JArray, "key", "rooms")); + } - if (system["sourceLists"] == null) - merged.Add("sourceLists", template["sourceLists"]); - else - merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists")); + if (system["sourceLists"] == null) + { + Debug.Console(2, "Using Template source lists"); - if (system["destinationLists"] == null) - merged.Add("destinationLists", template["destinationLists"]); - else - merged.Add("destinationLists", - Merge(template["destinationLists"], system["destinationLists"], "destinationLists")); + merged.Add("sourceLists", template["sourceLists"]); + } + else + { + Debug.Console(2, "Merging template & system source lists"); + merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists")); + } + + if (system["destinationLists"] == null) + { + Debug.Console(2, "Using Template destination lists"); + merged.Add("destinationLists", template["destinationLists"]); + } + else + { + Debug.Console(2, "Merging template & system destination lists"); + merged.Add("destinationLists", + Merge(template["destinationLists"], system["destinationLists"], "destinationLists")); + } // Template tie lines take precedence. Config tool doesn't do them at system // level anyway... @@ -134,19 +164,25 @@ namespace PepperDash.Core.Config /// static JArray MergeArraysOnTopLevelProperty(JArray template, JArray system, string propertyName, string path) { + Debug.Console(2, "Merging arrays using property {0} as match value. Writing at path {1}", propertyName, path); + var result = new JArray(); + if (system == null || system.Count == 0) // If the system array is null or empty, return the template array { + Debug.Console(2, "Return template array, system array not found"); return template; } if (template == null) { + Debug.Console(2, "Returnign empty array. Template array is null"); return result; } if (system[0]["key"] == null) // If the first item in the system array has no key, overwrite the template array { // with the system array + Debug.Console(2, "Overwriting template with system array"); return system; } @@ -158,11 +194,17 @@ namespace PepperDash.Core.Config var objectToAdd = templateObject; - if (systemObject != null) + if (systemObject == null) { - objectToAdd = Merge(templateObject, systemObject, string.Format("{0}[{1}].", path, i));// Merge(JObject.FromObject(a1Dev), JObject.FromObject(a2Match)); + Debug.Console(2, "Using template object"); + result.Add(objectToAdd); + continue; } + Debug.Console(2, "Merging template & system object"); + + objectToAdd = Merge(templateObject, systemObject, string.Format("{0}[{1}].", path, i));// Merge(JObject.FromObject(a1Dev), JObject.FromObject(a2Match)); + result.Add(objectToAdd); } @@ -179,22 +221,26 @@ namespace PepperDash.Core.Config } /// - /// Merge o2 onto o1 + /// Merge child onto parent /// - /// - /// + /// + /// /// static JObject Merge(JObject parent, JObject child, string path) { foreach (var childProperty in child) - { + { var childPropertyKey = childProperty.Key; var parentValue = parent[childPropertyKey]; var childValue = child[childPropertyKey]; - // if the property doesn't exist on o1, then add it. + Debug.Console(2, "Checking property {0} on child. Parent: {1} Child: {2}", childProperty.Key, parentValue, childValue); + + // if the property doesn't exist on parent, then add it. if (parentValue == null) { + Debug.Console(2, "Property {0} doesn't exist on parent. Adding to parent", childPropertyKey); + parent.Add(childPropertyKey, childValue); continue; } @@ -202,21 +248,31 @@ namespace PepperDash.Core.Config // Drill down var propPath = String.Format("{0}.{1}", path, childPropertyKey); + try { if (parentValue is JArray && childValue is JArray) - { - parentValue.Replace(MergeArraysOnTopLevelProperty(parentValue as JArray, childValue as JArray, "key", propPath)); + { + Debug.Console(2, "Value is array. Merging array"); + + // assuming keyed array here...might not be a valid assumption... + var mergedArray = MergeArraysOnTopLevelProperty(parentValue as JArray, childValue as JArray, "key", propPath); + + parentValue.Replace(mergedArray); continue; } if (childProperty.Value.HasValues && parentValue.HasValues) { - parentValue.Replace(Merge(parentValue, childValue, propPath)); + Debug.Console(2, "Value is object. Merging objects"); + + var mergedValue = Merge(parentValue, childValue, propPath); + parentValue.Replace(mergedValue); continue; } - + + Debug.Console(2, "Replacing parent value with child value"); parentValue.Replace(childProperty.Value); } catch (Exception e)