bool FindMember(SerializationMap map, string name, out object member, out Type memberType) { FieldInfo fi = map.Type.GetField(name, bindingFlags); if (fi != null) { memberType = fi.FieldType; member = fi; return(true); } PropertyInfo pi = map.Type.GetProperty(name, bindingFlags); if (pi != null) { memberType = pi.PropertyType; member = pi; return(true); } foreach (ItemMember mem in map.ExtendedMembers) { if (mem.Name == name) { member = mem; memberType = mem.Type; return(true); } } member = null; memberType = null; return(false); }
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; } } }
bool FindMember (SerializationMap map, string name, out object member, out Type memberType) { FieldInfo fi = map.Type.GetField (name, bindingFlags); if (fi != null) { memberType = fi.FieldType; member = fi; return true; } PropertyInfo pi = map.Type.GetProperty (name, bindingFlags); if (pi != null) { memberType = pi.PropertyType; member = pi; return true; } foreach (ItemMember mem in map.ExtendedMembers) { if (mem.Name == name) { member = mem; memberType = mem.Type; return true; } } member = null; memberType = null; return false; }