PageRenderTime 24ms CodeModel.GetById 1ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/ResourceManagement.Client/RmResourceFactory.cs

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