namespace HaWeb.XMLParser; using System.Xml.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; using HaWeb.Models; public class XMLService : IXMLService { private Dictionary? _Used; private Dictionary? _Roots; public XMLService() { // Getting all classes which implement IXMLRoot for possible document endpoints var types = _GetAllTypesThatImplementInterface().ToList(); types.ForEach( x => { if (this._Roots == null) this._Roots = new Dictionary(); var instance = (IXMLRoot)Activator.CreateInstance(x)!; if (instance != null) this._Roots.Add(instance.Prefix, instance); }); if (_Roots == null || !_Roots.Any()) throw new Exception("No classes for upload endpoints were found!"); } public IXMLRoot? GetRoot(string name) { if (_Roots == null) return null; _Roots.TryGetValue(name, out var root); return root; } public List? GetRootsList() => this._Roots == null ? null : this._Roots.Values.ToList(); public Dictionary? GetRootsDictionary() => this._Roots == null ? null : this._Roots; public List? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) { if (document.Root!.Name != "opus") { ModelState.AddModelError("Error", "A valid Hamann-Docuemnt must begin with "); return null; } List? res = null; if (document.Root != null && _Roots != null) { foreach (var (_, root) in _Roots) { var elements = root.IsTypeOf(document.Root); if (elements != null && elements.Any()) foreach (var elem in elements) { if (res == null) res = new List(); res.Add(_createXMLRootDocument(root, elem)); } } } if (res == null) ModelState.AddModelError("Error", "Kein zum Hamann-Briefe-Projekt passendes XML gefunden."); return res; } public Dictionary? GetUsedDictionary() => this._Used; // Adds a document and sets it to used public void Use(XMLRootDocument doc) { if (_Used == null) _Used = new Dictionary(); if (!_Used.ContainsKey(doc.Prefix)) _Used.Add(doc.Prefix, new FileList(doc.XMLRoot)); _Used[doc.Prefix]!.Add(doc); } // Performs detection of using on the specified document type public void AutoUse(string prefix) { if (_Used == null || !_Used.ContainsKey(prefix)) return; AutoUse(_Used[prefix]!); } // Performs detection of using given a list of files public void AutoUse(FileList filelist) { FileList? res = null; var list = filelist.GetFileList(); var prefix = filelist.XMLRoot.Prefix; if (list == null) return; if (_Used != null && _Used.ContainsKey(prefix)) _Used.Remove(prefix); // TODO: Item1 var lookup = list.ToLookup(x => x.IdentificationString.Item2); foreach (var idstring in lookup) { var ordered = idstring.OrderBy(x => x.Date); if (res == null) res = new FileList(filelist.XMLRoot); Use(ordered.Last()); } } public XElement? MergeUsedDocuments(ModelStateDictionary ModelState) { if (_Used == null || _Roots == null) { ModelState.AddModelError("Error", "Keine Dokumente ausgewählt"); return null; } var opus = new XElement("opus"); foreach (var category in _Used) { if (category.Value == null || category.Value.GetFileList() == null || !category.Value.GetFileList()!.Any()) { ModelState.AddModelError("Error", _Roots![category.Key].Type + " nicht vorhanden."); return null; } var documents = category.Value.GetFileList(); foreach (var document in documents!) { document.XMLRoot.MergeIntoFile(opus, document); } } return opus; } private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) { var doc = new XMLRootDocument(Root, Root.Prefix, Root.GenerateIdentificationString(element), element); doc.Fields = Root.GenerateFields(doc); return doc; } private IEnumerable _GetAllTypesThatImplementInterface() { return System.Reflection.Assembly.GetExecutingAssembly() .GetTypes() .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface); } }