summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IfThenComponent.cs
blob: e44c0f29a34aae5dc3feab791fb2dfaaa6e78558 (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
78
79
80
81
82
83
84
85
86
87
// 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.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

using System.Reflection;

namespace Microsoft.Ddue.Tools {

	public class IfThenComponent : BuildComponent {

		private XPathExpression condition;

		private IEnumerable<BuildComponent> true_branch = new List<BuildComponent>();

		private IEnumerable<BuildComponent> false_branch = new List<BuildComponent>();

		public IfThenComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
			
			// get the condition
			XPathNavigator if_node = configuration.SelectSingleNode("if");
			if (if_node == null) throw new ConfigurationErrorsException("You must specify a condition using the <if> element.");
			string condition_xpath = if_node.GetAttribute("condition", String.Empty);
			if (String.IsNullOrEmpty(condition_xpath)) throw new ConfigurationErrorsException();
			condition = XPathExpression.Compile(condition_xpath);

			// construct the true branch
			XPathNavigator then_node = configuration.SelectSingleNode("then");
			if (then_node != null) true_branch = BuildAssembler.LoadComponents(then_node);

			// construct the false branch
			XPathNavigator else_node = configuration.SelectSingleNode("else");
			if (else_node != null) false_branch = BuildAssembler.LoadComponents(else_node);

            // keep a pointer to the context for future use
            context = assembler.Context;

		}

		private BuildContext context;

		public override void Apply (XmlDocument document, string key) {

            // set up the test
			context["key"] = key;
			XPathExpression test = condition.Clone();
			test.SetContext(context.XsltContext);

			// evaluate the condition
			bool result = (bool) document.CreateNavigator().Evaluate(test);

			// on the basis of the condition, execute either the true or the false branch
			if (result) {
				foreach (BuildComponent component in true_branch) {
					component.Apply(document, key);
				}
			} else {
				foreach (BuildComponent component in false_branch) {
					component.Apply(document, key);
				}
			}

		}

        protected override void Dispose(bool disposing) {
            if (disposing) {
                foreach (BuildComponent component in true_branch) {
                    component.Dispose();
                }
                foreach (BuildComponent component in false_branch) {
                    component.Dispose();
                }
            }
            base.Dispose(disposing);
        }

	}


}