private void WriteTemplateToCode(DataTemplate dataTemplate, SourceCode code) { var templateCanonicalName = _define.GetCanonicalName(dataTemplate); // root만 IData를 상속 받는다. code.Append(dataTemplate.Parent.IsRoot ? "public class {0} : IData" : "public class {0}", templateCanonicalName); code.BracketStart(); foreach (var child in dataTemplate.Children) WriteTemplateToCode(child, code); foreach (var attribute in dataTemplate.Attributes) { var valueType = DataTemplateHelper.InferenceType(attribute.Value); if (valueType == "enum") { var enumName = attribute.Key + (attribute.Key.EndsWith("s") || attribute.Key.EndsWith("x") ? "es" : "s"); if (attribute.Key.Equals("id", StringComparison.OrdinalIgnoreCase)) code.Append("public int {0} {{ get; set; }}", attribute.Key); else code.Append("public {0} {1} {{ get; set; }}", enumName, attribute.Key); code.Append("public enum {0}", enumName); code.BracketStart(); foreach (var value in attribute.Value.Distinct()) code.Append("{0},", value.Substring(1).ToCamelCase()); // remove leading _ character. code.BracketEnd(); } else code.Append("public {0} {1} {{ get; set; }}", valueType, attribute.Key); } foreach (var attributeName in from e in dataTemplate.Attributes where e.Key.EndsWith("Ref") select e.Key) { // Ref를 제거하고 남은 이름 var typeName = attributeName.Substring(0, attributeName.Length - 3); code.Append("public {0} {0} {{ get {{ return DataCenter.Instance[typeof ({0}), {1}] as {0}; }} }}", typeName, attributeName); } foreach (var child in dataTemplate.Children) code.Append("public List<{0}> {0}s {{ get; private set; }}", _define.GetCanonicalName(child)); if (dataTemplate.Children.Count > 0) { code.NewLine(); code.Append("public {0}()", templateCanonicalName); code.BracketStart(); foreach (var child in dataTemplate.Children) code.Append("{0}s = new List<{0}>();", _define.GetCanonicalName(child)); code.BracketEnd(); } code.BracketEnd(); code.NewLine(); }
private static void FillTemplateFromXml(XmlNode dataListNode, DataTemplate dataTemplate) { foreach (var dataNode in dataListNode.ChildNodes.OfType<XmlElement>()) { foreach (var attribute in dataNode.Attributes.OfType<XmlAttribute>()) dataTemplate.AddAttribute(attribute.Name.ToCamelCase(), attribute.Value); if (!dataNode.HasChildNodes) continue; var childNode = dataNode.FirstChild; if (childNode is XmlText) dataTemplate.AddAttribute("Text", dataNode.FirstChild.Value); else { LoadOrFillChildTemplateFromXml(dataTemplate, childNode); } } }
public string GetCanonicalName(DataTemplate dataTemplate) { if (dataTemplate.Parent.IsRoot) return dataTemplate.Name; var concatenated = GetCanonicalName(dataTemplate.Parent).ToUnderscored() + '_' + dataTemplate.Name.ToUnderscored(); var firstCandidate = dataTemplate.Name; var secondCandidate = string.Join("_", concatenated.Split('_').Distinct()).ToCamelCase(); var thirdCandiate = concatenated.ToCamelCase(); var usingNames = new HashSet<string>(); for (var iterator = dataTemplate.Parent; iterator != null; iterator = iterator.Parent) usingNames.Add(iterator.Name); foreach (var each in _rootTemplate.Children) usingNames.Add(each.Name); if (!usingNames.Contains(firstCandidate)) return firstCandidate; if (!usingNames.Contains(secondCandidate)) return secondCandidate; if (!usingNames.Contains(thirdCandiate)) return thirdCandiate; throw new InvalidDataException("Cannot make acceptable name(" + dataTemplate.Name + ")."); }
public void AddChild(DataTemplate child) { child.Parent = this; Children.Add(child); }
private static DataTemplate LoadTemplateFromXml(XmlNode dataListNode) { var template = new DataTemplate {Name = GetDataTemplateNameFromListNode(dataListNode)}; FillTemplateFromXml(dataListNode, template); return template; }
private static void LoadOrFillChildTemplateFromXml(DataTemplate dataTemplate, XmlNode dataListNode) { var childName = GetDataTemplateNameFromListNode(dataListNode); var childTemplate = dataTemplate.Children.SingleOrDefault(e => e.Name.Equals(childName)); if (childTemplate != null) FillTemplateFromXml(dataListNode, childTemplate); else dataTemplate.AddChild(LoadTemplateFromXml(dataListNode)); }
private object ReadObjectFromXml(XmlNode dataNode, Type parentType, DataTemplate template) { var dataClassName = _define.GetCanonicalName(template); Type dataType; if (parentType == null) { if (!TypeMap.ContainsKey(dataClassName)) { return(null); } dataType = TypeMap[dataClassName]; } else { dataType = parentType.GetNestedType(dataClassName); } var idEnumType = dataType.GetNestedType("Ids"); var hasIdEnum = idEnumType != null; var dataObject = Activator.CreateInstance(dataType); if (dataNode.Attributes != null) { foreach (var attribute in dataNode.Attributes.OfType <XmlAttribute>()) { var attributeName = attribute.Name.ToCamelCase(); var attributeProperty = dataType.GetProperty(attributeName); if (attributeProperty == null) { continue; } var isIdAttribute = attributeProperty.Name.Equals("Id"); if (attributeProperty.PropertyType.IsEnum || (isIdAttribute && hasIdEnum)) { var enumString = attribute.Value.Substring(1); // remove leading _ character. var enumType = isIdAttribute ? idEnumType : attributeProperty.PropertyType; Debug.Assert(enumType != null); var enumValue = Enum.Parse(enumType, enumString, true); attributeProperty.SetValue(dataObject, Convert.ChangeType(enumValue, attributeProperty.PropertyType)); } else { attributeProperty.SetValue(dataObject, Convert.ChangeType(attribute.Value, attributeProperty.PropertyType)); } } } if (dataNode.HasChildNodes) { var childNode = dataNode.FirstChild; if (childNode is XmlText) { var textProperty = dataType.GetProperty("Text"); textProperty.SetValue(dataObject, dataNode.FirstChild.Value); } else { var listMap = new Dictionary <PropertyInfo, IList>(); foreach (var childDataNode in childNode.ChildNodes.OfType <XmlElement>()) { var childNodeName = DataTemplateDefine.GetDataTemplateNameFromDataNode(childDataNode); var childTemplate = template.Children.Single(e => e.Name.Equals(childNodeName)); var childClassName = _define.GetCanonicalName(childTemplate); var listProperty = dataType.GetProperty(childClassName + "s"); if (!listMap.ContainsKey(listProperty)) { listMap.Add(listProperty, Activator.CreateInstance(listProperty.PropertyType) as IList); } var childObject = ReadObjectFromXml(childDataNode, dataType, childTemplate); if (childObject == null) { continue; } listMap[listProperty].Add(childObject); } foreach (var pair in listMap) { pair.Key.SetValue(dataObject, pair.Value); } } } return(dataObject); }