internal static DataTypeDescriptor FromXml(XElement element, bool inheritedFieldsIncluded)
{
Verify.ArgumentNotNull(element, "element");
if (element.Name != "DataTypeDescriptor") throw new ArgumentException("The xml is not correctly formatted.");
Guid dataTypeId = (Guid) element.GetRequiredAttribute("dataTypeId");
string name = element.GetRequiredAttributeValue("name");
string @namespace = element.GetRequiredAttributeValue("namespace");
bool isCodeGenerated = (bool) element.GetRequiredAttribute("isCodeGenerated");
XAttribute cachableAttribute = element.Attribute("cachable");
XAttribute buildNewHandlerTypeNameAttribute = element.Attribute("buildNewHandlerTypeName");
XElement dataAssociationsElement = element.GetRequiredElement("DataAssociations");
XElement dataScopesElement = element.GetRequiredElement("DataScopes");
XElement keyPropertyNamesElement = element.GetRequiredElement("KeyPropertyNames");
XElement versionKeyPropertyNamesElement = element.Element("VersionKeyPropertyNames");
XElement superInterfacesElement = element.GetRequiredElement("SuperInterfaces");
XElement fieldsElement = element.GetRequiredElement("Fields");
XElement indexesElement = element.Element("Indexes");
XAttribute titleAttribute = element.Attribute("title");
XAttribute labelFieldNameAttribute = element.Attribute("labelFieldName");
XAttribute internalUrlPrefixAttribute = element.Attribute("internalUrlPrefix");
string typeManagerTypeName = (string) element.Attribute("typeManagerTypeName");
bool cachable = cachableAttribute != null && (bool)cachableAttribute;
var dataTypeDescriptor = new DataTypeDescriptor(dataTypeId, @namespace, name, isCodeGenerated)
{
Cachable = cachable
};
if (titleAttribute != null) dataTypeDescriptor.Title = titleAttribute.Value;
if (labelFieldNameAttribute != null) dataTypeDescriptor.LabelFieldName = labelFieldNameAttribute.Value;
if (internalUrlPrefixAttribute != null) dataTypeDescriptor.InternalUrlPrefix = internalUrlPrefixAttribute.Value;
if (typeManagerTypeName != null)
{
typeManagerTypeName = TypeManager.FixLegasyTypeName(typeManagerTypeName);
dataTypeDescriptor.TypeManagerTypeName = typeManagerTypeName;
}
if (buildNewHandlerTypeNameAttribute != null) dataTypeDescriptor.BuildNewHandlerTypeName = buildNewHandlerTypeNameAttribute.Value;
foreach (XElement elm in dataAssociationsElement.Elements())
{
var dataTypeAssociationDescriptor = DataTypeAssociationDescriptor.FromXml(elm);
dataTypeDescriptor.DataAssociations.Add(dataTypeAssociationDescriptor);
}
foreach (XElement elm in dataScopesElement.Elements("DataScopeIdentifier"))
{
string dataScopeName = elm.GetRequiredAttributeValue("name");
if (DataScopeIdentifier.IsLegasyDataScope(dataScopeName))
{
Log.LogWarning(LogTitle, "Ignored legacy data scope '{0}' on type '{1}.{2}' while deserializing DataTypeDescriptor. The '{0}' data scope is no longer supported.".FormatWith(dataScopeName, @namespace, name));
continue;
}
DataScopeIdentifier dataScopeIdentifier = DataScopeIdentifier.Deserialize(dataScopeName);
dataTypeDescriptor.DataScopes.Add(dataScopeIdentifier);
}
foreach (XElement elm in superInterfacesElement.Elements("SuperInterface"))
{
string superInterfaceTypeName = elm.GetRequiredAttributeValue("type");
if (superInterfaceTypeName.StartsWith("Composite.Data.ProcessControlled.IDeleteControlled"))
{
Log.LogWarning(LogTitle, $"Ignored legacy super interface '{superInterfaceTypeName}' on type '{@namespace}.{name}' while deserializing DataTypeDescriptor. This super interface is no longer supported.");
continue;
}
Type superInterface;
try
{
superInterface = TypeManager.GetType(superInterfaceTypeName);
}
catch (Exception ex)
{
throw XmlConfigurationExtensionMethods.GetConfigurationException($"Failed to load super interface '{superInterfaceTypeName}'", ex, elm);
}
dataTypeDescriptor.AddSuperInterface(superInterface, !inheritedFieldsIncluded);
}
foreach (XElement elm in fieldsElement.Elements())
{
var dataFieldDescriptor = DataFieldDescriptor.FromXml(elm);
try
{
dataTypeDescriptor.Fields.Add(dataFieldDescriptor);
}
catch (Exception ex)
{
throw XmlConfigurationExtensionMethods.GetConfigurationException("Failed to add a data field: " + ex.Message, ex, elm);
}
}
foreach (XElement elm in keyPropertyNamesElement.Elements("KeyPropertyName"))
{
var propertyName = elm.GetRequiredAttributeValue("name");
bool isDefinedOnSuperInterface = dataTypeDescriptor.SuperInterfaces.Any(f => f.GetProperty(propertyName) != null);
if (!isDefinedOnSuperInterface)
{
dataTypeDescriptor.KeyPropertyNames.Add(propertyName);
}
}
if (versionKeyPropertyNamesElement != null)
{
foreach (XElement elm in versionKeyPropertyNamesElement.Elements("VersionKeyPropertyName"))
{
var propertyName = elm.GetRequiredAttributeValue("name");
dataTypeDescriptor.VersionKeyPropertyNames.Add(propertyName);
}
}
if (indexesElement != null)
{
dataTypeDescriptor.Indexes = indexesElement.Elements("Index").Select(DataTypeIndex.FromXml).ToList();
}
// Loading field rendering profiles for static data types
if (!isCodeGenerated && typeManagerTypeName != null)
{
Type type = Type.GetType(typeManagerTypeName);
if (type != null)
{
foreach (var fieldDescriptor in dataTypeDescriptor.Fields)
{
var property = type.GetProperty(fieldDescriptor.Name);
if (property != null)
{
var formRenderingProfile = DynamicTypeReflectionFacade.GetFormRenderingProfile(property);
if (formRenderingProfile != null)
{
fieldDescriptor.FormRenderingProfile = formRenderingProfile;
}
}
}
}
}
return dataTypeDescriptor;
}