# Blake2b-Hash-Implementierung für XML-Dateien ## Übersicht Diese Dokumentation beschreibt die Implementierung der automatischen blake2b-Hash-Berechnung für XML-Dateien in der XSL-Validator-Anwendung. ## Funktionalität ### Automatische Hash-Berechnung beim Projektladen Beim Laden eines Projekts in der `MainWindow`-Klasse werden automatisch alle XML-Dateien auf fehlende `hashsum`-Eigenschaften geprüft. Für Dateien ohne Hash-Wert wird dieser asynchron im Hintergrund berechnet. ### Hash-Algorithmus - **Algorithmus**: blake2b (aus Python's `hashlib`) - **Präfix**: `blake2b:` - **Format**: `blake2b:<64-stelliger-hex-hash>` ### Beispiel ``` blake2b:c0d6043a79e953f31921a68f008d20ef3bce5bc7f9613d0f53c3a3d3f0a5879e4a18b955f1741ddf190cf7769c1be47d4cf48246f455fa9f84e6599ce5b45119 ``` ## Technische Implementierung ### Erweiterte XmlFile-Klasse Die `conf.XmlFile`-Klasse wurde um die optionale `hashsum`-Eigenschaft erweitert: ```python class XmlFile(BaseModel): xml: Path hashsum: str | None = None # Neue Eigenschaft ``` ### Asynchrone Hash-Berechnung #### XmlHashCalculatorThread Eine spezialisierte `QThread`-Klasse für die asynchrone Hash-Berechnung: ```python class XmlHashCalculatorThread(QThread): hash_calculated = pyqtSignal(object, str) calculation_finished = pyqtSignal(int, int) error_occurred = pyqtSignal(str, str) ``` **Hauptmethoden:** - `_calculate_blake2b_hash()`: Berechnet den blake2b-Hash einer Datei - `run()`: Hauptschleife für die asynchrone Verarbeitung #### Integration in MainWindow **Automatischer Start:** ```python def load_project_from_file(self, file_path: Path): # ... Projekt laden ... # Starte Hash-Berechnung für alle XML-Dateien self._start_xml_hash_calculation() ``` **Kern-Methoden:** - `_start_xml_hash_calculation()`: Startet die asynchrone Hash-Berechnung - `_collect_all_xml_files()`: Sammelt alle XML-Dateien rekursiv - `_on_hash_calculated()`: Signal-Handler für berechnete Hashes - `_calculate_hash_for_xml_file()`: Synchrone Hash-Berechnung für neue Dateien ### Rekursive Datensammlung Die Implementierung durchsucht rekursiv alle `TreeNode`- und `XslFile`-Strukturen: ```python def _collect_all_xml_files(self, node: TreeNode) -> list[XmlFile]: xml_files = [] # Sammle XML-Dateien aus XSL-Dateien for xsl_file in node.xsl_files: xml_files.extend(xsl_file.xml_files) # Rekursiv durch Kindknoten for child in node.children: xml_files.extend(self._collect_all_xml_files(child)) return xml_files ``` ## Verwendung ### Automatische Hash-Berechnung Die Hash-Berechnung erfolgt automatisch beim Laden von Projekten. Keine manuelle Intervention erforderlich. ### Neue XML-Dateien Beim Hinzufügen neuer XML-Dateien wird der Hash synchron berechnet: ```python def add_xml_file(self, xml_file: XmlFile): if xml_file.hashsum is None: xml_file.hashsum = self._calculate_hash_for_xml_file(xml_file) ``` ## Fehlerbehandlung ### Nicht existierende Dateien ```python def _calculate_blake2b_hash(self, file_path: Path) -> str | None: try: if not file_path.exists(): return None # ... Hash-Berechnung ... except Exception as e: self.error_occurred.emit(str(file_path), str(e)) return None ``` ### Thread-Sicherheit - Verwendung von Qt-Signalen für Thread-Kommunikation - Keine direkten UI-Updates aus Worker-Thread - Graceful handling von Thread-Fehlern ## Performance-Optimierung ### Asynchrone Verarbeitung - Hash-Berechnung läuft im Hintergrund - UI bleibt responsiv während der Berechnung - Batch-Verarbeitung mehrerer Dateien ### Selektive Berechnung - Nur Dateien ohne bestehende `hashsum` werden verarbeitet - Vermeidung redundanter Berechnungen - Effiziente Speichernutzung ## Testen ### Test-Skript Ein umfassendes Test-Skript (`test_hash_implementation.py`) validiert: - Korrekte Hash-Berechnung - XmlFile-Modell-Funktionalität - Hash-Konsistenz - Fehlerbehandlung ### Ausführung ```bash uv run python test_hash_implementation.py ``` ## Wartung und Erweiterung ### Hinzufügung neuer Hash-Algorithmen Die Implementierung kann einfach erweitert werden: ```python def _calculate_hash(self, file_path: Path, algorithm: str = "blake2b") -> str | None: if algorithm == "blake2b": return self._calculate_blake2b_hash(file_path) elif algorithm == "sha256": return self._calculate_sha256_hash(file_path) # ... weitere Algorithmen ``` ### Konfiguration Hash-Einstellungen können über die Anwendungskonfiguration gesteuert werden: ```python class HashConfig: algorithm: str = "blake2b" prefix_format: str = "{algorithm}:" async_calculation: bool = True ``` ## Bekannte Einschränkungen 1. **Dateigröße**: Sehr große XML-Dateien können die Hash-Berechnung verlangsamen 2. **Netzwerk-Dateien**: Dateien auf Netzlaufwerken werden möglicherweise langsamer verarbeitet 3. **Encoding**: Binärer Dateizugriff für konsistente Hash-Berechnung ## Changelog ### Version 1.0.0 - Initiale Implementierung der blake2b-Hash-Berechnung - Asynchrone Verarbeitung mit QThread - Integration in Projektlade-Prozess - Umfassende Fehlerbehandlung - Test-Suite für Validierung