486 lines
15 KiB
C#

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<object> objects = new List<object>();
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<string> list = new List<string>();
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 = "<p:Datetime xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">" + ((DateTime)value).ToUniversalTime().ToString("s") + "Z</p:Datetime>";
}
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);
}
}
}
}