mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 17:25:32 +00:00
Erste checks
This commit is contained in:
@@ -9,6 +9,7 @@ using HaWeb.Filters;
|
|||||||
using HaWeb.FileHelpers;
|
using HaWeb.FileHelpers;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
using HaWeb.Models;
|
using HaWeb.Models;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using HaDocument.Interfaces;
|
using HaDocument.Interfaces;
|
||||||
@@ -28,17 +29,19 @@ public class APIController : Controller {
|
|||||||
private readonly string _targetFilePath;
|
private readonly string _targetFilePath;
|
||||||
private readonly IXMLService _xmlService;
|
private readonly IXMLService _xmlService;
|
||||||
private readonly IXMLProvider _xmlProvider;
|
private readonly IXMLProvider _xmlProvider;
|
||||||
|
private readonly IXMLTestService _testService;
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
private static readonly string[] _permittedExtensions = { ".xml" };
|
private static readonly string[] _permittedExtensions = { ".xml" };
|
||||||
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
||||||
|
|
||||||
|
|
||||||
public APIController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IXMLProvider xmlProvider, IConfiguration config) {
|
public APIController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IXMLProvider xmlProvider, IXMLTestService testService, IConfiguration config) {
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_xmlProvider = xmlProvider;
|
_xmlProvider = xmlProvider;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
_xmlService = xmlService;
|
_xmlService = xmlService;
|
||||||
|
_testService = testService;
|
||||||
_fileSizeLimit = config.GetValue<long>("FileSizeLimit");
|
_fileSizeLimit = config.GetValue<long>("FileSizeLimit");
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
||||||
_targetFilePath = config.GetValue<string>("StoredFilePathWindows");
|
_targetFilePath = config.GetValue<string>("StoredFilePathWindows");
|
||||||
@@ -154,6 +157,7 @@ public class APIController : Controller {
|
|||||||
};
|
};
|
||||||
|
|
||||||
string json = JsonSerializer.Serialize(docs);
|
string json = JsonSerializer.Serialize(docs);
|
||||||
|
_testService.Test();
|
||||||
return Created(nameof(UploadController), json);
|
return Created(nameof(UploadController), json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,11 +264,12 @@ public class APIController : Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_xmlService.UnUse(id);
|
||||||
if (newUsed != null && newUsed.Any()) {
|
if (newUsed != null && newUsed.Any()) {
|
||||||
_xmlService.UnUse(id);
|
|
||||||
newUsed.ForEach(x => _xmlService.Use(x));
|
newUsed.ForEach(x => _xmlService.Use(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_testService.Test();
|
||||||
return Created("/", newUsed);
|
return Created("/", newUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,9 @@ public static class XMLFileHelpers {
|
|||||||
isUsed = usedFiles[id]!.Contains(document);
|
isUsed = usedFiles[id]!.Contains(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileModel(document.FileName, document.Prefix, document.File.LastModified.LocalDateTime, isUsed, inProduction) { Fields = document.Fields };
|
var model = new FileModel(document.FileName, document.Prefix, document.File.LastModified.LocalDateTime, isUsed, inProduction) { Fields = document.Fields };
|
||||||
|
model.Messages = document.GetLog();
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<byte[]?> ProcessStreamedFile(
|
public static async Task<byte[]?> ProcessStreamedFile(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using HaWeb.Models;
|
|||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
// XMLService provides a wrapper around the available XML data on a FILE basis
|
// XMLProvider provides a wrapper around the available XML data on a FILE basis
|
||||||
public class XMLProvider : IXMLProvider {
|
public class XMLProvider : IXMLProvider {
|
||||||
private IFileProvider _fileProvider;
|
private IFileProvider _fileProvider;
|
||||||
private Dictionary<string, FileList?>? _Files;
|
private Dictionary<string, FileList?>? _Files;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public class FileModel {
|
|||||||
public bool IsUsed { get; private set; }
|
public bool IsUsed { get; private set; }
|
||||||
public bool InProduction { get; private set; }
|
public bool InProduction { get; private set; }
|
||||||
public List<(string, string?)>? Fields { get; set; }
|
public List<(string, string?)>? Fields { get; set; }
|
||||||
|
public string? Messages { get; set; }
|
||||||
|
|
||||||
public FileModel(string name, string prefix, DateTime lastModified, bool isUsed, bool inProduction) {
|
public FileModel(string name, string prefix, DateTime lastModified, bool isUsed, bool inProduction) {
|
||||||
FileName = name;
|
FileName = name;
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ using System.Text.Json.Serialization;
|
|||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
public class XMLRootDocument {
|
public class XMLRootDocument {
|
||||||
private XElement? _Element;
|
private XElement? _Element;
|
||||||
private string? _filename;
|
private string? _filename;
|
||||||
private IFileInfo? _file;
|
private IFileInfo? _file;
|
||||||
|
|
||||||
|
private StringBuilder? _log;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IXMLRoot XMLRoot { get; private set; }
|
public IXMLRoot XMLRoot { get; private set; }
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ public class XMLRootDocument {
|
|||||||
_file = value;
|
_file = value;
|
||||||
// After saving, we don't need to save the ELement anymore, it can get read in if it's used.
|
// After saving, we don't need to save the ELement anymore, it can get read in if it's used.
|
||||||
// We do this to prevent memory hogging. TODO: MAKE IT MORE EFFICIENT, EG ALL USED FILES HAVE SET ELEMENTS OR SO
|
// We do this to prevent memory hogging. TODO: MAKE IT MORE EFFICIENT, EG ALL USED FILES HAVE SET ELEMENTS OR SO
|
||||||
if (value != null) _Element = null;
|
// if (value != null) _Element = null;
|
||||||
} }
|
} }
|
||||||
public string Prefix { get; private set; }
|
public string Prefix { get; private set; }
|
||||||
public DateTime Date { get; private set; }
|
public DateTime Date { get; private set; }
|
||||||
@@ -89,12 +92,39 @@ public class XMLRootDocument {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string? GetLog() {
|
||||||
|
if (_log == null) return null;
|
||||||
|
return _log.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(string msg) {
|
||||||
|
if (_log == null) _log = new StringBuilder();
|
||||||
|
var prefix = DateTime.Now.ToString() + " ";
|
||||||
|
if (File != null) prefix += File.Name + ": ";
|
||||||
|
_log.Append("<br>" + prefix + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetLog() {
|
||||||
|
if (_log != null) _log.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call on UnUse to prevent memory hogging
|
||||||
|
public void UnUse() {
|
||||||
|
_Element = null;
|
||||||
|
_log = null;
|
||||||
|
}
|
||||||
|
|
||||||
public XElement GetElement() {
|
public XElement GetElement() {
|
||||||
|
if (_Element == null)
|
||||||
|
_Element = _GetElement();
|
||||||
|
return _Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement _GetElement() {
|
||||||
if (File == null || String.IsNullOrWhiteSpace(File.PhysicalPath) || !File.Exists)
|
if (File == null || String.IsNullOrWhiteSpace(File.PhysicalPath) || !File.Exists)
|
||||||
throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden.");
|
throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden.");
|
||||||
|
|
||||||
var root = XMLRoot;
|
if (XMLRoot == null)
|
||||||
if (root == null)
|
|
||||||
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
||||||
|
|
||||||
XDocument? doc = null;
|
XDocument? doc = null;
|
||||||
@@ -107,7 +137,7 @@ public class XMLRootDocument {
|
|||||||
if (doc == null || doc.Root == null)
|
if (doc == null || doc.Root == null)
|
||||||
throw new Exception("Das Dokument ist ungültig und kann nicht gelesen werden: " + File.PhysicalPath);
|
throw new Exception("Das Dokument ist ungültig und kann nicht gelesen werden: " + File.PhysicalPath);
|
||||||
|
|
||||||
var element = root.IsTypeOf(doc.Root);
|
var element = XMLRoot.IsTypeOf(doc.Root);
|
||||||
if (element == null || !element.Any())
|
if (element == null || !element.Any())
|
||||||
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
||||||
|
|
||||||
@@ -115,8 +145,7 @@ public class XMLRootDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task Save(Stream stream, ModelStateDictionary state) {
|
public async Task Save(Stream stream, ModelStateDictionary state) {
|
||||||
var root = XMLRoot;
|
if (XMLRoot == null) {
|
||||||
if (root == null) {
|
|
||||||
state.AddModelError("Error", "No corresponding Root Element found.");
|
state.AddModelError("Error", "No corresponding Root Element found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -129,6 +158,6 @@ public class XMLRootDocument {
|
|||||||
_Element = GetElement();
|
_Element = GetElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
await root.CreateHamannDocument(_Element).SaveAsync(stream, SaveOptions.DisableFormatting, new CancellationToken());
|
await XMLRoot.CreateHamannDocument(_Element).SaveAsync(stream, SaveOptions.DisableFormatting, new CancellationToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using HaXMLReader;
|
|||||||
using HaXMLReader.Interfaces;
|
using HaXMLReader.Interfaces;
|
||||||
using HaDocument.Interfaces;
|
using HaDocument.Interfaces;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
using HaWeb.FileHelpers;
|
using HaWeb.FileHelpers;
|
||||||
using Microsoft.FeatureManagement;
|
using Microsoft.FeatureManagement;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -34,6 +35,7 @@ builder.Services.AddTransient<IReaderService, ReaderService>();
|
|||||||
builder.Services.AddSingleton<IXMLProvider, XMLProvider>();
|
builder.Services.AddSingleton<IXMLProvider, XMLProvider>();
|
||||||
builder.Services.AddSingleton<IXMLService, XMLService>();
|
builder.Services.AddSingleton<IXMLService, XMLService>();
|
||||||
builder.Services.AddSingleton<HaWeb.FileHelpers.IHaDocumentWrappper, HaWeb.FileHelpers.HaDocumentWrapper>();
|
builder.Services.AddSingleton<HaWeb.FileHelpers.IHaDocumentWrappper, HaWeb.FileHelpers.HaDocumentWrapper>();
|
||||||
|
builder.Services.AddSingleton<IXMLTestService, XMLTestService>();
|
||||||
builder.Services.AddFeatureManagement();
|
builder.Services.AddFeatureManagement();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|||||||
15
HaWeb/Settings/NodeRules/AutopsicNode.cs
Normal file
15
HaWeb/Settings/NodeRules/AutopsicNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class AutopsicNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "autopsic";
|
||||||
|
public string XPath => "//autopsic";
|
||||||
|
public string[]? Attributes { get; } = { "value" };
|
||||||
|
public string? uniquenessAttribute => "value" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
16
HaWeb/Settings/NodeRules/EditNode.cs
Normal file
16
HaWeb/Settings/NodeRules/EditNode.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class EditNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "edit";
|
||||||
|
public string XPath => "//edit";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => null;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
("ref", "//editreason", "index")
|
||||||
|
};
|
||||||
|
}
|
||||||
16
HaWeb/Settings/NodeRules/HandNode.cs
Normal file
16
HaWeb/Settings/NodeRules/HandNode.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class HandNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "hand";
|
||||||
|
public string XPath => "//hand";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => null;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
("ref", "//handDef", "index")
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/KommentarNode.cs
Normal file
15
HaWeb/Settings/NodeRules/KommentarNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class KommentarNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "kommentar";
|
||||||
|
public string XPath => "//kommentar";
|
||||||
|
public string[]? Attributes { get; } = { "id" };
|
||||||
|
public string? uniquenessAttribute => "id" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/LetterDescNode.cs
Normal file
15
HaWeb/Settings/NodeRules/LetterDescNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class LetterDescNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "letterDesc";
|
||||||
|
public string XPath => "//letterDesc";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => "ref" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/LetterTextNode.cs
Normal file
15
HaWeb/Settings/NodeRules/LetterTextNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class LetterTextNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "letterText";
|
||||||
|
public string XPath => "//letterText";
|
||||||
|
public string[]? Attributes { get; } = { "index" };
|
||||||
|
public string? uniquenessAttribute => "index" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/LetterTraditionNode.cs
Normal file
15
HaWeb/Settings/NodeRules/LetterTraditionNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class LetterTraditionNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "letterTradition";
|
||||||
|
public string XPath => "//letterTradition";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => "ref" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/MarginalNode.cs
Normal file
15
HaWeb/Settings/NodeRules/MarginalNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class MarginalNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "marginal";
|
||||||
|
public string XPath => "//marginal";
|
||||||
|
public string[]? Attributes { get; } = { "index", "letter", "page", "line" };
|
||||||
|
public string? uniquenessAttribute => "index";
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
16
HaWeb/Settings/NodeRules/ReceiverNode.cs
Normal file
16
HaWeb/Settings/NodeRules/ReceiverNode.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class Receiver : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "receiver";
|
||||||
|
public string XPath => "//receiver";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => null;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
("ref", "//personDef", "index")
|
||||||
|
};
|
||||||
|
}
|
||||||
16
HaWeb/Settings/NodeRules/SenderNode.cs
Normal file
16
HaWeb/Settings/NodeRules/SenderNode.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class SenderNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "sender";
|
||||||
|
public string XPath => "//sender";
|
||||||
|
public string[]? Attributes { get; } = { "ref" };
|
||||||
|
public string? uniquenessAttribute => null;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
("ref", "//personDef", "index")
|
||||||
|
};
|
||||||
|
}
|
||||||
15
HaWeb/Settings/NodeRules/SubsectionNode.cs
Normal file
15
HaWeb/Settings/NodeRules/SubsectionNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace HaWeb.Settings.NodeRules;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public class SubsectionNode : INodeRule
|
||||||
|
{
|
||||||
|
public string Name => "subsection";
|
||||||
|
public string XPath => "//subsection";
|
||||||
|
public string[]? Attributes { get; } = { "id" };
|
||||||
|
public string? uniquenessAttribute => "id" ;
|
||||||
|
public List<(string, string, string)>? References { get; } = new List<(string, string, string)>()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -70,17 +70,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (Model.UsedFiles != null && Model.Prefix != null && Model.UsedFiles.ContainsKey(Model.Prefix)) {
|
@if (Model.UsedFiles != null && Model.Prefix != null && Model.UsedFiles.ContainsKey(Model.Prefix)) {
|
||||||
<div class="ha-errorswarnings">
|
<div class="ha-crossfilechecking text-sm">
|
||||||
<div class="ha-criticalerrors">
|
@foreach (var f in Model.UsedFiles[Model.Prefix])
|
||||||
|
{
|
||||||
</div>
|
<div>
|
||||||
<div class="ha-warnings">
|
@Html.Raw(f.Messages)
|
||||||
|
</div>
|
||||||
</div>
|
}
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ha-crossfilechecking">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Text;
|
|||||||
using HaXMLReader.Interfaces;
|
using HaXMLReader.Interfaces;
|
||||||
using HaDocument.Interfaces;
|
using HaDocument.Interfaces;
|
||||||
using HaDocument.Models;
|
using HaDocument.Models;
|
||||||
|
using HaWeb.XMLTests;
|
||||||
|
|
||||||
// XMLService provides a wrapper around the loaded and used XML data
|
// XMLService provides a wrapper around the loaded and used XML data
|
||||||
public class XMLService : IXMLService {
|
public class XMLService : IXMLService {
|
||||||
@@ -231,10 +232,20 @@ public class XMLService : IXMLService {
|
|||||||
if (_Used == null) _Used = new Dictionary<string, FileList?>();
|
if (_Used == null) _Used = new Dictionary<string, FileList?>();
|
||||||
if (!_Used.ContainsKey(doc.Prefix)) _Used.Add(doc.Prefix, new FileList(doc.XMLRoot));
|
if (!_Used.ContainsKey(doc.Prefix)) _Used.Add(doc.Prefix, new FileList(doc.XMLRoot));
|
||||||
_Used[doc.Prefix]!.Add(doc);
|
_Used[doc.Prefix]!.Add(doc);
|
||||||
|
_ = doc.GetElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnUse(string prefix) {
|
public void UnUse(string prefix) {
|
||||||
if (_Used != null && _Used.ContainsKey(prefix)) _Used.Remove(prefix);
|
if (_Used != null && _Used.ContainsKey(prefix)) {
|
||||||
|
// Unload the Elements so unused files don't use up the memory.
|
||||||
|
if (_Used[prefix]!.GetFileList() != null) {
|
||||||
|
foreach (var e in _Used[prefix]!.GetFileList()) {
|
||||||
|
e.UnUse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_Used.Remove(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
HaWeb/XMLTests/IXMLTestService.cs
Normal file
8
HaWeb/XMLTests/IXMLTestService.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public interface IXMLTestService {
|
||||||
|
|
||||||
|
public Dictionary<string, INodeRule>? Ruleset { get; }
|
||||||
|
|
||||||
|
public void Test();
|
||||||
|
}
|
||||||
9
HaWeb/XMLTests/InodeRule.cs
Normal file
9
HaWeb/XMLTests/InodeRule.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace HaWeb.XMLTests;
|
||||||
|
|
||||||
|
public interface INodeRule {
|
||||||
|
public string Name { get; }
|
||||||
|
public string XPath { get; }
|
||||||
|
public string? uniquenessAttribute { get; }
|
||||||
|
public List<(string LinkAttribute, string RemoteElement, string RemoteAttribute)>? References { get; }
|
||||||
|
public string[]? Attributes { get; }
|
||||||
|
}
|
||||||
38
HaWeb/XMLTests/XMLTestService.cs
Normal file
38
HaWeb/XMLTests/XMLTestService.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
namespace HaWeb.XMLTests;
|
||||||
|
using HaWeb.XMLParser;
|
||||||
|
|
||||||
|
public class XMLTestService : IXMLTestService {
|
||||||
|
private IXMLService _XMLService;
|
||||||
|
public Dictionary<string, INodeRule>? Ruleset { get; private set; }
|
||||||
|
public XMLTestService(IXMLService xmlService) {
|
||||||
|
_XMLService = xmlService;
|
||||||
|
|
||||||
|
var roottypes = _GetAllTypesThatImplementInterface<INodeRule>().ToList();
|
||||||
|
roottypes.ForEach( x => {
|
||||||
|
if (this.Ruleset == null) this.Ruleset = new Dictionary<string, INodeRule>();
|
||||||
|
var instance = (INodeRule)Activator.CreateInstance(x)!;
|
||||||
|
if (instance != null) this.Ruleset.Add(instance.Name, instance);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Test() {
|
||||||
|
var docs = _XMLService.GetUsedDictionary();
|
||||||
|
if (docs == null) return;
|
||||||
|
foreach (var d in docs.Values) {
|
||||||
|
var fl = d.GetFileList();
|
||||||
|
if (fl == null) continue;
|
||||||
|
foreach (var v in fl) {
|
||||||
|
v.ResetLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tester = new XMLTester(this, _XMLService.GetUsedDictionary());
|
||||||
|
tester.Test();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Type> _GetAllTypesThatImplementInterface<T>()
|
||||||
|
{
|
||||||
|
return System.Reflection.Assembly.GetExecutingAssembly()
|
||||||
|
.GetTypes()
|
||||||
|
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
|
||||||
|
}
|
||||||
|
}
|
||||||
105
HaWeb/XMLTests/XMLTester.cs
Normal file
105
HaWeb/XMLTests/XMLTester.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
namespace HaWeb.XMLTests;
|
||||||
|
using HaWeb.Models;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using System.Xml.XPath;
|
||||||
|
|
||||||
|
public class XMLTester {
|
||||||
|
private Dictionary<string, INodeRule>? _Ruleset;
|
||||||
|
private List<XMLRootDocument>? _Documents;
|
||||||
|
private Dictionary<string, HashSet<string>>? _IDs;
|
||||||
|
private Dictionary<string, List<(XElement, XMLRootDocument)>?> _XPathEvaluated;
|
||||||
|
public XMLTester (IXMLTestService testService, Dictionary<string, Models.FileList?>? filelists) {
|
||||||
|
_Ruleset = testService.Ruleset;
|
||||||
|
if (filelists != null) {
|
||||||
|
foreach (var fl in filelists) {
|
||||||
|
if (fl.Value != null) {
|
||||||
|
if (_Documents == null) _Documents = new List<XMLRootDocument>();
|
||||||
|
var docs = fl.Value.GetFileList();
|
||||||
|
if (docs != null) _Documents.AddRange(docs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_XPathEvaluated = new Dictionary<string, List<(XElement, XMLRootDocument)>?>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Test() {
|
||||||
|
if (_Ruleset == null) return;
|
||||||
|
_IDs = new System.Collections.Generic.Dictionary<string, HashSet<string>>();
|
||||||
|
foreach (var rule in _Ruleset) {
|
||||||
|
buildIDs(rule.Value);
|
||||||
|
checkRequiredAttributes(rule.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRequiredAttributes(INodeRule rule) {
|
||||||
|
if (rule.Attributes == null) return;
|
||||||
|
var elements = GetEvaluateXPath(rule.XPath);
|
||||||
|
if (elements != null && elements.Any()) {
|
||||||
|
foreach (var e in elements) {
|
||||||
|
foreach (var attr in rule.Attributes) {
|
||||||
|
checkAttribute(e.Item1, attr, e.Item2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildIDs(INodeRule rule) {
|
||||||
|
if (!String.IsNullOrWhiteSpace(rule.uniquenessAttribute)) {
|
||||||
|
checkUniqueness(rule.Name, rule.XPath, rule.uniquenessAttribute);
|
||||||
|
}
|
||||||
|
if (rule.References != null && rule.References.Any()) {
|
||||||
|
foreach (var reference in rule.References) {
|
||||||
|
checkUniqueness(rule.Name, reference.RemoteElement, reference.RemoteAttribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUniqueness(string name, string xpathelement, string attribute) {
|
||||||
|
if (_Documents == null || _IDs == null || _IDs.ContainsKey(name)) return;
|
||||||
|
var hs = new HashSet<string>();
|
||||||
|
var elements = GetEvaluateXPath(xpathelement);
|
||||||
|
if (elements != null)
|
||||||
|
foreach (var e in elements) {
|
||||||
|
if (checkAttribute(e.Item1, attribute, e.Item2)) {
|
||||||
|
if (!hs.Add(e.Item1.Attribute(attribute)!.Value)) {
|
||||||
|
e.Item2.Log(generateLogMessage(e.Item1) + "Attributwert " + e.Item1.Attribute(attribute)!.Value + " doppelt.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_IDs.TryAdd(name, hs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool checkAttribute(XElement element, string attributename, XMLRootDocument doc) {
|
||||||
|
if (!element.HasAttributes || element.Attribute(attributename) == null) {
|
||||||
|
doc.Log(generateLogMessage(element) + "Attribut " + attributename + " fehlt.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string generateLogMessage(XElement element) {
|
||||||
|
return "Zeile " +
|
||||||
|
((IXmlLineInfo)element).LineNumber.ToString() +
|
||||||
|
", Element " +
|
||||||
|
element.Name +
|
||||||
|
": ";
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<(XElement, XMLRootDocument)>? GetEvaluateXPath(string xpath) {
|
||||||
|
if (_XPathEvaluated.ContainsKey(xpath)) return _XPathEvaluated[xpath];
|
||||||
|
if (!_XPathEvaluated.ContainsKey(xpath)) _XPathEvaluated.Add(xpath, null);
|
||||||
|
if (_Documents == null) return null;
|
||||||
|
foreach (var d in _Documents) {
|
||||||
|
var elements = d.GetElement().XPathSelectElements(xpath).ToList();
|
||||||
|
if (elements != null && elements.Any()) {
|
||||||
|
if (_XPathEvaluated[xpath] == null) _XPathEvaluated[xpath] = new List<(XElement, XMLRootDocument)>();
|
||||||
|
foreach (var res in elements) {
|
||||||
|
_XPathEvaluated[xpath]!.Add((res, d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _XPathEvaluated[xpath];
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user