protected ItemPropertyAttribute FindPropertyAttribute(object[] attributes, string scope) { scope = scope.TrimStart('/'); foreach (object at in attributes) { ItemPropertyAttribute iat = at as ItemPropertyAttribute; if (iat != null && iat.Scope == scope) { return(iat); } } return(null); }
internal protected override object GetMapData(object[] attributes, string scope) { // We only need the fallback type for now ItemPropertyAttribute at = FindPropertyAttribute(attributes, scope); if (at != null) { return(at.FallbackType); } else { return(null); } }
internal protected override object GetMapData(object[] attributes, string scope) { DataType itemDataType = null; Type itemType = null; ItemPropertyAttribute at = FindPropertyAttribute(attributes, scope + "/*"); if (at != null) { itemType = at.ValueType; if (itemType == null) { itemType = handler.GetItemType(); } if (at.SerializationDataType != null) { itemDataType = (DataType)Activator.CreateInstance(at.SerializationDataType, new object[] { itemType }); } } if (itemType == null) { itemType = handler.GetItemType(); } if (itemDataType == null) { itemDataType = Context.GetConfigurationDataType(itemType); } object itemMapData = itemDataType.GetMapData(attributes, scope + "/*"); if (at == null && itemMapData == null) { return(null); } MapData data = new MapData(); data.ItemType = itemDataType; data.ItemName = (at != null && at.Name != null) ? at.Name : itemDataType.Name; data.ItemMapData = itemMapData; return(data); }
void AddProperty(object member, string name, Type memberType) { // Using inherit=false because if a base class already has an ItemProperty applied to the property // then that property will already have been added while copying props from the base class. object[] ats = Context.AttributeProvider.GetCustomAttributes(member, typeof(Attribute), false); ItemPropertyAttribute at = FindPropertyAttribute(ats, ""); if (at == null) { return; } ItemProperty prop = new ItemProperty(); prop.Name = (at.Name != null) ? at.Name : name; prop.ExpandedCollection = Context.AttributeProvider.IsDefined(member, typeof(ExpandedCollectionAttribute), true); prop.DefaultValue = at.DefaultValue; prop.IsExternal = at.IsExternal; prop.SkipEmpty = at.SkipEmpty; prop.ReadOnly = at.ReadOnly; prop.WriteOnly = at.WriteOnly; if (prop.ExpandedCollection) { ICollectionHandler handler = Context.GetCollectionHandler(memberType); if (handler == null) { throw new InvalidOperationException("ExpandedCollectionAttribute can't be applied to property '" + prop.Name + "' in type '" + ValueType + "' becuase it is not a valid collection."); } memberType = handler.GetItemType(); prop.ExpandedCollectionHandler = handler; } if (at.ValueType != null) { prop.PropertyType = at.ValueType; } else { prop.PropertyType = memberType; } if (at.SerializationDataType != null) { try { prop.DataType = (DataType)Activator.CreateInstance(at.SerializationDataType, new object[] { prop.PropertyType }); } catch (MissingMethodException ex) { throw new InvalidOperationException("Constructor not found for custom data type: " + at.SerializationDataType.Name + " (Type propertyType);", ex); } } if (member is MemberInfo) { prop.Member = (MemberInfo)member; AddProperty(prop); } else { prop.InitValue = ((ItemMember)member).InitValue; AddProperty(prop, ((ItemMember)member).InsertBefore); } prop.Initialize(ats, ""); if (prop.ExpandedCollection && prop.DataType.IsSimpleType) { throw new InvalidOperationException("ExpandedCollectionAttribute is not allowed in collections of simple types"); } }
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; } } }
internal protected override object GetMapData(object[] attributes, string scope) { Type keyType, valType; GetMapData(ValueType, out keyType, out valType); MapData data = new MapData(); data.KeyName = "Key"; data.ValueName = "Value"; data.ItemName = "Item"; DataType keyDataType = null; DataType valueDataType = null; ItemPropertyAttribute at = FindPropertyAttribute(attributes, scope + "/key"); if (at != null) { if (at.ValueType != null) { keyType = at.ValueType; } if (at.SerializationDataType != null) { keyDataType = (DataType)Activator.CreateInstance(at.SerializationDataType, new object[] { keyType }); } if (!string.IsNullOrEmpty(at.Name)) { data.KeyName = at.Name; } } if (keyDataType != null) { data.KeyType = keyDataType; } else { data.KeyType = Context.GetConfigurationDataType(keyType); } data.KeyMapData = data.KeyType.GetMapData(attributes, scope + "/key"); at = FindPropertyAttribute(attributes, scope + "/value"); if (at != null) { if (at.ValueType != null) { valType = at.ValueType; } if (at.SerializationDataType != null) { valueDataType = (DataType)Activator.CreateInstance(at.SerializationDataType, new object[] { valType }); } if (!string.IsNullOrEmpty(at.Name)) { data.ValueName = at.Name; } } if (valueDataType != null) { data.ValueType = valueDataType; } else { data.ValueType = Context.GetConfigurationDataType(valType); } data.ValueMapData = data.ValueType.GetMapData(attributes, scope + "/value"); at = FindPropertyAttribute(attributes, scope + "/item"); if (at != null && !string.IsNullOrEmpty(at.Name)) { data.ItemName = at.Name; } return(data); }