Skip to content

Commit 8565480

Browse files
committed
[version_converter] Automatically Add UUIDs For Properties
Adding UUIDs, when converting from odML version 1.0 to 1.1. If an ID already exists, it stays the same, if it is compatible with the python uuid types. Otherwise (also if empty) a new ID is created for the property.
1 parent ed8c0fe commit 8565480

File tree

2 files changed

+103
-9
lines changed

2 files changed

+103
-9
lines changed

odml/tools/version_converter.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from ..info import FORMAT_VERSION
1010
from ..terminology import Terminologies, REPOSITORY_BASE
1111

12+
import uuid
13+
1214
try:
1315
unicode = unicode
1416
except NameError:
@@ -194,6 +196,8 @@ def _convert(self, tree):
194196
if e.tag == "repository":
195197
self._handle_repository(e)
196198

199+
tree = self._check_add_ids(tree)
200+
197201
return tree
198202

199203
def _handle_include(self, element):
@@ -410,6 +414,45 @@ def _change_entity_name(tree, elem_map, name):
410414
elem_map[named_path] += 1
411415
name.text += "-" + str(elem_map[named_path])
412416

417+
def _check_add_ids(self, tree):
418+
"""
419+
Checks, whether elements (properties) possess an UUID
420+
and adds one in case of absence.
421+
:param tree: ElementTree of the doc
422+
:return: ElementTree
423+
"""
424+
root = tree.getroot()
425+
for sec in root.iter("section"):
426+
for prop in sec.iter("property"):
427+
self._add_id(prop)
428+
429+
return tree
430+
431+
@staticmethod
432+
def _add_id(element):
433+
"""
434+
Checks, whether element possesses ID. If yes, make sure, it has right format.
435+
Otherwise a new UUID is created.
436+
:param element: lxml element.
437+
"""
438+
oid = element.find("id")
439+
new_id = ET.Element("id")
440+
try:
441+
if oid is not None:
442+
try:
443+
if oid.text is not None:
444+
new_id.text = str(uuid.UUID(oid.text))
445+
except ValueError as e:
446+
print(e)
447+
new_id.text = str(uuid.uuid4())
448+
element.remove(oid)
449+
else:
450+
new_id.text = str(uuid.uuid4())
451+
except ValueError as e:
452+
print(e)
453+
new_id.text = str(uuid.uuid4())
454+
element.append(new_id)
455+
413456
def _log(self, msg):
414457
"""
415458
Adds the passed message to the conversion_log attribute and

test/test_version_converter.py

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,19 +379,21 @@ def test_convert_odml_file_property(self):
379379
self.assertEqual(sec[0].find("name").text, "Valid Property tags test")
380380
self.assertEqual(len(sec[0].findall("property")), 1)
381381
prop = sec[0].find("property")
382-
self.assertEqual(len(prop), 5)
382+
self.assertEqual(len(prop), 6)
383383
self.assertEqual(prop.find("name").text, "Property name")
384384
self.assertEqual(prop.find("type").text, "Property type")
385385
self.assertEqual(prop.find("definition").text, "Property definition")
386386
self.assertEqual(prop.find("dependency").text, "Property dependency")
387387
self.assertEqual(prop.find("dependencyvalue").text, "Property dependency value")
388+
self.assertEqual(len(prop.findall("id")), 1)
388389

389390
# Test non-import of Property w/o name
390391
self.assertEqual(len(sec[1].findall("property")), 1)
391392
# Test absence of non-Property tags
392393
prop = sec[1].find("property")
393-
self.assertEqual(len(prop), 1)
394+
self.assertEqual(len(prop), 2)
394395
self.assertEqual(len(prop.findall("name")), 1)
396+
self.assertEqual(len(prop.findall("id")), 1)
395397

396398
def test_convert_odml_file_value(self):
397399
"""Test proper conversion of the odml.Value entity from
@@ -511,6 +513,22 @@ def test_convert_odml_file_value(self):
511513
<value> 3 <type>int</type></value>
512514
<name>testIntListWhiteSpace</name>
513515
</property>
516+
517+
<property>
518+
<name>Single value with UUID</name>
519+
<value>1</value>
520+
<id>aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa</id>
521+
</property>
522+
523+
<property>
524+
<name>Single value with none-UUID ID</name>
525+
<id>1</id>
526+
</property>
527+
528+
<property>
529+
<name>Single value with empty ID</name>
530+
<id></id>
531+
</property>
514532
515533
</section>
516534
</odML>
@@ -521,85 +539,118 @@ def test_convert_odml_file_value(self):
521539
conv_doc = vc._convert(vc._parse_xml())
522540
root = conv_doc.getroot()
523541
sec = root.find("section")
524-
self.assertEqual(len(sec), 14)
542+
self.assertEqual(len(sec), 17)
525543

526544
# Test single value export
527545
prop = sec.findall("property")[0]
528-
self.assertEqual(len(prop), 2)
546+
self.assertEqual(len(prop), 3)
529547
self.assertEqual(prop.find("value").text, "1")
548+
self.assertEqual(len(prop.findall("id")), 1)
530549

531550
# Test multiple value export
532551
prop = sec.findall("property")[1]
533-
self.assertEqual(len(prop), 2)
552+
self.assertEqual(len(prop), 3)
534553
self.assertEqual(prop.find("value").text, "[1,2,3]")
554+
self.assertEqual(len(prop.findall("id")), 1)
535555

