using System;
using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Models
{
public static class PropertyExtensions
{
///
/// Creates the xml representation for the object
///
/// to generate xml for
/// Xml of the property and its value
public static XElement ToXml(this Property property)
{
return property.ToXml(ApplicationContext.Current.Services.DataTypeService);
}
internal static XElement ToXml(this Property property, IDataTypeService dataTypeService)
{
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
var xd = new XmlDocument();
var xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
//Add the property alias to the legacy schema
if (UmbracoSettings.UseLegacyXmlSchema)
{
var alias = xd.CreateAttribute("alias");
alias.Value = property.Alias.ToSafeAlias();
xmlNode.Attributes.Append(alias);
}
//TODO: We'll need to clean this up eventually but for now here's what we're doing:
// * Check if the property's DataType is assigned from a Property Editor or a legacy IDataType
// * Get the XML result from the IDataType if there is one, otherwise just construct a simple
// XML construct from the value returned from the Property Editor.
// More details discussed here: https://groups.google.com/forum/?fromgroups=#!topic/umbraco-dev/fieWZzHj7oY
//var dataType = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(property.PropertyType.DataTypeDefinitionId);
//if (dataType == null) throw new InvalidOperationException("No data type definition found with id " + property.PropertyType.DataTypeDefinitionId);
//We've already got the value for the property so we're going to give it to the
// data type's data property so it doesn't go re-look up the value from the db again.
var defaultData = dt.Data as IDataValueSetter;
if (defaultData != null)
{
defaultData.SetValue(property.Value, property.PropertyType.DataTypeDatabaseType.ToString());
}
xmlNode.AppendChild(dt.Data.ToXMl(xd));
var propertyEditor = PropertyEditorResolver.Current.GetById(property.PropertyType.DataTypeId);
if (propertyEditor != null)
{
switch (property.PropertyType.DataTypeDatabaseType)
{
case DataTypeDatabaseType.Nvarchar:
xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString()));
break;
case DataTypeDatabaseType.Integer:
xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString(property.Value.GetType())));
break;
case DataTypeDatabaseType.Ntext:
//put text in cdata
xmlNode.AppendChild(xd.CreateCDataSection(property.Value.ToXmlString()));
break;
case DataTypeDatabaseType.Date:
//treat dates differently, output the format as xml format
if (property.Value == null)
{
xmlNode.AppendChild(xd.CreateTextNode(string.Empty));
}
else
{
var dt = (DateTime)property.Value;
xmlNode.AppendChild(xd.CreateTextNode(dt.ToXmlString()));
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
else
{
//NOTE: An exception will be thrown if this doesn't exist
var legacyDataType = property.PropertyType.DataType(property.Id);
xmlNode.AppendChild(legacyDataType.Data.ToXMl(xd));
}
var element = xmlNode.GetXElement();
return element;
}
}
}