196 lines
5.7 KiB
Python
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) |