Works on: U4-1979 Some legacy business logic APIs do not wrap the new Service APIs. Deprecates the ctor passing in a parent id for the data type (since it's always -1). Wraps legacy DataTypeDefinition to use the new services layer.

This commit is contained in:
Shannon
2015-05-18 16:06:22 +10:00
parent 1d0b5f3251
commit 76a10fc776
11 changed files with 104 additions and 190 deletions

View File

@@ -33,6 +33,7 @@ namespace Umbraco.Core.Models
private DataTypeDatabaseType _databaseType;
[Obsolete("Property editor's are defined by a string alias from version 7 onwards, use the alternative contructor that specifies an alias")]
[EditorBrowsable(EditorBrowsableState.Never)]
public DataTypeDefinition(int parentId, Guid controlId)
{
_parentId = parentId;
@@ -47,6 +48,9 @@ namespace Umbraco.Core.Models
_additionalData = new Dictionary<string, object>();
}
[Obsolete("Don't use this, parentId is always -1 for data types")]
[EditorBrowsable(EditorBrowsableState.Never)]
public DataTypeDefinition(int parentId, string propertyEditorAlias)
{
_parentId = parentId;
@@ -55,6 +59,14 @@ namespace Umbraco.Core.Models
_additionalData = new Dictionary<string, object>();
}
public DataTypeDefinition(string propertyEditorAlias)
{
_parentId = -1;
_propertyEditorAlias = propertyEditorAlias;
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, string>(x => x.Name);
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, int>(x => x.ParentId);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, int>(x => x.SortOrder);

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Factories
public IDataTypeDefinition BuildEntity(DataTypeDto dto)
{
var dataTypeDefinition = new DataTypeDefinition(dto.NodeDto.ParentId, dto.PropertyEditorAlias)
var dataTypeDefinition = new DataTypeDefinition(dto.PropertyEditorAlias)
{
CreateDate = dto.NodeDto.CreateDate,
DatabaseType = dto.DbType.EnumParse<DataTypeDatabaseType>(true),

View File

@@ -134,6 +134,8 @@ namespace Umbraco.Core.PropertyEditors
CreateMap(Guid.Parse(Constants.PropertyEditors.UploadField), Constants.PropertyEditors.UploadFieldAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.XPathCheckBoxList), Constants.PropertyEditors.XPathCheckBoxListAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.XPathDropDownList), Constants.PropertyEditors.XPathDropDownListAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.MacroContainer), Constants.PropertyEditors.MacroContainerAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.ImageCropper), Constants.PropertyEditors.ImageCropperAlias);
//Being mapped to different editors
//TODO: Map this somewhere!
@@ -144,10 +146,8 @@ namespace Umbraco.Core.PropertyEditors
//Not being converted - convert to label
CreateMap(Guid.Parse(Constants.PropertyEditors.DictionaryPicker), Constants.PropertyEditors.NoEditAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.UmbracoUserControlWrapper), Constants.PropertyEditors.NoEditAlias);
//Not ready for v7.0! - will need to create for 7.1
CreateMap(Guid.Parse(Constants.PropertyEditors.MacroContainer), Constants.PropertyEditors.NoEditAlias);
CreateMap(Guid.Parse(Constants.PropertyEditors.ImageCropper), Constants.PropertyEditors.NoEditAlias);
}
}

View File

