276 lines
8.4 KiB
C#

using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
namespace Intel.Management.Wsman
{
class WsmanEnumeration : IWsmanEnumeration, IEnumerable
{
private WsmanConnection _conn;
private XmlDocument _document;
private XmlNamespaceManager _ns;
private WsmanEnumerator _internal;
public WsmanEnumeration(WsmanConnection conn,
XmlDocument document,
XmlNamespaceManager ns)
{
_conn = conn;
_document = document;
_ns=ns;
}
public IWsmanConnection Connection
{
get
{
return _conn;
}
}
[DispId(-4)]
public IEnumerator GetEnumerator()
{
if (_internal == null)
_internal = new WsmanEnumerator(this);
return _internal;
}
public bool HasNext
{
get
{
XmlElement itemsElt;
XmlNode endSeqNod;
if (_internal == null)
_internal = new WsmanEnumerator(this);
return _internal.CheckForItems(out itemsElt,out endSeqNod);
}
}
public IWsmanItem Next()
{
if (_internal == null)
_internal = new WsmanEnumerator(this);
_internal.MoveNext();
return (IWsmanItem)_internal.Current;
}
internal class WsmanEnumerator : IEnumerator
{
private XmlDocument _items;
private XmlNamespaceManager _itemsNs;
private object _object;
private WsmanEnumeration _enum;
private XmlNode _endSeqNode;
public WsmanEnumerator(WsmanEnumeration wsEnum)
{
_enum = wsEnum;
_items = null;
_itemsNs = null;
_object = null;
}
public bool CheckForItems(out XmlElement itemsElt, out XmlNode endSeqNode)
{
itemsElt = null;
endSeqNode = null;
// check for dead enumerator
if (_enum._document == null)
{
_object = null;
return false;
}
// we don't have a dead enumerator so pull items
if (_items == null)
{
_items = (XmlDocument)_enum._conn.SubmitRequest(_enum._document, null, null);
if(_items != null)
LoadNamespaces(_items);
}
if (_items != null)
{
_endSeqNode = endSeqNode = _items.DocumentElement.SelectSingleNode("s:Body/n:PullResponse/n:EndOfSequence", _itemsNs);
itemsElt = (XmlElement)_items.DocumentElement.SelectSingleNode("s:Body/n:PullResponse/n:Items", _itemsNs);
if ((itemsElt != null && itemsElt.HasChildNodes) || endSeqNode==null)
return true;
}
return false;
}
public object Current
{
get
{
if (_object == null)
throw new InvalidOperationException();
return _object;
}
}
public bool MoveNext()
{
XmlElement itemsElt;
XmlNode endSeqNode;
if (!CheckForItems(out itemsElt,out endSeqNode))
return false;
_object = null;
XmlNode node = null;
if(itemsElt != null)
node = itemsElt.FirstChild;
if (node != null)
{
if (node.NamespaceURI.Equals(WsmanResources.ADDRESSING_NS))
{
_object = new WsmanItem(
new ManagedReference(_enum._conn, node.OuterXml));
}
else if (node.NamespaceURI.Equals(WsmanResources.WSMAN_NS)
&& node.LocalName.Equals("Item"))
{
IManagedReference refObj=null;
IManagedInstance instObj=null;
XmlNode child = node.FirstChild;
if (child != null)
{
if (node.NamespaceURI.Equals(WsmanResources.ADDRESSING_NS))
refObj = new ManagedReference(_enum._conn, child.OuterXml);
else
instObj = new ManagedInstance(_enum._conn, child.OuterXml);
child = child.NextSibling;
if (child != null && instObj == null)
instObj = new ManagedInstance(_enum._conn, child.OuterXml);
else if (child != null && refObj == null)
refObj = new ManagedReference(_enum._conn, child.OuterXml);
}
_object = new WsmanItem(instObj,refObj);
}
else
{
_object = new WsmanItem(
new ManagedInstance(_enum._conn, node.OuterXml));
}
itemsElt.RemoveChild(node);
if (itemsElt.ChildNodes.Count == 0)
{
if (endSeqNode != null)
{
_enum._document = null;
_enum._ns = null;
_items = null;
_itemsNs = null;
}
else
{
_items = null;
_itemsNs = null;
}
}
return true;
}
return false;
}
public void Reset()
{
throw new NotSupportedException();
}
public void Dispose()
{
// check for dead enumerator
if (_enum._document == null)
return;
// Check if the pulling objects from the FW not already ended.
if (_endSeqNode == null)
{
// Build the enumeration conext node.
string enumContaxt = _enum._document.DocumentElement.GetElementsByTagName("n:Pull")[0].ChildNodes[0].OuterXml;
StringBuilder releaseNode = new StringBuilder();
releaseNode.Append("<n:Release>");
releaseNode.Append(enumContaxt);
releaseNode.Append("</n:Release>");
// Plannt the relevant action.
_enum._document.DocumentElement.GetElementsByTagName("a:Action")[0].InnerText = "http://schemas.xmlsoap.org/ws/2004/09/enumeration/Release";
_enum._document.DocumentElement.GetElementsByTagName("s:Body")[0].RemoveAll(); // Remove the exist body.
_enum._document.DocumentElement.GetElementsByTagName("s:Body")[0].InnerXml = releaseNode.ToString(); // Plant the new body.
_enum._conn.SubmitRequest(_enum._document, null, null);
}
_object = null;
_enum._document = null;
_enum._ns = null;
_items = null;
_itemsNs = null;
}
private void LoadNamespaces(XmlDocument document)
{
_itemsNs = new XmlNamespaceManager(document.NameTable);
_itemsNs.AddNamespace("s", WsmanResources.SOAP_NS);
_itemsNs.AddNamespace("n", WsmanResources.ENUM_NS);
}
}
public void Dispose()
{
//release the enumerator if not complete
//firmware only supports 3 enumerators
Close();
}
public void Close()
{
_internal.Dispose();
}
}
}