using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
///
/// A Property contains a single piece of data
///
[Serializable]
[DataContract(IsReference = true)]
public class Property : Entity
{
private PropertyType _propertyType;
private Guid _version;
private object _value;
private readonly PropertyTags _tagSupport = new PropertyTags();
protected Property()
{
}
public Property(PropertyType propertyType)
{
_propertyType = propertyType;
}
public Property(PropertyType propertyType, object value)
{
_propertyType = propertyType;
Value = value;
}
public Property(int id, Guid version, PropertyType propertyType, object value)
{
Id = id;
_propertyType = propertyType;
_version = version;
Value = value;
}
private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo(x => x.Value);
private static readonly PropertyInfo VersionSelector = ExpressionHelper.GetPropertyInfo(x => x.Version);
///
/// Returns the instance of the tag support, by default tags are not enabled
///
internal PropertyTags TagSupport
{
get { return _tagSupport; }
}
///
/// Returns the Alias of the PropertyType, which this Property is based on
///
[DataMember]
public string Alias { get { return _propertyType.Alias; } }
///
/// Returns the Id of the PropertyType, which this Property is based on
///
[IgnoreDataMember]
internal int PropertyTypeId { get { return _propertyType.Id; } }
///
/// Returns the DatabaseType that the underlaying DataType is using to store its values
///
///
/// Only used internally when saving the property value.
///
[IgnoreDataMember]
internal DataTypeDatabaseType DataTypeDatabaseType
{
get { return _propertyType.DataTypeDatabaseType; }
}
///
/// Returns the PropertyType, which this Property is based on
///
[IgnoreDataMember]
internal PropertyType PropertyType { get { return _propertyType; } }
///
/// Gets or Sets the version id for the Property
///
///
/// The version will be the same for all Property objects in a collection on a Content
/// object, so not sure how much this makes sense but adding it to align with:
/// umbraco.interfaces.IProperty
///
[DataMember]
public Guid Version
{
get { return _version; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_version = value;
return _version;
}, _version, VersionSelector);
}
}
///
/// Gets or Sets the value of the Property
///
///
/// Setting the value will trigger a type validation.
/// The type of the value has to be valid in order to be saved.
///
[DataMember]
public object Value
{
get { return _value; }
set
{
bool typeValidation = _propertyType.IsPropertyTypeValid(value);
if (typeValidation == false)
throw new Exception(
string.Format(
"Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'",
value == null ? "null" : value.GetType().Name, Alias));
SetPropertyValueAndDetectChanges(o =>
{
_value = value;
return _value;
}, _value, ValueSelector,
new DelegateEqualityComparer