@@ -828,7 +828,7 @@ namespace Umbraco.Core.Services
else
{
//the Id field is actually the string property editor Alias
var dataTypeDefinition = new DataTypeDefinition(-1, dataTypeElement.Attribute("Id").Value.Trim())
var dataTypeDefinition = new DataTypeDefinition(dataTypeElement.Attribute("Id").Value.Trim())
{
Key = dataTypeDefinitionId,
Name = dataTypeDefinitionName,

View File

@@ -199,7 +199,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork))
{
var dataTypeDefinition = new DataTypeDefinition(-1, "Test.TestEditor")
var dataTypeDefinition = new DataTypeDefinition("Test.TestEditor")
{
DatabaseType = DataTypeDatabaseType.Integer,
Name = "AgeDataType",
@@ -226,7 +226,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork))
{
var dataTypeDefinition = new DataTypeDefinition(-1, "Test.blah")
var dataTypeDefinition = new DataTypeDefinition("Test.blah")
{
DatabaseType = DataTypeDatabaseType.Integer,
Name = "AgeDataType",
@@ -260,7 +260,7 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork))
{
var dataTypeDefinition = new DataTypeDefinition(-1, "Test.TestEditor")
var dataTypeDefinition = new DataTypeDefinition("Test.TestEditor")
{
DatabaseType = DataTypeDatabaseType.Integer,
Name = "AgeDataType",

View File

@@ -46,9 +46,7 @@ namespace Umbraco.Web.Cache
//Bind to data type events
//NOTE: we need to bind to legacy and new API events currently: http://issues.umbraco.org/issue/U4-1979
//TODO: Wrap as much of this api as possible so that we don't need to listen to legacy events!
global::umbraco.cms.businesslogic.datatype.DataTypeDefinition.AfterDelete += DataTypeDefinitionDeleting;
global::umbraco.cms.businesslogic.datatype.DataTypeDefinition.Saving += DataTypeDefinitionSaving;
DataTypeService.Deleted += DataTypeServiceDeleted;
DataTypeService.Saved += DataTypeServiceSaved;
@@ -380,15 +378,7 @@ namespace Umbraco.Web.Cache
e.DeletedEntities.ForEach(x => DistributedCache.Instance.RemoveDataTypeCache(x));
}
static void DataTypeDefinitionSaving(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e)
{
DistributedCache.Instance.RefreshDataTypeCache(sender);
}
static void DataTypeDefinitionDeleting(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e)
{
DistributedCache.Instance.RemoveDataTypeCache(sender);
}
#endregion
#region Stylesheet and stylesheet property event handlers

View File

@@ -27,20 +27,7 @@ namespace Umbraco.Web.Cache
var serializer = new JavaScriptSerializer();
var jsonObject = serializer.Deserialize<JsonPayload[]>(json);
return jsonObject;
}
/// <summary>
/// Creates the custom Json payload used to refresh cache amongst the servers
/// </summary>
/// <param name="dataTypes"></param>
/// <returns></returns>
internal static string SerializeToJsonPayload(params global::umbraco.cms.businesslogic.datatype.DataTypeDefinition[] dataTypes)
{
var serializer = new JavaScriptSerializer();
var items = dataTypes.Select(FromDataTypeDefinition).ToArray();
var json = serializer.Serialize(items);
return json;
}
}
/// <summary>
/// Creates the custom Json payload used to refresh cache amongst the servers
@@ -54,22 +41,7 @@ namespace Umbraco.Web.Cache
var json = serializer.Serialize(items);
return json;
}
/// <summary>
/// Converts a macro to a jsonPayload object
/// </summary>
/// <param name="dataType"></param>
/// <returns></returns>
private static JsonPayload FromDataTypeDefinition(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType)
{
var payload = new JsonPayload
{
UniqueId = dataType.UniqueId,
Id = dataType.Id
};
return payload;
}
/// <summary>
/// Converts a macro to a jsonPayload object
/// </summary>

View File

