diff --git a/sdk/basyx/aas/adapter/aasx.py b/sdk/basyx/aas/adapter/aasx.py index 8bb5958f6..7ddf91316 100644 --- a/sdk/basyx/aas/adapter/aasx.py +++ b/sdk/basyx/aas/adapter/aasx.py @@ -824,15 +824,25 @@ def add_file(self, name: str, file: IO[bytes], content_type: str) -> str: if hash not in self._store: self._store[hash] = data self._store_refcount[hash] = 0 - name_map_data = (hash, content_type) + return self._assign_unique_name(name, hash, content_type) + + def rename_file(self, old_name: str, new_name: str) -> str: + if old_name not in self._name_map: + raise KeyError(f"File with name {old_name} not found in SupplementaryFileContainer.") + if new_name == old_name: + return new_name + file_hash, file_content_type = self._name_map[old_name] + del self._name_map[old_name] + return self._assign_unique_name(new_name, file_hash, file_content_type) + + def _assign_unique_name(self, name: str, sha: bytes, content_type: str) -> str: new_name = name i = 1 while True: if new_name not in self._name_map: - self._name_map[new_name] = name_map_data - self._store_refcount[hash] += 1 + self._name_map[new_name] = (sha, content_type) return new_name - elif self._name_map[new_name] == name_map_data: + elif self._name_map[new_name] == (sha, content_type): return new_name new_name = self._append_counter(name, i) i += 1 diff --git a/sdk/test/adapter/aasx/test_aasx.py b/sdk/test/adapter/aasx/test_aasx.py index a83c60186..caf4e24c9 100644 --- a/sdk/test/adapter/aasx/test_aasx.py +++ b/sdk/test/adapter/aasx/test_aasx.py @@ -22,19 +22,43 @@ class TestAASXUtils(unittest.TestCase): def test_supplementary_file_container(self) -> None: container = aasx.DictSupplementaryFileContainer() with open(os.path.join(os.path.dirname(__file__), 'TestFile.pdf'), 'rb') as f: - new_name = container.add_file("/TestFile.pdf", f, "application/pdf") + saved_file_name = container.add_file("/TestFile.pdf", f, "application/pdf") # Name should not be modified, since there is no conflict - self.assertEqual("/TestFile.pdf", new_name) + self.assertEqual("/TestFile.pdf", saved_file_name) f.seek(0) - container.add_file("/TestFile.pdf", f, "application/pdf") + # Add the same file again with the same name + same_file_with_same_name = container.add_file("/TestFile.pdf", f, "application/pdf") # Name should not be modified, since there is still no conflict - self.assertEqual("/TestFile.pdf", new_name) + self.assertEqual("/TestFile.pdf", same_file_with_same_name) + # Add other file with the same name to create a conflict with open(__file__, 'rb') as f: - new_name = container.add_file("/TestFile.pdf", f, "application/pdf") + saved_file_name_2 = container.add_file("/TestFile.pdf", f, "application/pdf") # Now, we have a conflict - self.assertNotEqual("/TestFile.pdf", new_name) - self.assertIn(new_name, container) + self.assertNotEqual(saved_file_name, saved_file_name_2) + self.assertIn(saved_file_name_2, container) + + # Rename file to a new unique name + renamed = container.rename_file(saved_file_name_2, "/RenamedTestFile.pdf") + self.assertIn(renamed, container) + # Old name should no longer exist + self.assertNotIn(saved_file_name_2, container) + self.assertEqual(renamed, "/RenamedTestFile.pdf") + + # Renaming to the same name should be no-op + renamed_same = container.rename_file(renamed, renamed) + self.assertEqual(renamed, renamed_same) + + # Renaming to an existing name should create a conflict + renamed_conflict = container.rename_file(renamed, "/TestFile.pdf") + self.assertNotEqual(renamed_conflict, "/TestFile.pdf") + self.assertIn(renamed_conflict, container) + + # Renaming a non-existing file should raise KeyError + with self.assertRaises(KeyError): + container.rename_file("/NonExistingFile.pdf", "/AnotherName.pdf") + + new_name = renamed_conflict # Check metadata self.assertEqual("application/pdf", container.get_content_type("/TestFile.pdf"))