//---------------------------------------------------------------------------- // // 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 { /// [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 /// /// WS-Management namespace URI /// public const string WSMAN_ADDRESSING_NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing"; #endregion CONSTANTS /// /// Constructor /// public CimReference() { Namespace = WSMAN_ADDRESSING_NAMESPACE_URI; Name = "EndpointReference"; Address = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"; referenceParameters = new ReferenceParameters(); } /// /// Constructor /// /// Name of the object. /// Namespace of the object. /// Address of the object. /// public CimReference(string name, string ns, string address, ReferenceParameters referenceParams) { Namespace = ns; Name = name; Address = address; referenceParameters = referenceParams; } /// /// Constructor /// /// Name of the object. /// Namespace of the object. /// Inner XML to be deserialized into the object. 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; } /// /// Namespace of the object. /// [XmlIgnore] public string Namespace { get; set; } /// /// Name of the object. /// [XmlIgnoreAttribute] public string Name { get; set; } /// /// Address of the object. /// [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; } /// /// Deserialize XML to create a CimReference object. /// /// Outer XML which represents the object. /// 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; } /// /// Create the outer XML for Cim reference /// /// Inner xml /// Name of the object (used as the outer tag) /// Namespace of the cim reference /// public static string CreateEPR(string innerXml, string objectName, string xmlNamespace) { string xml = "<" + objectName + " xmlns=\"" + xmlNamespace + "\">" + innerXml + ""; return xml; } /// /// Get the ResourceUri of an object /// /// /// Uri which represent the ResourceUri 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(""); } /// /// Get Resource URI /// /// public Uri GetResourceUri() { Uri res = new Uri(referenceParameters.ResourceURI); return res; } /// /// Compare the given CimReference to this CimReference, /// return true if both objects refer to the same resource. /// /// The reference object to compare /// True if both references refer to the same resource 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 selectors1 = this.referenceParameters.keys; List selectors2 = reference.referenceParameters.keys; if (false == CompareSelectors(selectors1, selectors2)) { return false; } return true; } /// /// Determines whether the specified CimReference is equal to the current CimReference. /// /// The CimReference to compare with the current CimReference. /// true if the specified CimReference is equal to the current CimReference; otherwise, false. 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); } /// /// Compare two selectors sets, return true if equal, false otherwise /// /// First selector set to compare /// Second selector set to compare /// true if equal, false otherwise private static bool CompareSelectors(List selectors1, List 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; } /// /// Return the the type specified in the endpoint reference /// /// The type specified in the endpoint reference 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; } /// /// Get Selectors /// /// public List GetKeys() { return referenceParameters.keys; } /// /// Serialize Cim reference object /// /// Boolean to indicate whether to return inner or outer XML /// XML string which represent the object 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; } /// /// Returns a System.String that represents the current CimReference. /// /// A System.String that represents the current CimReference. public override string ToString() { return Serialize(true); } } /// /// Class which represent the reference parameters of an object. /// [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; } /// /// List of selectors /// [XmlArray(ElementName = WSMAN_SELECTOR_SET_FIELD, Namespace = WSMAN_NAMESPACE_URI)] [XmlArrayItem(ElementName = WSMAN_SELECTOR_FIELD, Namespace = WSMAN_NAMESPACE_URI)] public List keys { get; set; } /// /// Constructor. /// public ReferenceParameters() { keys = new List(); } /// /// Constructor. /// /// /// public ReferenceParameters(string resourceURI, List selectorSet) { keys = selectorSet; ResourceURI = resourceURI; } } /// /// A class which represents a key inside CimReference. /// [ComVisible(false)] public class Key { /// /// Value of the key. /// [XmlText(Type = typeof(string))] public string Value; /// /// Value of the key (in case the key is CimReference) /// [XmlElement(Type = typeof(CimReference), ElementName = "EndpointReference", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")] public CimReference cimReference; /// /// Name of the key /// [XmlAttribute(AttributeName = "Name")] public string Name; /// /// Constructor. /// public Key() { } /// /// Constructor. /// /// Name of the key /// Value of the key public Key(string name, Object value) { Name = name; if (value is CimReference) { cimReference = (CimReference)value; } else { Value = (string)value; } } /// /// Determines whether the specified Key is equal to the current Key. /// /// The Key to compare with the current Key. /// true if the specified Key is equal to the current Key; otherwise, false. 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; } } }