// Copyright © Microsoft Corporation. // This source file is subject to the Microsoft Permissive License. // See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. // All other rights reserved. using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Xml; using System.Xml.XPath; namespace Microsoft.Ddue.Tools { public class SwitchComponent : BuildComponent { public SwitchComponent(BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) { // get the condition XPathNavigator condition_element = configuration.SelectSingleNode("switch"); if (condition_element == null) { throw new ConfigurationErrorsException("You must specifiy a condition using the statement with a 'value' attribute."); } string condition_value = condition_element.GetAttribute("value", String.Empty); if (String.IsNullOrEmpty(condition_value)) { throw new ConfigurationErrorsException("The switch statement must have a 'value' attribute, which is an xpath expression."); } condition = XPathExpression.Compile(condition_value); // load the component stacks for each case XPathNodeIterator case_elements = configuration.Select("case"); foreach (XPathNavigator case_element in case_elements) { string case_value = case_element.GetAttribute("value", String.Empty); BuildComponent[] components = BuildAssembler.LoadComponents(case_element); cases.Add(case_value, components); } } // data held by the component private XPathExpression condition; private Dictionary> cases = new Dictionary>(); // the action of the component public override void Apply(XmlDocument document, string key) { // evaluate the condition string result = document.CreateNavigator().Evaluate(condition).ToString(); // get the corresponding component stack IEnumerable components; if (cases.TryGetValue(result, out components)) { // apply it foreach (BuildComponent component in components) { component.Apply(document, key); } } else { // no such case exists } } protected override void Dispose(bool disposing) { if (disposing) { foreach (IEnumerable components in cases.Values) { foreach (BuildComponent component in components) { component.Dispose(); } } } base.Dispose(disposing); } } }