PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/ThinkEmailFomatter/Models/BusinessObjects/ThinkStreamToObject.cs

https://bitbucket.org/nicdao/frg-think-emailformatter
C# | 132 lines | 96 code | 19 blank | 17 comment | 18 complexity | 07debde784bc6b1710f2d5c3062c61f6 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.IO;
  6. using System.Xml;
  7. using System.Xml.Linq;
  8. using ThinkEmailFormatter.Models;
  9. namespace ThinkEmailFormatter.Models
  10. {
  11. /// <summary>
  12. /// Convert the HTTP-POSTed XML stream coming from THINK into
  13. /// a Business object
  14. /// </summary>
  15. /// <typeparam name="T"></typeparam>
  16. public class ThinkStreamToObject<T> where T: new()
  17. {
  18. #region[ MEMBERS ]
  19. public readonly XElement _xmlElement;
  20. #endregion
  21. #region [ CONSTRUCTORS ]
  22. public ThinkStreamToObject(Stream xmlStream)
  23. {
  24. XmlDocument doc = new XmlDocument();
  25. doc.Load(xmlStream);
  26. _xmlElement = XElement.Load(new XmlNodeReader(doc));
  27. }
  28. public ThinkStreamToObject(XElement xmlElement)
  29. {
  30. _xmlElement = xmlElement;
  31. }
  32. #endregion
  33. #region [ METHODS ]
  34. /// <summary>
  35. /// Convert XML stream. So far that convertion can, at least,
  36. /// convert the XML related to the following THINK events:
  37. /// - Order Item Added
  38. /// - Customer Added
  39. /// - Order Renewed
  40. /// - Password Changed
  41. /// </summary>
  42. /// <returns></returns>
  43. public T Convert()
  44. {
  45. if (_xmlElement == null)
  46. {
  47. return default(T);
  48. }
  49. else
  50. {
  51. T convertedObj = new T();
  52. var properties = convertedObj.GetType().GetProperties();
  53. Type stringType = typeof(string);
  54. foreach (var property in properties)
  55. {
  56. dynamic propertyValue = null;
  57. // if this is a string, it means this is an attribute of node convertedObj.XmlElementName
  58. // Gets its value from the xmlStream
  59. if (property.PropertyType == stringType)
  60. {
  61. // TODO: FIx this horrible "td_email_recipient" hard-coded value
  62. if (property.Name == "td_email_recipient")
  63. {
  64. var emailAddress = _xmlElement.Element("td_email_recipient").FirstNode;
  65. propertyValue = emailAddress == null ? string.Empty : emailAddress.ToString();
  66. }
  67. else
  68. {
  69. var attrValue = _xmlElement.Attribute(property.Name);
  70. if (attrValue != null)
  71. propertyValue = (string)attrValue;
  72. }
  73. }
  74. else if (property.PropertyType.IsGenericType) // This is a children of node convertedObj.XmlElementName, and there may be more than one
  75. {
  76. var childrenElements = _xmlElement.Elements(property.Name);
  77. propertyValue = Activator.CreateInstance(property.PropertyType);
  78. foreach (XElement xelement in childrenElements)
  79. {
  80. if (xelement != null)
  81. {
  82. dynamic o = CreateInstance(property.PropertyType.GetGenericArguments()[0], xelement);
  83. propertyValue.Add(o.Convert());
  84. }
  85. }
  86. }
  87. else // This is a children of node convertedObj.XmlElementName
  88. {
  89. XElement childrenElement = _xmlElement.Elements(property.Name).FirstOrDefault();
  90. if (childrenElement != null)
  91. {
  92. dynamic o = CreateInstance(property.PropertyType, childrenElement);
  93. propertyValue = o.Convert();
  94. }
  95. }
  96. if (propertyValue != null)
  97. property.SetValue(convertedObj, propertyValue, null);
  98. }
  99. return convertedObj;
  100. }
  101. }
  102. private dynamic CreateInstance(Type genericType, XElement arg )
  103. {
  104. Type d1 = typeof(ThinkStreamToObject<>);
  105. Type[] typeArgs = { genericType };
  106. Type constructed = d1.MakeGenericType(typeArgs);
  107. object[] args = { arg };
  108. dynamic o = Activator.CreateInstance(constructed, args);
  109. return o;
  110. }
  111. #endregion
  112. }
  113. }