2018-01-24 11:44:44 +01:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using Newtonsoft.Json ;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Represents a data type configuration editor.
/// </summary>
public class ConfigurationEditor
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationEditor"/> class.
/// </summary>
public ConfigurationEditor ( )
{
Fields = new List < ConfigurationField > ( ) ;
}
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationEditor"/> class.
/// </summary>
protected ConfigurationEditor ( List < ConfigurationField > fields )
{
Fields = fields ;
}
/// <summary>
/// Gets the fields.
/// </summary>
[JsonProperty("fields")]
public List < ConfigurationField > Fields { get ; }
/// <summary>
2018-02-05 17:48:54 +01:00
/// Gets a field by property name.
2018-01-24 11:44:44 +01:00
/// </summary>
2018-02-05 17:48:54 +01:00
/// <remarks>Can be used in constructors to add infos to a field that has been defined
/// by a property marked with the <see cref="ConfigurationFieldAttribute"/>.</remarks>
protected ConfigurationField Field ( string name )
= > Fields . First ( x = > x . PropertyName = = name ) ;
2018-01-24 11:44:44 +01:00
2018-01-29 19:23:25 +01:00
/// <summary>
/// Gets the configuration as a typed object.
/// </summary>
2018-01-24 11:44:44 +01:00
public static TConfiguration ConfigurationAs < TConfiguration > ( object obj )
{
2018-01-29 19:23:25 +01:00
if ( obj = = null ) return default ;
2018-01-24 11:44:44 +01:00
if ( obj is TConfiguration configuration ) return configuration ;
2018-01-29 19:23:25 +01:00
throw new InvalidCastException ( $"Cannot cast configuration of type {obj.GetType().Name} to {typeof(TConfiguration).Name}." ) ;
2018-01-24 11:44:44 +01:00
}
2018-02-05 17:48:54 +01:00
/// <summary>
/// Gets the default configuration.
/// </summary>
/// <remarks>The default configuration is used to initialize new datatypes.</remarks>
public virtual IDictionary < string , object > DefaultConfiguration = > new Dictionary < string , object > ( ) ;
2018-01-24 11:44:44 +01:00
// notes
2018-02-05 17:48:54 +01:00
// ToConfigurationEditor returns a dictionary, and FromConfigurationEditor accepts a dictionary.
2018-01-24 11:44:44 +01:00
// this is due to the way our front-end editors work, see DataTypeController.PostSave
// and DataTypeConfigurationFieldDisplayResolver - we are not going to change it now.
/// <summary>
2018-02-05 17:48:54 +01:00
/// Converts the serialized database value into the actual configuration object.
2018-01-24 11:44:44 +01:00
/// </summary>
2018-02-05 17:48:54 +01:00
/// <remarks>Converting the configuration object to the serialized database value is
/// achieved by simply serializing the configuration.</remarks>
public virtual object FromDatabase ( string configurationJson )
= > string . IsNullOrWhiteSpace ( configurationJson )
? new Dictionary < string , object > ( )
: JsonConvert . DeserializeObject < Dictionary < string , object > > ( configurationJson ) ;
/// <summary>
/// Converts the values posted by the configuration editor into the actual configuration object.
/// </summary>
/// <param name="editorValues">The values posted by the configuration editor.</param>
2018-01-24 11:44:44 +01:00
/// <param name="configuration">The current configuration object.</param>
2018-02-05 17:48:54 +01:00
public virtual object FromConfigurationEditor ( Dictionary < string , object > editorValues , object configuration )
2018-01-24 11:44:44 +01:00
{
// by default, return the posted dictionary
2018-02-05 17:48:54 +01:00
// but only keep entries that have a non-null/empty value
// rest will fall back to default during ToConfigurationEditor()
var keys = editorValues . Where ( x = > x . Value = = null | | x . Value is string stringValue & & string . IsNullOrWhiteSpace ( stringValue ) ) . Select ( x = > x . Key ) ;
foreach ( var key in keys ) editorValues . Remove ( key ) ;
return editorValues ;
2018-01-24 11:44:44 +01:00
}
/// <summary>
2018-02-05 17:48:54 +01:00
/// Converts the configuration object to values for the configuration editor.
2018-01-24 11:44:44 +01:00
/// </summary>
/// <param name="configuration">The configuration.</param>
2018-02-05 17:48:54 +01:00
public virtual Dictionary < string , object > ToConfigurationEditor ( object configuration )
2018-01-24 11:44:44 +01:00
{
// editors that do not override ToEditor/FromEditor have their configuration
// as a dictionary of <string, object> and, by default, we merge their default
// configuration with their current configuration
2018-01-26 17:55:20 +01:00
if ( configuration = = null )
configuration = new Dictionary < string , object > ( ) ;
2018-01-24 11:44:44 +01:00
if ( ! ( configuration is IDictionary < string , object > c ) )
throw new ArgumentException ( $"Expecting a {typeof(Dictionary<string,object>).Name} instance but got {configuration.GetType().Name}." , nameof ( configuration ) ) ;
// clone the default configuration, and apply the current configuration values
2018-02-05 17:48:54 +01:00
var d = new Dictionary < string , object > ( DefaultConfiguration ) ;
2018-01-24 11:44:44 +01:00
foreach ( ( var key , var value ) in c )
2018-02-05 17:48:54 +01:00
d [ key ] = value ;
return d ;
2018-01-24 11:44:44 +01:00
}
2018-02-05 17:48:54 +01:00
/// <summary>
/// Converts the configuration object to values for the value editror.
/// </summary>
/// <param name="configuration">The configuration.</param>
public virtual Dictionary < string , object > ToValueEditor ( object configuration )
= > ToConfigurationEditor ( configuration ) ;
2018-01-24 11:44:44 +01:00
}
}