MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Globalization;6using System.Xml;7 8namespace Microsoft.WSMan.Management9{10 /// <summary>11 /// Class that queries the server and gets current configurations.12 /// Also provides a generic way to update the configurations.13 /// </summary>14 internal sealed class CurrentConfigurations15 {16 /// <summary>17 /// Prefix used to add NameSpace of root element to namespace manager.18 /// </summary>19 public const string DefaultNameSpacePrefix = "defaultNameSpace";20 21 /// <summary>22 /// This holds the current configurations XML.23 /// </summary>24 private readonly XmlDocument rootDocument;25 26 /// <summary>27 /// Holds the reference to the current document element.28 /// </summary>29 private XmlElement documentElement;30 31 /// <summary>32 /// Holds the Namespace Manager to use for XPATH queries.33 /// </summary>34 private XmlNamespaceManager nameSpaceManger;35 36 /// <summary>37 /// Session of the WsMan sserver.38 /// </summary>39 private readonly IWSManSession serverSession;40 41 /// <summary>42 /// Gets the server session associated with the configuration.43 /// </summary>44 public IWSManSession ServerSession45 {46 get { return serverSession; }47 }48 49 /// <summary>50 /// Gets the current configuration XML.51 /// </summary>52 public XmlDocument RootDocument53 {54 get { return this.rootDocument; }55 }56 57 /// <summary>58 /// Gets the current configuration on the given server and for given URI.59 /// This issues a GET request to the server.60 /// </summary>61 /// <param name="serverSession">Current server session.</param>62 public CurrentConfigurations(IWSManSession serverSession)63 {64 ArgumentNullException.ThrowIfNull(serverSession);65 66 this.rootDocument = new XmlDocument();67 this.serverSession = serverSession;68 }69 70 /// <summary>71 /// Refresh the CurrentConfiguration. This method calls GET operation for the given72 /// URI on the server and update the current configuration. It also initialize some73 /// of required class members.74 /// </summary>75 /// <param name="responseOfGet">Plugin configuration.</param>76 /// <returns>False, if operation failed.</returns>77 public bool RefreshCurrentConfiguration(string responseOfGet)78 {79 ArgumentException.ThrowIfNullOrEmpty(responseOfGet);80 81 this.rootDocument.LoadXml(responseOfGet);82 this.documentElement = this.rootDocument.DocumentElement;83 84 this.nameSpaceManger = new XmlNamespaceManager(this.rootDocument.NameTable);85 this.nameSpaceManger.AddNamespace(CurrentConfigurations.DefaultNameSpacePrefix, this.documentElement.NamespaceURI);86 87 return string.IsNullOrEmpty(this.serverSession.Error);88 }89 90 /// <summary>91 /// Update the server with updated XML.92 /// Issues a PUT request with the ResourceUri provided.93 /// </summary>94 /// <param name="resourceUri">Resource URI to use.</param>95 /// <returns>False, if operation is not successful.</returns>96 public void PutConfigurationOnServer(string resourceUri)97 {98 ArgumentException.ThrowIfNullOrEmpty(resourceUri);99 100 this.serverSession.Put(resourceUri, this.rootDocument.InnerXml, 0);101 }102 103 /// <summary>104 /// This method will remove the configuration from the XML.105 /// Currently the method will only remove the attributes. But it is extensible enough to support106 /// Node removals in future.107 /// </summary>108 /// <param name="pathToNodeFromRoot">Path with namespace to the node from Root element. Must not end with '/'.</param>109 public void RemoveOneConfiguration(string pathToNodeFromRoot)110 {111 ArgumentNullException.ThrowIfNull(pathToNodeFromRoot);112 113 XmlNode nodeToRemove =114 this.documentElement.SelectSingleNode(115 pathToNodeFromRoot,116 this.nameSpaceManger);117 118 if (nodeToRemove != null)119 {120 if (nodeToRemove is XmlAttribute)121 {122 RemoveAttribute(nodeToRemove as XmlAttribute);123 }124 }125 else126 {127 throw new ArgumentException("Node is not present in the XML, Please give valid XPath", nameof(pathToNodeFromRoot));128 }129 }130 131 /// <summary>132 /// Create or Update the value of the configuration on the given Node. Currently this133 /// method is supported for updating attributes, but can be easily updated for nodes.134 /// Caller should call this method to add a new attribute to the Node.135 /// </summary>136 /// <param name="pathToNodeFromRoot">Path with namespace to the node from Root element. Must not end with '/'.</param>137 /// <param name="configurationName">Name of the configuration with name space to update or create.</param>138 /// <param name="configurationValue">Value of the configurations.</param>139 public void UpdateOneConfiguration(string pathToNodeFromRoot, string configurationName, string configurationValue)140 {141 ArgumentNullException.ThrowIfNull(pathToNodeFromRoot);142 ArgumentException.ThrowIfNullOrEmpty(configurationName);143 ArgumentNullException.ThrowIfNull(configurationValue);144 145 XmlNode nodeToUpdate =146 this.documentElement.SelectSingleNode(147 pathToNodeFromRoot,148 this.nameSpaceManger);149 150 if (nodeToUpdate != null)151 {152 foreach (XmlAttribute attribute in nodeToUpdate.Attributes)153 {154 if (attribute.Name.Equals(configurationName, StringComparison.OrdinalIgnoreCase))155 {156 attribute.Value = configurationValue;157 return;158 }159 }160 161 XmlNode attr = this.rootDocument.CreateNode(XmlNodeType.Attribute, configurationName, string.Empty);162 attr.Value = configurationValue;163 164 nodeToUpdate.Attributes.SetNamedItem(attr);165 }166 }167 168 /// <summary>169 /// Gets the value of the configuration on the given Node or attribute.170 /// </summary>171 /// <param name="pathFromRoot">Path with namespace to the node from Root element.</param>172 /// <returns>Value of the Node, or Null if no node present.</returns>173 public string GetOneConfiguration(string pathFromRoot)174 {175 ArgumentNullException.ThrowIfNull(pathFromRoot);176 177 XmlNode requiredNode =178 this.documentElement.SelectSingleNode(179 pathFromRoot,180 this.nameSpaceManger);181 182 if (requiredNode != null)183 {184 return requiredNode.Value;185 }186 187 return null;188 }189 190 /// <summary>191 /// Removes the attribute from OwnerNode.192 /// </summary>193 /// <param name="attributeToRemove">Attribute to Remove.</param>194 private static void RemoveAttribute(XmlAttribute attributeToRemove)195 {196 XmlElement ownerElement = attributeToRemove.OwnerElement;197 ownerElement.RemoveAttribute(attributeToRemove.Name);198 }199 }200}201 