From fa174ba15a20dbb572b1e881affe230b89c7b6f0 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Thu, 24 Apr 2014 22:29:58 -0600 Subject: [PATCH 1/4] Move deserialization methods to a Helper class --- .../Archetype.Umbraco.csproj | 1 + .../Extensions/ArchetypeHelper.cs | 106 ++++++++++++++++++ .../ArchetypeValueConverter.cs | 84 +------------- 3 files changed, 111 insertions(+), 80 deletions(-) create mode 100644 app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs diff --git a/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj b/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj index e86b51e..f821384 100644 --- a/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj +++ b/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj @@ -231,6 +231,7 @@ + diff --git a/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs new file mode 100644 index 0000000..6d5a0f8 --- /dev/null +++ b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mime; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http.ModelBinding; +using Archetype.Umbraco.Models; +using Newtonsoft.Json; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; + +namespace Archetype.Umbraco.Extensions +{ + public class ArchetypeHelper + { + + protected JsonSerializerSettings _jsonSettings; + protected ApplicationContext _app; + + public ArchetypeHelper() + { + var dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver(); + dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; + + _jsonSettings = new JsonSerializerSettings { ContractResolver = dcr }; + _app = ApplicationContext.Current; + } + + public Models.Archetype DeserializeJsonToArchetype(string sourceJson, int dataTypeId) + { + try + { + var archetype = JsonConvert.DeserializeObject(sourceJson, _jsonSettings); + + try + { + // Get list of configured properties and their types and map them to the deserialized archetype model + var preValue = GetArchetypePreValueFromDataTypeId(dataTypeId); + foreach (var fieldset in preValue.Fieldsets) + { + var fieldsetAlias = fieldset.Alias; + foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) + { + foreach (var property in fieldset.Properties) + { + var propertyAlias = property.Alias; + foreach ( + var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) + { + propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; + propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; + } + } + } + } + } + catch (Exception ex) + { + } + + return archetype; + } + catch + { + return new Models.Archetype(); + } + } + + private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId) + { + return _app.ApplicationCache.RuntimeCache.GetCacheItem( + Constants.CacheKey_PreValueFromDataTypeId + dataTypeId, + () => + { + var preValues = _app.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId); + + var configJson = preValues.IsDictionaryBased + ? preValues.PreValuesAsDictionary[Constants.PreValueAlias].Value + : preValues.PreValuesAsArray.First().Value; + + var config = JsonConvert.DeserializeObject(configJson, _jsonSettings); + + foreach (var fieldset in config.Fieldsets) + { + foreach (var property in fieldset.Properties) + { + property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; + } + } + + return config; + + }) as ArchetypePreValue; + } + + private IDataTypeDefinition GetDataTypeByGuid(Guid guid) + { + return (IDataTypeDefinition) ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( + Constants.CacheKey_DataTypeByGuid + guid, + () => _app.Services.DataTypeService.GetDataTypeDefinitionById(guid)); + } + + } +} diff --git a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs index 3604acb..2834b36 100644 --- a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs +++ b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs @@ -16,15 +16,6 @@ namespace Archetype.Umbraco.PropertyConverters [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] public class ArchetypeValueConverter : PropertyValueConverterBase { - protected JsonSerializerSettings _jsonSettings; - - public ArchetypeValueConverter() - { - var dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver(); - dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; - - _jsonSettings = new JsonSerializerSettings { ContractResolver = dcr }; - } public ServiceContext Services { @@ -46,79 +37,12 @@ namespace Archetype.Umbraco.PropertyConverters var sourceString = source.ToString(); if (!sourceString.DetectIsJson()) - return defaultValue; + return defaultValue; + + var archetype = new ArchetypeHelper().DeserializeJsonToArchetype(source.ToString(), propertyType.DataTypeId); - try - { - // Deserialize value to archetype model - var archetype = JsonConvert.DeserializeObject(sourceString, _jsonSettings); - - try - { - // Get list of configured properties and their types and map them to the deserialized archetype model - var preValue = GetArchetypePreValueFromDataTypeId(propertyType.DataTypeId); - foreach (var fieldset in preValue.Fieldsets) - { - var fieldsetAlias = fieldset.Alias; - foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) - { - foreach (var property in fieldset.Properties) - { - var propertyAlias = property.Alias; - foreach (var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) - { - propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; - propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; - } - } - } - } - } - catch (Exception ex) - { - } - - return archetype; - } - catch (Exception ex) - { - } - - return defaultValue; + return archetype; } - private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId) - { - return ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( - Constants.CacheKey_PreValueFromDataTypeId + dataTypeId, - () => - { - var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId); - - var configJson = preValues.IsDictionaryBased - ? preValues.PreValuesAsDictionary[Constants.PreValueAlias].Value - : preValues.PreValuesAsArray.First().Value; - - var config = JsonConvert.DeserializeObject(configJson, _jsonSettings); - - foreach (var fieldset in config.Fieldsets) - { - foreach (var property in fieldset.Properties) - { - property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; - } - } - - return config; - - }) as ArchetypePreValue; - } - - private IDataTypeDefinition GetDataTypeByGuid(Guid guid) - { - return (IDataTypeDefinition) ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( - Constants.CacheKey_DataTypeByGuid + guid, - () => Services.DataTypeService.GetDataTypeDefinitionById(guid)); - } } } From f52bbc2d0aff43bb0b1a6eaee02be8d6f53d37e2 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Thu, 24 Apr 2014 22:39:22 -0600 Subject: [PATCH 2/4] Extract methods to retrieve metadata not stored in the model --- .../Extensions/ArchetypeHelper.cs | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs index 6d5a0f8..8484202 100644 --- a/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs +++ b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs @@ -38,23 +38,7 @@ namespace Archetype.Umbraco.Extensions { // Get list of configured properties and their types and map them to the deserialized archetype model var preValue = GetArchetypePreValueFromDataTypeId(dataTypeId); - foreach (var fieldset in preValue.Fieldsets) - { - var fieldsetAlias = fieldset.Alias; - foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) - { - foreach (var property in fieldset.Properties) - { - var propertyAlias = property.Alias; - foreach ( - var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) - { - propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; - propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; - } - } - } - } + RetrieveAdditionalProperties(ref archetype, preValue); } catch (Exception ex) { @@ -81,14 +65,7 @@ namespace Archetype.Umbraco.Extensions : preValues.PreValuesAsArray.First().Value; var config = JsonConvert.DeserializeObject(configJson, _jsonSettings); - - foreach (var fieldset in config.Fieldsets) - { - foreach (var property in fieldset.Properties) - { - property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; - } - } + RetrieveAdditionalProperties(ref config); return config; @@ -102,5 +79,46 @@ namespace Archetype.Umbraco.Extensions () => _app.Services.DataTypeService.GetDataTypeDefinitionById(guid)); } + /// + /// Retrieves additional metadata that isn't available on the stored model of an Archetype + /// + /// The Archetype to add the additional metadata to + /// The configuration of the Archetype + private void RetrieveAdditionalProperties(ref Models.Archetype archetype, ArchetypePreValue preValue) + { + foreach (var fieldset in preValue.Fieldsets) + { + var fieldsetAlias = fieldset.Alias; + foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) + { + foreach (var property in fieldset.Properties) + { + var propertyAlias = property.Alias; + foreach ( var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) + { + propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; + propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; + } + } + } + } + } + + /// + /// Retrieves additional metadata that isn't available on the stored model of an ArchetypePreValue + /// + /// The Archetype to add the additional metadata to + /// The configuration of the Archetype + private void RetrieveAdditionalProperties(ref Models.ArchetypePreValue preValue) + { + foreach (var fieldset in preValue.Fieldsets) + { + foreach (var property in fieldset.Properties) + { + property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; + } + } + } + } } From 7a29683008e3fe4db77450b79d0127dab5ffd797 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Thu, 24 Apr 2014 22:39:22 -0600 Subject: [PATCH 3/4] Mark helper methods internal for now --- .../Extensions/ArchetypeHelper.cs | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs index 6d5a0f8..29b203d 100644 --- a/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs +++ b/app/Umbraco/Umbraco.Archetype/Extensions/ArchetypeHelper.cs @@ -19,7 +19,7 @@ namespace Archetype.Umbraco.Extensions protected JsonSerializerSettings _jsonSettings; protected ApplicationContext _app; - public ArchetypeHelper() + internal ArchetypeHelper() { var dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver(); dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; @@ -28,7 +28,7 @@ namespace Archetype.Umbraco.Extensions _app = ApplicationContext.Current; } - public Models.Archetype DeserializeJsonToArchetype(string sourceJson, int dataTypeId) + internal Models.Archetype DeserializeJsonToArchetype(string sourceJson, int dataTypeId) { try { @@ -38,23 +38,7 @@ namespace Archetype.Umbraco.Extensions { // Get list of configured properties and their types and map them to the deserialized archetype model var preValue = GetArchetypePreValueFromDataTypeId(dataTypeId); - foreach (var fieldset in preValue.Fieldsets) - { - var fieldsetAlias = fieldset.Alias; - foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) - { - foreach (var property in fieldset.Properties) - { - var propertyAlias = property.Alias; - foreach ( - var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) - { - propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; - propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; - } - } - } - } + RetrieveAdditionalProperties(ref archetype, preValue); } catch (Exception ex) { @@ -81,14 +65,7 @@ namespace Archetype.Umbraco.Extensions : preValues.PreValuesAsArray.First().Value; var config = JsonConvert.DeserializeObject(configJson, _jsonSettings); - - foreach (var fieldset in config.Fieldsets) - { - foreach (var property in fieldset.Properties) - { - property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; - } - } + RetrieveAdditionalProperties(ref config); return config; @@ -102,5 +79,46 @@ namespace Archetype.Umbraco.Extensions () => _app.Services.DataTypeService.GetDataTypeDefinitionById(guid)); } + /// + /// Retrieves additional metadata that isn't available on the stored model of an Archetype + /// + /// The Archetype to add the additional metadata to + /// The configuration of the Archetype + private void RetrieveAdditionalProperties(ref Models.Archetype archetype, ArchetypePreValue preValue) + { + foreach (var fieldset in preValue.Fieldsets) + { + var fieldsetAlias = fieldset.Alias; + foreach (var fieldsetInst in archetype.Fieldsets.Where(x => x.Alias == fieldsetAlias)) + { + foreach (var property in fieldset.Properties) + { + var propertyAlias = property.Alias; + foreach ( var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) + { + propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid).Id; + propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; + } + } + } + } + } + + /// + /// Retrieves additional metadata that isn't available on the stored model of an ArchetypePreValue + /// + /// The Archetype to add the additional metadata to + /// The configuration of the Archetype + private void RetrieveAdditionalProperties(ref Models.ArchetypePreValue preValue) + { + foreach (var fieldset in preValue.Fieldsets) + { + foreach (var property in fieldset.Properties) + { + property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid).PropertyEditorAlias; + } + } + } + } } From ea017fa6cdb6baa8650cacfdb4eb89f4c97979b8 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Thu, 24 Apr 2014 23:11:47 -0600 Subject: [PATCH 4/4] Make tests pass Quick null check for PublishedPropertyType - we can't create a dummy one from a test due to some internal Umbraco dependencies, and we can't mock it as the relevant properties aren't virtual, so just adding a quick null check for now. --- .../PropertyConverters/ArchetypeValueConverter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs index 2834b36..f38a029 100644 --- a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs +++ b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs @@ -39,8 +39,9 @@ namespace Archetype.Umbraco.PropertyConverters if (!sourceString.DetectIsJson()) return defaultValue; - var archetype = new ArchetypeHelper().DeserializeJsonToArchetype(source.ToString(), propertyType.DataTypeId); - + var archetype = new ArchetypeHelper().DeserializeJsonToArchetype(source.ToString(), + (propertyType != null ? propertyType.DataTypeId : -1)); + return archetype; }