Removing PropertyValues-method from Content and Media and making it an extension method instead.

Adding the PropertyEditor model as internal to slowly adopt it using a slightly different model approach then in v5.
Minor refactoring of IEntity/Entity.
This commit is contained in:
Morten@Thinkpad-X220
2012-10-05 11:03:08 -02:00
parent fe7d57ce12
commit dc1689bdf2
20 changed files with 473 additions and 102 deletions
-40
View File
@@ -278,46 +278,6 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Set property values by alias with an annonymous object
/// </summary>
[IgnoreDataMember]
public object PropertyValues
{
set
{
if (value == null)
throw new Exception("No properties has been passed in");
var propertyInfos = value.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//Check if a PropertyType with alias exists thus being a valid property
var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (propertyType == null)
throw new Exception(
string.Format(
"The property alias {0} is not valid, because no PropertyType with this alias exists",
propertyInfo.Name));
//Check if a Property with the alias already exists in the collection thus being updated or inserted
var item = Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (item != null)
{
item.Value = propertyInfo.GetValue(value, null);
//Update item with newly added value
Properties.Add(item);
}
else
{
//Create new Property to add to collection
var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
Properties.Add(property);
}
}
}
}
/// <summary>
/// Collection of properties, which make up all the data available for this Content object
/// </summary>
@@ -0,0 +1,44 @@
using System;
using System.Linq;
namespace Umbraco.Core.Models
{
public static class ContentExtensions
{
/// <summary>
/// Set property values by alias with an annonymous object
/// </summary>
public static void PropertyValues(this IContent content, object value)
{
if (value == null)
throw new Exception("No properties has been passed in");
var propertyInfos = value.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//Check if a PropertyType with alias exists thus being a valid property
var propertyType = content.PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (propertyType == null)
throw new Exception(
string.Format(
"The property alias {0} is not valid, because no PropertyType with this alias exists",
propertyInfo.Name));
//Check if a Property with the alias already exists in the collection thus being updated or inserted
var item = content.Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (item != null)
{
item.Value = propertyInfo.GetValue(value, null);
//Update item with newly added value
content.Properties.Add(item);
}
else
{
//Create new Property to add to collection
var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
content.Properties.Add(property);
}
}
}
}
}
+6 -6
View File
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public abstract class Entity : IEntity
public abstract class Entity : IEntity, ICanBeDirty
{
private bool _hasIdentity;
private int? _hash;
@@ -59,13 +59,13 @@ namespace Umbraco.Core.Models.EntityBase
/// Gets or sets the Created Date
/// </summary>
[DataMember]
public DateTime CreatedDate { get; set; }
public DateTime CreateDate { get; set; }
/// <summary>
/// Gets or sets the Modified Date
/// </summary>
[DataMember]
public DateTime ModifiedDate { get; set; }
public DateTime UpdateDate { get; set; }
/// <summary>
/// Property changed event
@@ -91,8 +91,8 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
internal virtual void AddingEntity()
{
CreatedDate = DateTime.UtcNow;
ModifiedDate = DateTime.UtcNow;
CreateDate = DateTime.UtcNow;
UpdateDate = DateTime.UtcNow;
}
/// <summary>
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
internal virtual void UpdatingEntity()
{
ModifiedDate = DateTime.UtcNow;
UpdateDate = DateTime.UtcNow;
}
/// <summary>
@@ -29,13 +29,13 @@ namespace Umbraco.Core.Models.EntityBase
/// Gets or sets the Created Date
/// </summary>
[DataMember]
DateTime CreatedDate { get; set; }
DateTime CreateDate { get; set; }
/// <summary>
/// Gets or sets the Modified Date
/// </summary>
[DataMember]
DateTime ModifiedDate { get; set; }
DateTime UpdateDate { get; set; }
/// <summary>
/// Indicates whether the current entity has an identity, eg. Id.
-6
View File
@@ -74,12 +74,6 @@ namespace Umbraco.Core.Models
/// <remarks>PropertyTypes are kind of lazy loaded as part of the object graph</remarks>
IEnumerable<PropertyType> PropertyTypes { get; }
/// <summary>
/// Set property values by alias with an annonymous object
/// </summary>
[IgnoreDataMember]
object PropertyValues { set; }
/// <summary>
/// Indicates whether the content object has a property with the supplied alias
/// </summary>
-40
View File
@@ -185,46 +185,6 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Set property values by alias with an annonymous object
/// </summary>
[IgnoreDataMember]
public object PropertyValues
{
set
{
if (value == null)
throw new Exception("No properties has been passed in");
var propertyInfos = value.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//Check if a PropertyType with alias exists thus being a valid property
var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (propertyType == null)
throw new Exception(
string.Format(
"The property alias {0} is not valid, because no PropertyType with this alias exists",
propertyInfo.Name));
//Check if a Property with the alias already exists in the collection thus being updated or inserted
var item = Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name);
if (item != null)
{
item.Value = propertyInfo.GetValue(value, null);
//Update item with newly added value
Properties.Add(item);
}
else
{
//Create new Property to add to collection
var property = propertyType.CreatePropertyFromValue(propertyInfo.GetValue(value, null));
Properties.Add(property);
}
}
}
}
/// <summary>
/// List of properties, which make up all the data available for this Media object
/// </summary>
+1 -1
View File
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class Relation : Entity
{
//NOTE: The datetime column from umbracoRelation is set on CreatedDate on the Entity
//NOTE: The datetime column from umbracoRelation is set on CreateDate on the Entity
private int _parentId;
private int _childId;
private RelationType _relationType;
@@ -31,8 +31,8 @@ namespace Umbraco.Core.Persistence.Factories
SortOrder = documentDto.ContentVersionDto.ContentDto.NodeDto.SortOrder,
Trashed = documentDto.ContentVersionDto.ContentDto.NodeDto.Trashed,
Published = documentDto.Published,
CreatedDate = documentDto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
ModifiedDate = documentDto.ContentVersionDto.VersionDate,
CreateDate = documentDto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
UpdateDate = documentDto.ContentVersionDto.VersionDate,
ExpireDate = documentDto.ExpiresDate,
ReleaseDate = documentDto.ReleaseDate,
Version = documentDto.ContentVersionDto.VersionId,
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Persistence.Factories
{
var nodeDto = new NodeDto
{
CreateDate = entity.CreatedDate,
CreateDate = entity.CreateDate,
NodeId = entity.Id,
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
NodeObjectType = new Guid(nodeObjectType),
@@ -64,7 +64,7 @@ namespace Umbraco.Core.Persistence.Factories
{
var nodeDto = new NodeDto
{
CreateDate = entity.CreatedDate,
CreateDate = entity.CreateDate,
NodeId = entity.Id,
Level = short.Parse(level.ToString(CultureInfo.InvariantCulture)),
NodeObjectType = new Guid(nodeObjectType),
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.Factories
var contentVersionDto = new ContentVersionDto
{
NodeId = entity.Id,
VersionDate = entity.ModifiedDate,
VersionDate = entity.UpdateDate,
VersionId = entity.Version
};
return contentVersionDto;
@@ -118,7 +118,7 @@ namespace Umbraco.Core.Persistence.Factories
Published = entity.Published,
ReleaseDate = entity.ReleaseDate,
Text = entity.Name,
UpdateDate = entity.ModifiedDate,
UpdateDate = entity.UpdateDate,
UserId = entity.UserId,
VersionId = entity.Version
};
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Persistence.Mappers
case "Key":
columnName = "[umbracoNode].[uniqueID]";
return true;
case "CreatedDate":
case "CreateDate":
columnName = "[umbracoNode].[createDate]";
return true;
case "Name":
@@ -0,0 +1,48 @@
using System;
namespace Umbraco.Core.PropertyEditors.Attributes
{
/// <summary>
/// Defines a PropertyEditor
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
internal sealed class PropertyEditorAttribute : Attribute
{
public PropertyEditorAttribute(string id, string alias, string name)
{
Mandate.ParameterNotNullOrEmpty(id, "id");
Mandate.ParameterNotNullOrEmpty(alias, "alias");
Mandate.ParameterNotNullOrEmpty(name, "name");
Id = Guid.Parse(id);
Alias = alias;
Name = name;
IsContentPropertyEditor = true;
}
public Guid Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the alias.
/// </summary>
/// <value>The alias.</value>
public string Alias { get; set; }
/// <summary>
/// Flag determining if this property editor is used to edit content
/// </summary>
public bool IsContentPropertyEditor { get; set; }
/// <summary>
/// Flag determining if this property editor is used to edit parameters
/// </summary>
public bool IsParameterEditor { get; set; }
}
}
@@ -0,0 +1,22 @@
using System;
namespace Umbraco.Core.PropertyEditors.Attributes
{
/// <summary>
/// Attribute determining whether or not to hide/show the label of a property
/// </summary>
/// <remarks>
/// This directly affects the meta data property: HideSurroundingHtml
/// </remarks>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal class ShowLabelAttribute : Attribute
{
public ShowLabelAttribute(bool show)
{
ShowLabel = show;
}
public bool ShowLabel { get; private set; }
}
}
@@ -0,0 +1,13 @@
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// A class representing a blank, null or empty pre-value editor.
/// </summary>
/// <remarks>
/// This class can be used for Property Editors who do not define a Pre value editor
/// </remarks>
internal class BlankPreValueModel : PreValueModel
{
}
}
@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
namespace Umbraco.Core.PropertyEditors
{
internal abstract class EditorModel<TValueModel> where TValueModel : IValueModel, new()
{
protected EditorModel()
{
// Set the UI Elements collection to an empty list
//UIElements = new List<UIElement>();
}
[ReadOnly(true)]
public virtual bool ShowUmbracoLabel
{
get { return true; }
}
/// <summary>
/// Gets a list of UI Elements for the property editor.
/// </summary>
//[ScaffoldColumn(false)]
//public virtual IList<UIElement> UIElements { get; protected internal set; }
private ModelMetadata _modelMetadata;
/// <summary>
/// Returns the meta data for the current editor model
/// </summary>
protected internal ModelMetadata MetaData
{
get
{
return _modelMetadata ?? (_modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => this, GetType()));
}
}
/// <summary>
/// Returns the serialized value for the PropertyEditor
/// </summary>
/// <returns></returns>
public virtual IDictionary<string, object> GetSerializedValue()
{
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
var d = new Dictionary<string, object>();
foreach (var p in editableProps)
{
//by default, we will not support complex modelled properties, developers will need to override
//the GetSerializedValue method if they need support for this.
if (p.IsComplexType)
{
//TODO: We should magically support this
throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
}
d.Add(p.PropertyName, p.Model);
}
return d;
}
public virtual void SetModelValues(IDictionary<string, object> serializedVal)
{
if (serializedVal == null || serializedVal.Count == 0)
{
return;
}
var modelProperties = GetType().GetProperties();
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
foreach (var i in serializedVal)
{
if (i.Value == null)
continue;
//get the property with the name
var prop = editableProps.Where(x => x.PropertyName == i.Key).SingleOrDefault();
if (prop != null)
{
//set the property value
var toConverter = TypeDescriptor.GetConverter(prop.ModelType);
if (toConverter != null)
{
//get the model property for this property meta data to set its value
var propInfo = modelProperties.Where(x => x.Name == prop.PropertyName).Single();
object convertedVal;
//if value is already of the same type, just use the current value, otherwise try and convert it
if (i.Value.GetType() == propInfo.PropertyType)
{
convertedVal = i.Value;
}
else
{
try
{
convertedVal = toConverter.ConvertFrom(i.Value);
}
catch (NotSupportedException)
{
//this occurs when the converter doesn't know how, so we can try the opposite way as a last ditch effort
var fromConverter = TypeDescriptor.GetConverter(i.Value.GetType());
if (fromConverter == null)
{
throw;
}
convertedVal = fromConverter.ConvertTo(i.Value, prop.ModelType);
}
}
propInfo.SetValue(this, convertedVal, null);
}
}
}
}
public virtual TValueModel GetValueModel()
{
var editableProps = MetaData.Properties.Where(x => x.ShowForEdit && !x.IsReadOnly);
var d = new TValueModel();
foreach (var p in editableProps)
{
//by default, we will not support complex modelled properties, developers will need to override
//the GetSerializedValue method if they need support for this.
//TODO Test if this exception is still valid
if (p.IsComplexType)
{
throw new NotSupportedException("The default serialization implementation of EditorModel does not support properties that are complex models");
}
var property = d.GetType().GetProperty(p.PropertyName);
if(property != null)
{
property.SetValue(d, p.Model, null);
}
}
return d;
}
}
}
@@ -0,0 +1,27 @@
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// An abstract class representing the model to render a Property Editor's content editor with PreValues
/// </summary>
/// <typeparam name="TPreValueModel">The type of the PreValue model.</typeparam>
/// <typeparam name="TValueModel"> </typeparam>
internal abstract class EditorModel<TValueModel, TPreValueModel> : EditorModel<TValueModel>
where TValueModel : IValueModel, new()
where TPreValueModel : PreValueModel
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="preValues">The pre value options used to construct the editor</param>
protected EditorModel(TPreValueModel preValues)
{
PreValueModel = preValues;
}
/// <summary>
/// The pre value options used to configure the editor
/// </summary>
/// <value>The pre value model.</value>
public TPreValueModel PreValueModel { get; protected internal set; }
}
}
@@ -0,0 +1,7 @@
namespace Umbraco.Core.PropertyEditors
{
internal interface IValueModel
{
}
}
@@ -0,0 +1,21 @@
using System;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// A class representing a single value of a Pre-Value editor to be saved
/// </summary>
internal class PreValueDefinition
{
public PreValueDefinition(string propertyName, Type modeType, object modelValue)
{
ModelType = modeType;
PropertyName = propertyName;
ModelValue = modelValue;
}
public Type ModelType { get; private set; }
public string PropertyName { get; private set; }
public object ModelValue { get; private set; }
}
}
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Abstract class representing a Property Editor's model to render it's Pre value editor
/// </summary>
internal abstract class PreValueModel
{
protected virtual IEnumerable<PreValueDefinition> GetValueDefinitions()
{
throw new NotImplementedException();
}
public virtual string GetSerializedValue()
{
throw new NotImplementedException();
}
protected virtual void SetModelPropertyValue(PreValueDefinition def, Action<object> setProperty)
{
throw new NotImplementedException();
}
public virtual void SetModelValues(string serializedVal)
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,37 @@
using System;
using System.Linq;
using Umbraco.Core.PropertyEditors.Attributes;
namespace Umbraco.Core.PropertyEditors
{
internal abstract class PropertyEditor
{
/// <summary>
/// Constructor for a PropertyEditor
/// </summary>
protected PropertyEditor()
{
//Locate the metadata attribute
var docTypeAttributes = GetType()
.GetCustomAttributes(typeof(PropertyEditorAttribute), true)
.OfType<PropertyEditorAttribute>();
if (!docTypeAttributes.Any())
throw new InvalidOperationException(
string.Format("The PropertyEditor of type {0} is missing the {1} attribute", GetType().FullName,
typeof(PropertyEditorAttribute).FullName));
//assign the properties of this object to those of the metadata attribute
var attr = docTypeAttributes.First();
Id = attr.Id;
Name = attr.Name;
Alias = attr.Alias;
}
public virtual Guid Id { get; protected set; }
public virtual string Name { get; protected set; }
public virtual string Alias { get; protected set; }
}
}
@@ -0,0 +1,49 @@
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Abstract class that all Property editors should inherit from
/// </summary>
/// <typeparam name="TEditorModel"></typeparam>
/// <typeparam name="TPreValueModel"></typeparam>
/// <typeparam name="TValueModel"> </typeparam>
internal abstract class PropertyEditor<TValueModel, TEditorModel, TPreValueModel> : PropertyEditor
where TValueModel : IValueModel, new()
where TEditorModel : EditorModel<TValueModel>
where TPreValueModel : PreValueModel
{
/// <summary>
/// Returns the editor model to be used for the property editor
/// </summary>
/// <returns></returns>
public abstract TEditorModel CreateEditorModel(TPreValueModel preValues);
/// <summary>
/// Returns the editor model to be used for the prevalue editor
/// </summary>
/// <returns></returns>
public abstract TPreValueModel CreatePreValueEditorModel();
}
/// <summary>
/// Abstract class that Property editors should inherit from that don't require a pre-value editor
/// </summary>
/// <typeparam name="TEditorModel"></typeparam>
/// <typeparam name="TValueModel"> </typeparam>
internal abstract class PropertyEditor<TValueModel, TEditorModel> : PropertyEditor<TValueModel, TEditorModel, BlankPreValueModel>
where TValueModel : IValueModel, new()
where TEditorModel : EditorModel<TValueModel>
{
public override BlankPreValueModel CreatePreValueEditorModel()
{
return new BlankPreValueModel();
}
public sealed override TEditorModel CreateEditorModel(BlankPreValueModel preValues)
{
return CreateEditorModel();
}
public abstract TEditorModel CreateEditorModel();
}
}
+11
View File
@@ -63,6 +63,7 @@
<Compile Include="DictionaryExtensions.cs" />
<Compile Include="Dictionary\CultureDictionaryFactoryResolver.cs" />
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
<Compile Include="Models\ContentExtensions.cs" />
<Compile Include="Models\Css\CssCompactor.cs" />
<Compile Include="Models\Css\CssParser.cs" />
<Compile Include="Models\Css\CssSyntax.cs" />
@@ -101,6 +102,16 @@
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkProvider.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWorkProvider.cs" />
<Compile Include="PropertyEditors\Attributes\PropertyEditorAttribute.cs" />
<Compile Include="PropertyEditors\Attributes\ShowLabelAttribute.cs" />
<Compile Include="PropertyEditors\BlankPreValueModel.cs" />
<Compile Include="PropertyEditors\EditorModel.cs" />
<Compile Include="PropertyEditors\EditorModel`T.cs" />
<Compile Include="PropertyEditors\IValueModel.cs" />
<Compile Include="PropertyEditors\PreValueDefinition.cs" />
<Compile Include="PropertyEditors\PreValueModel.cs" />
<Compile Include="PropertyEditors\PropertyEditor.cs" />
<Compile Include="PropertyEditors\PropertyEditor`T.cs" />
<Compile Include="PublishedContentExtensions.cs" />
<Compile Include="Dictionary\ICultureDictionary.cs" />
<Compile Include="Dynamics\ClassFactory.cs" />