/// <summary> /// Creates an XElement from the given IRecord /// </summary> /// <param name="obj"></param> /// <returns></returns> private XElement GetBeerXElement(IRecord obj) { XElement element = new XElement(obj.GetType().Name.ToUpperInvariant()); Type objType = obj.GetType(); foreach (KeyValuePair <string, BeerXMLProperty> typeProperty in BeerXMLProperty.GetBeerXMLPropertyList(objType)) { BeerXMLProperty beerXmlProperty = typeProperty.Value; string propertyName = beerXmlProperty.Name; object propertyValue = beerXmlProperty.Property.GetValue(obj); if (ShouldAddProperty(beerXmlProperty.Attribute, propertyValue)) { if (beerXmlProperty.IsIBeerXMLEntity) { element.Add(GetBeerXElement((IBeerXMLEntity)propertyValue)); } else { element.Add(new XElement(propertyName, GetStringFromProperty(beerXmlProperty.Property.PropertyType, propertyValue))); } } } return(element); }
/// <summary> /// Sets the type of the property by. /// </summary> /// <param name="beerXMLProperty">The beer XML property.</param> /// <param name="entity">The entity.</param> /// <param name="currentXElement">The current x element.</param> private void SetPropertyByType(BeerXMLProperty beerXMLProperty, IBeerXMLEntity entity, XElement currentXElement) { if (beerXMLProperty.IsIBeerXMLEntity) { IBeerXMLEntity childEntity = this.GetEntityFromElement(currentXElement); // could be null if it is an invalid tag if (childEntity != null) { beerXMLProperty.Property.SetValue(entity, childEntity); } } else { // not an IBeerXMLEntity beerXMLProperty.Property.SetValue(entity, ParseType(beerXMLProperty.Property.PropertyType, currentXElement.Value)); } }
/// <summary> /// Ensures the property mapping dictionaries are built. /// </summary> private static void EnsurePropertyMappings() { // dictionaries are built, just return if (_isInit) { return; } // get the assembly Assembly assembly = Assembly.GetExecutingAssembly(); // find every IBeerXMLEntity type in the assembly that is a non-abstract class foreach (Type type in assembly.GetTypes().Where(t => typeof(IBeerXMLEntity).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)) { // add the name -> type mapping _typeNameToTypeMap.Add(type.Name, type); IDictionary <string, BeerXMLProperty> propInfoList = new Dictionary <string, BeerXMLProperty>(StringComparer.OrdinalIgnoreCase); // find every property that has the BeerXMLIncludeAttribute on it foreach (PropertyInfo property in type.GetProperties()) { BeerXMLIncludeAttribute attribute = property.GetCustomAttribute(typeof(BeerXMLIncludeAttribute), inherit: true) as BeerXMLIncludeAttribute; if (attribute != null) { BeerXMLProperty prop = new BeerXMLProperty(property, attribute, typeof(IBeerXMLEntity).IsAssignableFrom(property.PropertyType)); propInfoList.Add(prop.Name, prop); } } // add to dictionary _typeToPropertyMap.Add(type, propInfoList); } // don't run this again _isInit = true; }
/// <summary> /// Parses an IBeerXMLEntity from the given XElement /// </summary> /// <param name="element">The element.</param> /// <returns></returns> private IBeerXMLEntity GetEntityFromElement(XElement element) { // get the name of the child property string propertyName = element.Name.ToString(); Type objectType = BeerXMLProperty.TryGetTypeByName(propertyName); // throw if the name of this tag does not have a corresponding // BeerXML type if (objectType == null) { if (this.StrictModeEnabled) { throw new BeerXMLUnknownTypeTagException(propertyName, string.Format("Tag with name [{0}] has no corresponding IBeerXMLEntity type!", propertyName)); } return(null); } // create the empty IBeerXMLEntity IBeerXMLEntity objectFromXElement = (IBeerXMLEntity)Activator.CreateInstance(objectType, nonPublic: true); // IRecordSets need to have their child records // deserialized and added to the collection if (objectFromXElement is IRecordSet) { IRecordSet objAsRecordSet = objectFromXElement as IRecordSet; foreach (XElement childElement in element.Elements()) { IRecord child = GetEntityFromElement(childElement) as IRecord; // could be null if it was an invalid tag. // Invalid tags are ignored if (child != null) { objAsRecordSet.Add(child); } } return(objAsRecordSet); } // get the dictionary of property name to property for this type IDictionary <string, BeerXMLProperty> propertyList = BeerXMLProperty.GetBeerXMLPropertyList(objectType); // foreach child element, set the property foreach (XElement childElement in element.Elements()) { string childName = childElement.Name.ToString(); // this means that the given tag is unrecognized - since the overall // property type is recognized, just ignore it if (!propertyList.ContainsKey(childName)) { continue; } BeerXMLProperty property = propertyList[childName]; SetPropertyByType(property, objectFromXElement, childElement); } return(objectFromXElement); }