2023-11-26 23:31:32 -05:00

196 lines
5.7 KiB
Python

from .LibraryParser import LibraryParser
from ..Guid import Guid
class YAMLLibraryParser (LibraryParser):
def __init__(self, manager):
LibraryParser.__init__(self, manager)
self.yamlIds = dict()
# these two are special reserved tagNames
# self.yamlIds["entityDefinitions"] = None
# self.yamlIds["instance"] = { }
self.manager = manager
self._instances_awaiting_sugar = []
def apply_sugar(self):
print("applying syntactic sugar to remaining instances...")
for inst in self._instances_awaiting_sugar:
self.load_instance(inst)
def load_sugar_from_file(self, filename):
print("loading sugar from " + filename)
import yaml
with open(filename, 'r') as file:
content = yaml.safe_load_all(file)
for doc in content:
for elem in doc:
if "entityDefinitions" in elem or "instance" in elem:
continue
self.load_instance(elem)
pass
def load_entity_definitions_from_file(self, filename):
print("loading entity defs from " + filename)
import yaml
with open(filename, 'r') as file:
content = yaml.safe_load_all(file)
for doc in content:
for elem in doc:
if "entityDefinitions" in elem:
entities = elem["entityDefinitions"]
for entity in entities:
for key in entity:
self.manager.register_entity_reference(key, entity[key])
def load_instance_with_template(self, elem, template):
parentInstanceId = None
if "instance" in template:
parentInstanceId = self.manager.expand_entity_references(template["instance"])
else:
for key in self.yamlIds:
if key in template:
parentInstanceId = self.manager.expand_entity_references(template[key])
break
if "instance" in elem:
instanceId = Guid(self.manager.expand_entity_references(elem["instance"]))
creatorKey = 'instance'
else:
for key in self.yamlIds:
if key in elem:
instanceId = Guid(self.manager.expand_entity_references(elem[key]))
creatorKey = key
break
if "attributes" in template:
attrs = template["attributes"]
if isinstance(attrs, list):
for attr in attrs:
if "customTagName" in attr:
customTagName = attr["customTagName"]
if customTagName in elem:
attrinst = Guid(self.manager.expand_entity_references(attr["instance"]))
attrval = elem[customTagName]
self.manager.set_attribute_value(instanceId, attrinst, attrval)
if "relationships" in template:
rels = template["relationships"]
for rel in rels:
if "customTagName" in rel:
customTagName = rel["customTagName"]
if customTagName in elem:
relinst = Guid(self.manager.expand_entity_references(rel["instance"]))
relval = Guid(self.manager.expand_entity_references(elem[customTagName]))
self.manager.assign_relationship(instanceId, relinst, relval)
def load_instance(self, elem, elemParent = None):
# 'class' and 'relationship' are both at the 'same level'
# so we can't define 'relationship' without first defining 'class'
# we could try to keep looping as long as we're still getting "unknown tag name"
# (instanceID is None), but we could get stuck that way...
# for now, let's just forward define important classes (e.g. IDC_Relationship)
customTagName = None
if "customTagName" in elem:
customTagName = elem["customTagName"]
self.yamlIds[customTagName] = elem
print("registering customTagName '" + customTagName + "'")
template = None
templateKey = None
if not "instance" in elem:
for key in self.yamlIds:
#print(elem)
if key != "instance" and key in elem:
template = self.yamlIds[key]
templateKey = key
#print("got template " + key)
break
classId = None
classIndex = None
if template is None and elemParent is not None:
template = elemParent
if template is not None:
if "instance" in template:
classId = Guid(self.manager.expand_entity_references(template["instance"]))
else:
for key in self.yamlIds:
if key in template:
classId = Guid(self.manager.expand_entity_references(template[key]))
break
if "index" in template:
classIndex = template["index"]
instanceId = None
creatorKey = None
if "instance" in elem:
instanceId = Guid(self.manager.expand_entity_references(elem["instance"]))
creatorKey = 'instance'
else:
for key in self.yamlIds:
if key in elem:
instanceId = Guid(self.manager.expand_entity_references(elem[key]))
creatorKey = key
break
index = None
if "index" in elem:
index = elem["index"]
# else:
# print("index not found for element")
# print(elem)
if classId is None and instanceId is not None:
classId = instanceId # HACK HACK
if instanceId is not None:
self.manager.add_instance(classId, instanceId, classIndex, index)
if creatorKey == 'class':
print("creating class " + instanceId.get_value())
if "instances" in elem:
classInsts = elem["instances"]
for inst in classInsts:
self.load_instance(inst, elem)
self.manager.create_class(instanceId, index)
else:
print("creating instance " + instanceId.get_value() + " (of class " + classId.get_value() + ")")
self.manager.create_instance_of(classId, instanceId, classIndex, index)
if templateKey is not None:
if template is not None:
#print("using template (" + templateKey + ")")
#print(template)
self.load_instance_with_template(elem, template)
else:
#print("ignoring '" + templateKey + "'")
pass
def load_instances_from_file(self, filename):
print("loading instances from " + filename)
import yaml
with open(filename, 'r') as file:
content = yaml.safe_load_all(file)
for doc in content:
for elem in doc:
if "instance" in elem:
self.load_instance(elem)
else:
self._instances_awaiting_sugar.append(elem)