Files
Umbraco-CMS/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs

121 lines
5.3 KiB
C#
Raw Normal View History

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
/// <summary>
/// Gets the configuration as a typed object.
/// </summary>
2018-01-24 11:44:44 +01:00
public static TConfiguration ConfigurationAs<TConfiguration>(object obj)
{
if (obj == null) return default;
2018-01-24 11:44:44 +01:00
if (obj is TConfiguration configuration) return configuration;
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
}
}