using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; namespace Umbraco.Core.Manifest { /// /// Used to convert a property editor manifest to a property editor object /// internal class PropertyEditorConverter : JsonCreationConverter { protected override PropertyEditor Create(Type objectType, JObject jObject) { return new PropertyEditor(); } protected override void Deserialize(JObject jObject, PropertyEditor target, JsonSerializer serializer) { if (jObject["editor"] != null) { //since it's a manifest editor, we need to create it's instance. //we need to specify the view value for the editor here otherwise we'll get an exception. target.ManifestDefinedPropertyValueEditor = new PropertyValueEditor { View = jObject["editor"]["view"].ToString() }; //the manifest JSON is a simplified json for the validators which is actually a dictionary, however, the //c# model requires an array of validators not a dictionary so we need to change the json to an array //to deserialize properly. JArray converted; if (TryConvertValidatorDictionaryToArray(jObject["editor"]["validation"] as JObject, out converted)) { jObject["editor"]["validation"] = converted; } } if (jObject["prevalues"] != null) { target.ManifestDefinedPreValueEditor = new PreValueEditor(); //the manifest JSON is a simplified json for the validators which is actually a dictionary, however, the //c# model requires an array of validators not a dictionary so we need to change the json to an array //to deserialize properly. var fields = jObject["prevalues"]["fields"] as JArray; if (fields != null) { foreach (var f in fields) { JArray converted; if (TryConvertValidatorDictionaryToArray(f["validation"] as JObject, out converted)) { f["validation"] = converted; } } } } base.Deserialize(jObject, target, serializer); } private bool TryConvertValidatorDictionaryToArray(JObject validation, out JArray result) { if (validation == null) { result = null; return false; } result = new JArray(); foreach (var entry in validation) { //in a special case if the value is simply 'true' (boolean) this just indicates that the // validator is enabled, the config should just be empty. var formattedItem = JObject.FromObject(new { type = entry.Key, config = entry.Value }); if (entry.Value.Type == JTokenType.Boolean) { formattedItem["config"] = ""; } result.Add(formattedItem); } return true; } } }