@@ -125,19 +125,7 @@ namespace Umbraco.Web.Cache
#endregion
#region Data type cache
public static void RefreshDataTypeCache(this DistributedCache dc, global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType)
{
if (dataType == null) return;
dc.RefreshByJson(DistributedCache.DataTypeCacheRefresherGuid, DataTypeCacheRefresher.SerializeToJsonPayload(dataType));
}
public static void RemoveDataTypeCache(this DistributedCache dc, global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType)
{
if (dataType == null) return;
dc.RefreshByJson(DistributedCache.DataTypeCacheRefresherGuid, DataTypeCacheRefresher.SerializeToJsonPayload(dataType));
}
#region Data type cache
public static void RefreshDataTypeCache(this DistributedCache dc, IDataTypeDefinition dataType)
{

View File

@@ -81,7 +81,7 @@ namespace Umbraco.Web.Editors
public DataTypeDisplay GetEmpty()
{
var dt = new DataTypeDefinition(-1, "");
var dt = new DataTypeDefinition("");
return Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(dt);
}

View File

@@ -59,7 +59,7 @@ namespace Umbraco.Web.Models.Mapping
});
config.CreateMap<DataTypeSave, IDataTypeDefinition>()
.ConstructUsing(save => new DataTypeDefinition(-1, save.SelectedEditor) {CreateDate = DateTime.Now})
.ConstructUsing(save => new DataTypeDefinition(save.SelectedEditor) {CreateDate = DateTime.Now})
.ForMember(definition => definition.Id, expression => expression.MapFrom(save => Convert.ToInt32(save.Id)))
//we have to ignore the Key otherwise this will reset the UniqueId field which should never change!
// http://issues.umbraco.org/issue/U4-3911

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Data;
using System.Linq;
@@ -13,12 +14,11 @@ using umbraco.cms.businesslogic.media;
using umbraco.interfaces;
using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace umbraco.cms.businesslogic.datatype
{
//TODO: Wrap as much of this api as possible so that we don't need to listen to legacy events!
/// <summary>
/// Datatypedefinitions is the basic buildingblocks of umbraco's documents/medias/members generic datastructure
///
@@ -30,17 +30,16 @@ namespace umbraco.cms.businesslogic.datatype
[Obsolete("This class is no longer used and will be removed from the codebase in the future.")]
public class DataTypeDefinition : CMSNode
{
#region Private fields
internal string PropertyEditorAlias { get; private set; }
private static readonly Guid ObjectType = new Guid(Constants.ObjectTypes.DataType);
private string _text1;
#endregion
internal IDataTypeDefinition DataTypeItem;
#region Constructors
internal DataTypeDefinition(IDataTypeDefinition dataType)
: base(dataType)
{
DataTypeItem = dataType;
}
/// <summary>
/// Initialization of the datatypedefinition
/// </summary>
@@ -59,8 +58,8 @@ namespace umbraco.cms.businesslogic.datatype
public override string Text
{
get { return _text1 ?? (_text1 = base.Text); }
set { _text1 = value; }
get { return DataTypeItem.Name; }
set { DataTypeItem.Name = value; }
}
/// <summary>
@@ -70,7 +69,7 @@ namespace umbraco.cms.businesslogic.datatype
{
get
{
if (PropertyEditorAlias.IsNullOrWhiteSpace())
if (DataTypeItem.PropertyEditorAlias.IsNullOrWhiteSpace())
return null;
//Attempt to resolve a legacy control id from the alias. If one is not found we'll generate one -
@@ -79,7 +78,7 @@ namespace umbraco.cms.businesslogic.datatype
//So, we'll generate an id for it based on the alias which will remain consistent, but then we'll try to resolve a legacy
// IDataType which of course will not exist. In this case we'll have to create a new one on the fly for backwards compatibility but
// this instance will have limited capabilities and will really only work for saving data so the legacy APIs continue to work.
var controlId = LegacyPropertyEditorIdToAliasConverter.GetLegacyIdFromAlias(PropertyEditorAlias, LegacyPropertyEditorIdToAliasConverter.NotFoundLegacyIdResponseBehavior.GenerateId);
var controlId = LegacyPropertyEditorIdToAliasConverter.GetLegacyIdFromAlias(DataTypeItem.PropertyEditorAlias, LegacyPropertyEditorIdToAliasConverter.NotFoundLegacyIdResponseBehavior.GenerateId);
var dt = DataTypesResolver.Current.GetById(controlId.Value);
@@ -91,7 +90,7 @@ namespace umbraco.cms.businesslogic.datatype
{
//Ok so it was not found, we can only assume that this is because this is a new property editor that does not have a legacy predecessor.
//we'll have to attempt to generate one at runtime.
dt = BackwardsCompatibleDataType.Create(PropertyEditorAlias, controlId.Value, Id);
dt = BackwardsCompatibleDataType.Create(DataTypeItem.PropertyEditorAlias, controlId.Value, Id);
}
@@ -99,23 +98,16 @@ namespace umbraco.cms.businesslogic.datatype
}
set
{
if (SqlHelper == null)
throw new InvalidOperationException("Cannot execute a SQL command when the SqlHelper is null");
if (value == null)
throw new InvalidOperationException("The value passed in is null. The DataType property cannot be set to a null value");
var alias = LegacyPropertyEditorIdToAliasConverter.GetAliasFromLegacyId(value.Id, true);
SqlHelper.ExecuteNonQuery("update cmsDataType set propertyEditorAlias = @alias where nodeID = " + this.Id,
SqlHelper.CreateParameter("@alias", alias));
PropertyEditorAlias = alias;
DataTypeItem.PropertyEditorAlias = alias;
}
}
internal string DbType { get; private set; }
//internal string DbType { get; private set; }
#endregion
@@ -126,22 +118,8 @@ namespace umbraco.cms.businesslogic.datatype
FireBeforeDelete(e);
if (e.Cancel == false)
{
//first clear the prevalues
PreValues.DeleteByDataTypeDefinition(this.Id);
//next clear out the property types
var propTypes = PropertyType.GetByDataTypeDefinition(this.Id);
foreach (var p in propTypes)
{
p.delete();
}
//delete the cmsDataType role, then the umbracoNode
SqlHelper.ExecuteNonQuery("delete from cmsDataType where nodeId=@nodeId",
SqlHelper.CreateParameter("@nodeId", this.Id));
base.delete();
ApplicationContext.Current.Services.DataTypeService.Delete(DataTypeItem);
FireAfterDelete(e);
}
}
@@ -157,58 +135,24 @@ namespace umbraco.cms.businesslogic.datatype
/// </summary>
public override void Save()
{
//Cannot change to a duplicate alias
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataType
INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id
WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + @"= @name
AND umbracoNode.id <> @id",
new { id = this.Id, name = this.Text });
if (exists > 0)
{
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(
string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, this.Id));
throw new DuplicateNameException("A data type with the name " + this.Text + " already exists");
}
//this actually does the persisting.
base.Text = _text1;
ApplicationContext.Current.Services.DataTypeService.Save(DataTypeItem);
OnSaving(EventArgs.Empty);
}
public XmlElement ToXml(XmlDocument xd)
{
//here we need to get the property editor alias from it's id
var alias = LegacyPropertyEditorIdToAliasConverter.GetAliasFromLegacyId(DataType.Id, true);
var serializer = new EntityXmlSerializer();
var xml = serializer.Serialize(ApplicationContext.Current.Services.DataTypeService, DataTypeItem);
return (XmlElement)xml.GetXmlNode(xd);
var dt = xd.CreateElement("DataType");
dt.Attributes.Append(xmlHelper.addAttribute(xd, "Name", Text));
//The 'ID' when exporting is actually the property editor alias (in pre v7 it was the IDataType GUID id)
dt.Attributes.Append(xmlHelper.addAttribute(xd, "Id", alias));
dt.Attributes.Append(xmlHelper.addAttribute(xd, "Definition", UniqueId.ToString()));
dt.Attributes.Append(xmlHelper.addAttribute(xd, "DatabaseType", DbType));
// templates
var prevalues = xd.CreateElement("PreValues");
foreach (DictionaryEntry item in PreValues.GetPreValues(Id))
{
var prevalue = xd.CreateElement("PreValue");
prevalue.Attributes.Append(xmlHelper.addAttribute(xd, "Id", ((PreValue)item.Value).Id.ToString(CultureInfo.InvariantCulture)));
prevalue.Attributes.Append(xmlHelper.addAttribute(xd, "Value", ((PreValue)item.Value).Value));
prevalue.Attributes.Append(xmlHelper.addAttribute(xd, "Alias", ((PreValue)item.Value).Alias));
prevalues.AppendChild(prevalue);
}
dt.AppendChild(prevalues);
return dt;
}
#endregion
#region Static methods
[Obsolete("Do not use this method, it will not function correctly because legacy property editors are not supported in v7")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static DataTypeDefinition Import(XmlNode xmlData)
{
var name = xmlData.Attributes["Name"].Value;
@@ -254,23 +198,8 @@ AND umbracoNode.id <> @id",
/// <returns>A list of all datatypedefinitions</returns>
public static DataTypeDefinition[] GetAll()
{
var retvalSort = new SortedList();
var tmp = getAllUniquesFromObjectType(ObjectType);
var retval = new DataTypeDefinition[tmp.Length];
for (var i = 0; i < tmp.Length; i++)
{
var dt = GetDataTypeDefinition(tmp[i]);
retvalSort.Add(dt.Text + "|||" + Guid.NewGuid(), dt);
}
var ide = retvalSort.GetEnumerator();
var counter = 0;
while (ide.MoveNext())
{
retval[counter] = (DataTypeDefinition)ide.Value;
counter++;
}
return retval;
var result = ApplicationContext.Current.Services.DataTypeService.GetAllDataTypeDefinitions();
return result.Select(x => new DataTypeDefinition(x)).ToArray();
}
/// <summary>
@@ -293,21 +222,21 @@ AND umbracoNode.id <> @id",
/// <returns></returns>
public static DataTypeDefinition MakeNew(BusinessLogic.User u, string Text, Guid UniqueId)
{
//Cannot add a duplicate data type
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataType
INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id
WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + "= @name", new { name = Text });
if (exists > 0)
var found = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionByName(Text);
if (found != null)
{
throw new DuplicateNameException("A data type with the name " + Text + " already exists");
}
var newId = MakeNew(-1, ObjectType, u.Id, 1, Text, UniqueId).Id;
var created = new Umbraco.Core.Models.DataTypeDefinition("")
{
Name = Text,
Key = UniqueId
};
//insert empty prop ed alias
SqlHelper.ExecuteNonQuery("Insert into cmsDataType (nodeId, propertyEditorAlias, dbType) values (" + newId + ",'','Ntext')");
ApplicationContext.Current.Services.DataTypeService.Save(created);
var dtd = new DataTypeDefinition(newId);
var dtd = new DataTypeDefinition(created);
dtd.OnNew(EventArgs.Empty);
return dtd;
@@ -353,37 +282,60 @@ WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("te
public static DataTypeDefinition GetDataTypeDefinition(int id)
{
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id),
() => new DataTypeDefinition(id));
var found = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(id);
return found == null ? null : new DataTypeDefinition(found);
}
[Obsolete("Use GetDataTypeDefinition(int id) instead", false)]
public static DataTypeDefinition GetDataTypeDefinition(Guid id)
{
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id),
() => new DataTypeDefinition(id));
var found = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(id);
return found == null ? null : new DataTypeDefinition(found);
}
#endregion
#region Protected methods
protected override void setupNode()
{
base.setupNode();
using (var dr = SqlHelper.ExecuteReader("select dbType, propertyEditorAlias from cmsDataType where nodeId = '" + this.Id.ToString() + "'"))
DataTypeItem = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(Id);
if (DataTypeItem == null)
{
if (dr.Read())
{
PropertyEditorAlias = dr.GetString("propertyEditorAlias");
DbType = dr.GetString("dbType");
}
else
throw new ArgumentException("No dataType with id = " + this.Id.ToString() + " found");
throw new ArgumentException("No dataType with id = " + this.Id.ToString() + " found");
}
//base.setupNode();
//using (var dr = SqlHelper.ExecuteReader("select dbType, propertyEditorAlias from cmsDataType where nodeId = '" + this.Id.ToString() + "'"))
//{
// if (dr.Read())
// {
// PropertyEditorAlias = dr.GetString("propertyEditorAlias");
// DbType = dr.GetString("dbType");
// }
// else
// throw new ArgumentException("No dataType with id = " + this.Id.ToString() + " found");
//}
}
//protected void SetupNode(IDataTypeDefinition dtd)
//{
// base.setupNode();
// using (var dr = SqlHelper.ExecuteReader("select dbType, propertyEditorAlias from cmsDataType where nodeId = '" + this.Id.ToString() + "'"))
// {
// if (dr.Read())
// {
// PropertyEditorAlias = dr.GetString("propertyEditorAlias");
// DbType = dr.GetString("dbType");
// }
// else
// throw new ArgumentException("No dataType with id = " + this.Id.ToString() + " found");
// }
//}
#endregion
#region Events
@@ -425,7 +377,7 @@ WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("te
/// Raises the <see cref="E:BeforeDelete"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected new virtual void FireBeforeDelete(DeleteEventArgs e)
protected override void FireBeforeDelete(DeleteEventArgs e)
{
if (BeforeDelete != null)
BeforeDelete(this, e);
@@ -439,7 +391,7 @@ WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("te
/// Raises the <see cref="E:AfterDelete"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected new virtual void FireAfterDelete(DeleteEventArgs e)
protected override void FireAfterDelete(DeleteEventArgs e)
{
if (AfterDelete != null)
AfterDelete(this, e);