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;
}
}
}