summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SwitchComponent.cs
blob: 48f9fbeecbd3f5b88dc79d781383840ad7c7e0bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 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 <switch> 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<string,IEnumerable<BuildComponent>> cases = new Dictionary<string,IEnumerable<BuildComponent>>();

		// 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<BuildComponent> 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<BuildComponent> components in cases.Values) {
                    foreach (BuildComponent component in components) {
                        component.Dispose();
                    }
                }
            }
            base.Dispose(disposing);
        }
	}

}