initial commit
This commit is contained in:
parent
d7cb7dc88d
commit
9da10a15e7
20
mocha-python/src/mocha-python/examples/server.yaml
Normal file
20
mocha-python/src/mocha-python/examples/server.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
# Mocha Local Server Configuration
|
||||
- server:
|
||||
- port: 8081
|
||||
pathMappings:
|
||||
- source: /
|
||||
destination: /home/beckermj
|
||||
defaultTenantName: default
|
||||
assets:
|
||||
- type: local
|
||||
path: /usr/share/mocha/assets # /module/version/...path...
|
||||
# these could even be .zip files of asset bundles
|
||||
# which would be decompressed on-the-fly and streamed to the client
|
||||
- type: remote
|
||||
# for example
|
||||
path: https://static.alcehosting.net/prod/mocha/assets
|
||||
tenants:
|
||||
- name: default
|
||||
- name: starlight1
|
||||
libraryReferences:
|
||||
- filename: /usr/share/mocha/system/Mocha.System.mcl
|
||||
504
mocha-python/src/mocha-python/mocha-shell.py
Normal file
504
mocha-python/src/mocha-python/mocha-shell.py
Normal file
@ -0,0 +1,504 @@
|
||||
#
|
||||
# mocha-shell - the 'latte' python REPL shell for mocha
|
||||
# Copyright (C) 2024 Michael Becker
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from mocha.core import InstanceKey, InstanceReference
|
||||
from mocha.oms import Oms
|
||||
from mocha.definitions import KnownClassGuids, KnownInstanceGuids, KnownAttributeGuids, KnownRelationshipGuids
|
||||
|
||||
from framework import REPLApplication, Guid, format_cwd, parse_cwd
|
||||
|
||||
import atexit
|
||||
import colorama
|
||||
import os
|
||||
import readline
|
||||
import sys
|
||||
|
||||
from colorama import Fore, Style
|
||||
from getpass import getpass
|
||||
|
||||
configpath = os.path.join(os.path.expanduser("~"), ".config", "latte")
|
||||
if not os.path.exists(configpath):
|
||||
os.mkdir(configpath)
|
||||
|
||||
histfile = os.path.join(configpath, "history")
|
||||
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
# default history len is -1 (infinite), which may grow unruly
|
||||
readline.set_history_length(1000)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
atexit.register(readline.write_history_file, histfile)
|
||||
|
||||
colorama.init()
|
||||
|
||||
class MochaShell (REPLApplication):
|
||||
|
||||
def print_instance_list(self, instances : list):
|
||||
print("")
|
||||
print("instance key global identifier comment ")
|
||||
print("--------------- -------------------------------------- -------------------------")
|
||||
for inst in instances:
|
||||
print(str(inst.get_instance_key()).ljust(16) + str(inst.get_global_identifier()) + " " + self.oms.get_instance_text(inst))
|
||||
print("")
|
||||
|
||||
def print_instance_list_with_attribute_values(self, instances : list, oms : Oms, refobj : InstanceReference):
|
||||
print("")
|
||||
print("instance key global identifier value")
|
||||
print("--------------- -------------------------------------- ---------")
|
||||
for inst in instances:
|
||||
print(str(inst.get_instance_key()).ljust(16) + str(inst.get_global_identifier()) + " " + str(oms.get_attribute_value(refobj, inst)))
|
||||
print("")
|
||||
|
||||
def print_instance_list_with_relationship_values(self, instances : list, oms : Oms, refobj : InstanceReference):
|
||||
print("")
|
||||
print("instance key global identifier value")
|
||||
print("--------------- -------------------------------------- ---------")
|
||||
for inst in instances:
|
||||
print(str(inst.get_instance_key()).ljust(16) + str(inst.get_global_identifier()) + " ", end = "")
|
||||
|
||||
rels = oms.get_related_instances(refobj, inst)
|
||||
for rel in rels:
|
||||
if rels.index(rel) > 0:
|
||||
print (" ", end = "")
|
||||
|
||||
print(str(rel.get_instance_key()))
|
||||
|
||||
print("")
|
||||
|
||||
def print_error(self, text : str):
|
||||
print (f"{Fore.RED}error: {Style.RESET_ALL}" + text)
|
||||
|
||||
def print_error_not_open(self):
|
||||
self.print_error ("no database specified, use `create` or `open` first")
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.current_user = None
|
||||
self.current_file = None
|
||||
|
||||
from mocha.oms.db.sqlite import SQLiteDatabaseOms
|
||||
self.oms = SQLiteDatabaseOms()
|
||||
|
||||
def open_file(self, oms : Oms, filename : str):
|
||||
|
||||
if not os.path.exists(filename):
|
||||
print ("file not found")
|
||||
return False
|
||||
|
||||
oms.open(filename)
|
||||
|
||||
print("opening '" + filename + "'")
|
||||
un = input("user name: ")
|
||||
pw = getpass("password: ")
|
||||
|
||||
user = oms.get_user_by_username(un)
|
||||
if user is not None:
|
||||
hash = oms.get_attribute_value(user, oms.get_instance_by_global_identifier(KnownAttributeGuids.PasswordHash))
|
||||
salt = oms.get_attribute_value(user, oms.get_instance_by_global_identifier(KnownAttributeGuids.PasswordSalt))
|
||||
|
||||
passsalt = str(pw + salt).encode("utf-8")
|
||||
import hashlib
|
||||
passhash = hashlib.sha512(passsalt).hexdigest()
|
||||
|
||||
if (hash == passhash):
|
||||
self.current_user = un
|
||||
self.current_file = filename
|
||||
|
||||
login = oms.create_instance_of(oms.get_instance_by_global_identifier(KnownClassGuids.UserLogin))
|
||||
oms.assign_relationship(login, oms.get_instance_by_global_identifier(KnownRelationshipGuids.User_Login__has__User), user)
|
||||
# oms.assign_relationship(user, oms.get_instance_by_global_identifier(KnownRelationshipGuids.User__for__User_Login), login)
|
||||
|
||||
token = Guid.create()
|
||||
oms.set_attribute_value(login, oms.get_instance_by_global_identifier(KnownAttributeGuids.Token), str(token))
|
||||
return True
|
||||
|
||||
print ("invalid user name or password")
|
||||
self.current_file = None
|
||||
|
||||
oms.close()
|
||||
return False
|
||||
|
||||
def strip(self, iid_or_gid : str) -> str:
|
||||
if iid_or_gid[0] == "[" and iid_or_gid[-1] == "]":
|
||||
return iid_or_gid[1:-1]
|
||||
|
||||
return iid_or_gid
|
||||
|
||||
def parse(self, iid_or_gid : str) -> InstanceReference:
|
||||
|
||||
if len(iid_or_gid) < 3:
|
||||
return None
|
||||
|
||||
if iid_or_gid[0] == "[" and iid_or_gid[-1] == "]":
|
||||
ik = InstanceKey.parse(self.strip(iid_or_gid))
|
||||
return self.oms.get_instance_by_key(ik)
|
||||
elif iid_or_gid[0] == "{" and iid_or_gid[-1] == "}":
|
||||
ik = Guid.parse(iid_or_gid)
|
||||
return self.oms.get_instance_by_global_identifier(ik)
|
||||
|
||||
def create_file(self, oms : Oms, filename : str):
|
||||
self.oms.open(filename)
|
||||
self.oms.init()
|
||||
self.oms.close()
|
||||
|
||||
def before_start_internal(self):
|
||||
print (f"latte v0.3 - {Fore.GREEN}Local Application Testing and Troubleshooting Environment{Style.RESET_ALL}")
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
if os.path.exists(sys.argv[1]):
|
||||
self.current_file = sys.argv[1]
|
||||
else:
|
||||
print(f"{Fore.RED}error:{Style.RESET_ALL} file not found '" + sys.argv[1] + "'")
|
||||
if input("would you like to create it? (Y/N) [N] > ").lower() == "y":
|
||||
self.create_file(self.oms, sys.argv[1])
|
||||
self.current_file = sys.argv[1]
|
||||
|
||||
if self.current_file is None:
|
||||
self.print_error_not_open()
|
||||
else:
|
||||
self.open_file(self.oms, self.current_file)
|
||||
|
||||
print ("")
|
||||
|
||||
def get_prompt(self):
|
||||
|
||||
prompt = f"{Fore.GREEN}{Style.BRIGHT}" + os.getlogin() + f"@localhost{Style.RESET_ALL}:{Fore.BLUE}{Style.BRIGHT}" + format_cwd(os.getcwd()) + f"{Style.RESET_ALL}\n↳ latte "
|
||||
if self.current_file is not None:
|
||||
if self.current_user is not None:
|
||||
prompt += f"{Fore.GREEN}" + self.current_user + f"{Style.RESET_ALL}" + "@"
|
||||
prompt += f"{Fore.CYAN}" + self.current_file + f"{Style.RESET_ALL}" + " "
|
||||
|
||||
prompt += "> "
|
||||
return prompt
|
||||
|
||||
def interactive_create_attribute(self, attr_class : InstanceReference):
|
||||
|
||||
att_Name = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.Name)
|
||||
|
||||
name = input("name: ")
|
||||
if name == "":
|
||||
print("please specify a name")
|
||||
return None
|
||||
|
||||
attr = self.oms.create_instance_of(attr_class)
|
||||
self.oms.set_attribute_value(attr, att_Name, name)
|
||||
return attr
|
||||
|
||||
def process_input(self, value, quotes):
|
||||
|
||||
if len(value) > 0:
|
||||
|
||||
if value[0] == "cd":
|
||||
os.chdir(parse_cwd(value[1]))
|
||||
|
||||
elif value[0] == "ls":
|
||||
os.system("ls --color=always")
|
||||
|
||||
elif value[0] == "open":
|
||||
|
||||
if len(value) == 2:
|
||||
|
||||
if value[1] == "database":
|
||||
|
||||
if len(value) > 2:
|
||||
|
||||
self.open_file(self.oms, value[2])
|
||||
return
|
||||
|
||||
else:
|
||||
print("usage: open database|tenant 'filename'")
|
||||
|
||||
elif value[1] == "tenant":
|
||||
|
||||
print("error: not implemented")
|
||||
|
||||
return
|
||||
|
||||
else:
|
||||
|
||||
# default to "open database ..."
|
||||
self.open_file(self.oms, value[1])
|
||||
return
|
||||
|
||||
|
||||
else:
|
||||
print("usage: open database|tenant 'filename'")
|
||||
|
||||
elif value[0] == "create":
|
||||
|
||||
if len (value) > 1:
|
||||
|
||||
self.create_file(self.oms, value[1])
|
||||
|
||||
self.open_file(self.oms, value[1])
|
||||
|
||||
else:
|
||||
|
||||
print("usage: create filename.mql")
|
||||
# print ("error: no database open, use `open filename.mql` first")
|
||||
|
||||
elif value[0] == "instance":
|
||||
|
||||
if len(value) > 1:
|
||||
|
||||
if value[1] == "create":
|
||||
|
||||
if len(value) == 3:
|
||||
|
||||
iid = self.parse(value[2])
|
||||
inst = self.oms.create_instance_of(iid)
|
||||
print(inst)
|
||||
|
||||
else:
|
||||
print("usage: instance create class_iid [index]")
|
||||
|
||||
elif value[1] == "get":
|
||||
|
||||
if len(value) == 3:
|
||||
iid = self.parse(value[2])
|
||||
print(iid)
|
||||
|
||||
elif value[1] == "list":
|
||||
|
||||
if not self.oms.is_open():
|
||||
self.print_error_not_open()
|
||||
return
|
||||
|
||||
ik_of = None
|
||||
if len(value) > 2:
|
||||
ik_of = self.parse(value[2])
|
||||
|
||||
instances = self.oms.get_instances(ik_of)
|
||||
self.print_instance_list(instances)
|
||||
|
||||
else:
|
||||
|
||||
print("usage: instance create|get|list")
|
||||
|
||||
elif value[0] == "attribute":
|
||||
|
||||
if len(value) > 1:
|
||||
|
||||
if value[1] == "create":
|
||||
|
||||
if len(value) > 2:
|
||||
|
||||
if value[2] == "text" or value[2] == "richtext":
|
||||
|
||||
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.TextAttribute)
|
||||
if value[2] == "richtext":
|
||||
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.RichTextAttribute)
|
||||
|
||||
attr = self.interactive_create_attribute(attrClass)
|
||||
|
||||
if attr is None:
|
||||
return
|
||||
|
||||
att_MaximumLength = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MaximumLength)
|
||||
|
||||
maxlen = input("maximum length (leave empty for infinite): ")
|
||||
if maxlen != "":
|
||||
self.oms.set_attribute_value(attr, att_MaximumLength, int(maxlen))
|
||||
|
||||
elif value[2] == "boolean":
|
||||
|
||||
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.BooleanAttribute)
|
||||
attr = self.interactive_create_attribute(attrClass)
|
||||
|
||||
if attr is None:
|
||||
return
|
||||
|
||||
elif value[2] == "numeric":
|
||||
|
||||
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.NumericAttribute)
|
||||
attr = self.interactive_create_attribute(attrClass)
|
||||
|
||||
if attr is None:
|
||||
return
|
||||
|
||||
att_MinimumValue = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MinimumValue)
|
||||
att_MaximumValue = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MaximumValue)
|
||||
|
||||
if att_MinimumValue is None:
|
||||
print("warning: numeric attribute `Minimum Value` is not defined")
|
||||
else:
|
||||
minimum_value = input("minimum value (empty for infinite): ")
|
||||
if minimum_value != "":
|
||||
self.oms.set_attribute_value(attr, att_MinimumValue, int(minimum_value))
|
||||
|
||||
if att_MaximumValue is None:
|
||||
print("warning: numeric attribute `Maximum Value` is not defined")
|
||||
else:
|
||||
maximum_value = input("maximum value (empty for infinite): ")
|
||||
if maximum_value != "":
|
||||
self.oms.set_attribute_value(attr, att_MaximumValue, int(maximum_value))
|
||||
|
||||
else:
|
||||
|
||||
print("usage: attribute create text|boolean|numeric|date|xml|richtext")
|
||||
|
||||
else:
|
||||
|
||||
print("usage: attribute create text|boolean|numeric|date|xml|richtext")
|
||||
|
||||
if value[1] == "list":
|
||||
|
||||
if len(value) == 3:
|
||||
|
||||
inst_id = self.parse(value[2])
|
||||
if inst_id is None:
|
||||
print("invalid inst id " + value[2] + " (inst not found)")
|
||||
return
|
||||
|
||||
attrs = self.oms.get_attributes(inst_id)
|
||||
self.print_instance_list_with_attribute_values(attrs, self.oms, inst_id)
|
||||
|
||||
else:
|
||||
|
||||
print ("usage: attribute list instance_id")
|
||||
|
||||
elif value[1] == "get":
|
||||
|
||||
if len(value) == 4:
|
||||
|
||||
if not self.oms.is_open():
|
||||
self.print_error_not_open()
|
||||
return
|
||||
|
||||
inst_id = self.parse(value[2])
|
||||
att_id = self.parse(value[3])
|
||||
|
||||
if inst_id is None:
|
||||
print("invalid inst id " + self.strip(value[2]) + " (inst not found)")
|
||||
return
|
||||
if att_id is None:
|
||||
print("invalid inst id " + self.strip(value[3]) + " (inst not found)")
|
||||
return
|
||||
|
||||
value = self.oms.get_attribute_value(inst_id, att_id)
|
||||
print(value)
|
||||
|
||||
else:
|
||||
|
||||
print("usage: attribute get inst_iid|inst_gid att_iid|att_gid")
|
||||
|
||||
elif value[1] == "set":
|
||||
|
||||
if len(value) == 5:
|
||||
|
||||
if not self.oms.is_open():
|
||||
self.print_error_not_open()
|
||||
return
|
||||
|
||||
inst_id = self.parse(value[2])
|
||||
att_id = self.parse(value[3])
|
||||
value = value[4]
|
||||
|
||||
if inst_id is None:
|
||||
print("invalid inst id " + self.strip(value[2]) + " (inst not found)")
|
||||
return
|
||||
if att_id is None:
|
||||
print("invalid inst id " + self.strip(value[3]) + " (inst not found)")
|
||||
return
|
||||
|
||||
result = self.oms.set_attribute_value(inst_id, att_id, value)
|
||||
if result.success:
|
||||
print("ok")
|
||||
else:
|
||||
print ("error: " + result.message)
|
||||
|
||||
else:
|
||||
|
||||
print("usage: attribute set inst_iid|inst_gid att_iid|att_gid value")
|
||||
else:
|
||||
|
||||
print("usage: attribute list|get|set")
|
||||
|
||||
elif value[0] == "relationship":
|
||||
|
||||
if value[1] == "list":
|
||||
|
||||
if len(value) == 3:
|
||||
|
||||
inst_id = self.parse(value[2])
|
||||
if inst_id is None:
|
||||
print("invalid inst id " + value[2] + " (inst not found)")
|
||||
return
|
||||
|
||||
rels = self.oms.get_relationships(inst_id)
|
||||
self.print_instance_list_with_relationship_values(rels, self.oms, inst_id)
|
||||
|
||||
else:
|
||||
|
||||
print ("usage: relationship list instance_id")
|
||||
|
||||
elif value[0] == "user":
|
||||
|
||||
if value[1] == "list":
|
||||
|
||||
ik_User = self.oms.get_instance_by_global_identifier(KnownClassGuids.User)
|
||||
ik_UserName = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.UserName)
|
||||
|
||||
users = self.oms.get_instances(ik_User)
|
||||
if users is None:
|
||||
self.print_error_not_open()
|
||||
return
|
||||
|
||||
print ("user name ")
|
||||
print ("---------------------")
|
||||
for user in users:
|
||||
user_name = self.oms.get_attribute_value(user, ik_UserName)
|
||||
print(user_name)
|
||||
|
||||
return
|
||||
|
||||
elif value[1] == "set-password":
|
||||
|
||||
if len(value) > 2:
|
||||
|
||||
my_username = value[2]
|
||||
my_user = self.oms.get_user_by_username(my_username)
|
||||
|
||||
if my_user is None:
|
||||
print("passwd: user '" + my_username + "' does not exist")
|
||||
return
|
||||
|
||||
print("Changing password for " + my_username + ".")
|
||||
pw = getpass("New password: ")
|
||||
pw2 = getpass("Confirm new password: ")
|
||||
if pw == pw2:
|
||||
|
||||
self.oms.set_user_password(my_user, pw)
|
||||
print("passwd: password updated successfully")
|
||||
|
||||
else:
|
||||
print("Sorry, passwords do not match.")
|
||||
return
|
||||
|
||||
elif value[0] == "close":
|
||||
self.oms.close()
|
||||
|
||||
else:
|
||||
|
||||
print("invalid cmd '" + value[0] + "'")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
prog = MochaShell()
|
||||
prog.start()
|
||||
49
mocha-python/src/mocha-python/mocha-web.py
Normal file
49
mocha-python/src/mocha-python/mocha-web.py
Normal file
@ -0,0 +1,49 @@
|
||||
from mocha.web.WebServer import WebServer
|
||||
|
||||
from mocha.oms import Oms
|
||||
from mocha.oms.memory import MemoryOms
|
||||
|
||||
import sys
|
||||
from getopt import getopt
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
port = 8081
|
||||
libraries = [ ]
|
||||
|
||||
(opts, remaining) = getopt(sys.argv[1:], "p", [ "port=", "library=" ])
|
||||
for opt in opts:
|
||||
if opt[0] == "--port":
|
||||
port = int(opt[1])
|
||||
|
||||
print("Mocha User Interface Service v2.1")
|
||||
|
||||
from mocha.web.manager import ServerManager
|
||||
svrmgr = ServerManager()
|
||||
|
||||
if len(remaining) == 0:
|
||||
print("error: no server configurations specified")
|
||||
|
||||
for library in remaining:
|
||||
svrmgr.add_server_config(library)
|
||||
|
||||
svrmgr.start()
|
||||
|
||||
# from mocha.lib.LibraryManager import MochaLibraryManager
|
||||
# manager = MochaLibraryManager()
|
||||
|
||||
# from mocha.lib.parser.YAMLLibraryParser import YAMLLibraryParser
|
||||
# yamlmgr = YAMLLibraryParser(manager)
|
||||
|
||||
# print("loading entity definitions...")
|
||||
# for library in remaining:
|
||||
# print("\t" + library)
|
||||
# yamlmgr.load_entity_definitions_from_file(library)
|
||||
|
||||
# print("loading instances...")
|
||||
# for library in remaining:
|
||||
# print("\t" + library)
|
||||
# yamlmgr.load_instances_from_file(library)
|
||||
|
||||
# oms = MemoryOms()
|
||||
|
||||
@ -9,8 +9,6 @@ class InstanceKey():
|
||||
return InstanceKey(tup[0], tup[1])
|
||||
|
||||
def __init__(self, class_id : int, inst_id : int):
|
||||
|
||||
|
||||
self.__class_id = class_id
|
||||
self.__inst_id = inst_id
|
||||
|
||||
@ -23,7 +21,7 @@ class InstanceKey():
|
||||
def __str__(self):
|
||||
|
||||
return str(self.get_class_index()) + '$' + str(self.get_instance_index())
|
||||
|
||||
|
||||
def to_tuple(self):
|
||||
return (self.__class_id, self.__inst_id)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__class_id == other.__class_id and self.__inst_id == other.__inst_id
|
||||
@ -1,8 +1,10 @@
|
||||
from .InstanceKey import InstanceKey
|
||||
|
||||
from framework import Guid
|
||||
|
||||
class InstanceReference:
|
||||
|
||||
def __init__(self, dbid, inst_key : InstanceKey, global_id):
|
||||
def __init__(self, dbid, inst_key : InstanceKey, global_id : Guid):
|
||||
self.dbid = dbid
|
||||
self.inst_key = inst_key
|
||||
self.global_id = global_id
|
||||
@ -14,7 +16,10 @@ class InstanceReference:
|
||||
return self.inst_key
|
||||
|
||||
def get_global_identifier(self):
|
||||
return self.global_id.lower()
|
||||
return self.global_id
|
||||
|
||||
def __str__(self):
|
||||
return str(self.inst_key) + ' ' + self.global_id
|
||||
return str(self.inst_key) + ' ' + str(self.global_id)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.inst_key) + ' ' + str(self.global_id)
|
||||
@ -0,0 +1,55 @@
|
||||
from framework import Guid
|
||||
|
||||
"""
|
||||
Represents the Text Attribute `Name`
|
||||
"""
|
||||
Name = Guid.parse("{9153A637-992E-4712-ADF2-B03F0D9EDEA6}")
|
||||
|
||||
"""
|
||||
Represents the Text Attribute `Value`
|
||||
"""
|
||||
Value = Guid.parse("{041DD7FD-2D9C-412B-8B9D-D7125C166FE0}")
|
||||
|
||||
"""
|
||||
Represents the Text Attribute `Debug Definition File Name`
|
||||
"""
|
||||
DebugDefinitionFileName = Guid.parse("{03bf47c7-dc97-43c8-a8c9-c6147bee4e1f}")
|
||||
DebugDefinitionLineNumber = Guid.parse("{822be9b7-531d-4aa1-818a-6e4de1609057}")
|
||||
DebugDefinitionColumnNumber = Guid.parse("{0f75c750-e738-4410-9b4e-deb422efc7aa}")
|
||||
|
||||
|
||||
Singular = Guid.parse("F1A06573C4474D85B4E754A438C4A960")
|
||||
Value = Guid.parse("041DD7FD2D9C412B8B9DD7125C166FE0")
|
||||
CSSValue = Guid.parse("C0DD4A42F5034EB380347C428B1B8803")
|
||||
RelationshipType = Guid.parse("71106B1219344834B0F6D894637BAEED")
|
||||
LabelOverride = Guid.parse("{89b361e0-9f13-4fea-9b1e-6eca573bd6ba}")
|
||||
Label = Guid.parse("69cdf8affcf24477b75d71593e7dbb22")
|
||||
Order = Guid.parse("{49423f66-8837-430d-8cac-7892ebdcb1fe}")
|
||||
MethodType = Guid.parse("{47ae57a9-7723-48a8-80f2-dd410d929e14}")
|
||||
|
||||
ClassName = Guid.parse("c7e8d78ecfac4dacae242ac67a0ba9d3")
|
||||
ThemeName = Guid.parse("{8cfc012c-52fd-4a66-8b2f-1b9b5e4af474}")
|
||||
|
||||
"""
|
||||
A Numeric Attribute specifying the maximum length of an input field.
|
||||
"""
|
||||
MaximumLength = Guid.parse("6d69fee2f2204aadab8901bfa491dae1")
|
||||
|
||||
TargetURL = Guid.parse("970F79A09EFE4E7D92869908C6F06A67")
|
||||
|
||||
UserName = Guid.parse("960FAF025C5940F791A720012A99D9ED")
|
||||
PasswordHash = Guid.parse("F377FC294DF14AFB96434191F37A00A9")
|
||||
PasswordSalt = Guid.parse("8C5A99BC40ED4FA2B23FF373C1F3F4BE")
|
||||
|
||||
Encoding = Guid.parse("a82f3c46055e4e129c5de40447134389")
|
||||
ContentType = Guid.parse("34142FCB172C490AAF03FF8451D00CAF")
|
||||
|
||||
BackgroundColor = Guid.parse("B817BE3BD0AC4A60A98A97F99E96CC89")
|
||||
ForegroundColor = Guid.parse("BB4B6E0DD9BA403D9E8193E8F7FB31C8")
|
||||
IPAddress = Guid.parse("ADE5A3C3A84E4798BC5BE08F21380208")
|
||||
Token = Guid.parse("da7686b638034f1597f67f8f3ae16668")
|
||||
|
||||
DebugDefinitionFileName = Guid.parse("03bf47c7dc9743c8a8c9c6147bee4e1f")
|
||||
|
||||
MinimumValue = Guid.parse('{bc90ffdf-9b6e-444a-a484-f9d06d7f3c31}')
|
||||
MaximumValue = Guid.parse('{b9353b1c-2597-4097-96eb-449a6fafcdab}')
|
||||
@ -0,0 +1,126 @@
|
||||
from framework import Guid
|
||||
|
||||
Class = Guid.parse("{B9C9B9B7-AD8A-4CBD-AA6B-E05784630B6B}")
|
||||
Attribute = Guid.parse("{F9CD7751-EF62-4F7C-8A28-EBE90B8F46AA}")
|
||||
Relationship = Guid.parse("{9B0A80F9-C325-4D36-997C-FB4106204648}")
|
||||
|
||||
InstanceDefinition = Guid.parse("{ee26f146-0b89-4cfe-a1af-ae6ac3533eae}")
|
||||
|
||||
Enumeration = Guid.parse("{70c3ee17-4d54-4342-9e7b-527cf73c93dd}")
|
||||
|
||||
# Attribute subclasses
|
||||
TextAttribute = Guid.parse("{C2F36542-60C3-4B9E-9A96-CA9B309C43AF}")
|
||||
BooleanAttribute = Guid.parse("{EA830448-A403-4ED9-A3D3-048D5D5C3A03}")
|
||||
NumericAttribute = Guid.parse("{9DE86AF1-EFD6-4B71-9DCC-202F247C94CB}")
|
||||
DateAttribute = Guid.parse("{0B7B1812-DFB4-4F25-BF6D-CEB0E1DF8744}")
|
||||
|
||||
RichTextAttribute = Guid.parse("{9e393eb5-0b2d-4c31-bc8c-419f9af8aee6}")
|
||||
|
||||
Element = Guid.parse("{91929595-3dbd-4eae-8add-6120a49797c7}")
|
||||
ElementContent = Guid.parse("{f85d4f5e-c69f-4498-9913-7a8554e233a4}")
|
||||
|
||||
Translation = Guid.parse("{04A53CC8-3206-4A97-99C5-464DB8CAA6E6}")
|
||||
TranslationValue = Guid.parse("{6D38E757-EC18-43AD-9C35-D15BB446C0E1}")
|
||||
|
||||
String = Guid.parse("{5AECB489-DBC2-432E-86AF-6BE349317238}")
|
||||
StringComponent = Guid.parse("{F9E2B671-13F5-4172-A568-725ACD8BBFAB}")
|
||||
ExtractSingleInstanceStringComponent = Guid.parse("{FCECCE4E-8D05-485A-AE34-B1B45E766661}")
|
||||
InstanceAttributeStringComponent = Guid.parse("{623565D5-5AEE-49ED-A5A9-0CFE670507BC}")
|
||||
|
||||
Prompt = Guid.parse("{EC889225-416A-4F73-B8D1-2A42B37AF43E}")
|
||||
TextPrompt = Guid.parse("{195DDDD7-0B74-4498-BF61-B0549FE05CF3}")
|
||||
ChoicePrompt = Guid.parse("{5597AEEB-922D-48AF-AE67-DF7D951C71DB}")
|
||||
InstancePrompt = Guid.parse("{F3ECBF1E-E732-4370-BE05-8FA7CC520F50}")
|
||||
BooleanPrompt = Guid.parse("{a7b49c03-c9ce-4a79-a4b2-e94fc8cd8b29}")
|
||||
|
||||
Method = Guid.parse("{D2813913-80B6-4DD6-9AD6-56D989169734}")
|
||||
|
||||
# MethodCall = Guid.parse("{084A6D58-32C9-4A5F-9D2B-86C46F74E522}")
|
||||
|
||||
ConditionalEvaluationCase = Guid.parse("{ba18abdc-11ae-46af-850a-eb30280b0ffa}")
|
||||
ConditionalSelectAttributeCase = Guid.parse("{a1115690-c400-4e3e-9c8f-24e2a9477e8f}")
|
||||
|
||||
AccessModifier = Guid.parse("{ca4fcc11-16c8-4872-a712-82e589d382ce}")
|
||||
|
||||
MethodBinding = Guid.parse("{CB36098E-B9BF-4D22-87FA-4186EC632C89}")
|
||||
ReturnAttributeMethodBinding = Guid.parse("{30FB6BA6-2BBB-41D2-B91A-709C00A07790}")
|
||||
ReturnInstanceSetMethodBinding = Guid.parse("{AADC20F9-7559-429B-AEF0-97E059295C76}")
|
||||
|
||||
Executable = Guid.parse("{6A1F66F7-8EA6-43D1-B2AF-198F63B84710}")
|
||||
ExecutableReturningAttribute = Guid.parse("{50b2db7a-3623-4be4-b40d-98fab89d3ff5}")
|
||||
ExecutableReturningInstanceSet = Guid.parse("{d5fbc5cb-13fb-4e68-b3ad-46b4ab8909f7}")
|
||||
ExecutableReturningElement = Guid.parse("{a15a4f52-1f1a-4ef3-80a7-033d45cc0548}")
|
||||
ExecutableReturningWorkData = Guid.parse("{a0365b76-ad1f-462e-84da-d6a1d5b9c88c}")
|
||||
|
||||
Event = Guid.parse("{ca727ecd-8536-4aeb-9e75-352dbb958767}")
|
||||
|
||||
WorkData = Guid.parse("{05e8f023-88cb-416b-913e-75299e665eb2}")
|
||||
WorkSet = Guid.parse("{c4c171d8-994b-485b-b0ac-053d11b963ab}")
|
||||
|
||||
Parameter = Guid.parse("{1ab99be0-43f1-495a-b85e-ec38ea606713}")
|
||||
ParameterAssignment = Guid.parse("{c7aa0c7c-50d8-44fd-9b05-a558a38a6954}") # 28
|
||||
ElementContentDisplayOption = Guid.parse("{bd68052a-daa4-43b9-8965-d38095473170}")
|
||||
|
||||
ReportObject = Guid.parse("{ff7d5757-d9d9-48ab-ab04-5932e7341a90}")
|
||||
|
||||
Validation = Guid.parse("{3E45AA17-6E8E-41DB-9C94-E84B4B4176E8}")
|
||||
ValidationClassification = Guid.parse("{8f43d578-a671-436b-afdc-c8689a5bd9b6}")
|
||||
|
||||
PrimaryObjectReportField = Guid.parse("{59EA0C72-4800-48BA-84A4-DDFE10E5F4D0}")
|
||||
RelationshipReportField = Guid.parse("{FC4E3BB5-1EA7-44FF-B828-2EA54CDD4ABB}")
|
||||
|
||||
ReportField = Guid.parse("{655A04D9-FE35-4F89-9AAB-B8FA34989D03}")
|
||||
AttributeReportField = Guid.parse("{C06E0461-A956-4599-9708-012C8FE04D94}")
|
||||
|
||||
Module = Guid.parse("{e009631d-6b9d-445c-95df-79f4ef8c8fff}")
|
||||
|
||||
Report = Guid.parse("{19D947B6-CE82-4EEE-92EC-A4E01E27F2DB}")
|
||||
ReportColumn = Guid.parse("{BEFE99A1-B2EB-4365-A2C9-061C6609037B}")
|
||||
StandardReport = Guid.parse("{FDF4A498-DE83-417D-BA01-707372125C8D}")
|
||||
|
||||
TaskCategory = Guid.parse("{e8d8060f-a20c-442f-8384-03488b63247f}")
|
||||
Task = Guid.parse("{D4F2564B-2D11-4A5C-8AA9-AF52D4EACC13}")
|
||||
UITask = Guid.parse("{BFD07772-178C-4885-A6CE-C85076C8461C}")
|
||||
|
||||
Tenant = Guid.parse("{703F9D65-C584-4D9F-A656-D0E3C247FF1F}")
|
||||
|
||||
User = Guid.parse("{9C6871C1-9A7F-4A3A-900E-69D1D9E24486}")
|
||||
|
||||
UserLogin = Guid.parse("{64F4BCDB-38D0-4373-BA30-8AE99AF1A5F7}")
|
||||
|
||||
MenuItemCommand = Guid.parse("{9D3EDE23-6DB9-4664-9145-ABCBD3A0A2C2}")
|
||||
MenuItemSeparator = Guid.parse("{798DECAB-5119-49D7-B0AD-D4BF45807188}")
|
||||
MenuItemHeader = Guid.parse("{1F148873-8A97-4409-A79B-C19D5D380CA4}")
|
||||
MenuItemInstance = Guid.parse("{6E3AA9AF-96B9-4208-BEA9-291A72C68418}")
|
||||
|
||||
Style = Guid.parse("{A48C843A-B24B-4BC3-BE6F-E2D069229B0A}")
|
||||
StyleRule = Guid.parse("{C269A1F3-E014-4230-B78D-38EAF6EA8A81}")
|
||||
StyleClass = Guid.parse("{a725f089-7763-4887-af37-da52358c378c}")
|
||||
|
||||
Page = Guid.parse("{D9626359-48E3-4840-A089-CD8DA6731690}")
|
||||
ContainerPageComponent = Guid.parse("{6AD6BD1C-7D1C-4AC9-9642-FEBC61E9D6FF}")
|
||||
ButtonPageComponent = Guid.parse("{F480787D-F51E-498A-8972-72128D808AEB}")
|
||||
HeadingPageComponent = Guid.parse("{FD86551E-E4CE-4B8B-95CB-BEC1E6A0EE2B}")
|
||||
ImagePageComponent = Guid.parse("{798B67FA-D4BE-42B9-B4BD-6F8E02C953C0}")
|
||||
PanelPageComponent = Guid.parse("{D349C489-9684-4A5A-9843-B906A7F803BC}")
|
||||
ParagraphPageComponent = Guid.parse("{ADFF93CE-9E85-4168-A7D4-5239B99BE36D}")
|
||||
SequentialContainerPageComponent = Guid.parse("{A66D9AE2-3BEC-4083-A5CB-7DE3B03A9CC7}")
|
||||
SummaryPageComponent = Guid.parse("{5EBA7BD6-BA0A-45B2-835C-C92489FD7E74}")
|
||||
TabContainerPageComponent = Guid.parse("{E52B02D7-895C-4642-9B03-EB0232868190}")
|
||||
DetailPageComponent = Guid.parse("{41F9508E-6CF0-4F3D-8762-FF17CD52C466}")
|
||||
ElementPageComponent = Guid.parse("{122d5565-9df9-4656-b6af-ba5df6630d32}")
|
||||
|
||||
IntegrationID = Guid.parse("{49a5ebda-baaa-4ede-bba5-decc250ce1a3}")
|
||||
IntegrationIDUsage = Guid.parse("{86084b9f-3860-4857-a41f-2f8b6877aff1}")
|
||||
|
||||
Dashboard = Guid.parse("{896B529C-452D-42AC-98C5-170ED4F826C6}")
|
||||
DashboardContent = Guid.parse("{2720ea77-cb09-4099-9f74-ccdacdd146e8}")
|
||||
Instance = Guid.parse("{263C4882-945F-4DE9-AED8-E0D6516D4903}")
|
||||
InstanceSet = Guid.parse("{53aac86e-ce60-4509-a869-417c38c305e0}")
|
||||
|
||||
AuditLine = Guid.parse("{a4124a76-02f6-406a-9583-a197675b493b}")
|
||||
|
||||
Theme = Guid.parse("{7c2cc4b5-8323-4478-863b-1759d7adf62e}")
|
||||
|
||||
CommonBoolean = Guid.parse("{5b025da3-b7bd-45a9-b084-48c4a922bf72}")
|
||||
CommonInstanceSet = Guid.parse("{3382da21-4fc5-45dc-bbd1-f7ba3ece1a1b}")
|
||||
@ -0,0 +1,14 @@
|
||||
from framework import Guid
|
||||
|
||||
class User:
|
||||
|
||||
superuser = Guid.parse("{69e291d8-381b-4ad8-9013-f3b0a0c693fe}")
|
||||
|
||||
zq_environments = Guid.parse("{B066A54B-B160-4510-A805-436D3F90C2E6}")
|
||||
zq_developer = Guid.parse("{098DDA82-CD04-4B53-8C75-89D420EA6902}")
|
||||
zq_support = Guid.parse("{232A8CBF-0D2B-4BDA-BE86-3E2FA25A3FB5}")
|
||||
zq_configurator = Guid.parse("{FB20A79C-EAA2-4A98-A1DA-BDC351854694}")
|
||||
zq_implementer = Guid.parse("{63F2EF51-DC73-48EC-856A-6FBBEDE01A8A}")
|
||||
admin = Guid.parse("{739C26BC-740F-4CB0-BCB1-2A28FA570E7D}")
|
||||
|
||||
|
||||
@ -0,0 +1,354 @@
|
||||
from framework import Guid
|
||||
|
||||
Instance__has__Source_Definition = Guid.parse("{57cbc351-0428-47e6-a6db-445e4503abab}")
|
||||
Class__has_super__Class = Guid.parse("{100F0308-855D-4EC5-99FA-D8976CA20053}")
|
||||
Class__has_sub__Class = Guid.parse("C14BC80D879C4E6F9123E8DFB13F4666")
|
||||
|
||||
Class__has__Method = Guid.parse("2DA282715E464472A6F5910B5DD6F608")
|
||||
Method__for__Class = Guid.parse("76D2CE0DAA4D460BB8442BD76EF9902B")
|
||||
|
||||
Class__has__Instance = Guid.parse("7EB41D3C2AE9488483A4E59441BCAEFB")
|
||||
Instance__for__Class = Guid.parse("494D5A6D04BE477B8763E3F57D0DD8C8")
|
||||
|
||||
Class__has__Relationship = Guid.parse("3997CAAD3BFA4EA69CFA2AA63E20F08D")
|
||||
Relationship__for__Class = Guid.parse("C00BD63F10DA4751B8EA0905436EA098")
|
||||
|
||||
Class__has_title__Translation = Guid.parse("B8BDB90569DD49CDB5570781F7EF2C50")
|
||||
|
||||
Class__has__Attribute = Guid.parse("DECBB61A2C6C4BC890420B5B701E08DE")
|
||||
Attribute__for__Class = Guid.parse("FFC8E435B9F844958C854DDA67F7E2A8")
|
||||
|
||||
Class__has_default__Task = Guid.parse("CF396DAA75EA41488468C66A71F2262D")
|
||||
|
||||
Class__has_owner__User = Guid.parse("D1A25625C90F4A73A6F2AFB530687705")
|
||||
User__owner_for__Class = Guid.parse("04DD2E6BEA5748408DD5F0AA943C37BB")
|
||||
|
||||
Instance__for__Module = Guid.parse("c60fda3c2c0a422980e8f644e4471d28")
|
||||
Module__has__Instance = Guid.parse("c3e5d7e35e114f8da212b175327b2648")
|
||||
|
||||
Class__has__Object_Source = Guid.parse("B62F9B81799B4ABEA4AF29B45347DE54")
|
||||
Object_Source__for__Class = Guid.parse("FBB9391DC4A243269F857801F377253C")
|
||||
|
||||
Relationship__has_source__Class = Guid.parse("7FB5D234042E45CBB11DAD72F8D45BD3")
|
||||
Relationship__has_destination__Class = Guid.parse("F220F1C204994E87A32EBDBF80C1F8A4")
|
||||
Relationship__has_sibling__Relationship = Guid.parse("656110FF450248B8A7F3D07F017AEA3F")
|
||||
|
||||
Translation__has__Translation_Value = Guid.parse("F9B60C00FF1D438FAC746EDFA8DD7324")
|
||||
Translation_Value__has__Language = Guid.parse("3655AEC2E2C94DDE8D980C4D3CE1E569")
|
||||
|
||||
String__has__String_Component = Guid.parse("3B6C4C25B7BC42428ED1BA6D01B834BA")
|
||||
Extract_Single_Instance_String_Component__has__Relationship = Guid.parse("5E499753F50F4A9EBF53DC013820499C")
|
||||
Instance_Attribute_String_Component__has__Attribute = Guid.parse("E15D427769FB4F1992DB8D087F361484")
|
||||
String_Component__has_source__Method = Guid.parse("1ef1c965e12048beb682aa040573b5fb")
|
||||
|
||||
# Class__instance_labeled_by__String = Guid.parse("F52FC851D65548A9B526C5FE0D7A29D2")
|
||||
Class__instances_labeled_by__Executable_returning_Attribute = Guid.parse("{c22fc17f-0c92-47dc-9a8b-28db0db68985}")
|
||||
|
||||
Class__has_summary__Report_Field = Guid.parse("D11050AD73764AB784DEE8D0336B74D2")
|
||||
|
||||
Class__uses_preview__Executable_returning_Element = Guid.parse("{059dc948-5f1b-4331-94f4-6d79dc324ebf}")
|
||||
Executable_returning_Element__preview_used_by__Class = Guid.parse("{07d5e08f-fe38-49fd-8fcb-c862a532ec57}")
|
||||
|
||||
|
||||
Class__has_related__Task = Guid.parse("4D8670E12AF14E7C9C87C910BD7B319B")
|
||||
|
||||
Report_Object__has__Report_Field = Guid.parse("0af6265642bc40a5b0bcdbba67c347f6")
|
||||
Report_Field__for__Report_Object = Guid.parse("b46c8caa3f46465fba117d6f385425a2")
|
||||
|
||||
Task__has_title__Translation = Guid.parse("D97AE03C261F4060A06D985E26FA662C")
|
||||
Task__has_instructions__Translation = Guid.parse("A93878989DC0400694F11FB02EB3ECD7")
|
||||
Task__has__Prompt = Guid.parse("929B106F7E3E4D30BB84E450A4FED063")
|
||||
Task__has__Task_Category = Guid.parse("84048159430d4f6c9361115c8629c517")
|
||||
Task__executes__Method_Call = Guid.parse("D8C0D4D4F8C64B92A2C18BF16B16203D")
|
||||
Task__has_preview_action_title__Translation = Guid.parse("3f65ce0211dd4829a46bb9ea1b43e56a")
|
||||
|
||||
Prompt__has__Report_Field = Guid.parse("922CCB0561EA441D96E063D58231D202") # 3de784b9456142f0946fb1e90d80029e
|
||||
Report_Field__for__Prompt = Guid.parse("5DED3DB4686445A9A5FF8E5A35AD6E6F") # b5f59216a1f149798642a4845e59daa8
|
||||
|
||||
Instance_Prompt__has_valid__Class = Guid.parse("D5BD754BF4014FD8A70782684E7E25F0")
|
||||
|
||||
Instance_Prompt_Value__has__Instance = Guid.parse("512B518EA89244ABAC354E9DBCABFF0B")
|
||||
|
||||
Method__executed_by__Method_Binding = Guid.parse("D52500F114214B739987223163BC9C04")
|
||||
Method_Binding__executes__Method = Guid.parse("B782A5928AF542288296E3D0B24C70A8")
|
||||
|
||||
Method__has_return_type__Class = Guid.parse("1241c599e55d4dcf9200d0e48c217ef8")
|
||||
|
||||
Method_Binding__has__Parameter_Assignment = Guid.parse("2493810994f1463a9314c49e667cf45b")
|
||||
Parameter_Assignment__for__Method_Binding = Guid.parse("19c4a5dbfd2644b8b431e081e6ffff8a")
|
||||
|
||||
Parameter_Assignment__assigns_from__Executable_returning_Work_Data = Guid.parse("{6f3687ed-7d88-4ece-914e-c47c57c1146d}")
|
||||
Parameter_Assignment__assigns_to__Work_Data = Guid.parse("{51c37636-35d2-4528-99ca-50cf09fa1427}")
|
||||
|
||||
|
||||
Parameter__has_data_type__Instance = Guid.parse("ccb5200c5faf4a3a9e8e2edf5c2e0785")
|
||||
Instance__data_type_for__Parameter = Guid.parse("ea1e6305b2e44ba591b41ecfbebfa490")
|
||||
|
||||
Instance_Set__has__Instance = Guid.parse("7c9010a269f1402999c872e05c78c41e")
|
||||
|
||||
Parameter_Assignment__assigns_to__Parameter = Guid.parse("a6d30e787bff4fccb109ee96681b0a9e")
|
||||
Parameter__assigned_from__Parameter_Assignment = Guid.parse("2085341e5e7e4a7fbb8ddfa58f6030d9")
|
||||
|
||||
Method_Binding__assigned_to__Parameter_Assignment = Guid.parse("cbcb23b710c449eba1cab9da73fe8b83")
|
||||
Parameter_Assignment__assigns_from__Method_Binding = Guid.parse("1e055d30a96849d893fe541994fc0c51")
|
||||
|
||||
Validation__has__Validation_Classification = Guid.parse("BCDB6FFDD2F24B63BD7E9C2CCD9547E0")
|
||||
Validation__has_true_condition__Executable = Guid.parse("AA2D3B5141534599A9836B4A13ADCBCB")
|
||||
Validation__has_false_condition__Executable = Guid.parse("419047F8852B4A4DB161A8BD022FD8EB")
|
||||
|
||||
Validation__has_failure_message__Translation = Guid.parse("E15A97DD2A1D4DC0BD6BA957B63D9802")
|
||||
Translation__failure_message_for__Validation = Guid.parse("46a7dfcb884847d59ad3d27fbd8b423f")
|
||||
|
||||
Build_Attribute_Method__returns__Attribute = Guid.parse("{dadbf0f3-7af0-4387-a6b7-a1724a216d88}")
|
||||
# Build_Attribute_Method__builds_with__Executable_returning_Attribute = Guid.parse("{bb64cd83-85c2-4c20-82eb-2a5a5ead31f1}")
|
||||
Build_Attribute_Method__builds_with__Build_Attribute_Method_Component = Guid.parse("{b4fad1b8-711c-4e84-82d0-e9a9e41e8aa7}")
|
||||
Build_Attribute_Method_Component__uses__Executable_returning_Attribute = Guid.parse("{9d2acd01-5c6d-4a95-b77e-5261ba109540}")
|
||||
Get_Attribute_Method__has__Attribute = Guid.parse("5eca9b3fbe754f6e8495781480774833")
|
||||
|
||||
Get_Referenced_Instance_Set_Method__returns__Work_Set = Guid.parse("{72057f5b-9b49-497d-852f-cd7e5e258d6c}")
|
||||
Get_Referenced_Instance_Set_Method__uses_reference__Executable_returning_Instance_Set = Guid.parse("{2978238f-7cb0-4ba3-8c6f-473df782cfef}")
|
||||
Get_Referenced_Instance_Set_Method__uses_answer__Executable_returning_Instance_Set = Guid.parse("{6a65819e-c8cb-4575-9af8-ee221364049b}")
|
||||
|
||||
Get_Referenced_Attribute_Method__returns__Attribute = Guid.parse("87f90fe95ec64b098f51b8a4d1544cae")
|
||||
Get_Referenced_Attribute_Method__uses_reference__Executable_returning_Instance_Set = Guid.parse("{c7ecd498-6d05-4e07-b1bc-f7127d0d6666}")
|
||||
Get_Referenced_Attribute_Method__uses_answer__Executable_returning_Attribute = Guid.parse("{022ccde3-2b9e-4573-a8fc-e7568f420cd3}")
|
||||
|
||||
Get_Specified_Instances_Method__returns__Work_Set = Guid.parse("{27796f3d-0cbd-42c5-a840-791d3af6c16d}")
|
||||
Get_Specified_Instances_Method__uses__Instance = Guid.parse("dea1aa0b2bef4bacb4f90ce8cf7006fc")
|
||||
|
||||
Evaluate_Boolean_Expression_Method__returns__Boolean_Attribute = Guid.parse("{53cf2cb6-f5f2-499f-9f18-26b86bf671c4}")
|
||||
Evaluate_Boolean_Expression_Method__has_source__Executable_returning_Work_Data = Guid.parse("{45d76d56-01ed-4641-9f68-cfe0c7d0d265}")
|
||||
IDR_Evaluate_Boolean_Expression_Method__uses__Boolean_Operator = Guid.parse("{aa9e17a2-e4d9-4598-bcfc-2d729031d11c}")
|
||||
Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data = Guid.parse("{0646df91-7e3e-4d59-be71-b978a22ced8e}")
|
||||
|
||||
Prompt_Value__has__Prompt = Guid.parse("7CD62362DDCE4BFC87B9B5499B0BC141")
|
||||
|
||||
User__has_display_name__Translatable_Text_Constant = Guid.parse("6C29856C3B104F5BA291DD3CA4C04A2F")
|
||||
User_Login__has__User = Guid.parse("85B40E4B849B4006A9C04E201B25975F")
|
||||
|
||||
User__has_default__Page = Guid.parse("f00cda6feded4e0fb6c59675ed664a75")
|
||||
|
||||
Dashboard__has__Dashboard_Content = Guid.parse("d26acf18afa54ccd8629e1d9dac394ed")
|
||||
Dashboard_Content__for__Dashboard = Guid.parse("9f236d2d1f454096a69c42f37abbeebc")
|
||||
Dashboard_Content__has__Instance = Guid.parse("1f0c40752b7d42c28488c7db06e91f5a")
|
||||
Instance__for__Dashboard_Content = Guid.parse("376951c9252b48438e1dca89c94ddfa6")
|
||||
|
||||
Return_Instance_Set_Method_Binding__has_source__Class = Guid.parse("EE7A30498E09410C84CBC2C0D652CF40")
|
||||
|
||||
Report__has__Report_Column = Guid.parse("7A8F57F1A4F34BAF84A5E893FD79447D")
|
||||
Report__has__Report_Data_Source = Guid.parse("1DE7B484F9E3476AA9D37D2A86B55845")
|
||||
Report__has__Prompt = Guid.parse("5D112697303F419F886F3F09F0670B07")
|
||||
|
||||
Report_Column__has__Report_Field = Guid.parse("B90269107E914EE1B5F2D7B740614831")
|
||||
Report_Column__has__Report_Column_Option = Guid.parse("41FFF5F0B4674986A6FD46FAF4A479E9")
|
||||
|
||||
Report_Data_Source__has_source__Method = Guid.parse("2D5CB496583946A09B9430D4E2227B56")
|
||||
|
||||
Report_Field__has_source__Method = Guid.parse("5db86b7669bf421f96e74c49452db82e")
|
||||
Attribute_Report_Field__has_target__Attribute = Guid.parse("3796430126FD41D886611F73684C0E0A")
|
||||
Relationship_Report_Field__has_target__Relationship = Guid.parse("134B2790F6DF4F979AB59878C4A715E5")
|
||||
|
||||
|
||||
Tenant__has__Application = Guid.parse("22936f5126294503a30ba02d61a6c0e0")
|
||||
Tenant__has_sidebar__Menu_Item = Guid.parse("D62DFB9F48D54697AAAD1CAD0EA7ECFA")
|
||||
Tenant__has__Tenant_Type = Guid.parse("E94B6C9D330748589726F24B7DB21E2D")
|
||||
|
||||
Tenant__has_company_logo_image__File = Guid.parse("3540c81cb2294eacb9b59d4b4c6ad1eb")
|
||||
|
||||
Menu__has__Menu_Section = Guid.parse("a22d949ff8d14dcca3ebd9f910228dfd")
|
||||
Menu_Item__has_title__Translatable_Text_Constant = Guid.parse("65E3C87EA2F74A339FA7781EFA801E02")
|
||||
Menu_Section__has__Menu_Item = Guid.parse("5b659d7c58f9453c9826dd3205c3c97f")
|
||||
|
||||
Command_Menu_Item__has__Icon = Guid.parse("8859DAEF01F746FA8F3E7B2F28E0A520")
|
||||
|
||||
Instance_Menu_Item__has_target__Instance = Guid.parse("C599C20EF01A4B12A9195DC3B0F545C2")
|
||||
|
||||
Page__has_title__Translation = Guid.parse("7BE6522A4BE84CD38701C8353F7DF630")
|
||||
Page__has__Style = Guid.parse("6E6E1A853EA94939B13ECBF645CB8B59")
|
||||
Page__has__Page_Component = Guid.parse("24F6C596D77D4754B02300321DEBA924")
|
||||
|
||||
Style__has__Style_Rule = Guid.parse("4CC8A654B2DF4B17A95624939530790E")
|
||||
Style_Rule__has__Style_Property = Guid.parse("B69C2708E78D413AB491ABB6F1D2A6E0")
|
||||
|
||||
Style__has_width__Measurement = Guid.parse("4930ca87641a426d9d67cda6d5f22303")
|
||||
Style__has_height__Measurement = Guid.parse("978e6de0af7345a0bb56aaf451615b06")
|
||||
|
||||
Measurement__has__Measurement_Unit = Guid.parse("C97200821F40406D80B781C1B690354D")
|
||||
|
||||
Page__has_master__Page = Guid.parse("9bdbfd640915419f83fde8cf8bcc74ae")
|
||||
Page__master_for__Page = Guid.parse("7fe8f2a2c94d401083aa9300cc99d71d")
|
||||
|
||||
Page_Component__has__Style = Guid.parse("818CFF507D4243B2B6A792C3C54D450D")
|
||||
Style__for__Page_Component = Guid.parse("007563E7727744368C8206D5F156D8E1")
|
||||
|
||||
Button_Page_Component__has_text__Translatable_Text_Constant = Guid.parse("C25230B14D234CFE8B7556C33E8293AF")
|
||||
Image_Page_Component__has_source__Method = Guid.parse("481E3FBEB82A4C769DDFD66C6BA8C590")
|
||||
|
||||
Sequential_Container_Page_Component__has__Sequential_Container_Orientation = Guid.parse("DD55F50687184240A89421346656E804")
|
||||
Container_Page_Component__has__Page_Component = Guid.parse("CB7B81621C9E4E72BBB8C1C37CA69CD5")
|
||||
|
||||
Panel_Page_Component__has_header__Page_Component = Guid.parse("223B4073F41749CDBCA10E0749144B9D")
|
||||
Panel_Page_Component__has_content__Page_Component = Guid.parse("AD8C5FAE24444700896EC5F968C0F85B")
|
||||
Panel_Page_Component__has_footer__Page_Component = Guid.parse("56E339BD61894BACAB83999543FB8060")
|
||||
|
||||
Element_Page_Component__has__Element = Guid.parse("fe833426e25d4cde89392a6c9baac20c")
|
||||
Element_Page_Component__has__Element_Content_Display_Option = Guid.parse("74e3c13a04fd4f49be7005a32cdcdfe7")
|
||||
Element_Content_Display_Option__for__Element_Page_Component = Guid.parse("7d3a7045092549db9b7d24863c9848a6")
|
||||
|
||||
Element__for__Element_Page_Component = Guid.parse("963c5c60397947fab201a26839b9ded9")
|
||||
|
||||
Tenant__has_logo_image__File = Guid.parse("4C399E80ECA24A68BFB426A5E6E97047")
|
||||
Tenant__has_background_image__File = Guid.parse("39B0D9634BE049C8BFA2607051CB0101")
|
||||
Tenant__has_icon_image__File = Guid.parse("CC4E65BD7AAA40DAAECAC607D7042CE3")
|
||||
Tenant__has_login_header__Translatable_Text_Constant = Guid.parse("41D66ACBAFDE4B6F892DE66255F10DEB")
|
||||
Tenant__has_login_footer__Translatable_Text_Constant = Guid.parse("A6203B6B5BEB4008AE49DB5E7DDBA45B")
|
||||
Tenant__has_application_title__Translation = Guid.parse("7668343767ba46d9a5e72945be635345")
|
||||
Tenant__has_mega__Menu = Guid.parse("cdd743cbc74a46719922652c7db9f2d8")
|
||||
|
||||
Tenant_Type__has_title__Translatable_Text_Constant = Guid.parse("79AAE09C5690471C84421B230610456C")
|
||||
|
||||
Prompt__has_title__Translatable_Text_Constant = Guid.parse("081ee211753443c499b524bd9537babc")
|
||||
|
||||
Report__has_title__Translatable_Text_Constant = Guid.parse("DF93EFB08B5E49E78BC0553F9E7602F9")
|
||||
Report__has_description__Translatable_Text_Constant = Guid.parse("D5AA18A77ACD4792B0396C620A151BAD")
|
||||
Report_Field__has_title__Translatable_Text_Constant = Guid.parse("6780BFC2DBC040AE83EEBFEF979F0054")
|
||||
|
||||
Content_Page_Component__gets_content_from__Method = Guid.parse("0E002E6FAA79457C93B82CCE1AEF5F7E")
|
||||
Method__provides_content_for__Content_Page_Component = Guid.parse("5E75000D24214AD49E5FB9FDD9CB4744")
|
||||
|
||||
Securable_Item__secured_by__Method = Guid.parse("15199c4995954288846d13b0ad5dcd4b")
|
||||
Get_Relationship_Method__has__Relationship = Guid.parse("321581d660c1454783449d5bda027adc")
|
||||
|
||||
Integration_ID__has__Integration_ID_Usage = Guid.parse("6cd30735df834253aabe360d6e1a3701")
|
||||
Integration_ID_Usage__for__Integration_ID = Guid.parse("d8d981ec768640dab89f006c85042444")
|
||||
|
||||
Conditional_Select_from_Instance_Set_Method__has__Conditional_Select_from_Instance_Set_Case = Guid.parse("b6715132b4384073b81d3ecf19584b7d")
|
||||
Conditional_Select_from_Instance_Set_Case__for__Conditional_Select_from_Instance_Set_Method = Guid.parse("1c868a068fb7432d839b7a5a02a50eb6")
|
||||
|
||||
Condition_Group__has_true_condition__Executable_returning_Attribute = Guid.parse("d955da3f7ef443748b86167c73434f75")
|
||||
Executable_returning_Attribute__true_condition_for__Condition_Group = Guid.parse("1acdefd1e1b445bb99e1bf73dea71da5")
|
||||
|
||||
Condition_Group__has_false_condition__Executable_returning_Attribute = Guid.parse("e46dbc4fae8d4ad8b9e610cedfa68b73")
|
||||
Executable_returning_Attribute__false_condition_for__Condition_Group = Guid.parse("633af008bf7f4da194d667a9a80586d6")
|
||||
|
||||
Audit_Line__has__Instance = Guid.parse("c91807ed0d734729990bd90750764fb5")
|
||||
Audit_Line__has__User = Guid.parse("7c1e048d3dcb44739f2ee21014a76aa5")
|
||||
|
||||
Method__has__Method_Parameter = Guid.parse("c455dc79ba9b4a7caf8e9ca59dbe511f")
|
||||
Method_Parameter__for__Method = Guid.parse("0bcb6e5b58854747843ced4c3d3dc234")
|
||||
Method__returns__Attribute = Guid.parse("eb015d320d4f4647b9b8715097f4434b")
|
||||
|
||||
Detail_Page_Component__has_caption__Translation = Guid.parse("4a15fa44fb7b4e268ce2f36652792b48")
|
||||
|
||||
Element__has__Element_Content = Guid.parse("c1d3248102f948c6baf837d93fa8da23")
|
||||
Element_Content__for__Element = Guid.parse("2eff7f580edd40b79c0600774257649e")
|
||||
|
||||
Element__has_label__Translation = Guid.parse("7147ea909f454bb9b151025b6e2bd834")
|
||||
|
||||
Element_Content__has__Instance = Guid.parse("315b71ba953d45fc87e54f0a268242a9")
|
||||
Instance__for__Element_Content = Guid.parse("c3959f84248d4edea3f2f262917c7b56")
|
||||
|
||||
Element_Content__has__Layout = Guid.parse("1ab7412005ea4acab6d3c7e0133e0c4f")
|
||||
Element_Content__has__EC_Dynamic_Display_Option = Guid.parse("{4a41391a-c325-4182-920a-a94ad28c15fa}")
|
||||
|
||||
EC_Dynamic_Display_Option__modifies__Element_Content = Guid.parse("{4d091643-2bfc-4b83-b3e4-8a3b22c665a9}")
|
||||
|
||||
Dynamic_Display_Option__add__Display_Option = Guid.parse("{2ed33b28-f84d-4120-b585-be965cfb691f}")
|
||||
Dynamic_Display_Option__remove__Display_Option = Guid.parse("{dc06bf0b-70dd-4f71-854d-0f5685e2124f}")
|
||||
|
||||
Element_Content__built_from__BEM_Process = Guid.parse("{3d7094ff-33e5-4800-9e4e-93dde0d1d331}")
|
||||
|
||||
BEM_Process__uses_loop__Executable_returning_Instance_Set = Guid.parse("{0fb2b538-eacb-418a-b7d8-43a584b85952}")
|
||||
|
||||
Layout__has__Style = Guid.parse("{e684bb26-7e78-4a21-b8b4-5a550f3053d5}")
|
||||
|
||||
Rotary_Switch_Layout__has__Rotary_Switch_Layout_Option = Guid.parse("{ae716c95-1e26-48f4-9013-001d1a1854aa}")
|
||||
|
||||
Element_Content__has__Element_Content_Display_Option = Guid.parse("f070dfa762604488a779fae291903f2d")
|
||||
|
||||
Element_Content__has__Parameter_Assignment = Guid.parse("51214ef0458a44fa8b9df3d9d2309388")
|
||||
Parameter__assigned_from__Element_Content = Guid.parse("dcef180ba2ca4d87bb05b946c319b562")
|
||||
|
||||
Element_Content__has__Validation = Guid.parse("265637cd2099416b88fa4f5ed88a87e3")
|
||||
Validation__for__Element_Content = Guid.parse("3a4677e89c78414980ad46e5ac3b12f5")
|
||||
|
||||
Instance__has__Instance_Definition = Guid.parse("329c54ee17b84550ae80be5dee9ac53c")
|
||||
|
||||
Task__has_initiating__Element = Guid.parse("78726736f5b74466b11429cbaf6c9329")
|
||||
Element__initiates_for__Task = Guid.parse("36964c5d348e4f888a620a795b43bc14")
|
||||
|
||||
Detail_Page_Component__has_row_source__Method_Binding = Guid.parse("54FBD0560BD444F4921C11FB0C77996E")
|
||||
Detail_Page_Component__has_column_source__Method_Binding = Guid.parse("ddabeedaaa264d87a4574e7da921a293")
|
||||
|
||||
Work_Set__has_valid__Class = Guid.parse("0808746241a5427184bca9bcd31a2c21")
|
||||
Class__valid_for__Work_Set = Guid.parse("73c65dcf781047d498c0898ca1b17a68")
|
||||
|
||||
Conditional_Select_Attribute_Method__returns__Attribute = Guid.parse("{b2b9d9cc-c4dd-491b-853e-e3669ea4e66a}")
|
||||
Attribute__returned_by__Conditional_Select_Attribute_Method = Guid.parse("{e3e734ce-953b-49b8-b50d-b1826b519053}")
|
||||
|
||||
Conditional_Select_Attribute_Method__has__Conditional_Select_Attribute_Case = Guid.parse("{49396bd0-b5a9-4384-99f4-2126d80b3b66}")
|
||||
Conditional_Select_Attribute_Case__for__Conditional_Select_Attribute_Method = Guid.parse("{38e2816e-ccb4-4e89-86ab-4981f5c2d7ac}")
|
||||
|
||||
Conditional_Select_Attribute_Case__invokes__Executable_returning_Attribute = Guid.parse("{dbd97430-9c55-430d-815c-77fce9887ba7}")
|
||||
Executable_returning_Attribute__invoked_by__Conditional_Select_Attribute_Case = Guid.parse("{f4b04072-abe8-452a-b8f8-e0369dde24d4}")
|
||||
|
||||
Style__gets_background_image_File_from__Return_Instance_Set_Method_Binding = Guid.parse("4b4a0a3e426c4f70bc15b6efeb338486")
|
||||
|
||||
Style__has__Style_Class = Guid.parse("2cebd83052aa44ff818db2d6ee273a1f")
|
||||
Style_Class__for__Style = Guid.parse("b2fbce51455a42b59fd1c28bb0cbe613")
|
||||
|
||||
Style__implements__Style = Guid.parse("99b1c16af2cb4cc5a3bb82a96335aa39")
|
||||
Style__implemented_for__Style = Guid.parse("271ef8161e944f02a8054f9536c28dca")
|
||||
|
||||
|
||||
Style__has_horizontal__Alignment = Guid.parse("{cc8d60e3-1b42-4ab1-a918-3d109891bb4e}")
|
||||
Style__has_vertical__Alignment = Guid.parse("{24c175dd-c34c-4ffc-aef0-440aa032ceeb}")
|
||||
|
||||
Get_Attribute_by_System_Routine_Method__uses__System_Attribute_Routine = Guid.parse("{f7aaac2c-0bfd-4b31-8c8c-3a76e9522574}")
|
||||
Get_Attribute_by_System_Routine_Method__returns__Attribute = Guid.parse("{e19cf181-b5bf-4595-b5c6-b9098a7a41bb}")
|
||||
|
||||
Get_Instance_Set_by_System_Routine_Method__uses__System_Instance_Set_Routine = Guid.parse("{085bd706-eece-4604-ac04-b7af114d1d21}")
|
||||
System_Instance_Set_Routine__used_by__Get_Instance_Set_By_System_Routine_Method = Guid.parse("{6fb6534c-2a46-4d6d-b9df-fd581f19efed}")
|
||||
|
||||
Get_Instance_Set_by_System_Routine_Method__returns__Instance_Set = Guid.parse("{84a864fe-84de-4901-a51c-1e103dc56aed}")
|
||||
|
||||
System_Account__has__User_Preferences = Guid.parse("{ada4deb2-adfd-409f-b13a-9856fabd5522}")
|
||||
User_Preferences__for__System_Account = Guid.parse("{ab2372a5-a4c7-488a-89f6-67e5834f8c83}")
|
||||
|
||||
Button_Layout__executes_task_from__Instance_Set = Guid.parse("04d104faa6c4425ea6cd56d847c63e9d")
|
||||
Button_Layout__gets_related_instance_from__Instance_Set = Guid.parse("{462bb1ab-aefa-4455-8d56-eff233e3caa7}")
|
||||
|
||||
Element__processed_by__Process_Related_Updates_Method = Guid.parse("{ed9c836a-04a4-4505-8953-3c567e841c66}")
|
||||
Element__processed_by__Control_Transaction_Method = Guid.parse("{0f182291-6784-47b3-a8d3-d2f6ebf3950c}")
|
||||
|
||||
Control_Transaction_Method__uses__Build_Response_Method_Binding = Guid.parse("{d8f2f0cc-54a2-4004-a383-8c1321495531}")
|
||||
Build_Response_Method_Binding__used_by__Control_Transaction_Method = Guid.parse("{9b83d1f3-6569-4e98-9d88-765684abfd18}")
|
||||
|
||||
Process_Related_Updates_Method__uses__Executable_for_PUMB = Guid.parse("{50e1f14a-d6e5-4c71-b7ab-1755442728dc}")
|
||||
Process_Related_Updates_Method__processes_for__Class = Guid.parse("{436a20fb-f672-4397-aca4-ec0ed6e2280a}")
|
||||
|
||||
Assign_Attribute_Method__uses__Executable_returning_Attribute = Guid.parse("{9313f96e-58af-416f-852e-ef83725057fc}")
|
||||
Assign_Attribute_Method__assigns__Attribute = Guid.parse("{74061875-8a27-403b-9456-02e52cfd13b2}")
|
||||
|
||||
Get_Instances_Method__returns__Work_Set = Guid.parse("{7d0f93b1-8c93-464e-a44d-d674f910b589}")
|
||||
Get_Instances_Method__selects_instances_of__Class = Guid.parse("{c0b85d90-de8c-44c2-9420-c5e724ccdf2c}")
|
||||
|
||||
Build_UI_Response_Method__uses__Executable_returning_Element = Guid.parse("{6f066ec6-b978-4627-81da-78fee1bed5e5}")
|
||||
Executable_returning_Element__used_by__Build_UI_Response_Method = Guid.parse("{0e662556-ca79-43fe-9a50-57ad22df65de}")
|
||||
|
||||
Select_from_Instance_Set_Method__returns__Work_Set = Guid.parse("{e7805b49-0eb3-46ea-bc8a-a5ed676a7726}")
|
||||
Work_Set__returned_by__Select_from_Instance_Set_Method = Guid.parse("{df12608a-e157-4a1b-bae2-0224a18f5b94}")
|
||||
Select_from_Instance_Set_Method__uses__Executable_returning_Instance_Set = Guid.parse("{a907f814-b996-4294-b347-ca16ccaf1f5b}")
|
||||
Executable_returning_Instance_Set__used_by__Select_from_Instance_Set_Method = Guid.parse("{a3ec06f9-54e8-4279-a31d-d221f8697a6a}")
|
||||
Select_from_Instance_Set_Method__uses__Set_Function = Guid.parse("{abda76ae-a969-40e3-aed2-1a20fcec8b31}")
|
||||
Set_Function__used_by__Select_from_Instance_Set_Method = Guid.parse("{753f9f4f-3fe3-470a-890d-d799c24e47af}")
|
||||
Select_from_Instance_Set_Method__uses__Selection_Function = Guid.parse("{6498e72e-f321-4be2-acfd-dfd6f916ce54}")
|
||||
Selection_Function__used_by__Select_from_Instance_Set_Method = Guid.parse("{e5e6a392-a436-41f7-bc80-cb6603503be1}")
|
||||
Select_from_Instance_Set_Method__uses_function__Executable_returning_Attribute = Guid.parse("{30905c53-0d64-4332-9023-12a03e60cd09}")
|
||||
Executable_returning_Attribute__function_used_by__Select_from_Instance_Set_Method = Guid.parse("{79adb5ea-0257-445b-9f7c-e5f8508a59a2}")
|
||||
Select_from_Instance_Set_Method__uses_order__Executable_returning_Attribute = Guid.parse("{c7a5ef47-fce3-4e7c-87b8-f5cab93b1b10}")
|
||||
Executable_returning_Attribute__order_used_by__Select_from_Instance_Set_Method = Guid.parse("{48c984ea-f4da-4090-bdd0-fd659b9be13d}")
|
||||
Select_from_Instance_Set_Method__uses_subset_index__Executable_returning_Attribute = Guid.parse("{b5ef8d8b-683a-4cb9-9e6c-bc470324f4e3}")
|
||||
Executable_returning_Attribute__as_subset_index_for__Select_from_Instance_Set_Method = Guid.parse("{7d03574f-db28-4aff-a96c-8013832b8269}")
|
||||
Select_from_Instance_Set_Method__uses_comparator__Executable_returning_Work_Data = Guid.parse("{974c6e8b-b04f-4e3c-8719-298052afa9c7}")
|
||||
Executable_returning_Work_Data__comparator_for__Select_from_Instance_Set_Method = Guid.parse("{c877ea85-ee9f-4e22-bae7-4a0d7b9272e1}")
|
||||
57
mocha-python/src/mocha-python/mocha/lib/InstanceCache.py
Normal file
57
mocha-python/src/mocha-python/mocha/lib/InstanceCache.py
Normal file
@ -0,0 +1,57 @@
|
||||
from .Normalization import Normalization
|
||||
from framework import Guid
|
||||
|
||||
class InstanceCache:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.next_inst_id = dict()
|
||||
self.next_inst_id[1] = 1
|
||||
|
||||
self.inst_indices = dict()
|
||||
self.inst_guids = dict()
|
||||
|
||||
self.dbids_gid = dict()
|
||||
|
||||
def add_instance(self, inst_key, inst_gid):
|
||||
self.inst_guids[inst_key] = inst_gid
|
||||
self.inst_indices[inst_gid] = inst_key
|
||||
|
||||
if not inst_key[0] in self.next_inst_id:
|
||||
self.next_inst_id[inst_key[0]] = 1
|
||||
|
||||
if inst_key[1] >= self.next_inst_id[inst_key[0]]:
|
||||
self.next_inst_id[inst_key[0]] = inst_key[1] + 1
|
||||
|
||||
def get_global_identifier(self, inst_key):
|
||||
return self.inst_guids[inst_key]
|
||||
|
||||
def get_instance_key(self, inst_gid):
|
||||
return self.inst_indices[inst_gid]
|
||||
|
||||
def get_next_instance_id(self, class_index):
|
||||
if not class_index in self.next_inst_id:
|
||||
# this is the first instance of this class
|
||||
self.next_inst_id[class_index] = 1
|
||||
|
||||
val = self.next_inst_id[class_index]
|
||||
self.next_inst_id[class_index] += 1
|
||||
return val
|
||||
|
||||
def has_instance_by_global_identifier(self, gid):
|
||||
return gid in self.inst_indices
|
||||
|
||||
def count(self) -> int:
|
||||
"""
|
||||
Returns the number of instances stored in this OMS.
|
||||
"""
|
||||
return len(self.inst_indices)
|
||||
|
||||
def get_instance_keys(self):
|
||||
return self.inst_indices
|
||||
|
||||
def set_database_id_by_global_identifier(self, gid : Guid, dbid):
|
||||
self.dbids_gid[Normalization.normalize_uuid(gid.get_value())] = dbid
|
||||
# self.dbids_idx[self.inst_indices[gid]] = dbid
|
||||
def get_database_id_by_global_identifier(self, gid : Guid):
|
||||
return self.dbids_gid[Normalization.normalize_uuid(gid.get_value())]
|
||||
442
mocha-python/src/mocha-python/mocha/lib/LibraryManager.py
Normal file
442
mocha-python/src/mocha-python/mocha/lib/LibraryManager.py
Normal file
@ -0,0 +1,442 @@
|
||||
import MySQLdb
|
||||
|
||||
from .parser import XMLLibraryParser, JSONLibraryParser, YAMLLibraryParser
|
||||
|
||||
from .LibraryOperation import LibraryOperation
|
||||
from .operations.AssignAttributeOperation import AssignAttributeOperation
|
||||
from .operations.AssignRelationshipOperation import AssignRelationshipOperation
|
||||
from .operations.PrepareInstanceOperation import PrepareInstanceOperation
|
||||
from .operations.StoredProcedureOperation import StoredProcedureOperation
|
||||
|
||||
from .Normalization import Normalization
|
||||
|
||||
from framework import Guid
|
||||
from mocha.definitions import KnownClassGuids, KnownAttributeGuids, KnownInstanceGuids, KnownRelationshipGuids
|
||||
|
||||
from .InstanceCache import InstanceCache
|
||||
from .SQLExpression import SQLExpression
|
||||
|
||||
# from redis import Redis
|
||||
|
||||
class MochaLibraryManager:
|
||||
|
||||
def __init__(self):
|
||||
self.entityReferences = dict()
|
||||
self.entityReferenceFileNames = dict()
|
||||
self.db = None
|
||||
self._instances = []
|
||||
self._attOps = []
|
||||
self._relOps = []
|
||||
self.redis = None
|
||||
|
||||
def connect(self, hostname, database, username, password):
|
||||
self.db = MySQLdb.connect(host=hostname, user=username, passwd=password, db=database)
|
||||
# self.redis = Redis(host=hostname, port=6379, decode_responses=True)
|
||||
|
||||
def process_instance_ops(self):
|
||||
# this version is much faster as it prepares everything in advanced on the CPU before
|
||||
# pushing it out to the database
|
||||
|
||||
instances = InstanceCache()
|
||||
|
||||
for key in self._instances:
|
||||
(class_gid, inst_gid, class_index, inst_index) = key
|
||||
# first import all the known classes
|
||||
if class_gid is not None and class_index is not None:
|
||||
# print ("known class import")
|
||||
# print ("class_gid = " + class_gid)
|
||||
# print ("inst_gid = " + inst_gid + " (" + str(class_index) + "$" + str(inst_index) + ")")
|
||||
if not instances.has_instance_by_global_identifier(class_gid):
|
||||
instances.add_instance((1, class_index), class_gid)
|
||||
|
||||
for key in self._instances:
|
||||
(class_gid, inst_gid, class_index, inst_index) = key
|
||||
# now get all the classes without specified IIDs
|
||||
if class_gid is not None and class_index is None:
|
||||
# print ("unknown class import")
|
||||
if not instances.has_instance_by_global_identifier(class_gid):
|
||||
class_index = instances.get_next_instance_id(class_index)
|
||||
else:
|
||||
class_index = instances.get_instance_key(class_gid)[1]
|
||||
|
||||
if inst_index is None:
|
||||
inst_index = instances.get_next_instance_id(class_index)
|
||||
|
||||
instances.add_instance((1, inst_index), inst_gid)
|
||||
|
||||
# print ("class_gid = " + class_gid)
|
||||
# print ("inst_gid = " + inst_gid + " (" + str(1) + "$" + str(inst_index) + ")")
|
||||
|
||||
for key in self._instances:
|
||||
(class_gid, inst_gid, class_index, inst_index) = key
|
||||
if class_gid is not None and class_index is not None and inst_gid is not None and inst_index is not None:
|
||||
# we know all there is to know about this one
|
||||
pass
|
||||
elif class_gid is not None and inst_gid is not None:
|
||||
if class_index is None:
|
||||
# we need to know the class index
|
||||
if instances.has_instance_by_global_identifier(class_gid):
|
||||
class_index = instances.get_instance_key(class_gid)[1]
|
||||
else:
|
||||
class_index = instances.get_next_instance_id(1)
|
||||
|
||||
if inst_index is None:
|
||||
# we need to know the instance index as well
|
||||
if instances.has_instance_by_global_identifier(inst_gid):
|
||||
inst_index = instances.get_instance_key(inst_gid)[1]
|
||||
else:
|
||||
inst_index = instances.get_next_instance_id(class_index)
|
||||
else:
|
||||
print("error: not implemened class_gid is None or inst_gid is None")
|
||||
|
||||
instances.add_instance((class_index, inst_index), inst_gid)
|
||||
|
||||
print (str(instances.count()) + " instances preloaded")
|
||||
|
||||
c = 0
|
||||
query = "INSERT INTO mocha_instances (tenant_id, class_id, inst_id, global_identifier) VALUES "
|
||||
for inst_gid in instances.get_instance_keys():
|
||||
(class_index, inst_index) = instances.get_instance_key(inst_gid)
|
||||
print("preparing inst " + str(class_index) + "$" + str(inst_index) + " with guid " + inst_gid)
|
||||
|
||||
inst_key_str = str(class_index) + "$" + str(inst_index)
|
||||
if self.redis is not None:
|
||||
self.redis.set(inst_key_str + ".gid", Normalization.normalize_uuid(inst_gid))
|
||||
self.redis.set(inst_key_str + ".attributes.count", "0")
|
||||
self.redis.set(inst_key_str + ".relationships.count", "0")
|
||||
self.redis.set(Normalization.normalize_uuid(inst_gid) + ".iid", inst_key_str)
|
||||
self.redis.set(Normalization.normalize_uuid(inst_gid) + ".attributes.count", "0")
|
||||
self.redis.set(Normalization.normalize_uuid(inst_gid) + ".relationships.count", "0")
|
||||
|
||||
query += "(1, " + str(class_index) + ", " + str(inst_index) + ", '" + Normalization.normalize_uuid(inst_gid) + "')"
|
||||
|
||||
if c < instances.count() - 1:
|
||||
query += ", "
|
||||
|
||||
c += 1
|
||||
|
||||
print ("process_instance_ops: query was: ")
|
||||
print (query)
|
||||
self.db.query(query)
|
||||
|
||||
self.instances = instances
|
||||
return True
|
||||
|
||||
def process_attribute_ops(self, ops):
|
||||
query = "INSERT INTO mocha_attributes (tenant_id, src_inst_id, att_inst_id, usr_inst_id, att_effective_date, att_value) VALUES "
|
||||
for op in ops:
|
||||
instanceId = op.instanceId
|
||||
attributeInstanceId = op.attributeInstanceId
|
||||
value = op.value
|
||||
|
||||
if attributeInstanceId.get_value() == "":
|
||||
print("skipping invalid blank attribute")
|
||||
continue
|
||||
|
||||
print (instanceId.get_value() + " : " + attributeInstanceId.get_value() + " = '" + str(value) + "'")
|
||||
|
||||
# query += "(1, " \
|
||||
# + "mocha_get_instance_by_global_identifier('" + Normalization.normalize_uuid(instanceId.get_value()) + "'), " \
|
||||
# + "mocha_get_instance_by_global_identifier('" + Normalization.normalize_uuid(attributeInstanceId.get_value()) + "'), " \
|
||||
# + "NULL, NOW(), " + SQLExpression.normalize_parm(value) + ")"
|
||||
|
||||
query += "(1, " \
|
||||
+ str(self.instances.get_database_id_by_global_identifier(instanceId)) + ", " \
|
||||
+ str(self.instances.get_database_id_by_global_identifier(attributeInstanceId)) + ", " \
|
||||
+ "NULL, NOW(), " + SQLExpression.normalize_parm(value) + ")"
|
||||
|
||||
if ops.index(op) < len(ops) - 1:
|
||||
query += ", "
|
||||
|
||||
# op.execute(self.db)
|
||||
|
||||
print ("process_attribute_ops: query was: ")
|
||||
print (query)
|
||||
self.db.query(query)
|
||||
|
||||
def process_relationship_ops(self, ops):
|
||||
query = "INSERT INTO mocha_relationships (tenant_id, source_inst_id, relationship_inst_id, destination_inst_id, user_inst_id, effective_date) VALUES "
|
||||
|
||||
for op in ops:
|
||||
instanceId = op.instanceId
|
||||
relationshipInstanceId = op.relationshipInstanceId
|
||||
targetInstanceId = op.targetInstanceId
|
||||
|
||||
print (instanceId.get_value() + " : " + relationshipInstanceId.get_value() + " = " + targetInstanceId.get_value())
|
||||
|
||||
query += "(1, " \
|
||||
+ str(self.instances.get_database_id_by_global_identifier(instanceId)) + ", " \
|
||||
+ str(self.instances.get_database_id_by_global_identifier(relationshipInstanceId)) + ", " \
|
||||
+ str(self.instances.get_database_id_by_global_identifier(targetInstanceId)) + ", " \
|
||||
+ "NULL, NOW() )"
|
||||
|
||||
if ops.index(op) < len(ops) - 1:
|
||||
query += ", "
|
||||
|
||||
# op.execute(self.db)
|
||||
|
||||
print ("process_relationship_ops: query was: ")
|
||||
print (query)
|
||||
self.db.query(query)
|
||||
|
||||
def before_commit(self):
|
||||
"""
|
||||
Called before the unstructured information is sorted and written to the database.
|
||||
---
|
||||
This is your last chance to add instances, set attributes, and assign
|
||||
relationships before the compilation is finalized. After this stage, calls made
|
||||
to modify the compilation are undefined and will almost certainly not do what you
|
||||
want.
|
||||
"""
|
||||
|
||||
self.write_debug_information()
|
||||
|
||||
def write_debug_information(self):
|
||||
"""
|
||||
Writes debugging information, such as entity definitions ('&IDC_...;') and source
|
||||
code definitions (filename, line number, column number, etc.)
|
||||
"""
|
||||
|
||||
print ("preparing debug information (use --no-debug or undefine DEBUG or etc. [NOT IMPLEMENTED] to turn off)")
|
||||
for key in self.entityReferences:
|
||||
val = self.entityReferences[key]
|
||||
|
||||
gidEntityDefinition = Guid.create()
|
||||
self.add_instance(IDC_EntityDefinition, gidEntityDefinition, None, None)
|
||||
self.set_attribute_value(gidEntityDefinition, IDA_Name, key)
|
||||
self.set_attribute_value(gidEntityDefinition, IDA_Value, val)
|
||||
|
||||
gidSourceDefinition = Guid.create()
|
||||
self.add_instance(IDC_SourceDefinition, gidSourceDefinition, None, None)
|
||||
self.set_attribute_value(gidSourceDefinition, IDA_DebugDefinitionFileName, self.entityReferenceFileNames[key])
|
||||
|
||||
self.assign_relationship(gidEntityDefinition, IDR_Instance__has__Source_Definition, gidSourceDefinition)
|
||||
|
||||
# Source Definition.has X
|
||||
# self.add_instance(KnownClassGuids.CLASS, Guid.parse("{dc0a5dd2-22e0-471f-87cf-a5ef1b764efa}"), 1, index)
|
||||
# self.assign_relationship(instGid, Guid.parse("{dc0a5dd2-22e0-471f-87cf-a5ef1b764efa}"), targetInstanceId)
|
||||
|
||||
def commit(self):
|
||||
|
||||
self.before_commit()
|
||||
|
||||
# first record all the instances
|
||||
if not self.process_instance_ops():
|
||||
return False
|
||||
|
||||
print("reading database ids...")
|
||||
query = "SELECT id, global_identifier FROM mocha_instances"
|
||||
|
||||
cur = self.db.cursor()
|
||||
cur.execute(query)
|
||||
rows = cur.fetchall()
|
||||
|
||||
for (dbid, gid) in rows:
|
||||
self.instances.set_database_id_by_global_identifier(Guid(gid), dbid)
|
||||
|
||||
print("assigning attributes...")
|
||||
self.process_attribute_ops(self._attOps)
|
||||
|
||||
print("assigning relationships...")
|
||||
self.process_relationship_ops(self._relOps)
|
||||
|
||||
hasSiblingRelationships = dict()
|
||||
for op in self._relOps:
|
||||
relationshipKey = self.instances
|
||||
|
||||
if op.relationshipInstanceId.get_value() == "{656110FF-4502-48B8-A7F3-D07F017AEA3F}":
|
||||
# Relationship.has sibling Relationship
|
||||
hasSiblingRelationships[op.instanceId.get_value()] = op.targetInstanceId
|
||||
|
||||
siblingOps = []
|
||||
for op in self._relOps:
|
||||
if op.relationshipInstanceId.get_value() in hasSiblingRelationships:
|
||||
siblingOp = AssignRelationshipOperation(op.targetInstanceId, hasSiblingRelationships[op.relationshipInstanceId.get_value()], op.instanceId)
|
||||
siblingOps.append(siblingOp)
|
||||
# print ("assigning sibling relationship " + siblingOp.instanceId.get_value() + " . " + siblingOp.relationshipInstanceId.get_value() + " = " + siblingOp.instanceId.get_value())
|
||||
# siblingOp.execute(self.db)
|
||||
|
||||
print("assigning sibling relationships...")
|
||||
self.process_relationship_ops(siblingOps)
|
||||
|
||||
print("setting creation user...")
|
||||
|
||||
cur = self.db.cursor()
|
||||
# cur.execute("UPDATE mocha_instances SET user_inst_id = mocha_get_instance_by_global_identifier(mocha_normalize_uuid('{B066A54B-B160-4510-A805-436D3F90C2E6}'))")
|
||||
cur.execute("UPDATE mocha_attributes SET usr_inst_id = " + str(self.instances.get_database_id_by_global_identifier(Guid.parse("{B066A54B-B160-4510-A805-436D3F90C2E6}"))))
|
||||
cur.execute("UPDATE mocha_relationships SET user_inst_id = " + str(self.instances.get_database_id_by_global_identifier(Guid.parse("{B066A54B-B160-4510-A805-436D3F90C2E6}"))))
|
||||
# rows = cur.fetchall()
|
||||
# print(rows)
|
||||
|
||||
# print ("ok , applying `Class.has Instance`...")
|
||||
|
||||
# for row in rows:
|
||||
# print(row)
|
||||
# id = row[0]
|
||||
# tenant_id = row[1]
|
||||
# class_id = row[2]
|
||||
# inst_id = row[3]
|
||||
# global_identifier = row[4]
|
||||
|
||||
# if class_id is not None and id is not None:
|
||||
|
||||
# # Class.has Instance
|
||||
# query2 = ("CALL mocha_assign_relationship (" +
|
||||
# "mocha_get_instance_by_key(1, " + str(class_id) + "), " +
|
||||
# "mocha_get_instance_by_global_identifier(mocha_normalize_uuid('7EB41D3C-2AE9-4884-83A4-E59441BCAEFB'))" + ", " +
|
||||
# str(id) + ", NULL, NULL)")
|
||||
# cur.execute(query2)
|
||||
|
||||
# # Instance.for Class
|
||||
# query3 = ("CALL mocha_assign_relationship (" +
|
||||
# str(id) + ", " +
|
||||
# "mocha_get_instance_by_global_identifier(mocha_normalize_uuid('494D5A6D-04BE-477B-8763-E3F57D0DD8C8'))" + ", " +
|
||||
# "mocha_get_instance_by_key(1, " + str(class_id) + "), NULL, NULL)")
|
||||
# cur.execute(query3)
|
||||
|
||||
self.db.commit()
|
||||
|
||||
def close(self):
|
||||
self.db.close()
|
||||
|
||||
def print_error(self, cur):
|
||||
rows = cur.fetchall()
|
||||
for row in rows:
|
||||
if 'error_description' in row:
|
||||
print (row['error_description'])
|
||||
|
||||
def select_tenant(self, tenantName):
|
||||
cur = self.db.cursor()
|
||||
cur.execute("CALL mocha_select_tenant(mocha_get_tenant_by_name('" + tenantName + "'))")
|
||||
self.print_error(cur)
|
||||
|
||||
def release_tenant(self):
|
||||
cur = self.db.cursor()
|
||||
cur.execute("CALL mocha_release_tenant()")
|
||||
self.print_error(cur)
|
||||
|
||||
def assign_relationship(self, instanceId : Guid, relationshipInstanceId : Guid, targetInstanceId : Guid):
|
||||
print("-- assigning relationship " + relationshipInstanceId.get_value() + " = '" + targetInstanceId.get_value() + "'")
|
||||
self._relOps.append(AssignRelationshipOperation(instanceId, relationshipInstanceId, targetInstanceId))
|
||||
# self._relOps.append(AssignRelationshipOperation(instanceId, relationshipInstanceId, targetInstanceId))
|
||||
# query = "CALL mocha_assign_relationship(mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + instanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + relationshipInstanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + targetInstanceId.get_value() + "')), NULL, NULL);"
|
||||
# print(query)
|
||||
# cur.execute(query)
|
||||
# self.print_error(cur)
|
||||
|
||||
def set_attribute_value(self, instanceId : Guid, attributeInstanceId : Guid, value):
|
||||
print("-- assigning attribute " + attributeInstanceId.get_value() + " = '" + str(value) + "'")
|
||||
self._attOps.append(AssignAttributeOperation(instanceId, attributeInstanceId, value))
|
||||
|
||||
def install_from_path(self, path):
|
||||
|
||||
from glob import glob
|
||||
|
||||
xl = XMLLibraryParser(self)
|
||||
jl = JSONLibraryParser(self)
|
||||
yl = YAMLLibraryParser(self)
|
||||
|
||||
#xml_files = glob(path + "/**/*.xml", recursive=True)
|
||||
#for xml_file in xml_files:
|
||||
#s xl.load_file(xml_file)
|
||||
|
||||
|
||||
#json_files = glob(path + "/**/*.json", recursive=True)
|
||||
#for json_file in json_files:
|
||||
# jl.load_file(json_file)
|
||||
|
||||
yaml_files = sorted(glob(path + "/**/*.yaml", recursive=True))
|
||||
if len(yaml_files) == 0:
|
||||
print ("no files found ; does the path exist?")
|
||||
return 3
|
||||
|
||||
# first, load the entity defs
|
||||
for yaml_file in yaml_files:
|
||||
yl.load_entity_definitions_from_file(yaml_file)
|
||||
|
||||
try:
|
||||
# then, load instance definitions (also loads sugar elements into memory for later use)
|
||||
for yaml_file in yaml_files:
|
||||
yl.load_instances_from_file(yaml_file)
|
||||
|
||||
# finally, apply syntactic sugar
|
||||
yl.apply_sugar()
|
||||
|
||||
return True
|
||||
|
||||
except NameError as ex:
|
||||
|
||||
print (ex)
|
||||
|
||||
rgx = "&(.*);"
|
||||
|
||||
# go through and get all entity references across all files
|
||||
import re
|
||||
import fileinput
|
||||
|
||||
stuff = []
|
||||
|
||||
for yaml_file in yaml_files:
|
||||
f = open(yaml_file, "r")
|
||||
text = f.read()
|
||||
matches = re.findall(rgx, text)
|
||||
for match in matches:
|
||||
stuff.append(match)
|
||||
f.close()
|
||||
|
||||
missingEntities = []
|
||||
for stuf in stuff:
|
||||
if not stuf in self.entityReferences:
|
||||
if not stuf in missingEntities:
|
||||
missingEntities.append(stuf)
|
||||
|
||||
if len(missingEntities) > 0:
|
||||
print("\nNOTE: there were undefined referenced entities:\n")
|
||||
for missingEntity in missingEntities:
|
||||
print("\t" + missingEntity)
|
||||
print("\n")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def exists_entity_reference(self, name):
|
||||
return name in self.entityReferences
|
||||
|
||||
def register_entity_reference(self, name, value, filename = None):
|
||||
self.entityReferences[name] = value
|
||||
self.entityReferenceFileNames[name] = filename
|
||||
|
||||
def define_entity_reference(self, name):
|
||||
return self.entityReferences[name]
|
||||
def expand_entity_references(self, value):
|
||||
insideName = False
|
||||
name = ""
|
||||
retval = ""
|
||||
for i in range(0, len(value)):
|
||||
if value[i] == "&":
|
||||
insideName = True
|
||||
elif value[i] == ';':
|
||||
insideName = False
|
||||
|
||||
if name in self.entityReferences:
|
||||
retval += self.define_entity_reference(name)
|
||||
else:
|
||||
raise NameError("unknown entity ref '" + name + "'")
|
||||
|
||||
name = ""
|
||||
elif insideName:
|
||||
name += value[i]
|
||||
else:
|
||||
retval += value[i]
|
||||
return retval
|
||||
|
||||
def add_instance(self, classGid : Guid, instGid : Guid, classIndex : int, index : int):
|
||||
print("adding instance for class '" + classGid.get_value() + "' with globalid '" + instGid.get_value() + "' [" + str(index) + "]")
|
||||
self._instances.append((classGid.get_value(), instGid.get_value(), classIndex, index))
|
||||
|
||||
# assign relationship `Instance.for Class`
|
||||
self.assign_relationship(instGid, Guid.parse("{494D5A6D-04BE-477B-8763-E3F57D0DD8C8}"), classGid)
|
||||
|
||||
# assign relationship `Class.has Instance`
|
||||
self.assign_relationship(classGid, Guid.parse("{7EB41D3C-2AE9-4884-83A4-E59441BCAEFB}"), instGid)
|
||||
|
||||
21
mocha-python/src/mocha-python/mocha/lib/LibraryOperation.py
Normal file
21
mocha-python/src/mocha-python/mocha/lib/LibraryOperation.py
Normal file
@ -0,0 +1,21 @@
|
||||
import MySQLdb
|
||||
|
||||
from MySQLdb.connections import Connection
|
||||
|
||||
class LibraryOperation:
|
||||
def build_query(self):
|
||||
return ''
|
||||
|
||||
def print_error(self, cur):
|
||||
rows = cur.fetchall()
|
||||
for row in rows:
|
||||
if 'error_description' in row:
|
||||
print (row['error_description'])
|
||||
|
||||
def execute(self, db : Connection):
|
||||
cur = db.cursor()
|
||||
|
||||
query = self.build_query()
|
||||
print(query)
|
||||
cur.execute(query)
|
||||
self.print_error(cur)
|
||||
5
mocha-python/src/mocha-python/mocha/lib/Normalization.py
Normal file
5
mocha-python/src/mocha-python/mocha/lib/Normalization.py
Normal file
@ -0,0 +1,5 @@
|
||||
class Normalization:
|
||||
@staticmethod
|
||||
def normalize_uuid(val : str):
|
||||
val = val.replace("{", "").replace("}", "").replace("-", "").strip().lower()
|
||||
return val
|
||||
47
mocha-python/src/mocha-python/mocha/lib/SQLExpression.py
Normal file
47
mocha-python/src/mocha-python/mocha/lib/SQLExpression.py
Normal file
@ -0,0 +1,47 @@
|
||||
from framework import Guid
|
||||
from .Normalization import Normalization
|
||||
|
||||
class SQLExpression:
|
||||
|
||||
@staticmethod
|
||||
def sqlescape(parm : str):
|
||||
return parm.replace("'", "\\'")
|
||||
|
||||
@staticmethod
|
||||
def normalize_parm(parm : str):
|
||||
query = ""
|
||||
if parm == None:
|
||||
query += "NULL"
|
||||
elif isinstance(parm, Guid):
|
||||
gid = None
|
||||
if parm is not None:
|
||||
gid = "'" + Normalization.normalize_uuid(parm.get_value()) + "'"
|
||||
else:
|
||||
gid = "NULL"
|
||||
|
||||
query += gid
|
||||
elif isinstance(parm, str):
|
||||
query += "'" + SQLExpression.sqlescape(str(parm)) + "'"
|
||||
else:
|
||||
query += str(parm)
|
||||
|
||||
return query
|
||||
|
||||
@staticmethod
|
||||
def to_string(parm):
|
||||
return SQLExpression.normalize_parm(parm)
|
||||
|
||||
@staticmethod
|
||||
def array_to_string(parms):
|
||||
i = 0
|
||||
query = ''
|
||||
for parm in parms:
|
||||
|
||||
query += SQLExpression.to_string(parm)
|
||||
|
||||
if i < len(parms) - 1:
|
||||
query += ", "
|
||||
|
||||
i += 1
|
||||
|
||||
return query
|
||||
20
mocha-python/src/mocha-python/mocha/lib/SQLFunctionCall.py
Normal file
20
mocha-python/src/mocha-python/mocha/lib/SQLFunctionCall.py
Normal file
@ -0,0 +1,20 @@
|
||||
from .SQLExpression import SQLExpression
|
||||
|
||||
class SQLFunctionCall (SQLExpression):
|
||||
|
||||
def __init__(self, funcname, parms):
|
||||
self.name = funcname
|
||||
self.parms = parms
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
def get_parameters(self):
|
||||
return self.parms
|
||||
|
||||
def get_parameter_list(self):
|
||||
return SQLExpression.array_to_string(self.parms)
|
||||
|
||||
def __str__(self):
|
||||
return self.get_name() + "(" + self.get_parameter_list() + ")"
|
||||
|
||||
12
mocha-python/src/mocha-python/mocha/lib/SQLParameter.py
Normal file
12
mocha-python/src/mocha-python/mocha/lib/SQLParameter.py
Normal file
@ -0,0 +1,12 @@
|
||||
from .SQLExpression import SQLExpression
|
||||
|
||||
class SQLParameter (SQLExpression):
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
def __str__(self):
|
||||
return "@" + self.get_name()
|
||||
@ -0,0 +1,21 @@
|
||||
from .StoredProcedureOperation import StoredProcedureOperation
|
||||
from framework import Guid
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
|
||||
class AssignAttributeOperation(StoredProcedureOperation):
|
||||
|
||||
def __init__(self, instanceId : Guid, attributeInstanceId : Guid, value):
|
||||
self.instanceId = instanceId
|
||||
self.attributeInstanceId = attributeInstanceId
|
||||
self.value = value
|
||||
|
||||
def get_sp_name(self):
|
||||
return "mocha_set_attribute_value"
|
||||
|
||||
def get_sp_parameters(self):
|
||||
return [ SQLFunctionCall('mocha_get_instance_by_global_identifier', [ self.instanceId ]), SQLFunctionCall('mocha_get_instance_by_global_identifier', [ self.attributeInstanceId ]), str(self.value), None, None ]
|
||||
#query = "CALL mocha_set_attribute_value(mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + instanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + attributeInstanceId.get_value() + "')), '" + str(value) + "', NULL, NULL);"
|
||||
#print(query)
|
||||
#cur.execute(query)
|
||||
#self.print_error(cur)
|
||||
@ -0,0 +1,21 @@
|
||||
from .StoredProcedureOperation import StoredProcedureOperation
|
||||
from framework import Guid
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
|
||||
class AssignRelationshipOperation(StoredProcedureOperation):
|
||||
|
||||
def __init__(self, instanceId : Guid, relationshipInstanceId : Guid, targetInstanceId : Guid):
|
||||
self.instanceId = instanceId
|
||||
self.relationshipInstanceId = relationshipInstanceId
|
||||
self.targetInstanceId = targetInstanceId
|
||||
|
||||
def get_sp_name(self):
|
||||
return "mocha_assign_relationship"
|
||||
|
||||
def get_sp_parameters(self):
|
||||
return [ SQLFunctionCall('mocha_get_instance_by_global_identifier', [ self.instanceId ]), SQLFunctionCall('mocha_get_instance_by_global_identifier', [ self.relationshipInstanceId ]), SQLFunctionCall('mocha_get_instance_by_global_identifier', [ self.targetInstanceId ]), None, None ]
|
||||
#query = "CALL mocha_set_attribute_value(mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + instanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + attributeInstanceId.get_value() + "')), '" + str(value) + "', NULL, NULL);"
|
||||
#print(query)
|
||||
#cur.execute(query)
|
||||
#self.print_error(cur)
|
||||
@ -0,0 +1,17 @@
|
||||
from .StoredProcedureOperation import StoredProcedureOperation
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
from ..core.Guid import Guid
|
||||
|
||||
class CreateClassOperation (StoredProcedureOperation):
|
||||
|
||||
def __init__(self, globalIdentifier : Guid, classIndex : int):
|
||||
self.globalIdentifier = globalIdentifier
|
||||
self.classIndex = classIndex
|
||||
|
||||
def get_sp_name(self):
|
||||
return 'mocha_create_class'
|
||||
|
||||
def get_sp_parameters(self):
|
||||
return [ self.classIndex, self.globalIdentifier, None, None, SQLParameter("dummy") ]
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
from .StoredProcedureOperation import StoredProcedureOperation
|
||||
from ..core.Guid import Guid
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
|
||||
class CreateInstanceOperation(StoredProcedureOperation):
|
||||
|
||||
def __init__(self, globalIdentifier : Guid, classIndex : int, instanceIndex : int):
|
||||
self.globalIdentifier = globalIdentifier
|
||||
self.classIndex = classIndex
|
||||
self.instanceIndex = instanceIndex
|
||||
|
||||
def get_sp_name(self):
|
||||
return 'mocha_create_instance'
|
||||
|
||||
def get_sp_parameters(self):
|
||||
return [ self.globalIdentifier, self.classIndex, self.instanceIndex, None, None, SQLParameter('assigned_inst_id') ]
|
||||
@ -0,0 +1,36 @@
|
||||
from .StoredProcedureOperation import StoredProcedureOperation
|
||||
from framework import Guid
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
|
||||
class PrepareInstanceOperation(StoredProcedureOperation):
|
||||
|
||||
def __init__(self, classGlobalIdentifier : Guid, globalIdentifier : Guid, classIndex : int, instanceIndex : int):
|
||||
self.classGlobalIdentifier = classGlobalIdentifier
|
||||
self.globalIdentifier = globalIdentifier
|
||||
self.classIndex = classIndex
|
||||
self.instanceIndex = instanceIndex
|
||||
|
||||
def get_sp_name(self):
|
||||
return "mocha_prepare_instance"
|
||||
|
||||
def get_sp_parameters(self):
|
||||
parms = []
|
||||
|
||||
globalId = None
|
||||
if self.globalIdentifier is not None:
|
||||
globalId = self.globalIdentifier
|
||||
|
||||
classGlobalId = None
|
||||
if self.classGlobalIdentifier is not None:
|
||||
classGlobalId = self.classGlobalIdentifier
|
||||
|
||||
strCid = None
|
||||
if self.classIndex is not None:
|
||||
strCid = self.classIndex
|
||||
|
||||
strIid = None
|
||||
if self.instanceIndex is not None:
|
||||
strIid = self.instanceIndex
|
||||
|
||||
return [strCid, strIid, classGlobalId, globalId, None, None, SQLParameter("p_assigned_inst_id")]
|
||||
@ -0,0 +1,23 @@
|
||||
import MySQLdb
|
||||
|
||||
from ..LibraryOperation import LibraryOperation
|
||||
from MySQLdb.connections import Connection
|
||||
from ..SQLExpression import SQLExpression
|
||||
from ..SQLParameter import SQLParameter
|
||||
from ..SQLFunctionCall import SQLFunctionCall
|
||||
|
||||
class StoredProcedureOperation (LibraryOperation):
|
||||
def get_sp_name(self):
|
||||
return ''
|
||||
|
||||
def get_sp_parameters(self):
|
||||
return []
|
||||
|
||||
def build_query(self):
|
||||
query = "CALL " + self.get_sp_name() + "("
|
||||
parms = self.get_sp_parameters()
|
||||
query += SQLExpression.array_to_string(parms)
|
||||
|
||||
query += ")"
|
||||
return query
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
from .LibraryParser import LibraryParser
|
||||
|
||||
class JSONLibraryParser (LibraryParser):
|
||||
|
||||
def cstyle_strip_comments(self, val):
|
||||
val2 = ""
|
||||
# possible values for comment: 0 = none, 1 = multiline, 2 = singleline
|
||||
comment = 0
|
||||
|
||||
xr = iter(range(0, len(val) - 1))
|
||||
for i in xr:
|
||||
if val[i] == '\n' and comment == 2:
|
||||
comment = 0
|
||||
|
||||
check = val[i:i+2]
|
||||
if check == "/*" and comment == 0:
|
||||
comment = 1
|
||||
next(xr)
|
||||
elif check == "*/" and comment == 1:
|
||||
comment = 0
|
||||
next(xr)
|
||||
elif check == "//":
|
||||
comment = 2
|
||||
next(xr)
|
||||
elif comment == 0:
|
||||
val2 += val[i]
|
||||
|
||||
val2 += val[-1:]
|
||||
return val2
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
class LibraryParser():
|
||||
def __init__(self, manager):
|
||||
|
||||
self.__manager = manager
|
||||
@ -0,0 +1,5 @@
|
||||
class MochaSyntaxError(RuntimeError):
|
||||
def __init__(self, *args):
|
||||
RuntimeError.__init__(self, args)
|
||||
|
||||
pass
|
||||
@ -0,0 +1,46 @@
|
||||
from .LibraryParser import LibraryParser
|
||||
|
||||
from xml.dom import minidom, Node
|
||||
from xml.dom.minidom import Entity
|
||||
|
||||
class XMLLibraryParser(LibraryParser):
|
||||
|
||||
def load_instance(self, xmlnode):
|
||||
print("instance : [" + xmlnode.getAttribute("id") + "]")
|
||||
|
||||
def load_library(self, xmlnode):
|
||||
"""
|
||||
Loads a library from the specified XML node.
|
||||
"""
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
if xmlnode.tagName != "library":
|
||||
return
|
||||
|
||||
id = xmlnode.getAttribute("id")
|
||||
for child in xmlnode.childNodes:
|
||||
if child.tagName == "instances":
|
||||
for child2 in child.childNodes:
|
||||
self.load_library_instance_from_xml(child)
|
||||
|
||||
|
||||
def load_file(self, filename):
|
||||
print("loading xml from " + filename + "... ")
|
||||
|
||||
dom = minidom.getDOMImplementation()
|
||||
dt = dom.createDocumentType("mocha", "-//MBS//DTD Mocha 1.0 Dev//EN", "https://doctype.schemas.alcetech.net/Mocha/1.0/mocha-1.0.dtd")
|
||||
dt.entities.setNamedItem(Entity("IDC_ReturnInstanceSetMethodBinding", "{AADC20F9-7559-429B-AEF0-97E059295C76}", None, None))
|
||||
|
||||
dom = minidom.parse(filename)
|
||||
if (dom.documentElement.tagName != "mocha"):
|
||||
print(filename + ": top-level tag is not 'mocha'")
|
||||
return
|
||||
|
||||
for child in dom.documentElement.childNodes:
|
||||
if child.nodeType == Node.ELEMENT_NODE:
|
||||
if child.tagName == "libraries":
|
||||
for child2 in child.childNodes:
|
||||
self.load_library(child)
|
||||
|
||||
print ("\n")
|
||||
@ -0,0 +1,345 @@
|
||||
from .LibraryParser import LibraryParser
|
||||
from framework import Guid
|
||||
from .MochaSyntaxError import MochaSyntaxError
|
||||
|
||||
class YAMLLibraryParser (LibraryParser):
|
||||
|
||||
def __init__(self, manager):
|
||||
LibraryParser.__init__(self, manager)
|
||||
|
||||
self.yamlIds = dict()
|
||||
self.templates = 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...")
|
||||
# _instances_also_awaiting_sugar = []
|
||||
|
||||
for inst in self._instances_awaiting_sugar:
|
||||
print("applying sugar from '" + inst["from_file_name"] + "'")
|
||||
self.load_instance(inst)
|
||||
print("\n")
|
||||
|
||||
# do recursively until we're all out of instances awaiting sugar
|
||||
# if len(self._instances_awaiting_sugar) > 0:
|
||||
# self.apply_sugar()
|
||||
|
||||
def load_library(self, elem):
|
||||
print("loading library from elem")
|
||||
|
||||
def load_tenant(self, elem):
|
||||
print("loading tenant from elem")
|
||||
|
||||
def find_custom_tag_name(self, elem) -> (str, Guid):
|
||||
# return tuple (tagname, value)
|
||||
if "instance" in elem:
|
||||
return ("instance", Guid.parse(self.manager.expand_entity_references(elem["instance"])))
|
||||
|
||||
for key in self.yamlIds:
|
||||
if key in elem:
|
||||
k = str(key)
|
||||
v = Guid.parse(self.manager.expand_entity_references(elem[key]))
|
||||
return (k, v)
|
||||
|
||||
return (None, None)
|
||||
|
||||
|
||||
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"]
|
||||
if not entities is None:
|
||||
for entity in entities:
|
||||
for key in entity:
|
||||
if self.manager.exists_entity_reference(key):
|
||||
print("duplicate entity definition: '" + key + "'")
|
||||
exit(1)
|
||||
|
||||
self.manager.register_entity_reference(key, entity[key], filename)
|
||||
|
||||
def load_instance_with_template(self, elem, template):
|
||||
(parentCreatorKey, parentInstanceId) = self.find_custom_tag_name(template)
|
||||
(creatorKey, instanceId) = self.find_custom_tag_name(elem)
|
||||
|
||||
self.apply_template(elem, template, instanceId)
|
||||
|
||||
def assign_relationship_value(self, instanceId, rel, rel_iid, relationshipValue):
|
||||
if (isinstance(relationshipValue, str)):
|
||||
# single instance, this should be a GUID or entityref
|
||||
# we should only need to refer to existing instance in this case
|
||||
relationshipValueInst = Guid.parse(self.manager.expand_entity_references(relationshipValue))
|
||||
if "instance" in rel:
|
||||
self.manager.assign_relationship(instanceId, Guid.parse(self.manager.expand_entity_references(rel["instance"])), relationshipValueInst)
|
||||
else:
|
||||
print("no relationship instance specified for relationship sugar")
|
||||
|
||||
else:
|
||||
# dynamically created instance
|
||||
#FIXME: this 'instance' isn't always the tag name, this can be subject to customTagName as well!and should be processed accordingly
|
||||
(relinst_key, relinst_iid) = self.find_custom_tag_name(relationshipValue)
|
||||
if relinst_key is not None:
|
||||
# for example, 'relinst_key' is 'elementContent' and 'relinst_iid' is '{8ECA14A4...}'
|
||||
|
||||
if rel_iid is not None:
|
||||
print("found customTagName '" + str(relinst_key) + "' with value '" + str(relinst_iid.get_value()) + "'")
|
||||
|
||||
# relval = Guid.parse(self.manager.expand_entity_references(elem[customTagName]))
|
||||
# we need to create the new instance and assign relationship
|
||||
self.manager.assign_relationship(instanceId, rel_iid, relinst_iid)
|
||||
else:
|
||||
if "globalIdentifier" in relationshipValue:
|
||||
globalIdentifier = Guid.parse(relationshipValue["globalIdentifier"])
|
||||
else:
|
||||
globalIdentifier = Guid.create()
|
||||
|
||||
print("creating new instance for relationship '%s' with globalid '%s'" % (rel_iid, globalIdentifier.get_value()))
|
||||
|
||||
createsInstanceOf = None
|
||||
if "type" in relationshipValue:
|
||||
print("found relationship override type '%s'" % (relationshipValue['type']))
|
||||
createsInstanceOf = Guid.parse(self.manager.expand_entity_references(relationshipValue["type"]))
|
||||
|
||||
elif "customTagNameCreatesInstanceOf" in rel:
|
||||
createsInstanceOf = Guid.parse(self.manager.expand_entity_references(rel["customTagNameCreatesInstanceOf"]))
|
||||
|
||||
if not createsInstanceOf is None:
|
||||
# create the new instance
|
||||
self.manager.add_instance(createsInstanceOf, globalIdentifier, None, None)
|
||||
|
||||
# assign relationships
|
||||
self.manager.assign_relationship(instanceId, rel_iid, globalIdentifier)
|
||||
# self.manager.assign_relationship(globalIdentifier, relationshipInstanceId, instanceId)
|
||||
|
||||
# FIXME: apply relationships from the parent class template
|
||||
|
||||
#? NOTE: You MUST specify 'registerForTemplate: yes' on the template definition for
|
||||
#? sibling relationships to be properly applied!
|
||||
|
||||
if createsInstanceOf.get_value() in self.templates:
|
||||
print("applying template for createsInstanceOf '%s'" % (createsInstanceOf.get_value()))
|
||||
createsInstanceOfTemplate = self.templates[createsInstanceOf.get_value()]
|
||||
self.apply_template(relationshipValue, createsInstanceOfTemplate, globalIdentifier)
|
||||
else:
|
||||
print("no template registered for createsInstanceOf '%s'" % (createsInstanceOf.get_value()))
|
||||
else:
|
||||
print ("neither createsInstanceOf nor override 'type' present for relationship value")
|
||||
|
||||
def apply_template(self, elem, template, instanceId):
|
||||
|
||||
if "value" in elem:
|
||||
print("VALUE found in ELEM:")
|
||||
print(elem["value"])
|
||||
|
||||
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.parse(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 "instance" in rel:
|
||||
rel_iid = rel["instance"] # the globalId of the relationship instance
|
||||
else:
|
||||
print("no relationship instance specified for relationship sugar")
|
||||
continue
|
||||
|
||||
if "customTagName" in rel:
|
||||
customTagName = rel["customTagName"]
|
||||
if customTagName in elem:
|
||||
relationshipValue = elem[customTagName]
|
||||
if relationshipValue is None:
|
||||
continue
|
||||
|
||||
if isinstance(relationshipValue, list):
|
||||
# multiple instances
|
||||
for v in relationshipValue:
|
||||
self.assign_relationship_value(instanceId, rel, Guid.parse(self.manager.expand_entity_references(rel_iid)), v)
|
||||
|
||||
else:
|
||||
self.assign_relationship_value(instanceId, rel, Guid.parse(self.manager.expand_entity_references(rel_iid)), relationshipValue)
|
||||
|
||||
def get_instance_sugar_for_elem(self, elem):
|
||||
if "instance" in elem:
|
||||
return (elem["instance"], "instance", None)
|
||||
else:
|
||||
for key in self.yamlIds:
|
||||
# no 'instance', see if we
|
||||
if key in elem:
|
||||
template = self.yamlIds[key]
|
||||
templateKey = key
|
||||
return (elem[templateKey], templateKey, template)
|
||||
|
||||
return (None, None, None) # should never get here
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
# all of these problems could be avoided by simply
|
||||
# LOADING EVERYTHING INTO MEMORY (like the .NET version does)
|
||||
# and only committing to the DB at the very end
|
||||
# this will resolve problems where we can't find instances, or use syntactic sugar
|
||||
|
||||
(globalIdentifier, templateKey, template) = self.get_instance_sugar_for_elem(elem)
|
||||
print ("globalIdentifier = " + str(globalIdentifier) + ", templateKey = " + str(templateKey))
|
||||
|
||||
if template is None:
|
||||
# no sugar
|
||||
pass
|
||||
|
||||
customTagName = None
|
||||
if "customTagName" in elem:
|
||||
customTagName = elem["customTagName"]
|
||||
self.yamlIds[customTagName] = elem
|
||||
print("registering customTagName '" + customTagName + "'")
|
||||
|
||||
if "registerForTemplate" in elem:
|
||||
if elem["registerForTemplate"] == True:
|
||||
self.templates[self.manager.expand_entity_references(globalIdentifier)] = elem
|
||||
print("registering elem for template")
|
||||
|
||||
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.parse(self.manager.expand_entity_references(template["instance"]))
|
||||
else:
|
||||
for key in self.yamlIds:
|
||||
if key in template:
|
||||
classId = Guid.parse(self.manager.expand_entity_references(template[key]))
|
||||
break
|
||||
|
||||
if "index" in template:
|
||||
classIndex = template["index"]
|
||||
|
||||
instanceId = None
|
||||
creatorKey = None
|
||||
if "instance" in elem:
|
||||
if "templateOnly" in elem and elem["templateOnly"] == True:
|
||||
# instanceId = None
|
||||
instanceId = Guid.parse(self.manager.expand_entity_references(elem["instance"]))
|
||||
else:
|
||||
instanceId = Guid.parse(self.manager.expand_entity_references(elem["instance"]))
|
||||
|
||||
creatorKey = 'instance'
|
||||
else:
|
||||
for key in self.yamlIds:
|
||||
if key in elem:
|
||||
instanceId = Guid.parse(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:
|
||||
#!!! HACK HACK HACK !!!
|
||||
classId = instanceId
|
||||
if classIndex is None and index is None:
|
||||
classIndex = 1
|
||||
index = 1
|
||||
print("WARNING: class hack used for instanceId " + instanceId.get_value() + " ( index " + str(classIndex) + "$" + str(index) + ")")
|
||||
|
||||
if instanceId is not None:
|
||||
self.manager.add_instance(classId, instanceId, classIndex, index)
|
||||
|
||||
if creatorKey == 'class': #FIXME: remove this special-case behavior
|
||||
print("creating class " + instanceId.get_value())
|
||||
|
||||
# # assign relationship `Instance.for Class`
|
||||
# self.manager.assign_relationship(instanceId, Guid.parse('494D5A6D04BE477B8763E3F57D0DD8C8'), Guid.parse('B9C9B9B7AD8A4CBDAA6BE05784630B6B'))
|
||||
|
||||
# # assign relationship `Class.has Instance`
|
||||
# self.manager.assign_relationship(Guid.parse('B9C9B9B7AD8A4CBDAA6BE05784630B6B'), Guid.parse('7EB41D3C2AE9488483A4E59441BCAEFB'), instanceId)
|
||||
|
||||
if "instances" in elem:
|
||||
classInsts = elem["instances"]
|
||||
for inst in classInsts:
|
||||
self.load_instance(inst, elem)
|
||||
|
||||
else:
|
||||
print("creating instance " + instanceId.get_value() + " (of class " + classId.get_value() + ")")
|
||||
|
||||
# # assign relationship `Instance.for Class`
|
||||
# self.manager.assign_relationship(instanceId, Guid.parse('494D5A6D04BE477B8763E3F57D0DD8C8'), classId)
|
||||
|
||||
# # assign relationship `Class.has Instance`
|
||||
# self.manager.assign_relationship(classId, Guid.parse('7EB41D3C2AE9488483A4E59441BCAEFB'), instanceId)
|
||||
|
||||
# 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 "entityDefinitions" in elem:
|
||||
continue
|
||||
elif "library" in elem:
|
||||
self.load_library(filename, elem)
|
||||
elif "tenant" in elem:
|
||||
self.load_tenant(filename, elem)
|
||||
else:
|
||||
raise MochaSyntaxError("neither 'library' nor 'tenant' top level element found")
|
||||
|
||||
def load_library(self, filename, elem):
|
||||
if "instances" in elem:
|
||||
instances = elem["instances"]
|
||||
for elem1 in instances:
|
||||
if "instance" in elem1:
|
||||
# this is an instance definition (no sugar), so just load it
|
||||
self.load_instance(elem1)
|
||||
else:
|
||||
# this is a syntactic sugar definition, so store it for later use
|
||||
elem1["from_file_name"] = filename
|
||||
self._instances_awaiting_sugar.append(elem1)
|
||||
|
||||
def load_tenant(self, filename, elem):
|
||||
pass
|
||||
@ -0,0 +1,4 @@
|
||||
from .LibraryParser import LibraryParser
|
||||
from .JSONLibraryParser import JSONLibraryParser
|
||||
from .XMLLibraryParser import XMLLibraryParser
|
||||
from .YAMLLibraryParser import YAMLLibraryParser
|
||||
294
mocha-python/src/mocha-python/mocha/oms/Oms.py
Normal file
294
mocha-python/src/mocha-python/mocha/oms/Oms.py
Normal file
@ -0,0 +1,294 @@
|
||||
from ..core import InstanceKey, InstanceReference, TenantReference
|
||||
from ..definitions import KnownClassGuids, KnownInstanceGuids, KnownAttributeGuids, KnownRelationshipGuids
|
||||
|
||||
from framework import Guid
|
||||
|
||||
from .OmsResult import OmsResult
|
||||
|
||||
class Oms:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_user_by_username(self, username : str):
|
||||
|
||||
ik_User = self.get_instance_by_global_identifier(KnownClassGuids.User)
|
||||
if ik_User is None:
|
||||
print ("error: class `User` is not defined")
|
||||
return None
|
||||
|
||||
users = self.get_instances(ik_User)
|
||||
for user in users:
|
||||
un = self.get_attribute_value(user, self.get_instance_by_global_identifier(KnownAttributeGuids.UserName))
|
||||
if un == username:
|
||||
return user
|
||||
|
||||
return None
|
||||
|
||||
def create_class(self, class_id : int, inst_id : int, name : str, global_identifier : Guid):
|
||||
pass
|
||||
|
||||
def create_relationship(self, src_class : InstanceReference, type : str, dst_class : InstanceReference, singular : bool = False, sibling_relationship : InstanceReference = None, global_identifier : Guid = None):
|
||||
|
||||
ik_current = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), global_identifier)
|
||||
|
||||
self.assign_relationship(ik_current, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_source__Class), src_class)
|
||||
self.assign_attribute(ik_current, self.get_instance_by_global_identifier(KnownAttributeGuids.RelationshipType), type)
|
||||
self.assign_relationship(ik_current, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_destination__Class), dst_class)
|
||||
self.assign_attribute(ik_current, self.get_instance_by_global_identifier(KnownAttributeGuids.Singular), singular)
|
||||
|
||||
if sibling_relationship is not None:
|
||||
self.assign_relationship(ik_current, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_sibling__Relationship), sibling_relationship)
|
||||
|
||||
return ik_current
|
||||
|
||||
def get_parent_class(self, instance : InstanceReference) -> InstanceReference:
|
||||
ik = InstanceKey(1, instance.get_instance_key().get_class_index())
|
||||
return self.get_instance_by_key(ik)
|
||||
|
||||
def assign_attribute(self, instance : InstanceReference, attribute : InstanceReference, value : str):
|
||||
pass
|
||||
|
||||
def assign_relationship(self, instance : InstanceReference, relationship : InstanceReference, related_instances : InstanceReference|list):
|
||||
pass
|
||||
|
||||
def get_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, default_value = None):
|
||||
pass
|
||||
|
||||
def get_attribute_value(self, inst : InstanceReference, att : InstanceReference, default_value = None):
|
||||
value = self.get_attribute_value_internal(inst, att, default_value)
|
||||
if value is None:
|
||||
return default_value
|
||||
|
||||
pclass = self.get_parent_class(att)
|
||||
if pclass is not None:
|
||||
if pclass.get_global_identifier() == KnownClassGuids.NumericAttribute:
|
||||
return float(value)
|
||||
|
||||
return value
|
||||
|
||||
def set_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, value):
|
||||
pass
|
||||
|
||||
def set_attribute_value(self, inst : InstanceReference, att : InstanceReference, value) -> OmsResult:
|
||||
|
||||
if inst is None or att is None:
|
||||
return OmsResult(False, "no value specified for instance reference: inst | att")
|
||||
|
||||
pclass = self.get_parent_class(att)
|
||||
if pclass is not None:
|
||||
if pclass.get_global_identifier() == KnownClassGuids.NumericAttribute:
|
||||
try:
|
||||
val = float(value)
|
||||
max_val = self.get_attribute_value(att, self.get_instance_by_global_identifier(KnownAttributeGuids.MaximumValue))
|
||||
min_val = self.get_attribute_value(att, self.get_instance_by_global_identifier(KnownAttributeGuids.MinimumValue))
|
||||
|
||||
if (min_val is not None and val < min_val) or (max_val is not None and val > max_val):
|
||||
return OmsResult(False, "parameter out of range: value")
|
||||
|
||||
except ValueError:
|
||||
return OmsResult(False, "parameter type mismatch: expected int, got " + str(type(value)))
|
||||
|
||||
self.set_attribute_value_internal(inst, att, value)
|
||||
return OmsResult.SUCCESS
|
||||
|
||||
def get_instance_by_key(self, key : InstanceKey):
|
||||
pass
|
||||
|
||||
def get_instance_by_global_identifier(self, global_identifier : Guid):
|
||||
pass
|
||||
|
||||
def get_instances(self, of_class : InstanceReference = None):
|
||||
pass
|
||||
|
||||
def get_tenant_by_name(self, tenant_name : str) -> TenantReference:
|
||||
pass
|
||||
|
||||
def get_related_instances(self, inst : InstanceReference, rel : InstanceReference) -> list[InstanceReference]:
|
||||
pass
|
||||
|
||||
def get_related_instance(self, inst : InstanceReference, rel : InstanceReference) -> InstanceReference | None:
|
||||
rels = self.get_related_instances(inst, rel)
|
||||
if len(rels) == 0:
|
||||
return None
|
||||
|
||||
return rels[0]
|
||||
|
||||
def assign_attribute(self, instance : InstanceReference, attribute : InstanceReference, value : str):
|
||||
pass
|
||||
|
||||
def assign_relationship(self, instance : InstanceReference, relationship : InstanceReference, related_instances : InstanceReference|list):
|
||||
pass
|
||||
|
||||
def get_instance_text(self, inst : InstanceReference) -> str:
|
||||
# first see if we have a parent class with `Class.instance labeled by Executable returning Attribute`
|
||||
pclasz = self.get_parent_class(inst)
|
||||
if pclasz is not None:
|
||||
rel = self.get_instance_by_global_identifier(KnownRelationshipGuids.Class__instances_labeled_by__Executable_returning_Attribute)
|
||||
relinst = self.get_related_instance(pclasz, rel)
|
||||
if relinst is not None:
|
||||
text = "EXEC:" + str(relinst.get_instance_key()) # self.execute(relinst)
|
||||
return text
|
||||
|
||||
|
||||
# if all else fails, try getting the `Name` attribute
|
||||
attr = self.get_instance_by_global_identifier(KnownAttributeGuids.Name)
|
||||
text = self.get_attribute_value(inst, attr)
|
||||
|
||||
if text is None:
|
||||
text = ""
|
||||
|
||||
return text
|
||||
|
||||
def _create_instance_of(self, class_inst : InstanceReference, global_identifier : Guid = None):
|
||||
pass
|
||||
|
||||
def create_instance_of(self, class_inst : InstanceReference, global_identifier : Guid = None):
|
||||
|
||||
inst = self._create_instance_of(class_inst, global_identifier)
|
||||
|
||||
rel_Class__has__Instance = self.get_instance_by_global_identifier(KnownRelationshipGuids.Class__has__Instance)
|
||||
if rel_Class__has__Instance is None:
|
||||
return inst
|
||||
rel_Instance__for__Class = self.get_instance_by_global_identifier(KnownRelationshipGuids.Instance__for__Class)
|
||||
if rel_Instance__for__Class is None:
|
||||
return inst
|
||||
|
||||
self.assign_relationship(class_inst, rel_Class__has__Instance, inst)
|
||||
self.assign_relationship(inst, rel_Instance__for__Class, class_inst)
|
||||
|
||||
return inst
|
||||
|
||||
def set_user_password(self, user : InstanceReference, password : str):
|
||||
|
||||
ik_UserName = self.get_instance_by_global_identifier(KnownAttributeGuids.UserName)
|
||||
ik_PasswordHash = self.get_instance_by_global_identifier(KnownAttributeGuids.PasswordHash)
|
||||
ik_PasswordSalt = self.get_instance_by_global_identifier(KnownAttributeGuids.PasswordSalt)
|
||||
|
||||
username = self.get_attribute_value(user, self.get_instance_by_global_identifier(KnownAttributeGuids.UserName))
|
||||
salt = Guid.create().strip()
|
||||
|
||||
passsalt = str(password + salt).encode("utf-8")
|
||||
import hashlib
|
||||
passhash = hashlib.sha512(passsalt).hexdigest()
|
||||
|
||||
self.assign_attribute(user, ik_UserName, username)
|
||||
self.assign_attribute(user, ik_PasswordHash, passhash)
|
||||
self.assign_attribute(user, ik_PasswordSalt, salt)
|
||||
|
||||
def create_user(self, username : str, password : str, global_identifier : Guid = None):
|
||||
user = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.User), global_identifier)
|
||||
|
||||
if password is not None:
|
||||
self.set_user_password(user, password)
|
||||
|
||||
def before_init(self):
|
||||
pass
|
||||
|
||||
def _init(self):
|
||||
ik_Class = self.create_class(1, 1, 'Class', KnownClassGuids.Class)
|
||||
self.create_class(1, 2, 'Attribute', KnownClassGuids.Attribute)
|
||||
ik_Relationship = self.create_class(1, 3, 'Relationship', KnownClassGuids.Relationship)
|
||||
|
||||
ik_TextAttribute = self.create_class(1, 4, 'Text Attribute', KnownClassGuids.TextAttribute)
|
||||
ik_BooleanAttribute = self.create_class(1, 5, 'Boolean Attribute', KnownClassGuids.BooleanAttribute)
|
||||
self.create_class(1, 6, 'Element', KnownClassGuids.Element)
|
||||
ik_NumericAttribute = self.create_class(1, 20, 'Numeric Attribute', KnownClassGuids.NumericAttribute)
|
||||
ik_RichTextAttribute = self.create_class(1, 2737, 'Rich Text Attribute', KnownClassGuids.RichTextAttribute)
|
||||
|
||||
att_Name = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Name)
|
||||
att_Value = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Value)
|
||||
att_Token = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Token)
|
||||
|
||||
rel_Relationship__has_source__Class = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), KnownRelationshipGuids.Relationship__has_source__Class)
|
||||
rel_Relationship__has_destination__Class = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), KnownRelationshipGuids.Relationship__has_destination__Class)
|
||||
rel_Relationship__has_sibling__Relationship = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), KnownRelationshipGuids.Relationship__has_sibling__Relationship)
|
||||
|
||||
ik_Singular = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.BooleanAttribute), KnownAttributeGuids.Singular)
|
||||
ik_RelationshipType = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.RelationshipType)
|
||||
|
||||
|
||||
ik_Instance = self.create_class(1, 17, "Instance", KnownClassGuids.Instance)
|
||||
ik_User = self.create_class(1, 39, 'System User', KnownClassGuids.User)
|
||||
ik_UserLogin = self.create_class(1, 4328, 'System Account Signon', KnownClassGuids.UserLogin)
|
||||
|
||||
ik_UserName = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.UserName)
|
||||
self.assign_attribute(ik_UserName, self.get_instance_by_global_identifier(KnownAttributeGuids.Name), "User Name")
|
||||
|
||||
ik_PasswordHash = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.PasswordHash)
|
||||
self.assign_attribute(ik_PasswordHash, self.get_instance_by_global_identifier(KnownAttributeGuids.Name), "Password Hash")
|
||||
|
||||
ik_PasswordSalt = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.PasswordSalt)
|
||||
self.assign_attribute(ik_PasswordSalt, self.get_instance_by_global_identifier(KnownAttributeGuids.Name), "Password Salt")
|
||||
|
||||
superuser = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.User), KnownInstanceGuids.User.superuser)
|
||||
self.assign_attribute(superuser, ik_UserName, "superuser")
|
||||
self.assign_attribute(superuser, ik_PasswordHash, "0bdbeeecd24e93a0d84ff2946c519761d4db2c52d9449d2de5bf3b74a8bcdfbee9d72bb88121a63700d09554983e7f881021ecf493f83dec19e8f7e465529c34")
|
||||
self.assign_attribute(superuser, ik_PasswordSalt, "5e28b86839ed4ca9838c112723aeaa27")
|
||||
|
||||
self.create_user("zq-configurator", "Florida407!", KnownInstanceGuids.User.zq_configurator)
|
||||
self.create_user("zq-developer", "Florida407!", KnownInstanceGuids.User.zq_developer)
|
||||
self.create_user("zq-environments", "Florida407!", KnownInstanceGuids.User.zq_environments)
|
||||
self.create_user("zq-implementer", "Florida407!", KnownInstanceGuids.User.zq_implementer)
|
||||
self.create_user("zq-support", "Florida407!", KnownInstanceGuids.User.zq_support)
|
||||
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(1, 2)), self.get_instance_by_key(InstanceKey(4, 1)), 'Attribute')
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(1, 3)), self.get_instance_by_key(InstanceKey(4, 1)), 'Relationship')
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(1, 4)), self.get_instance_by_key(InstanceKey(4, 1)), 'Text Attribute')
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(4, 1)), self.get_instance_by_key(InstanceKey(4, 1)), 'Name')
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(4, 2)), self.get_instance_by_key(InstanceKey(4, 1)), 'Value')
|
||||
self.assign_attribute(self.get_instance_by_key(InstanceKey(4, 3)), self.get_instance_by_key(InstanceKey(4, 1)), 'Token')
|
||||
|
||||
ik_User_Login__for__User = self.create_relationship(ik_UserLogin, "for", ik_User, False, None, KnownRelationshipGuids.User_Login__has__User)
|
||||
# self.create_relationship(ik_User, "has", ik_UserLogin, False, ik_User_Login__for__User, KnownRelationshipGuids.User__has__User_Login)
|
||||
|
||||
self.update_relationship(rel_Relationship__has_source__Class, ik_Relationship, "has source", ik_Class, True, None)
|
||||
self.update_relationship(rel_Relationship__has_destination__Class, ik_Relationship, "has destination", ik_Class, True, None)
|
||||
self.update_relationship(rel_Relationship__has_sibling__Relationship, ik_Relationship, "has sibling", ik_Relationship, True, None)
|
||||
|
||||
rel_Class__has__Instance = self.create_relationship(ik_Class, "has", ik_Instance, False, None, KnownRelationshipGuids.Class__has__Instance)
|
||||
rel_Instance__for__Class = self.create_relationship(ik_Instance, "for", ik_Class, True, None, KnownRelationshipGuids.Instance__for__Class)
|
||||
self.update_relationship(rel_Class__has__Instance, None, None, None, None, rel_Instance__for__Class)
|
||||
self.update_relationship(rel_Instance__for__Class, None, None, None, None, rel_Class__has__Instance)
|
||||
|
||||
ik_MaximumLength = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MaximumLength)
|
||||
self.set_attribute_value(ik_MaximumLength, att_Name, "Maximum Length")
|
||||
|
||||
ik_MinimumValue = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MinimumValue)
|
||||
self.set_attribute_value(ik_MinimumValue, att_Name, "Minimum Value")
|
||||
ik_MaximumValue = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MaximumValue)
|
||||
self.set_attribute_value(ik_MaximumValue, att_Name, "Maximum Value")
|
||||
|
||||
self.set_attribute_value(ik_Class, att_Name, "Class")
|
||||
self.update_class_instances()
|
||||
|
||||
def update_relationship(self, relationship : InstanceReference, src_class : InstanceReference, type : str, dst_class : InstanceReference, singular: bool, sibling_relationship : InstanceReference):
|
||||
if src_class is not None:
|
||||
self.assign_relationship(relationship, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_source__Class), src_class)
|
||||
if type is not None:
|
||||
self.assign_attribute(relationship, self.get_instance_by_global_identifier(KnownAttributeGuids.RelationshipType), type)
|
||||
if dst_class is not None:
|
||||
self.assign_relationship(relationship, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_destination__Class), dst_class)
|
||||
if singular is not None:
|
||||
self.assign_attribute(relationship, self.get_instance_by_global_identifier(KnownAttributeGuids.Singular), singular)
|
||||
if sibling_relationship is not None:
|
||||
self.assign_relationship(relationship, self.get_instance_by_global_identifier(KnownRelationshipGuids.Relationship__has_sibling__Relationship), sibling_relationship)
|
||||
|
||||
def update_class_instances(self):
|
||||
|
||||
ik_Class = self.get_instance_by_global_identifier(KnownClassGuids.Class)
|
||||
rel_Class__has__Instance = self.get_instance_by_global_identifier(KnownRelationshipGuids.Class__has__Instance)
|
||||
rel_Instance__for__Class = self.get_instance_by_global_identifier(KnownRelationshipGuids.Instance__for__Class)
|
||||
|
||||
insts = self.get_instances()
|
||||
for inst in insts:
|
||||
clasz = self.get_instance_by_key(InstanceKey(1, inst.get_instance_key().get_class_index() ))
|
||||
self.assign_relationship(clasz, rel_Class__has__Instance, inst)
|
||||
self.assign_relationship(inst, rel_Instance__for__Class, clasz)
|
||||
|
||||
def after_init(self):
|
||||
pass
|
||||
|
||||
def init(self):
|
||||
self.before_init()
|
||||
self._init()
|
||||
self.after_init()
|
||||
9
mocha-python/src/mocha-python/mocha/oms/OmsResult.py
Normal file
9
mocha-python/src/mocha-python/mocha/oms/OmsResult.py
Normal file
@ -0,0 +1,9 @@
|
||||
class OmsResult:
|
||||
|
||||
def __init__(self, success : bool, message : str):
|
||||
self.success = success
|
||||
self.message = message
|
||||
|
||||
|
||||
OmsResult.SUCCESS = OmsResult(True, "the operation completed successfully")
|
||||
|
||||
2
mocha-python/src/mocha-python/mocha/oms/__init__.py
Normal file
2
mocha-python/src/mocha-python/mocha/oms/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from .Oms import Oms
|
||||
from .OmsResult import OmsResult
|
||||
@ -1,4 +1,4 @@
|
||||
from .Oms import Oms
|
||||
from ..Oms import Oms
|
||||
|
||||
class DatabaseOms(Oms):
|
||||
pass
|
||||
@ -1,7 +1,7 @@
|
||||
from .Oms import Oms
|
||||
from .DatabaseOms import DatabaseOms
|
||||
from ..DatabaseOms import DatabaseOms
|
||||
|
||||
from ..core import InstanceKey, InstanceReference, TenantReference
|
||||
from ...core import InstanceKey, InstanceReference, TenantReference
|
||||
|
||||
import mysql.connector
|
||||
|
||||
@ -118,6 +118,9 @@ class MySQLDatabaseOms(DatabaseOms):
|
||||
|
||||
return None
|
||||
|
||||
def get_related_instances(self, inst : InstanceReference, rel : InstanceReference) -> list[InstanceReference]:
|
||||
pass
|
||||
|
||||
def get_tenant_by_name(self, tenant_name : str) -> TenantReference:
|
||||
mycur = self.db.cursor()
|
||||
|
||||
@ -0,0 +1,260 @@
|
||||
from ..DatabaseOms import DatabaseOms
|
||||
|
||||
from ....core.InstanceKey import InstanceKey
|
||||
from ....core.InstanceReference import InstanceReference
|
||||
|
||||
import sqlite3
|
||||
|
||||
from framework import Guid
|
||||
|
||||
from ....definitions import KnownClassGuids, KnownInstanceGuids, KnownAttributeGuids, KnownRelationshipGuids
|
||||
|
||||
class SQLiteDatabaseOms (DatabaseOms):
|
||||
|
||||
def __init__(self):
|
||||
self.conn = None
|
||||
self.__is_open = False
|
||||
|
||||
def open(self, filename : str):
|
||||
"""
|
||||
Opens the SQLite database with the given filename.
|
||||
"""
|
||||
self.conn = sqlite3.Connection(filename)
|
||||
self.__is_open = True
|
||||
|
||||
def is_open(self):
|
||||
return self.__is_open
|
||||
|
||||
def get_next_instance_index(self, class_inst : InstanceReference):
|
||||
cursor = self.conn.execute("SELECT MAX(inst_id) + 1 FROM instances WHERE class_id = ?", [ class_inst.get_instance_key().get_instance_index() ])
|
||||
result = cursor.fetchone()[0]
|
||||
if result is None:
|
||||
result = 1
|
||||
|
||||
return result
|
||||
|
||||
def _create_instance_of(self, class_inst : InstanceReference, global_identifier : Guid = None):
|
||||
|
||||
if global_identifier is None:
|
||||
global_identifier = Guid.create()
|
||||
|
||||
next_iid = self.get_next_instance_index(class_inst)
|
||||
result = self.conn.execute("INSERT INTO instances (class_id, inst_id, global_identifier, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [ class_inst.get_instance_key().get_instance_index(), next_iid, global_identifier.strip() ])
|
||||
lastrowid = result.lastrowid
|
||||
|
||||
# self.conn.execute("INSERT INTO attributes (src_inst_id, att_inst_id, att_value, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [ result.lastrowid, 5, name ])
|
||||
self.conn.commit()
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances WHERE id = ?", [ lastrowid ])
|
||||
results = cursor.fetchall()
|
||||
result = results[0]
|
||||
|
||||
return self.get_instance_from_database(result)
|
||||
|
||||
|
||||
def create_class(self, class_id : int, inst_id : int, name : str, global_identifier : Guid):
|
||||
print ("create class : " + str(class_id) + "$" + str(inst_id) + " [" + name + "] " + str(global_identifier) + ";")
|
||||
|
||||
result = self.conn.execute("INSERT INTO instances (class_id, inst_id, global_identifier, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [ class_id, inst_id, global_identifier.strip() ])
|
||||
lastrowid = result.lastrowid
|
||||
|
||||
print ("lastrowid: " + str(result.lastrowid))
|
||||
|
||||
self.conn.execute("INSERT INTO attributes (src_inst_id, att_inst_id, att_value, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [ result.lastrowid, 5, name ])
|
||||
self.conn.commit()
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances WHERE id = ?", [ lastrowid ])
|
||||
results = cursor.fetchall()
|
||||
result = results[0]
|
||||
|
||||
return self.get_instance_from_database(result)
|
||||
|
||||
def get_attributes(self, instance : InstanceReference):
|
||||
if instance is None:
|
||||
return [ ]
|
||||
|
||||
cursor = self.conn.execute("SELECT DISTINCT att_inst_id FROM attributes WHERE src_inst_id = ? AND effective_date <= CURRENT_TIMESTAMP ORDER BY effective_date DESC", [ instance.dbid ])
|
||||
results = cursor.fetchall()
|
||||
retval = [ ]
|
||||
for result in results:
|
||||
retval.append(self.get_instance_by_dbid(result[0]))
|
||||
|
||||
return retval
|
||||
|
||||
def get_relationships(self, instance : InstanceReference):
|
||||
if instance is None:
|
||||
return [ ]
|
||||
|
||||
cursor = self.conn.execute("SELECT DISTINCT rel_inst_id FROM relationships WHERE src_inst_id = ? AND effective_date <= CURRENT_TIMESTAMP ORDER BY effective_date DESC", [ instance.dbid ])
|
||||
results = cursor.fetchall()
|
||||
retval = [ ]
|
||||
for result in results:
|
||||
retval.append(self.get_instance_by_dbid(result[0]))
|
||||
|
||||
return retval
|
||||
|
||||
def get_related_instances(self, instance : InstanceReference, relationship : InstanceReference):
|
||||
if instance is None:
|
||||
return [ ]
|
||||
if relationship is None:
|
||||
return [ ]
|
||||
|
||||
cursor = self.conn.execute("SELECT dst_inst_id, remove_flag FROM relationships WHERE src_inst_id = ? AND rel_inst_id = ? AND effective_date <= CURRENT_TIMESTAMP ORDER BY effective_date DESC", [ instance.dbid, relationship.dbid ])
|
||||
results = cursor.fetchall()
|
||||
retval_ids = [ ]
|
||||
retval = [ ]
|
||||
for result in results:
|
||||
if result[0] in retval_ids:
|
||||
if result[1] == 1:
|
||||
# remove flag
|
||||
retval_ids.remove(result[0])
|
||||
else:
|
||||
retval_ids.append(result[0])
|
||||
|
||||
for id in retval_ids:
|
||||
retval.append(self.get_instance_by_dbid(id))
|
||||
|
||||
return retval
|
||||
|
||||
def assign_attribute(self, instance : InstanceReference, attribute : InstanceReference, value : str):
|
||||
|
||||
self.conn.execute("INSERT INTO attributes (src_inst_id, att_inst_id, att_value, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [ instance.get_dbid(), attribute.get_dbid(), value ])
|
||||
self.conn.commit()
|
||||
|
||||
def assign_relationship(self, instance : InstanceReference, relationship : InstanceReference, related_instances : InstanceReference|list):
|
||||
|
||||
if relationship is None:
|
||||
raise ValueError("relationship for assign_relationship is None")
|
||||
|
||||
if related_instances is None:
|
||||
raise ValueError("related_instances must not be None")
|
||||
|
||||
if isinstance(related_instances, InstanceReference):
|
||||
related_instances = [ related_instances ]
|
||||
|
||||
if isinstance(related_instances, list):
|
||||
for inst in related_instances:
|
||||
if not inst is None:
|
||||
self.conn.execute("INSERT INTO relationships (src_inst_id, rel_inst_id, dst_inst_id, remove_flag, effective_date) VALUES (?, ?, ?, 0, CURRENT_TIMESTAMP)", [ instance.get_dbid(), relationship.get_dbid(), inst.get_dbid() ])
|
||||
else:
|
||||
print("error: target inst for assign_relationship is None")
|
||||
|
||||
else:
|
||||
print("related_instances must be either InstanceReference or list, was " + str(type(inst)))
|
||||
return
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
def get_instance_by_dbid(self, dbid : int) -> InstanceReference:
|
||||
if self.conn is None:
|
||||
return None
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances WHERE id = ? AND (effective_date IS NULL OR effective_date <= CURRENT_TIMESTAMP)", [ dbid ])
|
||||
results = cursor.fetchall()
|
||||
if len(results) > 0:
|
||||
return self.get_instance_from_database(results[0])
|
||||
|
||||
return None
|
||||
|
||||
def get_instance_by_key(self, key : InstanceKey) -> InstanceReference:
|
||||
if self.conn is None:
|
||||
return None
|
||||
|
||||
qry = "SELECT * FROM instances WHERE class_id = " + str(key.get_class_index()) + " AND inst_id = " + str(key.get_instance_index()) + " AND (effective_date IS NULL OR effective_date <= CURRENT_TIMESTAMP)"
|
||||
result = self.conn.execute(qry)
|
||||
results = result.fetchall()
|
||||
if len(results) > 0:
|
||||
return self.get_instance_from_database(results[0])
|
||||
|
||||
return None
|
||||
|
||||
# retval = [ ]
|
||||
|
||||
# for res in results:
|
||||
# retval.append(InstanceReference(int(res[0]), InstanceKey(int(res[1]), int(res[2])), res[3]))
|
||||
|
||||
# if len(retval) == 1:
|
||||
# return retval[0]
|
||||
# elif len(retval) == 0:
|
||||
# return None
|
||||
|
||||
# return retval
|
||||
|
||||
def get_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, default_value = None):
|
||||
if inst is None or att is None:
|
||||
return None
|
||||
|
||||
cursor = self.conn.execute("SELECT att_value FROM attributes WHERE src_inst_id = " + str(inst.dbid) + " AND att_inst_id = " + str(att.dbid) + " AND effective_date <= CURRENT_TIMESTAMP ORDER BY effective_date DESC, id DESC")
|
||||
results = cursor.fetchall()
|
||||
if (len(results) > 0):
|
||||
return results[0][0]
|
||||
return None
|
||||
|
||||
def set_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, value):
|
||||
cursor = self.conn.execute("INSERT INTO attributes (src_inst_id, att_inst_id, att_value, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [inst.dbid, att.dbid, value])
|
||||
self.conn.commit()
|
||||
|
||||
def before_init(self):
|
||||
self.conn.execute("DROP TABLE IF EXISTS instances")
|
||||
self.conn.execute("DROP TABLE IF EXISTS attributes")
|
||||
self.conn.execute("DROP TABLE IF EXISTS relationships")
|
||||
self.conn.execute("DROP TABLE IF EXISTS relationship_instances")
|
||||
|
||||
self.conn.execute("CREATE TABLE instances (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, class_id INT, inst_id INT, global_identifier CHAR(32), effective_date DATETIME)")
|
||||
self.conn.execute("CREATE TABLE attributes (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, src_inst_id INTEGER NOT NULL, att_inst_id INTEGER NOT NULL, att_value TEXT, effective_date DATETIME)")
|
||||
# self.conn.execute("CREATE TABLE relationships (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, src_inst_id INTEGER NOT NULL, rel_inst_id INTEGER NOT NULL, effective_date DATETIME)")
|
||||
# self.conn.execute("CREATE TABLE relationship_instances (rel_id INTEGER NOT NULL, inst_id INTEGER NOT NULL, remove_flag INTEGER NOT NULL, effective_date DATETIME)")
|
||||
self.conn.execute("CREATE TABLE relationships (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, src_inst_id INTEGER NOT NULL, rel_inst_id INTEGER NOT NULL, dst_inst_id INTEGER NOT NULL, remove_flag INTEGER NOT NULL, effective_date DATETIME)")
|
||||
|
||||
def after_init(self):
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
def get_instances(self, of_class : InstanceReference = None):
|
||||
|
||||
if self.conn is None:
|
||||
return None
|
||||
|
||||
if of_class is not None:
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances WHERE class_id = ?", [ of_class.get_instance_key().get_instance_index() ])
|
||||
results = cursor.fetchall()
|
||||
insts = [ ]
|
||||
|
||||
for result in results:
|
||||
inst = self.get_instance_from_database(result)
|
||||
insts.append(inst)
|
||||
|
||||
return insts
|
||||
|
||||
else:
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances")
|
||||
results = cursor.fetchall()
|
||||
insts = [ ]
|
||||
|
||||
for result in results:
|
||||
inst = self.get_instance_from_database(result)
|
||||
insts.append(inst)
|
||||
|
||||
return insts
|
||||
|
||||
|
||||
def get_instance_from_database(self, result):
|
||||
return InstanceReference(int(result[0]), InstanceKey(int(result[1]), int(result[2])), Guid.parse(result[3]))
|
||||
|
||||
def get_instance_by_global_identifier(self, global_identifier : Guid):
|
||||
if self.conn is None:
|
||||
return None
|
||||
|
||||
cursor = self.conn.execute("SELECT * FROM instances WHERE global_identifier = ?", [ global_identifier.strip() ])
|
||||
results = cursor.fetchall()
|
||||
if len(results) > 0:
|
||||
return self.get_instance_from_database(results[0])
|
||||
|
||||
return None
|
||||
|
||||
def close(self):
|
||||
self.conn.close()
|
||||
self.__is_open = False
|
||||
|
||||
@ -0,0 +1 @@
|
||||
from .SQLiteDatabaseOms import SQLiteDatabaseOms
|
||||
13
mocha-python/src/mocha-python/mocha/oms/memory/MemoryOms.py
Normal file
13
mocha-python/src/mocha-python/mocha/oms/memory/MemoryOms.py
Normal file
@ -0,0 +1,13 @@
|
||||
from ..Oms import Oms
|
||||
|
||||
class MemoryOms (Oms):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_tenant_name(self):
|
||||
return "super"
|
||||
|
||||
def load_from_path(self, path):
|
||||
|
||||
pass
|
||||
@ -0,0 +1 @@
|
||||
from .MemoryOms import MemoryOms
|
||||
23
mocha-python/src/mocha-python/mocha/web/AssetLocation.py
Normal file
23
mocha-python/src/mocha-python/mocha/web/AssetLocation.py
Normal file
@ -0,0 +1,23 @@
|
||||
class AssetLocation:
|
||||
|
||||
pass
|
||||
|
||||
class LocalAssetLocation(AssetLocation):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.path = None
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
return "local:" + self.path
|
||||
|
||||
class RemoteAssetLocation(AssetLocation):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.path = None
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
return "remote:" + self.path
|
||||
7
mocha-python/src/mocha-python/mocha/web/PathMapping.py
Normal file
7
mocha-python/src/mocha-python/mocha/web/PathMapping.py
Normal file
@ -0,0 +1,7 @@
|
||||
class PathMapping:
|
||||
|
||||
def __init__(self, source_pattern : str, destination_path : str):
|
||||
|
||||
self.source_pattern = source_pattern
|
||||
self.destination_path = destination_path
|
||||
|
||||
@ -1,21 +1,34 @@
|
||||
from .WebControl import WebControl
|
||||
from .ui.WebControl import WebControl
|
||||
from .WebStyleSheet import WebStyleSheet
|
||||
from .XmlTag import XmlTag
|
||||
from .xml import XmlTag
|
||||
|
||||
class WebPage (WebControl):
|
||||
|
||||
def __init__(self):
|
||||
WebControl.__init__(self, 'html')
|
||||
self.__initialized = False
|
||||
self.__title = None
|
||||
self.__body = XmlTag('body')
|
||||
self.__head = XmlTag('head')
|
||||
self.__style_sheet = WebStyleSheet()
|
||||
|
||||
self.add(self.__head)
|
||||
|
||||
self.__head.add(self.__style_sheet)
|
||||
|
||||
self.add(self.__body)
|
||||
|
||||
def initialize(self):
|
||||
if self.__initialized is True:
|
||||
return False
|
||||
|
||||
self.on_initializing()
|
||||
self.__initialized = True
|
||||
return True
|
||||
|
||||
def on_initializing(self):
|
||||
pass
|
||||
|
||||
def create_from_json(self, json):
|
||||
if "components" in json:
|
||||
for component in json["components"]:
|
||||
@ -49,6 +62,8 @@ class WebPage (WebControl):
|
||||
|
||||
def render_before_html(self):
|
||||
|
||||
self.initialize()
|
||||
|
||||
title = self.get_title()
|
||||
if title is None:
|
||||
title = ""
|
||||
@ -5,10 +5,12 @@ from urllib.parse import parse_qsl, urlparse
|
||||
import json
|
||||
|
||||
from ..oms import Oms
|
||||
from ..web.AssetLocation import LocalAssetLocation, RemoteAssetLocation
|
||||
|
||||
class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
def __init__(self, request, client_address, server):
|
||||
BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||
self.__oms = server._oms
|
||||
|
||||
@cached_property
|
||||
def url(self):
|
||||
@ -35,23 +37,29 @@ class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
self.send_response(302, "Found")
|
||||
self.send_header("Location", url)
|
||||
self.end_headers()
|
||||
self.close_connection()
|
||||
|
||||
def respond_with_content(self, response_code, response_text, content_type, content):
|
||||
def respond_with_content(self, response_code, response_text, content_type, content, headers = None):
|
||||
self.send_response(response_code, response_text)
|
||||
self.send_header("Content-Type", content_type)
|
||||
self.send_header("Content-Length", len(content))
|
||||
|
||||
if headers is not None:
|
||||
for (key, value) in headers:
|
||||
self.send_header(key, value)
|
||||
|
||||
self.end_headers()
|
||||
self.wfile.write(content.encode("utf-8"))
|
||||
|
||||
def get_oms(self) -> Oms:
|
||||
from ..oms import MySQLDatabaseOms
|
||||
|
||||
# from ..oms import MySQLDatabaseOms
|
||||
from ..oms.memory import MemoryOms
|
||||
|
||||
if not hasattr(self, "__oms"):
|
||||
self.__oms = None
|
||||
|
||||
if self.__oms is None:
|
||||
self.__oms = MySQLDatabaseOms("localhost", 13306, "mocha_user", "9Q5eLsKfL5AciM4U", "mocha_test")
|
||||
# self.__oms = MySQLDatabaseOms("localhost", 13306, "mocha_user", "9Q5eLsKfL5AciM4U", "mocha_test")
|
||||
self.__oms = MemoryOms()
|
||||
|
||||
return self.__oms
|
||||
|
||||
@ -62,23 +70,70 @@ class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
|
||||
path = self.url.path.split('/')
|
||||
path = path[1:]
|
||||
|
||||
mapping = self.server._server.find_path_mapping(path)
|
||||
if mapping is not None:
|
||||
self.respond_with_content(200, "OK", mapping.content_type, mapping.content)
|
||||
return
|
||||
|
||||
if (len(path) == 1 and path[0] == ""):
|
||||
self.respond_with_redirect("/" + default_tenant_name)
|
||||
return
|
||||
|
||||
print(path)
|
||||
|
||||
if (len(path) > 0):
|
||||
|
||||
tenant_name = path[0]
|
||||
|
||||
if len(path) == 1:
|
||||
self.respond_with_redirect("/madi/authgwy/" + tenant_name + "/login.htmld")
|
||||
return
|
||||
|
||||
if path[0] == "robots.txt":
|
||||
self.respond_with_content(200, "OK", "text/plain", """User-agent: *
|
||||
Disallow: /
|
||||
""")
|
||||
return
|
||||
else:
|
||||
self.respond_with_redirect("/madi/authgwy/" + tenant_name + "/login.htmld")
|
||||
return
|
||||
|
||||
if len(path) > 1:
|
||||
if tenant_name == "madi":
|
||||
authgwy = path[1]
|
||||
if authgwy == "authgwy":
|
||||
|
||||
if authgwy == "asset":
|
||||
|
||||
if len(path) > 4:
|
||||
module = path[2]
|
||||
version = path[3]
|
||||
assetPath = "/".join(path[4:])
|
||||
|
||||
print("module: " + module)
|
||||
print("version: " + version)
|
||||
print("assetPath: " + assetPath)
|
||||
|
||||
for assetLoc in self.server._server.assets:
|
||||
if isinstance(assetLoc, LocalAssetLocation):
|
||||
physicalPath = assetLoc.path + "/" + module + "/" + version + "/" + assetPath
|
||||
print("asset is local: " + physicalPath)
|
||||
elif isinstance(assetLoc, RemoteAssetLocation):
|
||||
remotePath = assetLoc.path + "/" + module + "/" + version + "/" + assetPath
|
||||
print("asset is remote: " + remotePath)
|
||||
|
||||
import os
|
||||
|
||||
if os.path.exists(physicalPath):
|
||||
|
||||
file = open(physicalPath, "r")
|
||||
content = file.read()
|
||||
self.respond_with_content(200, "OK", "text/css", content, [ ( "Content-Encoding", "UTF-8" )])
|
||||
return
|
||||
|
||||
self.respond_with_content(404, "Not Found", "text/html", "<h1>Not Found</h1><p>The requested resource is not available on this server.</p>")
|
||||
|
||||
return
|
||||
|
||||
elif authgwy == "authgwy":
|
||||
if len(path) == 4:
|
||||
tenant_name = path[2]
|
||||
file_name = path[3]
|
||||
@ -90,8 +145,11 @@ class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
print(tenant.get_name())
|
||||
|
||||
if file_name == "login.htmld":
|
||||
from .pages import LoginWebPage
|
||||
from .ui.pages import LoginWebPage
|
||||
|
||||
page = LoginWebPage()
|
||||
page.set_oms(self.get_oms())
|
||||
|
||||
self.respond_with_content(200, "OK", "application/xhtml+xml", page.render_html())
|
||||
return
|
||||
elif file_name == "tenant-config.xml":
|
||||
@ -116,6 +174,8 @@ class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
if jj["result"] == "failure" and jj["remedy"] == "login":
|
||||
self.respond_with_login_page(tenant_name)
|
||||
return
|
||||
else:
|
||||
print(jj)
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
@ -216,16 +276,22 @@ class WebRequestHandler(BaseHTTPRequestHandler):
|
||||
loginPage = path[3]
|
||||
else:
|
||||
# error out
|
||||
return
|
||||
return {
|
||||
"result": "error",
|
||||
"message": "path len not eq 4",
|
||||
"path": path
|
||||
}
|
||||
else:
|
||||
# error out
|
||||
return
|
||||
return {
|
||||
"result": "error",
|
||||
"message": "not found 'authgwy'"
|
||||
}
|
||||
|
||||
from ..core import InstanceKey
|
||||
from ..oms import MySQLDatabaseOms
|
||||
|
||||
oms = MySQLDatabaseOms("localhost", 13306, "mocha_user", "9Q5eLsKfL5AciM4U", "mocha_test")
|
||||
|
||||
oms = self.get_oms()
|
||||
|
||||
if len(path) > 3:
|
||||
if path[1] == "api":
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from .XmlTag import XmlTag
|
||||
from .xml import XmlTag
|
||||
|
||||
class WebScript (XmlTag):
|
||||
|
||||
42
mocha-python/src/mocha-python/mocha/web/WebServer.py
Normal file
42
mocha-python/src/mocha-python/mocha/web/WebServer.py
Normal file
@ -0,0 +1,42 @@
|
||||
from . import WebRequestHandler, PathMapping
|
||||
|
||||
from ..oms import Oms
|
||||
|
||||
class WebServer():
|
||||
|
||||
def __init__(self, endpoint, oms : Oms):
|
||||
"""
|
||||
Initializes a new instance of the Mocha User Interface Service.
|
||||
`endpoint` is a tuple consisting of (str address, int port)
|
||||
"""
|
||||
self.__tup = endpoint
|
||||
self._oms = oms
|
||||
self.path_mappings = [ ]
|
||||
self.assets = [ ]
|
||||
|
||||
def match_path_pattern(self, source_pattern, path_format):
|
||||
vars = [ ]
|
||||
|
||||
if source_pattern == path_format:
|
||||
return (True, vars)
|
||||
|
||||
# TODO: add intelligent path parsing from PHP/Phast
|
||||
# from framework.web import WebPathParser... (e.g.)
|
||||
return (False, vars)
|
||||
|
||||
def find_path_mapping(self, path_format : str):
|
||||
for mapping in self.path_mappings:
|
||||
(success, vars) = self.match_path_pattern(mapping.source_pattern, path_format)
|
||||
if success:
|
||||
for varname in vars:
|
||||
mapping.set_property_value(varname, vars[varname])
|
||||
return mapping
|
||||
return None
|
||||
|
||||
def serve_forever(self):
|
||||
from http.server import HTTPServer
|
||||
|
||||
server = HTTPServer(self.__tup, WebRequestHandler)
|
||||
server._oms = self._oms
|
||||
server._server = self
|
||||
server.serve_forever()
|
||||
@ -1,4 +1,4 @@
|
||||
from .XmlTag import XmlTag
|
||||
from .xml import XmlTag
|
||||
|
||||
class WebStyleSheet (XmlTag):
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
from .xml import XmlTag
|
||||
|
||||
class WebStyleSheetReference (XmlTag):
|
||||
|
||||
def __init__(self, path):
|
||||
XmlTag.__init__(self, 'link')
|
||||
self.add_attribute("rel", "stylesheet")
|
||||
self.add_attribute("type", "text/css")
|
||||
self.add_attribute("href", path)
|
||||
|
||||
def has_content_or_controls(self):
|
||||
return False
|
||||
7
mocha-python/src/mocha-python/mocha/web/__init__.py
Normal file
7
mocha-python/src/mocha-python/mocha/web/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
from .PathMapping import PathMapping
|
||||
from .WebPage import WebPage
|
||||
from .WebRequestHandler import WebRequestHandler
|
||||
from .WebScript import WebScript
|
||||
from .WebServer import WebServer
|
||||
from .WebStyleSheet import WebStyleSheet
|
||||
from .WebStyleSheetReference import WebStyleSheetReference
|
||||
@ -0,0 +1,77 @@
|
||||
from ...oms.memory import MemoryOms
|
||||
from ..WebServer import WebServer
|
||||
|
||||
from ..AssetLocation import LocalAssetLocation, RemoteAssetLocation
|
||||
from ..PathMapping import PathMapping
|
||||
|
||||
class ServerManager:
|
||||
|
||||
def __init__(self):
|
||||
self._servers = [ ]
|
||||
|
||||
def add_server_config(self, filename):
|
||||
import yaml
|
||||
|
||||
with open(filename, 'r') as file:
|
||||
content = yaml.safe_load_all(file)
|
||||
for doc in content:
|
||||
for d in doc:
|
||||
for s in d["server"]:
|
||||
if not "port" in s:
|
||||
print("error: 'port' not defined for server definition")
|
||||
return
|
||||
|
||||
port = s["port"]
|
||||
|
||||
print("[ INFO ]: running server on port " + str(port))
|
||||
|
||||
oms = MemoryOms()
|
||||
svr = WebServer(("127.0.0.1", port), oms)
|
||||
|
||||
if "pathMappings" in s:
|
||||
pathMappings = s["pathMappings"]
|
||||
for pathMapping in pathMappings:
|
||||
svr.path_mappings.append(PathMapping(pathMapping["source"], pathMapping["destination"]))
|
||||
print("[ INFO ]: map path '" + pathMapping["destination"] + "' to file path '" + pathMapping["source"] + "'")
|
||||
|
||||
if "assets" in s:
|
||||
for asset in s["assets"]:
|
||||
|
||||
theAsset = None
|
||||
if not "type" in asset:
|
||||
print("error: asset location definition does not contain 'type'")
|
||||
continue
|
||||
elif not "path" in asset:
|
||||
print("error: asset location definition does not contain 'path'")
|
||||
continue
|
||||
|
||||
if asset["type"] == "local":
|
||||
theAsset = LocalAssetLocation()
|
||||
elif asset["type"] == "remote":
|
||||
theAsset = RemoteAssetLocation()
|
||||
|
||||
if not theAsset is None:
|
||||
theAsset.path = asset["path"]
|
||||
svr.assets.append(theAsset)
|
||||
else:
|
||||
print("error: unsupported asset type " + str(asset["type"]))
|
||||
|
||||
print ("loaded assets")
|
||||
print(svr.assets)
|
||||
|
||||
if "tenants" in s:
|
||||
tenants = s["tenants"]
|
||||
else:
|
||||
print("warning: no tenants defined in server configuration")
|
||||
|
||||
self._servers.append(svr)
|
||||
|
||||
|
||||
def start(self):
|
||||
import threading
|
||||
for server in self._servers:
|
||||
t = threading.Thread(target = self._serve, args = [ server ])
|
||||
t.start()
|
||||
|
||||
def _serve(self, server):
|
||||
server.serve_forever()
|
||||
@ -0,0 +1 @@
|
||||
from .ServerManager import ServerManager
|
||||
@ -1,4 +1,4 @@
|
||||
from .XmlTag import XmlTag
|
||||
from ..xml import XmlTag
|
||||
|
||||
class WebControl (XmlTag):
|
||||
|
||||
@ -1,19 +1,31 @@
|
||||
from ..WebScript import WebScript
|
||||
from ..WebPage import WebPage
|
||||
from ...WebScript import WebScript
|
||||
from ...WebPage import WebPage
|
||||
from ....oms import Oms
|
||||
|
||||
from ...WebStyleSheetReference import WebStyleSheetReference
|
||||
|
||||
class BaseWebPage (WebPage):
|
||||
|
||||
def __init__(self):
|
||||
WebPage.__init__(self)
|
||||
self._oms = None
|
||||
|
||||
def on_initializing(self):
|
||||
self.get_style_sheet().add_rule('table', { 'width': '100%' })
|
||||
self.get_head().add(self.get_client_config_script())
|
||||
self.get_head().add(WebStyleSheetReference("/madi/asset/ui-html/2024.03.09/css/main.css"))
|
||||
|
||||
def get_oms(self):
|
||||
return self._oms
|
||||
|
||||
def set_oms(self, oms : Oms):
|
||||
self._oms = oms
|
||||
|
||||
def get_client_config_script(self):
|
||||
return WebScript("text/javascript", content="""
|
||||
// Add properties to mocha
|
||||
window.mocha = window.mocha || {};
|
||||
mocha.tenant = 'cityoforlando3';
|
||||
mocha.tenant = '""" + self.get_oms().get_tenant_name() + """';
|
||||
mocha.clientOrigin = 'https://wd5-impl.workday.com';
|
||||
mocha.language = 'en_US';
|
||||
mocha.clientVersion = '0';
|
||||
@ -0,0 +1,3 @@
|
||||
from .BaseWebPage import BaseWebPage
|
||||
from .HomeWebPage import HomeWebPage
|
||||
from .LoginWebPage import LoginWebPage
|
||||
3
mocha-python/src/mocha-python/mocha/web/xml/__init__.py
Normal file
3
mocha-python/src/mocha-python/mocha/web/xml/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .XmlAttribute import XmlAttribute
|
||||
from .XmlTag import XmlTag
|
||||
from .XmlTagStyles import XmlTagStyles
|
||||
10
mocha-web.py
10
mocha-web.py
@ -1,10 +0,0 @@
|
||||
from mocha.web.WebServer import WebServer
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
port = 8081
|
||||
print("Mocha User Interface Service - running on port", port)
|
||||
|
||||
server = WebServer(("127.0.0.1", port))
|
||||
server.serve_forever()
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from ..core import *
|
||||
from ..oms import Oms
|
||||
|
||||
class MemoryOms(Oms):
|
||||
|
||||
def __init__(self):
|
||||
self.__current_tenant = None
|
||||
self.__instances = dict()
|
||||
self.__tenants = dict()
|
||||
|
||||
def get_instance_by_key(self, key : InstanceKey):
|
||||
return self.__instances[key.to_tuple()]
|
||||
|
||||
# def get_instance_by_global_identifier(self, global_identifier : Guid):
|
||||
|
||||
def create_tenant(self, tenant_name : str):
|
||||
if tenant_name in self.__tenants:
|
||||
raise NameError("tenant with specified name already exists")
|
||||
|
||||
self.__tenants[tenant_name] = TenantReference(tenant_name, None)
|
||||
|
||||
def select_tenant(self, tenant : TenantReference):
|
||||
self.__current_tenant = tenant
|
||||
|
||||
def release_tenant(self):
|
||||
self.__current_tenant = None
|
||||
|
||||
def get_current_tenant(self):
|
||||
return self.__current_tenant
|
||||
|
||||
def get_tenant_by_name(self, tenant_name : str):
|
||||
if tenant_name in self.__tenants:
|
||||
return self.__tenants[tenant_name]
|
||||
|
||||
return None
|
||||
@ -1,14 +0,0 @@
|
||||
from ..core import InstanceKey, InstanceReference, TenantReference
|
||||
|
||||
class Oms:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_instance_by_key(self, key : InstanceKey):
|
||||
pass
|
||||
|
||||
def get_instances(self, of_class : InstanceReference = None):
|
||||
pass
|
||||
|
||||
def get_tenant_by_name(self, tenant_name : str) -> TenantReference:
|
||||
pass
|
||||
@ -1,4 +0,0 @@
|
||||
from .Oms import Oms
|
||||
from .DatabaseOms import DatabaseOms
|
||||
from .MemoryOms import MemoryOms
|
||||
from .MySQLDatabaseOms import MySQLDatabaseOms
|
||||
@ -1,12 +0,0 @@
|
||||
from .WebRequestHandler import WebRequestHandler
|
||||
|
||||
class WebServer():
|
||||
|
||||
def __init__(self, tup):
|
||||
self.__tup = tup
|
||||
|
||||
def serve_forever(self):
|
||||
from http.server import HTTPServer
|
||||
|
||||
server = HTTPServer(self.__tup, WebRequestHandler)
|
||||
server.serve_forever()
|
||||
@ -1,2 +0,0 @@
|
||||
from .LoginWebPage import LoginWebPage
|
||||
from .HomeWebPage import HomeWebPage
|
||||
Loading…
x
Reference in New Issue
Block a user