414 lines
14 KiB
C#

//----------------------------------------------------------------------------
//
// Copyright (c) Intel Corporation, 2008 - 2010 All Rights Reserved.
//
// File: Addressing.cs
//
// Contents: This file contains the implementation of the CimReference class.
//
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
namespace Intel.Manageability.Cim
{
/// <remarks/>
[Serializable]
[XmlType(Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
[XmlRoot("EndpointReference", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing", IsNullable = false)]
[ComVisible(false)]
public class CimReference
{
#region CONSTANTS
/// <summary>
/// WS-Management namespace URI
/// </summary>
public const string WSMAN_ADDRESSING_NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
#endregion CONSTANTS
/// <summary>
/// Constructor
/// </summary>
public CimReference()
{
Namespace = WSMAN_ADDRESSING_NAMESPACE_URI;
Name = "EndpointReference";
Address = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
referenceParameters = new ReferenceParameters();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="name">Name of the object.</param>
/// <param name="ns">Namespace of the object.</param>
/// <param name="address">Address of the object.</param>
/// <param name="referenceParams"></param>
public CimReference(string name, string ns, string address, ReferenceParameters referenceParams)
{
Namespace = ns;
Name = name;
Address = address;
referenceParameters = referenceParams;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="name">Name of the object.</param>
/// <param name="ns">Namespace of the object.</param>
/// <param name="innerXML">Inner XML to be deserialized into the object.</param>
public CimReference(string name, string ns, string innerXML)
{
string outerXML = CreateEPR(innerXML, "EndpointReference", WSMAN_ADDRESSING_NAMESPACE_URI);
CimReference reference = Deserialize(outerXML);
if(reference != null)
{
Address = reference.Address;
referenceParameters = reference.referenceParameters;
}
Namespace = ns;
Name = name;
}
/// <summary>
/// Namespace of the object.
/// </summary>
[XmlIgnore]
public string Namespace { get; set; }
/// <summary>
/// Name of the object.
/// </summary>
[XmlIgnoreAttribute]
public string Name { get; set; }
/// <summary>
/// Address of the object.
/// </summary>
[XmlElement(ElementName = "Address", Namespace = WSMAN_ADDRESSING_NAMESPACE_URI)]
public string Address { get; set; }
[XmlElement(ElementName = "ReferenceParameters", Namespace = WSMAN_ADDRESSING_NAMESPACE_URI)]
public ReferenceParameters referenceParameters { get; set; }
/// <summary>
/// Deserialize XML to create a CimReference object.
/// </summary>
/// <param name="xml">Outer XML which represents the object.</param>
/// <returns></returns>
public static CimReference Deserialize(string xml)
{
CimReference reference;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(CimReference));
UTF8Encoding encoding = new UTF8Encoding();
using (MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(xml)))
{
reference = xmlSerializer.Deserialize(memoryStream) as CimReference;
}
return reference;
}
/// <summary>
/// Create the outer XML for Cim reference
/// </summary>
/// <param name="innerXml">Inner xml</param>
/// <param name="objectName">Name of the object (used as the outer tag)</param>
/// <param name="xmlNamespace">Namespace of the cim reference</param>
/// <returns></returns>
public static string CreateEPR(string innerXml, string objectName, string xmlNamespace)
{
string xml = "<" + objectName + " xmlns=\"" + xmlNamespace + "\">" + innerXml
+ "</" + objectName + ">";
return xml;
}
/// <summary>
/// Get the ResourceUri of an object
/// </summary>
/// <param name="type"></param>
/// <returns>Uri which represent the ResourceUri</returns>
public static Uri GetResourceUri(Type type)
{
foreach (object at in type.GetCustomAttributes(false))
{
if (at.GetType() == typeof(XmlRootAttribute))
{
return new Uri(((XmlRootAttribute)at).Namespace);
}
}
return new Uri("");
}
/// <summary>
/// Get Resource URI
/// </summary>
/// <returns></returns>
public Uri GetResourceUri()
{
Uri res = new Uri(referenceParameters.ResourceURI);
return res;
}
/// <summary>
/// Compare the given CimReference to this CimReference,
/// return true if both objects refer to the same resource.
/// </summary>
/// <param name="reference">The reference object to compare</param>
/// <returns>True if both references refer to the same resource</returns>
public bool Compare(CimReference reference)
{
if (reference == null)
throw new ArgumentNullException("reference");
if (this.referenceParameters == null || reference.referenceParameters == null)
return false;
if (this.referenceParameters.keys.Count != reference.referenceParameters.keys.Count)
return false;
List<Key> selectors1 = this.referenceParameters.keys;
List<Key> selectors2 = reference.referenceParameters.keys;
if (false == CompareSelectors(selectors1, selectors2))
{
return false;
}
return true;
}
/// <summary>
/// Determines whether the specified CimReference is equal to the current CimReference.
/// </summary>
/// <param name="obj">The CimReference to compare with the current CimReference.</param>
/// <returns>true if the specified CimReference is equal to the current CimReference; otherwise, false.</returns>
public override bool Equals(object obj)
{
CimReference other = obj as CimReference;
if (other == null)
throw (new ArgumentException("Argument type should be Key"));
return Compare(other);
}
/// <summary>
/// Compare two selectors sets, return true if equal, false otherwise
/// </summary>
/// <param name="selectors1">First selector set to compare</param>
/// <param name="selectors2">Second selector set to compare</param>
/// <returns>true if equal, false otherwise</returns>
private static bool CompareSelectors(List<Key> selectors1, List<Key> selectors2)
{
if (null == selectors1 && null == selectors2)
{
return false;
}
if (((null == selectors1) && (null != selectors2)) ||
((null != selectors1) && (null == selectors2)))
{
return false;
}
if (selectors1.Count != selectors2.Count)
{
return false;
}
foreach (Key selector in selectors1)
{
if (!selectors2.Contains(selector))
{
return false;
}
}
return true;
}
/// <summary>
/// Return the the type specified in the endpoint reference
/// </summary>
/// <returns>The type specified in the endpoint reference</returns>
public Type GetReferenceType()
{
string uri = GetResourceUri().OriginalString;
if (uri != null)
{
string uriString = "Intel.Manageability.Cim.Typed." + uri.Remove(0, uri.LastIndexOf('/') + 1);
return Type.GetType(uriString);
}
return null;
}
/// <summary>
/// Get Selectors
/// </summary>
/// <returns></returns>
public List<Key> GetKeys()
{
return referenceParameters.keys;
}
/// <summary>
/// Serialize Cim reference object
/// </summary>
/// <param name="outer">Boolean to indicate whether to return inner or outer XML</param>
/// <returns>XML string which represent the object</returns>
public string Serialize(bool outer)
{
XmlDocument xDoc = new XmlDocument();
XmlSerializer filterSerializer = new XmlSerializer(typeof(CimReference));
using (StringWriter filterWriter = new StringWriter())
{
filterSerializer.Serialize(filterWriter, this);
xDoc.LoadXml(filterWriter.ToString());
}
string ret = xDoc.DocumentElement.InnerXml;
if (outer)
{
ret = CreateEPR(ret, Name, Namespace);
}
return ret;
}
/// <summary>
/// Returns a System.String that represents the current CimReference.
/// </summary>
/// <returns>A System.String that represents the current CimReference.</returns>
public override string ToString()
{
return Serialize(true);
}
}
/// <summary>
/// Class which represent the reference parameters of an object.
/// </summary>
[ComVisible(false)]
public class ReferenceParameters
{
private const string WSMAN_NAMESPACE_URI = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd";
private const string WSMAN_URI_FIELD = "ResourceURI";
private const string WSMAN_SELECTOR_SET_FIELD = "SelectorSet";
private const string WSMAN_SELECTOR_FIELD = "Selector";
[XmlElement(ElementName = WSMAN_URI_FIELD, Namespace = WSMAN_NAMESPACE_URI)]
public string ResourceURI { get; set; }
/// <summary>
/// List of selectors
/// </summary>
[XmlArray(ElementName = WSMAN_SELECTOR_SET_FIELD, Namespace = WSMAN_NAMESPACE_URI)]
[XmlArrayItem(ElementName = WSMAN_SELECTOR_FIELD, Namespace = WSMAN_NAMESPACE_URI)]
public List<Key> keys
{
get;
set;
}
/// <summary>
/// Constructor.
/// </summary>
public ReferenceParameters()
{
keys = new List<Key>();
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="resourceURI"></param>
/// <param name="selectorSet"></param>
public ReferenceParameters(string resourceURI, List<Key> selectorSet)
{
keys = selectorSet;
ResourceURI = resourceURI;
}
}
/// <summary>
/// A class which represents a key inside CimReference.
/// </summary>
[ComVisible(false)]
public class Key
{
/// <summary>
/// Value of the key.
/// </summary>
[XmlText(Type = typeof(string))]
public string Value;
/// <summary>
/// Value of the key (in case the key is CimReference)
/// </summary>
[XmlElement(Type = typeof(CimReference), ElementName = "EndpointReference", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
public CimReference cimReference;
/// <summary>
/// Name of the key
/// </summary>
[XmlAttribute(AttributeName = "Name")]
public string Name;
/// <summary>
/// Constructor.
/// </summary>
public Key() { }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name">Name of the key</param>
/// <param name="value">Value of the key</param>
public Key(string name, Object value)
{
Name = name;
if (value is CimReference)
{
cimReference = (CimReference)value;
}
else
{
Value = (string)value;
}
}
/// <summary>
/// Determines whether the specified Key is equal to the current Key.
/// </summary>
/// <param name="obj">The Key to compare with the current Key.</param>
/// <returns>true if the specified Key is equal to the current Key; otherwise, false.</returns>
public override bool Equals(object obj)
{
Key other = obj as Key;
if (other == null)
throw new ArgumentException("Argument type should be Key");
if ((cimReference == null && other.cimReference != null) || (cimReference != null && other.cimReference == null))
return false;
if (Name == other.Name && Value == other.Value)
{
if (cimReference == null && other.cimReference == null)
return true;
if (cimReference?.Compare(other.cimReference) ?? other.cimReference.Compare(cimReference))
return true;
}
return false;
}
}
}