示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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");
            }
        }
示例#5
0
        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);
        }