//---------------------------------------------------------------------- Attribute parsing private static NodeTypeRegistration ParseAttributes(Type type) { NodeTypeRegistration ntReg = null; ContentHandlerAttribute contentHandlerAttribute = null; foreach (object attrObject in type.GetCustomAttributes(false)) if ((contentHandlerAttribute = attrObject as ContentHandlerAttribute) != null) break; //-- Finish if there is not a ContentHandlerAttribute if (contentHandlerAttribute == null) return ntReg; //-- Must inherit from Node. if (!IsInheritedFromNode(type)) throw new ContentRegistrationException(String.Format(CultureInfo.CurrentCulture, SR.Exceptions.Registration.Msg_NodeTypeMustBeInheritedFromNode_1, type.FullName)); //-- Property checks RepositoryPropertyAttribute propertyAttribute = null; List<PropertyTypeRegistration> propertyTypeRegistrations = new List<PropertyTypeRegistration>(); Dictionary<string, RepositoryPropertyAttribute> propertyAttributes = new Dictionary<string, RepositoryPropertyAttribute>(); List<PropertyInfo> props = new List<PropertyInfo>(type.GetProperties(_publicPropertyBindingFlags)); props.AddRange(type.GetProperties(_nonPublicPropertyBindingFlags)); foreach (PropertyInfo propInfo in props) { string propName = propInfo.Name; propertyAttribute = null; foreach (object attrObject in propInfo.GetCustomAttributes(false)) if ((propertyAttribute = attrObject as RepositoryPropertyAttribute) != null) break; if (propertyAttribute == null) continue; if (propertyAttributes.ContainsKey(propName)) throw new RegistrationException(String.Format(CultureInfo.CurrentCulture, SR.Exceptions.Registration.Msg_PropertyTypeAttributesWithTheSameName_2, type.FullName, propInfo.Name)); propertyAttributes.Add(propName, propertyAttribute); //-- Override default name with passed name if (propertyAttribute.PropertyName != null) propName = propertyAttribute.PropertyName; //---- Build PropertyTypeRegistration PropertyTypeRegistration propReg = new PropertyTypeRegistration(propInfo, propertyAttribute); propertyTypeRegistrations.Add(propReg); } //-- Build NodeTypeRegistration ntReg = new NodeTypeRegistration(type, null, propertyTypeRegistrations); return ntReg; }
// ---------------------------------------------------------------------- Attribute parsing private static NodeTypeRegistration ParseAttributes(Type type) { NodeTypeRegistration ntReg = null; ContentHandlerAttribute contentHandlerAttribute = null; foreach (object attrObject in type.GetCustomAttributes(false)) { if ((contentHandlerAttribute = attrObject as ContentHandlerAttribute) != null) { break; } } // Finish if there is not a ContentHandlerAttribute if (contentHandlerAttribute == null) { return(ntReg); } // Must inherit from Node. if (!IsInheritedFromNode(type)) { throw new ContentRegistrationException(String.Format(CultureInfo.CurrentCulture, SR.Exceptions.Registration.Msg_NodeTypeMustBeInheritedFromNode_1, type.FullName)); } // Property checks RepositoryPropertyAttribute propertyAttribute = null; List <PropertyTypeRegistration> propertyTypeRegistrations = new List <PropertyTypeRegistration>(); Dictionary <string, RepositoryPropertyAttribute> propertyAttributes = new Dictionary <string, RepositoryPropertyAttribute>(); List <PropertyInfo> props = new List <PropertyInfo>(type.GetProperties(_publicPropertyBindingFlags)); props.AddRange(type.GetProperties(_nonPublicPropertyBindingFlags)); foreach (PropertyInfo propInfo in props) { string propName = propInfo.Name; propertyAttribute = null; foreach (object attrObject in propInfo.GetCustomAttributes(false)) { if ((propertyAttribute = attrObject as RepositoryPropertyAttribute) != null) { break; } } if (propertyAttribute == null) { continue; } if (propertyAttributes.ContainsKey(propName)) { throw new RegistrationException(String.Format(CultureInfo.CurrentCulture, SR.Exceptions.Registration.Msg_PropertyTypeAttributesWithTheSameName_2, type.FullName, propInfo.Name)); } propertyAttributes.Add(propName, propertyAttribute); // Override default name with passed name if (propertyAttribute.PropertyName != null) { propName = propertyAttribute.PropertyName; } // Build PropertyTypeRegistration PropertyTypeRegistration propReg = new PropertyTypeRegistration(propInfo, propertyAttribute); propertyTypeRegistrations.Add(propReg); } // Build NodeTypeRegistration ntReg = new NodeTypeRegistration(type, null, propertyTypeRegistrations); return(ntReg); }
internal static void ApplyChangesInEditor(ContentType contentType, SchemaEditor editor) { //-- Find ContentHandler Type handlerType = TypeHandler.GetType(contentType.HandlerName); if (handlerType == null) throw new RegistrationException(String.Concat( SR.Exceptions.Registration.Msg_ContentHandlerNotFound, ": ", contentType.HandlerName)); //-- parent type NodeType parentNodeType = null; if (contentType.ParentTypeName != null) { parentNodeType = editor.NodeTypes[contentType.ParentTypeName]; if (parentNodeType == null) throw new ContentRegistrationException(SR.Exceptions.Registration.Msg_UnknownParentContentType, contentType.Name); } //-- handler type NodeType nodeType = editor.NodeTypes[contentType.Name]; if (nodeType == null) nodeType = editor.CreateNodeType(parentNodeType, contentType.Name, contentType.HandlerName); if (nodeType.ClassName != contentType.HandlerName) editor.ModifyNodeType(nodeType, contentType.HandlerName); if (nodeType.Parent != parentNodeType) editor.ModifyNodeType(nodeType, parentNodeType); //-- 1: ContentHandler properties NodeTypeRegistration ntReg = ParseAttributes(handlerType); if (ntReg == null) throw new ContentRegistrationException( SR.Exceptions.Registration.Msg_DefinedHandlerIsNotAContentHandler, contentType.Name); //-- 2: Field properties foreach (FieldSetting fieldSetting in contentType.FieldSettings) { Type[][] slots = fieldSetting.HandlerSlots; int fieldSlotCount = slots.GetLength(0); if (fieldSetting.Bindings.Count != fieldSlotCount) throw new ContentRegistrationException(String.Format(CultureInfo.InvariantCulture, SR.Exceptions.Registration.Msg_FieldBindingsCount_1, fieldSlotCount), contentType.Name, fieldSetting.Name); for (int i = 0; i < fieldSetting.Bindings.Count; i++) { string propName = fieldSetting.Bindings[i]; var dataType = fieldSetting.DataTypes[i]; CheckDataType(propName, dataType, contentType.Name, editor); PropertyInfo propInfo = handlerType.GetProperty(propName); if (propInfo != null) { //-- #1: there is a property under the slot: bool ok = false; for (int j = 0; j < slots[i].Length; j++) { //if (slots[i][j] == propInfo.PropertyType) if (slots[i][j].IsAssignableFrom(propInfo.PropertyType)) { PropertyTypeRegistration propReg = ntReg.PropertyTypeRegistrationByName(propName); if (propInfo.DeclaringType != handlerType) { if (propReg == null) { object[] attrs = propInfo.GetCustomAttributes(typeof(RepositoryPropertyAttribute), false); if (attrs.Length > 0) { propReg = new PropertyTypeRegistration(propInfo, (RepositoryPropertyAttribute)attrs[0]); ntReg.PropertyTypeRegistrations.Add(propReg); } } } if (propReg != null && propReg.DataType != fieldSetting.DataTypes[i]) throw new ContentRegistrationException(String.Concat( "The data type of the field in the content type definition does not match the data type of its content handler's property. ", "Please modify the field type in the content type definition. ", "ContentTypeDefinition: '", contentType.Name, "', FieldName: '", fieldSetting.Name, "', DataType of Field's binding: '", fieldSetting.DataTypes[i], "', ContentHandler: '", handlerType.FullName, "', PropertyName: '", propReg.Name, "', DataType of property: '", propReg.DataType, "'")); ok = true; fieldSetting.HandlerSlotIndices[i] = j; fieldSetting.PropertyIsReadOnly = !PropertyHasPublicSetter(propInfo); break; } } if (!ok) { //if (fieldSetting.ShortName != "Reference") // if (fieldSetting.DataTypes[i] != RepositoryDataType.Reference) // throw new ContentRegistrationException(SR.Exceptions.Registration.Msg_PropertyAndFieldAreNotConnectable, // contentType.Name, fieldSetting.Name); //CheckReference(propInfo, slots[i], contentType, fieldSetting); if (fieldSetting.ShortName == "Reference" || fieldSetting.DataTypes[i] == RepositoryDataType.Reference) CheckReference(propInfo, slots[i], contentType, fieldSetting); //else if (fieldSetting.ShortName == "Choice") // CheckChoice(propInfo, slots[i], contentType, fieldSetting); else throw new ContentRegistrationException(SR.Exceptions.Registration.Msg_PropertyAndFieldAreNotConnectable, contentType.Name, fieldSetting.Name); } } else { //-- #2: there is not a property under the slot: PropertyTypeRegistration propReg = new PropertyTypeRegistration(propName, dataType); ntReg.PropertyTypeRegistrations.Add(propReg); } } } //-- Collect deletables. Check equals foreach (PropertyType propType in nodeType.PropertyTypes.ToArray()) { PropertyTypeRegistration propReg = ntReg.PropertyTypeRegistrationByName(propType.Name); if (propReg == null) { editor.RemovePropertyTypeFromPropertySet(propType, nodeType); } } //-- Register foreach (PropertyTypeRegistration ptReg in ntReg.PropertyTypeRegistrations) { PropertyType propType = nodeType.PropertyTypes[ptReg.Name]; if (propType == null) { propType = editor.PropertyTypes[ptReg.Name]; if (propType == null) propType = editor.CreatePropertyType(ptReg.Name, ConvertDataType(ptReg.DataType)); editor.AddPropertyTypeToPropertySet(propType, nodeType); } } }
internal static void ApplyChangesInEditor(ContentType contentType, SchemaEditor editor) { // Find ContentHandler var handlerType = TypeResolver.GetType(contentType.HandlerName, false); if (handlerType == null) { throw new RegistrationException(string.Concat( SR.Exceptions.Registration.Msg_ContentHandlerNotFound, ": ", contentType.HandlerName)); } // parent type NodeType parentNodeType = null; if (contentType.ParentTypeName != null) { parentNodeType = editor.NodeTypes[contentType.ParentTypeName]; if (parentNodeType == null) { throw new ContentRegistrationException(SR.Exceptions.Registration.Msg_UnknownParentContentType, contentType.Name); } // make sure that all content handlers defined on the parent chain exist var pnt = parentNodeType; while (pnt != null) { var ht = TypeResolver.GetType(pnt.ClassName, false); if (ht == null) { throw new RegistrationException($"Unknown content handler: {pnt.ClassName}"); } pnt = pnt.Parent; } } // handler type NodeType nodeType = editor.NodeTypes[contentType.Name]; if (nodeType == null) { nodeType = editor.CreateNodeType(parentNodeType, contentType.Name, contentType.HandlerName); } if (nodeType.ClassName != contentType.HandlerName) { editor.ModifyNodeType(nodeType, contentType.HandlerName); } if (nodeType.Parent != parentNodeType) { editor.ModifyNodeType(nodeType, parentNodeType); } // 1: ContentHandler properties NodeTypeRegistration ntReg = ParseAttributes(handlerType); if (ntReg == null) { throw new ContentRegistrationException( SR.Exceptions.Registration.Msg_DefinedHandlerIsNotAContentHandler, contentType.Name); } // 2: Field properties foreach (FieldSetting fieldSetting in contentType.FieldSettings) { Type[][] slots = fieldSetting.HandlerSlots; int fieldSlotCount = slots.GetLength(0); if (fieldSetting.Bindings.Count != fieldSlotCount) { throw new ContentRegistrationException(String.Format(CultureInfo.InvariantCulture, SR.Exceptions.Registration.Msg_FieldBindingsCount_1, fieldSlotCount), contentType.Name, fieldSetting.Name); } for (int i = 0; i < fieldSetting.Bindings.Count; i++) { string propName = fieldSetting.Bindings[i]; var dataType = fieldSetting.DataTypes[i]; CheckDataType(propName, dataType, contentType.Name, editor); PropertyInfo propInfo = handlerType.GetProperty(propName); if (propInfo != null) { // #1: there is a property under the slot: bool ok = false; for (int j = 0; j < slots[i].Length; j++) { if (slots[i][j].IsAssignableFrom(propInfo.PropertyType)) { PropertyTypeRegistration propReg = ntReg.PropertyTypeRegistrationByName(propName); if (propInfo.DeclaringType != handlerType) { if (propReg == null) { object[] attrs = propInfo.GetCustomAttributes(typeof(RepositoryPropertyAttribute), false); if (attrs.Length > 0) { propReg = new PropertyTypeRegistration(propInfo, (RepositoryPropertyAttribute)attrs[0]); ntReg.PropertyTypeRegistrations.Add(propReg); } } } if (propReg != null && propReg.DataType != fieldSetting.DataTypes[i]) { throw new ContentRegistrationException(String.Concat( "The data type of the field in the content type definition does not match the data type of its content handler's property. ", "Please modify the field type in the content type definition. ", "ContentTypeDefinition: '", contentType.Name, "', FieldName: '", fieldSetting.Name, "', DataType of Field's binding: '", fieldSetting.DataTypes[i], "', ContentHandler: '", handlerType.FullName, "', PropertyName: '", propReg.Name, "', DataType of property: '", propReg.DataType, "'")); } ok = true; fieldSetting.HandlerSlotIndices[i] = j; fieldSetting.PropertyIsReadOnly = !PropertyHasPublicSetter(propInfo); break; } } if (!ok) { if (fieldSetting.ShortName == "Reference" || fieldSetting.DataTypes[i] == RepositoryDataType.Reference) { CheckReference(propInfo, slots[i], contentType, fieldSetting); } else { throw new ContentRegistrationException(SR.Exceptions.Registration.Msg_PropertyAndFieldAreNotConnectable, contentType.Name, fieldSetting.Name); } } } else { // #2: there is not a property under the slot: PropertyTypeRegistration propReg = new PropertyTypeRegistration(propName, dataType); ntReg.PropertyTypeRegistrations.Add(propReg); } } } // Collect deletables. Check equals foreach (PropertyType propType in nodeType.PropertyTypes.ToArray()) { PropertyTypeRegistration propReg = ntReg.PropertyTypeRegistrationByName(propType.Name); if (propReg == null) { editor.RemovePropertyTypeFromPropertySet(propType, nodeType); } } // Register foreach (PropertyTypeRegistration ptReg in ntReg.PropertyTypeRegistrations) { PropertyType propType = nodeType.PropertyTypes[ptReg.Name]; if (propType == null) { propType = editor.PropertyTypes[ptReg.Name]; if (propType == null) { propType = editor.CreatePropertyType(ptReg.Name, ConvertDataType(ptReg.DataType)); } editor.AddPropertyTypeToPropertySet(propType, nodeType); } } }