-
Notifications
You must be signed in to change notification settings - Fork 365
/
CopyFromFilesComponent.cs
125 lines (97 loc) · 4.9 KB
/
CopyFromFilesComponent.cs
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// 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.
// 01/18/2013 - EFW - Moved CopyFromFilesCommand into its own file.
// 12/23/2013 - EFW - Updated the build component to be discoverable via MEF
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using Sandcastle.Core;
using Sandcastle.Core.BuildAssembler;
using Sandcastle.Core.BuildAssembler.BuildComponent;
using Sandcastle.Tools.BuildComponents.Commands;
namespace Sandcastle.Tools.BuildComponents
{
/// <summary>
/// This build component copies elements from one or more XML files determined using an XPath query into the
/// target document based on one or more copy commands that define the elements to copy and where to put them.
/// </summary>
public class CopyFromFilesComponent : BuildComponentCore
{
#region Build component factory for MEF
//=====================================================================
/// <summary>
/// This is used to create a new instance of the build component
/// </summary>
[BuildComponentExport("Copy From Files Component")]
public sealed class Factory : BuildComponentFactory
{
/// <inheritdoc />
public override BuildComponentCore Create()
{
return new CopyFromFilesComponent(this.BuildAssembler);
}
}
#endregion
#region Private data members
//=====================================================================
private readonly List<CopyFromFilesCommand> copyCommands = new List<CopyFromFilesCommand>();
#endregion
#region Constructor
//=====================================================================
/// <summary>
/// Constructor
/// </summary>
/// <param name="buildAssembler">A reference to the build assembler</param>
protected CopyFromFilesComponent(IBuildAssembler buildAssembler) : base(buildAssembler)
{
}
#endregion
#region Method overrides
//=====================================================================
/// <inheritdoc />
public override void Initialize(XPathNavigator configuration)
{
if(configuration == null)
throw new ArgumentNullException(nameof(configuration));
XPathNodeIterator copyNodes = configuration.Select("copy");
foreach(XPathNavigator copyNode in copyNodes)
{
string basePath = copyNode.GetAttribute("base", String.Empty);
if(String.IsNullOrWhiteSpace(basePath))
basePath = Environment.CurrentDirectory;
basePath = Environment.ExpandEnvironmentVariables(basePath);
if(!Directory.Exists(basePath))
this.WriteMessage(MessageLevel.Error, "The base directory '{0}' does not exist", basePath);
string fileXPath = copyNode.GetAttribute("file", String.Empty);
if(String.IsNullOrWhiteSpace(fileXPath))
this.WriteMessage(MessageLevel.Error, "Each copy element must have a file attribute " +
"specifying the file XPath used to get the file from which to copy elements");
string sourceXPath = copyNode.GetAttribute("source", String.Empty);
if(String.IsNullOrWhiteSpace(sourceXPath))
this.WriteMessage(MessageLevel.Error, "When instantiating a CopyFromFilesComponent, you " +
"must specify a source XPath format using the source attribute");
string targetXPath = copyNode.GetAttribute("target", String.Empty);
if(String.IsNullOrEmpty(targetXPath))
this.WriteMessage(MessageLevel.Error, "When instantiating a CopyFromFilesComponent, you " +
"must specify a target XPath format using the target attribute");
copyCommands.Add(new CopyFromFilesCommand(this, basePath, fileXPath, sourceXPath, targetXPath));
}
this.WriteMessage(MessageLevel.Info, "Loaded {0} copy commands", copyCommands.Count);
}
/// <inheritdoc />
public override void Apply(XmlDocument document, string key)
{
// Set the key in the XPath context
var context = new CustomContext();
context["key"] = key;
// Perform each copy command
foreach(CopyFromFilesCommand copyCommand in copyCommands)
copyCommand.Apply(document, context);
}
#endregion
}
}