PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/ResourceManagement.Client/RmResourceFactory.cs

#
C# | 276 lines | 233 code | 21 blank | 22 comment | 48 complexity | c1478073f83148deda925742ee835e85 MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Microsoft.ResourceManagement.Client.WsTransfer;
  5. using Microsoft.ResourceManagement.Client.WsEnumeration;
  6. using Microsoft.ResourceManagement.ObjectModel;
  7. using System.Xml;
  8. using System.Xml.Schema;
  9. using System.Text;
  10. namespace Microsoft.ResourceManagement.Client
  11. {
  12. /// <summary>
  13. /// This class constructs RmResource objects from web service request and response messages.
  14. /// </summary>
  15. public class RmResourceFactory : RmFactory
  16. {
  17. IResourceTypeFactory resourceTypeFactory;
  18. const String ObjectType = @"ObjectType";
  19. const String ObjectID = @"ObjectID";
  20. public RmResourceFactory()
  21. : this(new XmlSchemaSet())
  22. { }
  23. public RmResourceFactory(XmlSchemaSet rmSchema)
  24. : this(rmSchema, new DefaultResourceTypeFactory())
  25. {
  26. }
  27. public RmResourceFactory(XmlSchemaSet rmSchema, IResourceTypeFactory resourceTypeFactory)
  28. : base(rmSchema)
  29. {
  30. if (resourceTypeFactory == null)
  31. {
  32. throw new ArgumentNullException("resourceTypeFactory");
  33. }
  34. this.resourceTypeFactory = resourceTypeFactory;
  35. }
  36. /// <summary>
  37. /// Returns a generic RmResource object from the getResponse object.
  38. /// </summary>
  39. /// <param name="getResponse">The get response from the server.</param>
  40. /// <returns>The RmResource object with the attributes returned in getResponse.</returns>
  41. public RmResource CreateResource(GetResponse getResponse)
  42. {
  43. if (getResponse == null)
  44. {
  45. throw new ArgumentNullException("getResponse");
  46. }
  47. if (getResponse.BaseObjectSearchResponse == null)
  48. {
  49. throw new ArgumentNullException("getResponse.BaseObjectSearchResponse");
  50. }
  51. lock (getResponse)
  52. {
  53. // look ahead for the type
  54. String objectType = null;
  55. foreach (PartialAttributeType partialAttribute in getResponse.BaseObjectSearchResponse.PartialAttributes)
  56. {
  57. if (partialAttribute.Values.Count > 0)
  58. {
  59. String localName = partialAttribute.Values[0].LocalName;
  60. if (String.IsNullOrEmpty(localName))
  61. {
  62. continue;
  63. }
  64. if (localName.Equals(ObjectType))
  65. {
  66. objectType = partialAttribute.Values[0].InnerText;
  67. break;
  68. }
  69. }
  70. }
  71. if (objectType == null)
  72. {
  73. objectType = string.Empty;
  74. }
  75. RmResource rmResource = this.resourceTypeFactory.CreateResource(objectType);
  76. // fill in the attribute values
  77. foreach (PartialAttributeType partialAttribute in getResponse.BaseObjectSearchResponse.PartialAttributes)
  78. {
  79. RmAttributeName attributeName = null;
  80. RmAttributeValue newAttribute = null;
  81. if (partialAttribute.Values.Count > 0)
  82. {
  83. String localName = partialAttribute.Values[0].LocalName;
  84. if (String.IsNullOrEmpty(localName))
  85. {
  86. continue;
  87. }
  88. else
  89. {
  90. attributeName = new RmAttributeName(localName);
  91. }
  92. }
  93. else
  94. {
  95. continue;
  96. }
  97. if (rmResource.TryGetValue(attributeName, out newAttribute) == false)
  98. {
  99. newAttribute = new RmAttributeValue();
  100. }
  101. // add values to the typed list
  102. foreach (XmlNode value in partialAttribute.Values)
  103. {
  104. IComparable newValue = this.ConstructAttributeValue(attributeName, value.InnerText);
  105. if (base.IsMultiValued(attributeName) == false)
  106. newAttribute.Values.Clear();
  107. if (attributeName.Name.Equals(ObjectType) || attributeName.Name.Equals(ObjectID))
  108. newAttribute.Values.Clear();
  109. newAttribute.Values.Add(newValue);
  110. }
  111. }
  112. return rmResource;
  113. }
  114. }
  115. /// <summary>
  116. /// Creates a list of resources based on the pull or enumerate response.
  117. /// </summary>
  118. /// <param name="pullOrEnumerateResponse">The pull or enumerate response to use when creating resources.</param>
  119. /// <returns>The list of strongly-typed resources in the pull or enumerate response.</returns>
  120. public List<RmResource> CreateResource(PullResponse pullOrEnumerateResponse)
  121. {
  122. if (pullOrEnumerateResponse == null)
  123. {
  124. throw new ArgumentNullException("pullOrEnumerateResponse");
  125. }
  126. if (pullOrEnumerateResponse.Items == null || pullOrEnumerateResponse.Items.Values == null)
  127. {
  128. return new List<RmResource>();
  129. }
  130. lock (pullOrEnumerateResponse)
  131. {
  132. List<RmResource> retList = new List<RmResource>();
  133. foreach (XmlNode obj in pullOrEnumerateResponse.Items.Values)
  134. {
  135. // look ahead for the type info;
  136. String objectType = null;
  137. foreach (XmlNode child in obj.ChildNodes)
  138. {
  139. if (child.NodeType == XmlNodeType.Element)
  140. {
  141. if (child.LocalName.Equals(@"ObjectType"))
  142. {
  143. objectType = child.InnerText;
  144. break;
  145. }
  146. }
  147. }
  148. if (objectType == null)
  149. {
  150. objectType = String.Empty;
  151. }
  152. RmResource rmResource = this.resourceTypeFactory.CreateResource(objectType);
  153. // now add the attributes to the resource object
  154. foreach (XmlNode child in obj.ChildNodes)
  155. {
  156. if (child.NodeType == XmlNodeType.Element)
  157. {
  158. RmAttributeName attributeName = new RmAttributeName(child.LocalName);
  159. IComparable attributeValue = this.ConstructAttributeValue(attributeName, child.InnerText);
  160. if (attributeValue == null)
  161. continue;
  162. RmAttributeValue newAttribute = null;
  163. if (rmResource.TryGetValue(attributeName, out newAttribute) == false)
  164. {
  165. newAttribute = new RmAttributeValue();
  166. rmResource[attributeName] = newAttribute;
  167. }
  168. if (base.IsMultiValued(attributeName) == false)
  169. newAttribute.Values.Clear();
  170. if (attributeName.Name.Equals(ObjectType) || attributeName.Name.Equals(ObjectID))
  171. newAttribute.Values.Clear();
  172. newAttribute.Values.Add(attributeValue);
  173. }
  174. }
  175. retList.Add(rmResource);
  176. }
  177. return retList;
  178. }
  179. }
  180. protected IComparable ConstructAttributeValue(RmAttributeName attributeName, String innerText)
  181. {
  182. if (innerText == null)
  183. return null;
  184. RmAttributeInfo info = null;
  185. if (base.RmAttributeCache.TryGetValue(attributeName, out info) == false)
  186. {
  187. // just in case they forget to load schema... we know that ObjectId must remove the uuid reference
  188. if (attributeName.Name.Equals(ObjectID))
  189. {
  190. return new RmReference(innerText);
  191. }
  192. else
  193. {
  194. return innerText;
  195. }
  196. }
  197. try
  198. {
  199. switch (info.AttributeType)
  200. {
  201. case RmAttributeType.String:
  202. return innerText;
  203. case RmAttributeType.DateTime:
  204. return DateTime.Parse(innerText);
  205. case RmAttributeType.Integer:
  206. return Int32.Parse(innerText);
  207. case RmAttributeType.Reference:
  208. return new RmReference(innerText);
  209. case RmAttributeType.Binary:
  210. return new RmBinary(innerText);
  211. case RmAttributeType.Boolean:
  212. return Boolean.Parse(innerText);
  213. default:
  214. return innerText;
  215. }
  216. }
  217. catch (FormatException ex)
  218. {
  219. throw new ArgumentException(
  220. String.Format(
  221. "Failed to parse attribute {0} with value {1} into type {2}. Please ensure the resource management schema is up to date.",
  222. attributeName,
  223. innerText,
  224. info.AttributeType.ToString()),
  225. ex);
  226. }
  227. catch (System.Text.EncoderFallbackException ex)
  228. {
  229. throw new ArgumentException(
  230. String.Format(
  231. "Failed to convert the string on binary attribute {0} into byte array.",
  232. attributeName),
  233. ex);
  234. }
  235. }
  236. /// <summary>
  237. /// Gets or Sets the ResourceTypeFactory used to construct individual resource objects.
  238. /// </summary>
  239. public IResourceTypeFactory ResourceTypeFactory
  240. {
  241. get
  242. {
  243. return this.resourceTypeFactory;
  244. }
  245. set
  246. {
  247. if (value == null)
  248. {
  249. throw new ArgumentNullException("ResourceTypeFactory");
  250. }
  251. this.resourceTypeFactory = value;
  252. }
  253. }
  254. }
  255. }