using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Xml; namespace Intel.Management.Wsman { class ManagedInstance : IManagedInstance { private WsmanConnection _conn; private XmlDocument _document; private XmlNamespaceManager _ns; public ManagedInstance(WsmanConnection conn, string xmlString) { _conn = conn; _document = new XmlDocument(); if (xmlString == null || xmlString.Equals(string.Empty)) return; if (xmlString.StartsWith("<")) { LoadDocument(xmlString); return; } if (xmlString.ToLower().StartsWith("select * from ")) { IManagedInstance inst = conn.GetReferenceFromSQL(xmlString).Get(); LoadDocument(inst.Xml); return; } string name = null; int pos = xmlString.LastIndexOf('/'); if (pos >= 0) { name = xmlString.Substring(pos + 1); LoadDocument( string.Format(WsmanResources.WSMAN_INSTANCE, name, xmlString) ); } else { name = xmlString; pos = name.IndexOf('_'); if (pos > 0) { string temp = xmlString; xmlString = _conn.ResolveNamespace(temp.Substring(0, pos)); if (xmlString != null && xmlString.EndsWith("/")) xmlString = xmlString + temp; } else xmlString = _conn.ResolveNamespace(name); if (xmlString == null) { throw new IndexOutOfRangeException( string.Format(WsmanResources.NS_NOT_FOUND, xmlString)); } LoadDocument( string.Format(WsmanResources.WSMAN_INSTANCE, name, xmlString) ); } } public IWsmanConnection Connection { get { return _conn; } } public string Xml { get { return _document.InnerXml; } set { _document.LoadXml(value); } } public string SimpleName { get { if (_document.DocumentElement != null) return _document.DocumentElement.LocalName; return string.Empty; } } public string MethodName { get { if (_document.DocumentElement != null) { if (_document.DocumentElement.LocalName.EndsWith("_INPUT")) return _document.DocumentElement.LocalName.Substring(0, _document.DocumentElement.LocalName.Length - "_INPUT".Length); } return string.Empty; } } public string ResourceUri { get { if (_document.DocumentElement != null) return _document.DocumentElement.NamespaceURI; return string.Empty; } } public IWsmanItem GetProperty(string name) { object result = null; XmlNodeList nodeList = _document.DocumentElement.SelectNodes( "p:" + name, _ns); if (nodeList != null && nodeList.Count > 1) result = new IWsmanItem[nodeList.Count]; for (int i = 0; nodeList != null && i < nodeList.Count; i++) { XmlNode node = nodeList.Item(i); if (node == null) continue; object item = ManagedReference.GetEmbeddedRef(_conn, node, _ns); if (item == null && node.FirstChild != null && node.FirstChild.NodeType == XmlNodeType.Element) { if (node.ChildNodes.Count > 1) { WsmanItem[] children = new WsmanItem[node.ChildNodes.Count]; for (int k = 0; k < children.Length; k++) children[k] = new WsmanItem(node.ChildNodes[k].InnerText); result = children; } else item = new ManagedInstance(_conn, node.InnerXml); } if (item == null) item = node.InnerText; if (result != null) ((IWsmanItem[])result)[i] = new WsmanItem(item); else result = new WsmanItem(item); } if (result is IWsmanItem[]) { result = new WsmanItem(result); } if (result == null) result = new WsmanItem(); return (IWsmanItem)result; } public IWsmanItem GetPropertyArray(string name) { IWsmanItem value = GetProperty(name); if (value != null) { if (value.IsArray) return value; IWsmanItem[] arr = new IWsmanItem[1]; arr[0] = value; return new WsmanItem(arr); } return null; } public IWsmanItem GetPropertyNames() { XmlNode node = _document.DocumentElement.FirstChild; List objects = new List(); while (node != null) { if (node.NodeType == XmlNodeType.Element) { XmlElement elt = (XmlElement)node; // no duplicates if (!objects.Contains(elt.LocalName)) objects.Add(elt.LocalName); } node = node.NextSibling; } return new WsmanItem(objects.ToArray()); } public void RemoveProperty(string name) { SetProperty(name, null); } public void SetProperty(object value) { PutProperty(null, value, true); } public void SetProperty(string name, object value) { PutProperty(name, value, true); } public void AddProperty(string name, object value) { PutProperty(name, value, false); } public string Text { get { return _document.DocumentElement.InnerText; } set { _document.DocumentElement.InnerText = value; } } public IManagedReference Create() { return (IManagedReference)_conn.SubmitRequest( string.Format(WsmanResources.CREATE_XML, ResourceUri), null, this); } public IManagedReference ToReference() { IWsmanItem items = GetPropertyNames(); List list = new List(); foreach (string name in items) { list.Add(name); } return ToReference(list.ToArray()); } public IManagedReference ToReference(string keyname) { string[] args = keyname.Split(' '); return ToReference(args); } public IManagedReference ToReference(string keyname1, string keyname2) { string[] args = { keyname1, keyname2 }; return ToReference(args); } public IManagedReference ToReference(string[] keyNames) { IManagedReference result = _conn.NewReference(ResourceUri); foreach (string keyname in keyNames) { IWsmanItem item = GetProperty(keyname); if (item.IsString) result.AddSelector(keyname, item.ToString()); else if (item.IsRef) result.AddSelector(keyname, item.Ref); } return result; } private void PutObject(XmlElement propElt, object value) { if (value is string) propElt.InnerText = value.ToString(); else if (value is DateTime) { propElt.InnerXml = "" + ((DateTime)value).ToUniversalTime().ToString("s") + "Z"; } else if (value is IManagedReference) { propElt.InnerXml = ((IManagedReference)value).Xml; //merge addressing namespace XmlNode uriNode = propElt.SelectSingleNode("wsa:EndpointReference/wsa:ReferenceParameters/wsman:ResourceURI", _ns); XmlNode eprNode = propElt.SelectSingleNode("wsa:EndpointReference", _ns); if (eprNode != null) { if (_document.DocumentElement.GetAttribute("xmlns:" + eprNode.Prefix).Equals(string.Empty)) _document.DocumentElement.SetAttribute("xmlns:" + eprNode.Prefix, eprNode.NamespaceURI); if (uriNode != null) { if (_document.DocumentElement.GetAttribute("xmlns:" + uriNode.Prefix).Equals(string.Empty)) _document.DocumentElement.SetAttribute("xmlns:" + uriNode.Prefix, uriNode.NamespaceURI); } propElt.InnerXml = eprNode.InnerXml; } } else if (value is ManagedInstance) { string prefix = _document.DocumentElement.Prefix; int _prefixCount = 0; //int prefixCount = 0; XmlDocument doc = new XmlDocument(); doc.LoadXml(((IManagedInstance)value).Xml); //Detect namespace collisions if (_document.DocumentElement.Prefix.Equals(doc.DocumentElement.Prefix)) _prefixCount++; while (_document.DocumentElement.HasAttribute("xmlns:" + prefix + _prefixCount.ToString())) _prefixCount++; if (_prefixCount > 0) { _document.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); doc.DocumentElement.Prefix = prefix + _prefixCount; propElt.SetAttribute("xmlns:" + doc.DocumentElement.Prefix, doc.DocumentElement.NamespaceURI); //doc.DocumentElement.RemoveAttribute("xmlns:" + prefix); XmlNodeList list = doc.DocumentElement.GetElementsByTagName("*"); foreach (XmlElement elt in list) { if (elt.Prefix.Equals(prefix)) elt.Prefix = doc.DocumentElement.Prefix; } //propElt.SetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance", doc.DocumentElement.Prefix + ":" + doc.DocumentElement.LocalName + "_Type"); } if (doc.DocumentElement.NamespaceURI.Equals("http://schemas.dmtf.org/wbem/wscim/1/common")) propElt.InnerXml = doc.DocumentElement.OuterXml; else propElt.InnerXml = doc.DocumentElement.InnerXml; } } private void PutProperty(string name, object value, bool bReplace) { XmlElement propElt = null; // if name is null then the object must be the property if (name == null && value is IManagedInstance) { IManagedInstance inst = (IManagedInstance)value; name = inst.SimpleName; XmlDocument doc = new XmlDocument(); doc.LoadXml(inst.Xml); propElt = _document.CreateElement( _document.DocumentElement.Prefix, inst.SimpleName, inst.ResourceUri); propElt.InnerXml = doc.DocumentElement.InnerXml; value = null; } // delete all exsing values (if any) XmlNodeList list = _document.DocumentElement.SelectNodes("p:" + name, _ns); if (bReplace) { foreach (XmlNode listNode in list) _document.DocumentElement.RemoveChild(listNode); } if (propElt != null) { _document.DocumentElement.AppendChild(propElt); } // return all done if value is set to NULL if (value == null) return; propElt = _document.CreateElement( _document.DocumentElement.Prefix, name, _document.DocumentElement.NamespaceURI); if (value.GetType().IsArray) { object[] array = (object[])value; foreach (object item in array) { _document.DocumentElement.AppendChild(propElt); PutObject(propElt, item); propElt = (XmlElement)propElt.Clone(); } } else { _document.DocumentElement.AppendChild(propElt); PutObject(propElt, value); } } private void LoadDocument(string xmlString) { _document.LoadXml(xmlString); _ns = new XmlNamespaceManager(_document.NameTable); _ns.AddNamespace("p", _document.DocumentElement.NamespaceURI); _ns.AddNamespace("wsa", WsmanResources.ADDRESSING_NS); _ns.AddNamespace("wsman", WsmanResources.WSMAN_NS); } public bool Equals(ManagedInstance other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other._conn, _conn) && Equals(other._document, _document); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != typeof (ManagedInstance)) return false; return Equals((ManagedInstance) obj); } public override int GetHashCode() { unchecked { return ((_conn != null ? _conn.GetHashCode() : 0)*397) ^ (_document != null ? _document.GetHashCode() : 0); } } } }