public void AddMap (RuntimeAddin addin, string xmlMap, string fileId) { XmlDocument doc = new XmlDocument (); doc.LoadXml (xmlMap); foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("DataItem")) { string tname = elem.GetAttribute ("class"); Type type = addin.GetType (tname); if (type == null) { LoggingService.LogError ("[SerializationMap " + fileId + "] Type not found: '" + tname + "'"); continue; } string cname = elem.GetAttribute ("name"); string ftname = elem.GetAttribute ("fallbackType"); SerializationMap map; if (!maps.TryGetValue (type, out map)) { map = new SerializationMap (type); maps [type] = map; map.FileId = fileId; if (cname.Length > 0 || ftname.Length > 0) { DataItemAttribute iat = new DataItemAttribute (); if (cname.Length > 0) iat.Name = cname; if (ftname.Length > 0) iat.FallbackType = addin.GetType (ftname, true); map.TypeAttributes.Add (iat); } } else { if (!string.IsNullOrEmpty (cname)) throw new InvalidOperationException (string.Format ("Type name for type '{0}' in map '{1}' already specified in another serialization map for the same type ({2}).", type, fileId, map.FileId)); if (!string.IsNullOrEmpty (ftname)) throw new InvalidOperationException (string.Format ("Fallback type for type '{0}' in map '{1}' already specified in another serialization map for the same type ({2}).", type, fileId, map.FileId)); } string customDataItem = elem.GetAttribute ("customDataItem"); if (customDataItem.Length > 0) { ICustomDataItemHandler ch = (ICustomDataItemHandler) addin.CreateInstance (customDataItem, true); if (map.CustomHandler != null) map.CustomHandler = new CustomDataItemHandlerChain (map.CustomHandler, ch); else map.CustomHandler = ch; } ItemMember lastMember = null; int litc = 0; foreach (XmlElement att in elem.SelectNodes ("ItemProperty|ExpandedCollection|LiteralProperty|ItemMember")) { string memberName = null; ItemMember prevMember = lastMember; lastMember = null; if (att.Name == "LiteralProperty") { ItemMember mem = new ItemMember (); memberName = mem.Name = "_literal_" + (++litc); mem.Type = typeof(string); mem.InitValue = att.GetAttribute ("value"); mem.DeclaringType = map.Type; map.ExtendedMembers.Add (mem); ItemPropertyAttribute itemAtt = new ItemPropertyAttribute (); itemAtt.Name = att.GetAttribute ("name"); map.AddMemberAttribute (mem, itemAtt); lastMember = mem; continue; } else if (att.Name == "ItemMember") { ItemMember mem = new ItemMember (); memberName = mem.Name = att.GetAttribute ("name"); mem.Type = addin.GetType (att.GetAttribute ("type"), true); mem.DeclaringType = map.Type; map.ExtendedMembers.Add (mem); lastMember = mem; continue; } else { memberName = att.GetAttribute ("member"); Type mt; object mi; if (!FindMember (map, memberName, out mi, out mt)) { LoggingService.LogError ("[SerializationMap " + fileId + "] Member '" + memberName + "' not found in type '" + tname + "'"); continue; } if (att.Name == "ItemProperty") { ItemPropertyAttribute itemAtt = new ItemPropertyAttribute (); string val = att.GetAttribute ("name"); if (val.Length > 0) itemAtt.Name = val; val = att.GetAttribute ("scope"); if (val.Length > 0) itemAtt.Scope = val; if (att.Attributes ["defaultValue"] != null) { if (mt.IsEnum) itemAtt.DefaultValue = Enum.Parse (mt, att.GetAttribute ("defaultValue")); else itemAtt.DefaultValue = Convert.ChangeType (att.GetAttribute ("defaultValue"), mt); } val = att.GetAttribute ("serializationDataType"); if (val.Length > 0) itemAtt.SerializationDataType = addin.GetType (val, true); val = att.GetAttribute ("valueType"); if (val.Length > 0) itemAtt.ValueType = addin.GetType (val, true); val = att.GetAttribute ("readOnly"); if (val.Length > 0) itemAtt.ReadOnly = bool.Parse (val); val = att.GetAttribute ("writeOnly"); if (val.Length > 0) itemAtt.WriteOnly = bool.Parse (val); val = att.GetAttribute ("fallbackType"); if (val.Length > 0) itemAtt.FallbackType = addin.GetType (val, true); val = att.GetAttribute ("isExternal"); if (val.Length > 0) itemAtt.IsExternal = bool.Parse (val); val = att.GetAttribute ("skipEmpty"); if (val.Length > 0) itemAtt.SkipEmpty = bool.Parse (val); map.AddMemberAttribute (mi, itemAtt); } else if (att.Name == "ExpandedCollection") { ExpandedCollectionAttribute eat = new ExpandedCollectionAttribute (); map.AddMemberAttribute (mi, eat); } } if (prevMember != null) prevMember.InsertBefore = memberName; } } }
public void AddMap(RuntimeAddin addin, string xmlMap, string fileId) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlMap); foreach (XmlElement elem in doc.DocumentElement.SelectNodes("DataItem")) { string tname = elem.GetAttribute("class"); Type type = addin.GetType(tname); if (type == null) { LoggingService.LogError("[SerializationMap " + fileId + "] Type not found: '" + tname + "'"); continue; } string cname = elem.GetAttribute("name"); string ftname = elem.GetAttribute("fallbackType"); SerializationMap map; if (!maps.TryGetValue(type, out map)) { map = new SerializationMap(type); maps [type] = map; map.FileId = fileId; if (cname.Length > 0 || ftname.Length > 0) { DataItemAttribute iat = new DataItemAttribute(); if (cname.Length > 0) { iat.Name = cname; } if (ftname.Length > 0) { iat.FallbackType = addin.GetType(ftname, true); } map.TypeAttributes.Add(iat); } } else { if (!string.IsNullOrEmpty(cname)) { throw new InvalidOperationException(string.Format("Type name for type '{0}' in map '{1}' already specified in another serialization map for the same type ({2}).", type, fileId, map.FileId)); } if (!string.IsNullOrEmpty(ftname)) { throw new InvalidOperationException(string.Format("Fallback type for type '{0}' in map '{1}' already specified in another serialization map for the same type ({2}).", type, fileId, map.FileId)); } } string customDataItem = elem.GetAttribute("customDataItem"); if (customDataItem.Length > 0) { ICustomDataItemHandler ch = (ICustomDataItemHandler)addin.CreateInstance(customDataItem, true); if (map.CustomHandler != null) { map.CustomHandler = new CustomDataItemHandlerChain(map.CustomHandler, ch); } else { map.CustomHandler = ch; } } ItemMember lastMember = null; int litc = 0; foreach (XmlElement att in elem.SelectNodes("ItemProperty|ExpandedCollection|LiteralProperty|ItemMember")) { string memberName = null; ItemMember prevMember = lastMember; lastMember = null; if (att.Name == "LiteralProperty") { ItemMember mem = new ItemMember(); memberName = mem.Name = "_literal_" + (++litc); mem.Type = typeof(string); mem.InitValue = att.GetAttribute("value"); mem.DeclaringType = map.Type; map.ExtendedMembers.Add(mem); ItemPropertyAttribute itemAtt = new ItemPropertyAttribute(); itemAtt.Name = att.GetAttribute("name"); map.AddMemberAttribute(mem, itemAtt); lastMember = mem; continue; } else if (att.Name == "ItemMember") { ItemMember mem = new ItemMember(); memberName = mem.Name = att.GetAttribute("name"); mem.Type = addin.GetType(att.GetAttribute("type"), true); mem.DeclaringType = map.Type; map.ExtendedMembers.Add(mem); lastMember = mem; continue; } else { memberName = att.GetAttribute("member"); Type mt; object mi; if (!FindMember(map, memberName, out mi, out mt)) { LoggingService.LogError("[SerializationMap " + fileId + "] Member '" + memberName + "' not found in type '" + tname + "'"); continue; } if (att.Name == "ItemProperty") { ItemPropertyAttribute itemAtt = new ItemPropertyAttribute(); string val = att.GetAttribute("name"); if (val.Length > 0) { itemAtt.Name = val; } val = att.GetAttribute("scope"); if (val.Length > 0) { itemAtt.Scope = val; } if (att.Attributes ["defaultValue"] != null) { if (mt.IsEnum) { itemAtt.DefaultValue = Enum.Parse(mt, att.GetAttribute("defaultValue")); } else { itemAtt.DefaultValue = Convert.ChangeType(att.GetAttribute("defaultValue"), mt); } } val = att.GetAttribute("serializationDataType"); if (val.Length > 0) { itemAtt.SerializationDataType = addin.GetType(val, true); } val = att.GetAttribute("valueType"); if (val.Length > 0) { itemAtt.ValueType = addin.GetType(val, true); } val = att.GetAttribute("readOnly"); if (val.Length > 0) { itemAtt.ReadOnly = bool.Parse(val); } val = att.GetAttribute("writeOnly"); if (val.Length > 0) { itemAtt.WriteOnly = bool.Parse(val); } val = att.GetAttribute("fallbackType"); if (val.Length > 0) { itemAtt.FallbackType = addin.GetType(val, true); } val = att.GetAttribute("isExternal"); if (val.Length > 0) { itemAtt.IsExternal = bool.Parse(val); } val = att.GetAttribute("skipEmpty"); if (val.Length > 0) { itemAtt.SkipEmpty = bool.Parse(val); } map.AddMemberAttribute(mi, itemAtt); } else if (att.Name == "ExpandedCollection") { ExpandedCollectionAttribute eat = new ExpandedCollectionAttribute(); map.AddMemberAttribute(mi, eat); } } if (prevMember != null) { prevMember.InsertBefore = memberName; } } } }
protected override void Initialize() { DataItemAttribute atd = (DataItemAttribute)Context.AttributeProvider.GetCustomAttribute(ValueType, typeof(DataItemAttribute), false); if (atd != null) { if (!string.IsNullOrEmpty(atd.Name)) { Name = atd.Name; } if (atd.FallbackType != null) { fallbackType = atd.FallbackType; if (!typeof(IExtendedDataItem).IsAssignableFrom(fallbackType)) { throw new InvalidOperationException("Fallback type '" + fallbackType + "' must implement IExtendedDataItem"); } if (!ValueType.IsAssignableFrom(fallbackType)) { throw new InvalidOperationException("Fallback type '" + fallbackType + "' must be a subclass of '" + ValueType + "'"); } } } object[] incs = Attribute.GetCustomAttributes(ValueType, typeof(DataIncludeAttribute), true); foreach (DataIncludeAttribute incat in incs) { Context.IncludeType(incat.Type); } if (ValueType.BaseType != null) { ClassDataType baseType = (ClassDataType)Context.GetConfigurationDataType(ValueType.BaseType); baseType.AddSubtype(this); int n = 0; foreach (ItemProperty prop in baseType.Properties) { properties.Add(prop.Name, prop); sortedPoperties.Insert(n++, prop); } // Inherit the fallback type if (fallbackType == null && baseType.fallbackType != null) { fallbackType = baseType.fallbackType; } } foreach (Type interf in ValueType.GetInterfaces()) { ClassDataType baseType = (ClassDataType)Context.GetConfigurationDataType(interf); baseType.AddSubtype(this); } MemberInfo[] members = ValueType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (MemberInfo member in members) { if ((member is FieldInfo || member is PropertyInfo) && member.DeclaringType == ValueType) { Type memberType = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType; AddProperty(member, member.Name, memberType); } } foreach (ItemMember member in Context.AttributeProvider.GetItemMembers(ValueType)) { AddProperty(member, member.Name, member.Type); } if (fallbackType != null) { Context.IncludeType(fallbackType); } }