536556
# Test empty value export
537557
prop = sec.findall("property")[2]
538-
self.assertEqual(len(prop), 1)
558+
self.assertEqual(len(prop), 2)
539559
self.assertEqual(prop.find("name").text, "Empty value export")
560+
self.assertEqual(len(prop.findall("id")), 1)
540561

541562
# Test valid Value tags
542563
prop = sec.findall("property")[3]
543-
self.assertEqual(len(prop), 7)
564+
self.assertEqual(len(prop), 8)
544565
self.assertEqual(prop.find("value").text, "0.1")
545566
self.assertEqual(prop.find("type").text, "float")
546567
self.assertEqual(prop.find("uncertainty").text, "0.05")
547568
self.assertEqual(prop.find("unit").text, "mV")
548569
self.assertEqual(prop.find("value_origin").text, "raw.txt")
549570
self.assertEqual(prop.find("reference").text, "Value reference")
550571
self.assertEqual(len(prop.findall("filename")), 0)
572+
self.assertEqual(len(prop.findall("id")), 1)
551573

552574
# Test valid multiple Value tag export
553575
prop = sec.findall("property")[4]
554-
self.assertEqual(len(prop), 7)
576+
self.assertEqual(len(prop), 8)
555577
self.assertEqual(prop.find("value").text, "[0.1,0.2,3]")
556578
self.assertEqual(prop.find("type").text, "float")
557579
self.assertEqual(prop.find("uncertainty").text, "0.05")
558580
self.assertEqual(prop.find("unit").text, "mV")
559581
self.assertEqual(prop.find("value_origin").text, "raw.txt")
560582
self.assertEqual(prop.find("reference").text, "Value reference")
583+
self.assertEqual(len(prop.findall("id")), 1)
561584

562585
# Test non-export of invalid Value tags
563586
prop = sec.findall("property")[5]
564-
self.assertEqual(len(prop), 1)
587+
self.assertEqual(len(prop), 2)
565588
self.assertEqual(len(prop.findall("name")), 1)
589+
self.assertEqual(len(prop.findall("id")), 1)
566590

567591
# Test dtype 'binary' replacement
568592
prop = sec.findall("property")[6]
569593
self.assertEqual(prop.find("name").text, "Unsupported binary value type replace")
570594
self.assertEqual(prop.find("type").text, "text")
595+
self.assertEqual(len(prop.findall("id")), 1)
571596
prop = sec.findall("property")[7]
572597
self.assertEqual(prop.find("name").text, "Unsupported binary value dtype replace")
573598
self.assertEqual(prop.find("type").text, "text")
599+
self.assertEqual(len(prop.findall("id")), 1)
574600

575601
# Test single string value with commata
576602
prop = sec.findall("property")[8]
577603
self.assertEqual(prop.find("name").text, "testSingleString")
578604
self.assertEqual(prop.find("value").text,
579605
"Single, string, value, with, many, commata.")
606+
self.assertEqual(len(prop.findall("id")), 1)
580607

581608
# Test string list import
582609
prop = sec.findall("property")[9]
583610
self.assertEqual(prop.find("name").text, "testStringList")
584611
self.assertEqual(prop.find("value").text, "[A,B,C]")
612+
self.assertEqual(len(prop.findall("id")), 1)
585613

586614
# Test single string values wrapping whitespace removal
587615
prop = sec.findall("property")[10]
588616
self.assertEqual(prop.find("name").text, "testStringWhiteSpace")
589617
self.assertEqual(prop.find("value").text,
590618
"Single string value with wrapping whitespace")
619+
self.assertEqual(len(prop.findall("id")), 1)
591620

592621
# Test multiple string values with wrapping whitespace removal
593622
prop = sec.findall("property")[11]
594623
self.assertEqual(prop.find("name").text, "testStringListWhiteSpace")
595624
self.assertEqual(prop.find("value").text,
596625
"[Multiple Strings,with wrapping,Whitespace]")
626+
self.assertEqual(len(prop.findall("id")), 1)
597627

598628
# Test multiple int values with wrapping whitespaces
599629
prop = sec.findall("property")[12]
600630
self.assertEqual(prop.find("name").text, "testIntListWhiteSpace")
601631
self.assertEqual(prop.find("type").text, "int")
602632
self.assertEqual(prop.find("value").text, "[1,2,3]")
633+
self.assertEqual(len(prop.findall("id")), 1)
634+
635+
# Test single value export
636+
prop = sec.findall("property")[13]
637+
self.assertEqual(len(prop), 3)
638+
self.assertEqual(prop.find("value").text, "1")
639+
self.assertEqual(len(prop.findall("id")), 1)
640+
self.assertEqual(prop.find("id").text, "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")
641+
642+
# Test single value export
643+
prop = sec.findall("property")[14]
644+
self.assertEqual(len(prop), 2)
645+
self.assertEqual(len(prop.findall("id")), 1)
646+
self.assertNotEqual(prop.find("id").text, "1")
647+
648+
# Test single value export
649+
prop = sec.findall("property")[15]
650+
self.assertEqual(len(prop), 2)
651+
self.assertEqual(len(prop.findall("id")), 1)
652+
self.assertNotEqual(prop.find("id").text, "1")
653+
603654

604655
def test_parse_dict_document(self):
605656
# Test appending tags; not appending empty sections

0 commit comments

Comments
 (0)