mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 09:15:33 +00:00
Results of SyntaxCheck -> extra State
This commit is contained in:
@@ -13,12 +13,10 @@ public class XMLStateController : Controller {
|
|||||||
private IHaDocumentWrappper _lib;
|
private IHaDocumentWrappper _lib;
|
||||||
private readonly IXMLInteractionService _xmlService;
|
private readonly IXMLInteractionService _xmlService;
|
||||||
private readonly IXMLFileProvider _xmlProvider;
|
private readonly IXMLFileProvider _xmlProvider;
|
||||||
private readonly IMonitorLoop _loop;
|
public XMLStateController(IHaDocumentWrappper lib, IXMLInteractionService xmlService, IXMLFileProvider xmlProvider) {
|
||||||
public XMLStateController(IMonitorLoop loop, IHaDocumentWrappper lib, IXMLInteractionService xmlService, IXMLFileProvider xmlProvider) {
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_xmlService = xmlService;
|
_xmlService = xmlService;
|
||||||
_xmlProvider = xmlProvider;
|
_xmlProvider = xmlProvider;
|
||||||
_loop = loop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -26,7 +24,6 @@ public class XMLStateController : Controller {
|
|||||||
[FeatureGate(Features.AdminService)]
|
[FeatureGate(Features.AdminService)]
|
||||||
[GenerateAntiforgeryTokenCookie]
|
[GenerateAntiforgeryTokenCookie]
|
||||||
public IActionResult Index() {
|
public IActionResult Index() {
|
||||||
_loop.StartMonitorLoop();
|
|
||||||
var library = _lib.GetLibrary();
|
var library = _lib.GetLibrary();
|
||||||
var roots = _xmlService.GetRootsList();
|
var roots = _xmlService.GetRootsList();
|
||||||
if (roots == null) return error404();
|
if (roots == null) return error404();
|
||||||
@@ -39,6 +36,7 @@ public class XMLStateController : Controller {
|
|||||||
|
|
||||||
var model = new XMLStateViewModel("Dateiübersicht", gD, roots, hF, mF, vS) {
|
var model = new XMLStateViewModel("Dateiübersicht", gD, roots, hF, mF, vS) {
|
||||||
ActiveFile = activeF,
|
ActiveFile = activeF,
|
||||||
|
SyntaxCheck = _xmlService.Test()
|
||||||
};
|
};
|
||||||
return View("~/Views/Admin/Dynamic/XMLState.cshtml", model);
|
return View("~/Views/Admin/Dynamic/XMLState.cshtml", model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ namespace HaWeb.FileHelpers;
|
|||||||
|
|
||||||
public class ConfigurationMonitor {
|
public class ConfigurationMonitor {
|
||||||
private System.Timers.Timer? _timer;
|
private System.Timers.Timer? _timer;
|
||||||
|
private string[] _paths;
|
||||||
private (string, byte[])[]? _h;
|
private (string, byte[])[]? _h;
|
||||||
private IServiceProvider _serviceProvider;
|
private IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
public ConfigurationMonitor(string[] paths, IServiceProvider services) {
|
public ConfigurationMonitor(string[] paths, IServiceProvider services) {
|
||||||
|
_paths = paths;
|
||||||
_h = _getHash(paths);
|
_h = _getHash(paths);
|
||||||
_serviceProvider = services;
|
_serviceProvider = services;
|
||||||
}
|
}
|
||||||
@@ -33,27 +35,25 @@ public class ConfigurationMonitor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeChanged(string[] paths) {
|
public void InvokeChanged(IHostEnvironment _) {
|
||||||
var h = _getHash(paths);
|
var h = _getHash(_paths);
|
||||||
if (_timer == null && !isEqual(h, _h)) {
|
if (_timer == null && !isEqual(h, _h)) {
|
||||||
_h = h;
|
_h = h;
|
||||||
_timer = new(5000) { AutoReset = false };
|
_timer = new(8000) { AutoReset = false };
|
||||||
_timer.Enabled = true;
|
_timer.Enabled = true;
|
||||||
_timer.Elapsed += Action;
|
_timer.Elapsed += OnChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Action(Object source, System.Timers.ElapsedEventArgs e) {
|
private void OnChanged(Object source, System.Timers.ElapsedEventArgs e) {
|
||||||
Console.WriteLine("Configuration changed (ConfigurationMonitor Class)");
|
Console.WriteLine("Configuration changed (ConfigurationMonitor Class)");
|
||||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
IServiceProvider provider = serviceScope.ServiceProvider;
|
IServiceProvider provider = serviceScope.ServiceProvider;
|
||||||
|
|
||||||
var cP = provider.GetRequiredService<IConfiguration>();
|
var cP = provider.GetRequiredService<IConfiguration>();
|
||||||
var hP = provider.GetRequiredService<IHaDocumentWrappper>();
|
var hP = provider.GetRequiredService<IHaDocumentWrappper>();
|
||||||
hP.ParseConfiguration(cP);
|
hP.ParseConfiguration(cP);
|
||||||
var fP = provider.GetRequiredService<IXMLFileProvider>();
|
var fP = provider.GetRequiredService<IXMLFileProvider>();
|
||||||
fP.Reload(cP);
|
fP.ParseConfiguration(cP);
|
||||||
|
|
||||||
// _lifetime.StopApplication();
|
// _lifetime.StopApplication();
|
||||||
_timer = null;
|
_timer = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public interface IXMLFileProvider {
|
|||||||
public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState);
|
public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState);
|
||||||
public List<IFileInfo>? GetHamannFiles();
|
public List<IFileInfo>? GetHamannFiles();
|
||||||
public (DateTime PullTime, string Hash)? GetGitData();
|
public (DateTime PullTime, string Hash)? GetGitData();
|
||||||
public void Reload(IConfiguration config);
|
public void ParseConfiguration(IConfiguration config);
|
||||||
public bool HasChanged();
|
public bool HasChanged();
|
||||||
public void DeleteHamannFile(string filename);
|
public void DeleteHamannFile(string filename);
|
||||||
public void Scan();
|
public void Scan();
|
||||||
|
|||||||
@@ -49,19 +49,19 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
}
|
}
|
||||||
_HamannFiles = _ScanHamannFiles();
|
_HamannFiles = _ScanHamannFiles();
|
||||||
|
|
||||||
// Check if hamann file already is current working tree status
|
// Check if hamann file already is current working tree status
|
||||||
// -> YES: Load up the file via _lib.SetLibrary();
|
// -> YES: Load up the file via _lib.SetLibrary();
|
||||||
if (_IsAlreadyParsed()) {
|
if (_IsAlreadyParsed()) {
|
||||||
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
_Lib.SetLibrary(_HamannFiles!.First(), null, null);
|
||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> NO: Try to create a new file
|
// -> NO: Try to create a new file
|
||||||
var created = xmlservice.TryCreate();
|
var created = _XMLService.TryCreate();
|
||||||
if (created != null) {
|
if (created != null) {
|
||||||
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
_lib.SetLibrary(file, created.Document, null);
|
_Lib.SetLibrary(file, created.Document, null);
|
||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,36 +75,32 @@ public class XMLFileProvider : IXMLFileProvider {
|
|||||||
// -> There is none? Use Fallback:
|
// -> There is none? Use Fallback:
|
||||||
else {
|
else {
|
||||||
var options = new HaWeb.Settings.HaDocumentOptions();
|
var options = new HaWeb.Settings.HaDocumentOptions();
|
||||||
if (_lib.SetLibrary(null, null, null) == null) {
|
if (_Lib.SetLibrary(null, null, null) == null) {
|
||||||
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
|
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reload(IConfiguration config) {
|
public void ParseConfiguration(IConfiguration config) {
|
||||||
_Branch = config.GetValue<string>("RepositoryBranch");
|
_Branch = config.GetValue<string>("RepositoryBranch");
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
|
||||||
_hamannFileProvider = new PhysicalFileProvider(config.GetValue<string>("HamannFileStoreWindows"));
|
|
||||||
_bareRepositoryFileProvider = new PhysicalFileProvider(config.GetValue<string>("BareRepositoryPathWindows"));
|
|
||||||
_workingTreeFileProvider = new PhysicalFileProvider(config.GetValue<string>("WorkingTreePathWindows"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_hamannFileProvider = new PhysicalFileProvider(config.GetValue<string>("HamannFileStoreLinux"));
|
|
||||||
_bareRepositoryFileProvider = new PhysicalFileProvider(config.GetValue<string>("BareRepositoryPathLinux"));
|
|
||||||
_workingTreeFileProvider = new PhysicalFileProvider(config.GetValue<string>("WorkingTreePathLinux"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create File Lists; Here and in xmlservice, which does preliminary checking
|
|
||||||
Scan();
|
Scan();
|
||||||
|
// Reset XMLInteractionService
|
||||||
if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) {
|
if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) {
|
||||||
_XMLService.Collect(_WorkingTreeFiles);
|
_XMLService.Collect(_WorkingTreeFiles);
|
||||||
}
|
}
|
||||||
_HamannFiles = _ScanHamannFiles();
|
_HamannFiles = _ScanHamannFiles();
|
||||||
|
|
||||||
|
if (_HamannFiles != null && _HamannFiles.Select(x => x.Name).Contains(_Lib.GetActiveFile().Name)) {
|
||||||
|
_Lib.SetLibrary(_Lib.GetActiveFile(), null, null);
|
||||||
|
if (_Lib.GetLibrary() != null) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to reload File, reload it all, same procedure as above:
|
||||||
// Check if hamann file already is current working tree status
|
// Check if hamann file already is current working tree status
|
||||||
// -> YES: Load up the file via _lib.SetLibrary();
|
// -> YES: Load up the file via _lib.SetLibrary();
|
||||||
if (_IsAlreadyParsed()) {
|
if (_IsAlreadyParsed()) {
|
||||||
_Lib.SetLibrary(_HamannFiles.First(), null, null);
|
_Lib.SetLibrary(_HamannFiles!.First(), null, null);
|
||||||
if (_Lib.GetLibrary() != null) return;
|
if (_Lib.GetLibrary() != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,13 +27,4 @@ public class FileList {
|
|||||||
|
|
||||||
public List<XMLRootDocument>? GetFileList()
|
public List<XMLRootDocument>? GetFileList()
|
||||||
=> this._Files != null ? this._Files.ToList() : null;
|
=> this._Files != null ? this._Files.ToList() : null;
|
||||||
|
|
||||||
public FileList Clone() {
|
|
||||||
var ret = new FileList(this.XMLRoot);
|
|
||||||
if (_Files != null)
|
|
||||||
foreach (var file in _Files) {
|
|
||||||
ret.Add(file);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace HaWeb.Models;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
public class YearSetting {
|
|
||||||
[Required]
|
|
||||||
public int EndYear { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
|
|
||||||
public class SyntaxCheckModel {
|
public class SyntaxCheckModel {
|
||||||
public string Prefix { get; private set; }
|
public string File { get; private set; }
|
||||||
public List<SyntaxError>? Errors { get; set; }
|
public List<SyntaxError>? Errors { get; private set; }
|
||||||
public List<SyntaxError>? Warnings { get; set; }
|
|
||||||
|
|
||||||
public SyntaxCheckModel(string prefix) {
|
public SyntaxCheckModel(string file) {
|
||||||
Prefix = prefix;
|
File = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(int? line, int? column, string msg) {
|
||||||
|
if (String.IsNullOrWhiteSpace(msg)) return;
|
||||||
|
if (Errors == null) Errors = new();
|
||||||
|
// var prefix = DateTime.Now.ToLongDateString() + ": ";
|
||||||
|
Errors.Add(new SyntaxError(line, column, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetLog() {
|
||||||
|
Errors = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SyntaxError {
|
|
||||||
public string Message { get; private set; }
|
|
||||||
public string? File { get; set; }
|
|
||||||
public string? Line { get; set; }
|
|
||||||
public string? Column { get; set; }
|
|
||||||
|
|
||||||
public SyntaxError(string message) {
|
|
||||||
Message = message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
13
HaWeb/Models/SyntaxErrorModel.cs
Normal file
13
HaWeb/Models/SyntaxErrorModel.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace HaWeb.Models;
|
||||||
|
|
||||||
|
public class SyntaxError {
|
||||||
|
public string Message { get; private set; }
|
||||||
|
public int? Line { get; set; }
|
||||||
|
public int? Column { get; set; }
|
||||||
|
|
||||||
|
public SyntaxError(int? line, int? column, string message) {
|
||||||
|
Line = line;
|
||||||
|
Column = column;
|
||||||
|
Message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,9 @@ public class XMLStateViewModel {
|
|||||||
// Verfügbare (Gesamt-)Dateien
|
// Verfügbare (Gesamt-)Dateien
|
||||||
public List<IFileInfo>? HamannFiles { get; set; }
|
public List<IFileInfo>? HamannFiles { get; set; }
|
||||||
|
|
||||||
|
// Syntax-Check-Resultate
|
||||||
|
public Dictionary<string, SyntaxCheckModel>? SyntaxCheck { get; set; }
|
||||||
|
|
||||||
public XMLStateViewModel(
|
public XMLStateViewModel(
|
||||||
string title,
|
string title,
|
||||||
(DateTime PullTime, string Hash)? gitData,
|
(DateTime PullTime, string Hash)? gitData,
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
|||||||
builder.Configuration.AddJsonFile(p, optional: true, reloadOnChange: true);
|
builder.Configuration.AddJsonFile(p, optional: true, reloadOnChange: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create initial Data
|
// Create initial Data
|
||||||
var tS = new XMLTestService();
|
var tS = new XMLTestService();
|
||||||
var XMLIS = new XMLInteractionService(builder.Configuration, tS);
|
var XMLIS = new XMLInteractionService(builder.Configuration, tS);
|
||||||
@@ -59,7 +57,7 @@ var cM = new ConfigurationMonitor(configpaths.ToArray(), app.Services);
|
|||||||
ChangeToken.OnChange(
|
ChangeToken.OnChange(
|
||||||
() => app.Configuration.GetReloadToken(),
|
() => app.Configuration.GetReloadToken(),
|
||||||
(state) => cM.InvokeChanged(state),
|
(state) => cM.InvokeChanged(state),
|
||||||
configpaths.ToArray()
|
app.Environment
|
||||||
);
|
);
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|||||||
@@ -25,8 +25,18 @@
|
|||||||
<td>@f.GetLastModified()</td>
|
<td>@f.GetLastModified()</td>
|
||||||
@if (f.IsValid) {
|
@if (f.IsValid) {
|
||||||
<td>Valid! @f.GetLog()</td>
|
<td>Valid! @f.GetLog()</td>
|
||||||
|
<td>
|
||||||
|
@if (Model.SyntaxCheck[f.FileName] != null && Model.SyntaxCheck[f.FileName].Errors != null) {
|
||||||
|
<ul>
|
||||||
|
@foreach(var e in Model.SyntaxCheck[f.FileName]?.Errors) {
|
||||||
|
<li>@e.Line @e.Column @e.Message </li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
} else {
|
} else {
|
||||||
<td>@f.GetLog()</td>
|
<td>@f.GetLog()</td>
|
||||||
|
<td> </td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public interface IXMLInteractionService {
|
|||||||
public List<IXMLRoot>? GetRootsList();
|
public List<IXMLRoot>? GetRootsList();
|
||||||
public void CreateSearchables(XDocument document);
|
public void CreateSearchables(XDocument document);
|
||||||
public List<FileModel>? GetManagedFiles();
|
public List<FileModel>? GetManagedFiles();
|
||||||
|
public Dictionary<string, SyntaxCheckModel>? Test();
|
||||||
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader, ILibrary? lib);
|
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader, ILibrary? lib);
|
||||||
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? GetPreviews(List<(string, List<Marginal>)> places, IReaderService reader, ILibrary lib);
|
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? GetPreviews(List<(string, List<Marginal>)> places, IReaderService reader, ILibrary lib);
|
||||||
}
|
}
|
||||||
@@ -86,11 +86,12 @@ public class XMLInteractionService : IXMLInteractionService {
|
|||||||
public void Collect(List<IFileInfo> files) {
|
public void Collect(List<IFileInfo> files) {
|
||||||
if (files == null || !files.Any()) return;
|
if (files == null || !files.Any()) return;
|
||||||
_ValidState = true;
|
_ValidState = true;
|
||||||
List<FileModel> res = new List<FileModel>();
|
Dictionary<string, FileList?>? lF = new Dictionary<string, FileList?>();
|
||||||
|
List<FileModel> fM = new List<FileModel>();
|
||||||
foreach (var f in files) {
|
foreach (var f in files) {
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var m = _CreateFileModel(f, null);
|
var m = _CreateFileModel(f, null);
|
||||||
res.Add(m);
|
fM.Add(m);
|
||||||
// 1. Open File for Reading
|
// 1. Open File for Reading
|
||||||
try {
|
try {
|
||||||
using (Stream file = f.CreateReadStream()) {
|
using (Stream file = f.CreateReadStream()) {
|
||||||
@@ -118,9 +119,8 @@ public class XMLInteractionService : IXMLInteractionService {
|
|||||||
// Success! File can be recognized and parsed.
|
// Success! File can be recognized and parsed.
|
||||||
m.Validate();
|
m.Validate();
|
||||||
foreach (var d in docs) {
|
foreach (var d in docs) {
|
||||||
if (_Loaded == null) _Loaded = new Dictionary<string, FileList?>();
|
if (!lF.ContainsKey(d.Prefix)) lF.Add(d.Prefix, new FileList(d.XMLRoot));
|
||||||
if (!_Loaded.ContainsKey(d.Prefix)) _Loaded.Add(d.Prefix, new FileList(d.XMLRoot));
|
lF[d.Prefix]!.Add(d);
|
||||||
_Loaded[d.Prefix]!.Add(d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@@ -128,20 +128,26 @@ public class XMLInteractionService : IXMLInteractionService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(res.Any()) this._ManagedFiles = res;
|
|
||||||
|
|
||||||
// Set validity
|
// Set data
|
||||||
|
this._ManagedFiles = fM;
|
||||||
|
this._Loaded = lF;
|
||||||
foreach (var f in _ManagedFiles) {
|
foreach (var f in _ManagedFiles) {
|
||||||
if (!f.IsValid) _ValidState = false;
|
if (!f.IsValid) this._ValidState = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Speed up this:
|
public Dictionary<string, SyntaxCheckModel>? Test() {
|
||||||
|
if (_Loaded == null) return null;
|
||||||
|
// TODO: Speed up this, move it into a background task:
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
_testService.Test(this);
|
var res = this._Loaded?.SelectMany(x => x.Value?.GetFileList()?.Select(x => x.File)).Distinct().Select(x => x.FileName);
|
||||||
|
var ret = _testService.Test(this._Loaded, res.ToDictionary(x => x, y => new SyntaxCheckModel(y)));
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
Console.WriteLine("Syntaxcheck " + sw.ElapsedMilliseconds.ToString() + " ms");
|
Console.WriteLine("Syntaxcheck " + sw.ElapsedMilliseconds.ToString() + " ms");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XElement? TryCreate() {
|
public XElement? TryCreate() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using HaWeb.Models;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
|
|
||||||
namespace HaWeb.XMLTests;
|
namespace HaWeb.XMLTests;
|
||||||
@@ -7,5 +8,5 @@ public interface IXMLTestService {
|
|||||||
public Dictionary<string, INodeRule>? Ruleset { get; }
|
public Dictionary<string, INodeRule>? Ruleset { get; }
|
||||||
public Dictionary<string, ICollectionRule>? CollectionRuleset { get; }
|
public Dictionary<string, ICollectionRule>? CollectionRuleset { get; }
|
||||||
|
|
||||||
public void Test(IXMLInteractionService _XMLService);
|
public Dictionary<string, SyntaxCheckModel>? Test(Dictionary<string, FileList?>? _LoadedFiles, Dictionary<string, SyntaxCheckModel> _Results);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace HaWeb.XMLTests;
|
namespace HaWeb.XMLTests;
|
||||||
|
|
||||||
|
using HaWeb.Models;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
|
|
||||||
public class XMLTestService : IXMLTestService {
|
public class XMLTestService : IXMLTestService {
|
||||||
@@ -7,28 +9,26 @@ public class XMLTestService : IXMLTestService {
|
|||||||
public XMLTestService() {
|
public XMLTestService() {
|
||||||
var roottypes = _GetAllTypesThatImplementInterface<INodeRule>().ToList();
|
var roottypes = _GetAllTypesThatImplementInterface<INodeRule>().ToList();
|
||||||
roottypes.ForEach( x => {
|
roottypes.ForEach( x => {
|
||||||
if (this.Ruleset == null) this.Ruleset = new Dictionary<string, INodeRule>();
|
if (this.Ruleset == null) this.Ruleset = new();
|
||||||
var instance = (INodeRule)Activator.CreateInstance(x)!;
|
var instance = (INodeRule)Activator.CreateInstance(x)!;
|
||||||
if (instance != null) this.Ruleset.Add(instance.Name, instance);
|
if (instance != null) this.Ruleset.Add(instance.Name, instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
var collectionruleset = _GetAllTypesThatImplementInterface<ICollectionRule>().ToList();
|
var collectionruleset = _GetAllTypesThatImplementInterface<ICollectionRule>().ToList();
|
||||||
collectionruleset.ForEach( x => {
|
collectionruleset.ForEach( x => {
|
||||||
if (this.CollectionRuleset == null) this.CollectionRuleset = new Dictionary<string, ICollectionRule>();
|
if (this.CollectionRuleset == null) this.CollectionRuleset = new();
|
||||||
var instance = (ICollectionRule)Activator.CreateInstance(x)!;
|
var instance = (ICollectionRule)Activator.CreateInstance(x)!;
|
||||||
if (instance != null) this.CollectionRuleset.Add(instance.Name, instance);
|
if (instance != null) this.CollectionRuleset.Add(instance.Name, instance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Test(IXMLInteractionService _XMLService) {
|
public Dictionary<string, SyntaxCheckModel>? Test(Dictionary<string, FileList?>? _Loaded, Dictionary<string, SyntaxCheckModel> _Results) {
|
||||||
var docs = _XMLService.GetLoaded();
|
if (_Loaded == null) return null;
|
||||||
if (docs == null) return;
|
var tester = new XMLTester(this, _Loaded, _Results);
|
||||||
var tester = new XMLTester(this, docs);
|
return tester.Test();
|
||||||
tester.Test();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<Type> _GetAllTypesThatImplementInterface<T>()
|
private IEnumerable<Type> _GetAllTypesThatImplementInterface<T>() {
|
||||||
{
|
|
||||||
return System.Reflection.Assembly.GetExecutingAssembly()
|
return System.Reflection.Assembly.GetExecutingAssembly()
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
|
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ public class XMLTester {
|
|||||||
private Dictionary<string, INodeRule>? _Ruleset;
|
private Dictionary<string, INodeRule>? _Ruleset;
|
||||||
private Dictionary<string, ICollectionRule>? _CollectionRuleset;
|
private Dictionary<string, ICollectionRule>? _CollectionRuleset;
|
||||||
private List<XMLRootDocument>? _Documents;
|
private List<XMLRootDocument>? _Documents;
|
||||||
|
private Dictionary<string, SyntaxCheckModel> _Results;
|
||||||
private Dictionary<string, HashSet<string>>? _IDs;
|
private Dictionary<string, HashSet<string>>? _IDs;
|
||||||
private Dictionary<string, HashSet<string>>? _CollectionIDs;
|
private Dictionary<string, HashSet<string>>? _CollectionIDs;
|
||||||
private Dictionary<string, List<(XElement, XMLRootDocument)>?> _XPathEvaluated;
|
private Dictionary<string, List<(XElement, XMLRootDocument)>?> _XPathEvaluated;
|
||||||
public XMLTester (IXMLTestService testService, Dictionary<string, Models.FileList?>? filelists) {
|
public XMLTester (IXMLTestService testService, Dictionary<string, Models.FileList?>? filelists, Dictionary<string, SyntaxCheckModel> results) {
|
||||||
_Ruleset = testService.Ruleset;
|
_Ruleset = testService.Ruleset;
|
||||||
_CollectionRuleset = testService.CollectionRuleset;
|
_CollectionRuleset = testService.CollectionRuleset;
|
||||||
|
_Results = results;
|
||||||
if (filelists != null) {
|
if (filelists != null) {
|
||||||
foreach (var fl in filelists) {
|
foreach (var fl in filelists) {
|
||||||
if (fl.Value != null) {
|
if (fl.Value != null) {
|
||||||
@@ -27,20 +29,21 @@ public class XMLTester {
|
|||||||
_XPathEvaluated = new Dictionary<string, List<(XElement, XMLRootDocument)>?>();
|
_XPathEvaluated = new Dictionary<string, List<(XElement, XMLRootDocument)>?>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Test() {
|
public Dictionary<string, SyntaxCheckModel>? Test() {
|
||||||
if (_Ruleset == null) return;
|
if (_Ruleset == null) return null;
|
||||||
_IDs = new Dictionary<string, HashSet<string>>();
|
_IDs = new Dictionary<string, HashSet<string>>();
|
||||||
foreach (var rule in _Ruleset) {
|
foreach (var rule in _Ruleset) {
|
||||||
buildIDs(rule.Value);
|
buildIDs(rule.Value);
|
||||||
checkRequiredAttributes(rule.Value);
|
checkRequiredAttributes(rule.Value);
|
||||||
checkReferences(rule.Value);
|
checkReferences(rule.Value);
|
||||||
}
|
}
|
||||||
if (_CollectionRuleset == null) return;
|
if (_CollectionRuleset == null) return null;
|
||||||
_CollectionIDs = new Dictionary<string, HashSet<string>>();
|
_CollectionIDs = new Dictionary<string, HashSet<string>>();
|
||||||
foreach (var collectionrule in _CollectionRuleset) {
|
foreach (var collectionrule in _CollectionRuleset) {
|
||||||
buildIDs(collectionrule.Value);
|
buildIDs(collectionrule.Value);
|
||||||
checkReferences(collectionrule.Value);
|
checkReferences(collectionrule.Value);
|
||||||
}
|
}
|
||||||
|
return _Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkReferences(INodeRule rule) {
|
private void checkReferences(INodeRule rule) {
|
||||||
@@ -54,7 +57,8 @@ public class XMLTester {
|
|||||||
if (_IDs != null && _IDs.ContainsKey(keyname) && hasattr) {
|
if (_IDs != null && _IDs.ContainsKey(keyname) && hasattr) {
|
||||||
var val = e.Item1.Attribute(r.LinkAttribute)!.Value;
|
var val = e.Item1.Attribute(r.LinkAttribute)!.Value;
|
||||||
if (!_IDs[keyname].Contains(val)) {
|
if (!_IDs[keyname].Contains(val)) {
|
||||||
e.Item2.File.Log(generateLogMessage(e.Item1) + "Verlinktes Element " + val + " nicht gefunden.");
|
var lc = getLineColumn(e.Item1);
|
||||||
|
_Results[e.Item2.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + val + " nicht gefunden.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +73,8 @@ public class XMLTester {
|
|||||||
if (elemens != null && elemens.Any()) {
|
if (elemens != null && elemens.Any()) {
|
||||||
foreach(var r in rule.GenerateBacklinkString(elemens)) {
|
foreach(var r in rule.GenerateBacklinkString(elemens)) {
|
||||||
if (!r.Item4 && !_CollectionIDs[rule.Name].Contains(r.Item1)) {
|
if (!r.Item4 && !_CollectionIDs[rule.Name].Contains(r.Item1)) {
|
||||||
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
var lc = getLineColumn(r.Item2);
|
||||||
|
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
||||||
}
|
}
|
||||||
if (r.Item4) {
|
if (r.Item4) {
|
||||||
var coll = _CollectionIDs[rule.Name];
|
var coll = _CollectionIDs[rule.Name];
|
||||||
@@ -77,15 +82,18 @@ public class XMLTester {
|
|||||||
var searchterm = items[0];
|
var searchterm = items[0];
|
||||||
var found = coll.Where(x => x.StartsWith(searchterm));
|
var found = coll.Where(x => x.StartsWith(searchterm));
|
||||||
if (items[0] == "NA" || found == null || !found.Any()) {
|
if (items[0] == "NA" || found == null || !found.Any()) {
|
||||||
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
var lc = getLineColumn(r.Item2);
|
||||||
|
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
||||||
} else {
|
} else {
|
||||||
for (var i = 1; i < items.Length; i++) {
|
for (var i = 1; i < items.Length; i++) {
|
||||||
if (items[i] == "NA") break;
|
if (items[i] == "NA") break;
|
||||||
else {
|
else {
|
||||||
searchterm = searchterm + "-" + items[i];
|
searchterm = searchterm + "-" + items[i];
|
||||||
found = found.Where(x => x.StartsWith(searchterm));
|
found = found.Where(x => x.StartsWith(searchterm));
|
||||||
if (found == null || !found.Any())
|
if (found == null || !found.Any()) {
|
||||||
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
var lc = getLineColumn(r.Item2);
|
||||||
|
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +134,8 @@ public class XMLTester {
|
|||||||
if (elemens != null && elemens.Any()) {
|
if (elemens != null && elemens.Any()) {
|
||||||
foreach (var r in rule.GenerateIdentificationStrings(elemens)) {
|
foreach (var r in rule.GenerateIdentificationStrings(elemens)) {
|
||||||
if (!hs.Add(r.Item1)) {
|
if (!hs.Add(r.Item1)) {
|
||||||
r.Item3.File.Log(generateLogMessage(r.Item2) + "Brief-Seite-Zeile " + r.Item1 + " mehrdeutig.");
|
var lc = getLineColumn(r.Item2);
|
||||||
|
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Brief-Seite-Zeile " + r.Item1 + " mehrdeutig.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +152,8 @@ public class XMLTester {
|
|||||||
foreach (var e in elements) {
|
foreach (var e in elements) {
|
||||||
if (checkAttribute(e.Item1, attribute, e.Item2)) {
|
if (checkAttribute(e.Item1, attribute, e.Item2)) {
|
||||||
if (!hs.Add(e.Item1.Attribute(attribute)!.Value)) {
|
if (!hs.Add(e.Item1.Attribute(attribute)!.Value)) {
|
||||||
e.Item2.File.Log(generateLogMessage(e.Item1) + "Attributwert " + e.Item1.Attribute(attribute)!.Value + " doppelt.");
|
var lc = getLineColumn(e.Item1);
|
||||||
|
_Results[e.Item2.File.FileName].Log(lc.Item1, lc.Item2, "Attributwert " + e.Item1.Attribute(attribute)!.Value + " doppelt.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,18 +162,17 @@ public class XMLTester {
|
|||||||
|
|
||||||
private bool checkAttribute(XElement element, string attributename, XMLRootDocument doc, bool log = true) {
|
private bool checkAttribute(XElement element, string attributename, XMLRootDocument doc, bool log = true) {
|
||||||
if (!element.HasAttributes || element.Attribute(attributename) == null) {
|
if (!element.HasAttributes || element.Attribute(attributename) == null) {
|
||||||
if (log) doc.File.Log(generateLogMessage(element) + "Attribut " + attributename + " fehlt.");
|
if (log) {
|
||||||
|
var lc = getLineColumn(element);
|
||||||
|
_Results[doc.File.FileName].Log(lc.Item1, lc.Item2,"Attribut " + attributename + " fehlt.");
|
||||||
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string generateLogMessage(XElement element) {
|
private (int, int) getLineColumn(XElement element) {
|
||||||
return "Zeile " +
|
return (((IXmlLineInfo)element).LineNumber, ((IXmlLineInfo)element).LinePosition);
|
||||||
((IXmlLineInfo)element).LineNumber.ToString() +
|
|
||||||
", Element " +
|
|
||||||
element.Name +
|
|
||||||
": ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache for XPATH evaluation
|
// Cache for XPATH evaluation
|
||||||
|
|||||||
Reference in New Issue
Block a user