/
BaseTemplateReplaceGenerator.cs
273 lines (199 loc) · 13.5 KB
/
BaseTemplateReplaceGenerator.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yamua;
namespace Xteq5
{
/// <summary>
/// A base class for class that reads a template file and then replaces the content with the actual values.
/// </summary>
public abstract class BaseTemplateReplaceGenerator : BaseGenerator
{
protected StringBuilder _content = new StringBuilder();
protected void ReadTemplate(string TemplateFilepath)
{
if (string.IsNullOrWhiteSpace(TemplateFilepath))
throw new ArgumentException("TemplateFilepath can not be empty");
if (PathExtension.FileExists(TemplateFilepath) == false)
{
throw new TemplateFileNotFoundException(TemplateFilepath);
}
//If there is a load error, this will throw an exception
_content = new StringBuilder(File.ReadAllText(TemplateFilepath, Encoding.UTF8));
}
//Because we require a template, this function can't be used
public override string Generate(Report Report)
{
throw new NotImplementedException();
}
//Base function that is called by a consumer of an implementation of this class
public abstract string Generate(Report Report, string TemplateFilepath);
//This needs to be called by the implementation to start the replacement process
protected void StartGenerating(Report Report)
{
ReplaceHeaderValuesInternal(Report);
ReplaceAssetStatisticsInternal(Report);
ReplaceTestStatisticsInternal(Report);
ReplaceResultTextInternal();
ReplaceAssetConclusionTextInternal();
ReplaceTestConclusionTextInternal();
ReplaceTestRecommendedActionTextInternal();
//Begin details replacement for assets
StringBuilder sbAssets = new StringBuilder();
StartAssetDetails(sbAssets);
foreach (AssetRecord asset in Report.Assets)
{
BaseRecord baseRec = asset as BaseRecord;
ResultPrimarySecondary rps = new ResultPrimarySecondary(baseRec);
ProcessAsset(sbAssets, asset, baseRec, rps);
}
EndAssetDetails(sbAssets);
ReplaceAssetList("AssetRows".ToUpper(), sbAssets.ToString());
//Begin details replacment for tests
StringBuilder sbTests = new StringBuilder();
StartTestDetails(sbTests);
foreach (TestRecord test in Report.Tests)
{
BaseRecord baseRec = test as BaseRecord;
ResultPrimarySecondary rps = new ResultPrimarySecondary(baseRec);
ProcessTest(sbTests, test, baseRec, rps);
}
EndTestDetails(sbAssets);
ReplaceTestList("TestRows".ToUpper(), sbTests.ToString());
}
private void ReplaceHeaderValuesInternal(Report Report)
{
//Replace all known string values
ReplaceHeaderValueInternal("ReportID", Report.ID.ToString());
ReplaceHeaderValueInternal("UserName", Report.UserName);
ReplaceHeaderValueInternal("Computername", Report.ComputerName);
ReplaceHeaderValueInternal("UserText", Report.UserText);
ReplaceHeaderValueInternal("SourceFolder", Report.CompilationFolder);
ReplaceHeaderValueInternal("VersionString", Report.EngineVersion.ToString());
//Currently not used by any report
ReplaceHeaderValueInternal("AssetIssuesFound", Report.AssetIssuesFound.ToString());
ReplaceHeaderValueInternal("TestIssuesFound", Report.TestIssuesFound.ToString());
ReplaceHeaderValueInternal("IssuesFound", Report.IssuesFound.ToString());
//Datetime in UTC and ISO 8601 format without fraction of second
ReplaceHeaderValueInternal("StartDateTimeUTC", Report.StartedUTC.ToString("s") + "Z");
ReplaceHeaderValueInternal("EndDateTimeUTC", Report.EndedUTC.ToString("s") + "Z");
ReplaceHeaderValueInternal("RuntimeSeconds", Report.RuntimeSeconds);
}
private void ReplaceHeaderValueInternal(string ValueName, string Value)
{
ReplaceHeaderValue(ValueName.ToUpper(), Value);
}
//Called from this class to replace typical "Header" items: Data that is only found once in the report.
protected abstract void ReplaceHeaderValue(string ValueName, string Value);
private void ReplaceAssetStatisticsInternal(Report Report)
{
ReplaceAssetStaticValueInternal("Assets.DoesNotApply", Report.AssetStatiscs.DoesNotApplyCount);
ReplaceAssetStaticValueInternal("Assets.Fatal", Report.AssetStatiscs.FatalCount);
ReplaceAssetStaticValueInternal("Assets.Inconclusive", Report.AssetStatiscs.InconclusiveCount);
ReplaceAssetStaticValueInternal("Assets.Major", Report.AssetStatiscs.MajorCount);
ReplaceAssetStaticValueInternal("Assets.Minor", Report.AssetStatiscs.MinorCount);
ReplaceAssetStaticValueInternal("Assets.Success", Report.AssetStatiscs.SuccessCount);
ReplaceAssetStaticValueInternal("Assets.Total", Report.AssetStatiscs.Total);
}
private void ReplaceAssetStaticValueInternal(string ValueName, int Value)
{
ReplaceAssetStatisticValue(ValueName.ToUpper(), Value.ToString());
}
//Called from this class to replace statistical counter for all assets found
protected abstract void ReplaceAssetStatisticValue(string ValueName, string Value);
private void ReplaceTestStatisticsInternal(Report Report)
{
ReplaceTestStatisticValueInternal("Tests.DoesNotApply", Report.TestStatiscs.DoesNotApplyCount);
ReplaceTestStatisticValueInternal("Tests.Fatal", Report.TestStatiscs.FatalCount);
ReplaceTestStatisticValueInternal("Tests.Inconclusive", Report.TestStatiscs.InconclusiveCount);
ReplaceTestStatisticValueInternal("Tests.Major", Report.TestStatiscs.MajorCount);
ReplaceTestStatisticValueInternal("Tests.Minor", Report.TestStatiscs.MinorCount);
ReplaceTestStatisticValueInternal("Tests.Success", Report.TestStatiscs.SuccessCount);
ReplaceTestStatisticValueInternal("Tests.Total", Report.TestStatiscs.Total);
}
private void ReplaceTestStatisticValueInternal(string ValueName, int Value)
{
ReplaceTestStatisticValue(ValueName.ToUpper(), Value.ToString());
}
//Called from this class to replace statistical counter for all tests found
protected abstract void ReplaceTestStatisticValue(string ValueName, string Value);
private void ReplaceResultTextInternal()
{
ReplaceResultTextInternal("ResultText.DoesNotApply", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.DoesNotApply));
ReplaceResultTextInternal("ResultText.Success", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.Success));
ReplaceResultTextInternal("ResultText.Fatal", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.Fatal));
ReplaceResultTextInternal("ResultText.Inconclusive", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.Inconclusive));
ReplaceResultTextInternal("ResultText.Major", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.Major));
ReplaceResultTextInternal("ResultText.Minor", ConclusionEnumConverter.ConclusionHumanized(ConclusionEnum.Minor));
}
private void ReplaceResultTextInternal(string ValueName, string Value)
{
ReplaceResultText(ValueName.ToUpper(), Value);
}
//Called from this class to replace a description for the different conclusion an item can have (e.g. Success = "OK", Fatal = "Crashed" etc.)
protected abstract void ReplaceResultText(string ValueName, string Value);
private void ReplaceAssetConclusionTextInternal()
{
ReplaceAssetConclusionTextInternal("AssetText.DoesNotApply", ConclusionEnumConverter.AssetRecordConclusionDescription(ConclusionEnum.DoesNotApply));
ReplaceAssetConclusionTextInternal("AssetText.Success", ConclusionEnumConverter.AssetRecordConclusionDescription(ConclusionEnum.Success));
ReplaceAssetConclusionTextInternal("AssetText.Fatal", ConclusionEnumConverter.AssetRecordConclusionDescription(ConclusionEnum.Fatal));
}
private void ReplaceAssetConclusionTextInternal(string ValueName, string Value)
{
ReplaceAssetConclusionText(ValueName.ToUpper(), Value);
}
//Called from this class to replace a Conclusion with a human readable string (OK = The asset successfully retrieved data)
protected abstract void ReplaceAssetConclusionText(string ValueName, string Value);
private void ReplaceTestConclusionTextInternal()
{
//Replace text values for tests
ReplaceTestConclusionTextInternal("TestText.DoesNotApply", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.DoesNotApply));
ReplaceTestConclusionTextInternal("TestText.Success", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.Success));
ReplaceTestConclusionTextInternal("TestText.Fatal", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.Fatal));
ReplaceTestConclusionTextInternal("TestText.Inconclusive", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.Inconclusive));
ReplaceTestConclusionTextInternal("TestText.Major", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.Major));
ReplaceTestConclusionTextInternal("TestText.Minor", ConclusionEnumConverter.TestRecordConclusionDescription(ConclusionEnum.Minor));
}
private void ReplaceTestConclusionTextInternal(string ValueName, string Value)
{
ReplaceTestConclusionText(ValueName.ToUpper(), Value);
}
//Called from this class to replace a Conclusion with a human readable string (OK = The test found no issues)
protected abstract void ReplaceTestConclusionText(string ValueName, string Value);
private void ReplaceTestRecommendedActionTextInternal()
{
//Recplace recommended action for tests
ReplaceTestRecommendedActionTextInternal("TestActionText.DoesNotApply", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.DoesNotApply));
ReplaceTestRecommendedActionTextInternal("TestActionText.Success", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.Success));
ReplaceTestRecommendedActionTextInternal("TestActionText.Fatal", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.Fatal));
ReplaceTestRecommendedActionTextInternal("TestActionText.Inconclusive", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.Inconclusive));
ReplaceTestRecommendedActionTextInternal("TestActionText.Major", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.Major));
ReplaceTestRecommendedActionTextInternal("TestActionText.Minor", ConclusionEnumConverter.TestRecordConclusionRecommendedAction(ConclusionEnum.Minor));
}
private void ReplaceTestRecommendedActionTextInternal(string ValueName, string Value)
{
ReplaceTestRecommendedActionText(ValueName.ToUpper(), Value);
}
//Called from this class to replace a text what the user should do when a test has a given value (Fail = Fix the issue immediately)
protected abstract void ReplaceTestRecommendedActionText(string ValueName, string Value);
//Called once when the imlementation should start to begin asset value replacement. Can be used to add a header to the given StringBuilder
protected abstract void StartAssetDetails(StringBuilder sbAssets);
//Called by this class for each asset that exists. Imlementation must add the content to the given stringbuilder.
protected abstract void ProcessAsset(StringBuilder sbAssets, AssetRecord Asset, BaseRecord BaseRec, ResultPrimarySecondary ResultPrimSecond);
//Called once when the imlementation should end the asset replacement. Can be used to add a footer to the given StringBuilder
protected abstract void EndAssetDetails(StringBuilder sbAssets);
//Called once to replace the generated details in the template
protected abstract void ReplaceAssetList(string ValueName, string AssetList);
//Called once when the imlementation should start to begin asset value replacement. Can be used to add a header to the given StringBuilder
protected abstract void StartTestDetails(StringBuilder sbTests);
//Called by this class for each test that exists. Imlementation must add the content to the given stringbuilder.
protected abstract void ProcessTest(StringBuilder sbTests, TestRecord Test, BaseRecord BaseRec, ResultPrimarySecondary ResultPrimSecond);
//Called once when the imlementation should end the test replacement. Can be used to add a footer to the given StringBuilder
protected abstract void EndTestDetails(StringBuilder sbTests);
//Called once to replace the generated details in the template
protected abstract void ReplaceTestList(string ValueName, string TestList);
}
}