Simple prompt implemented

This commit is contained in:
Andrei Bondarenko 2021-07-19 07:09:39 +02:00
parent 65886dc694
commit d7ba998cd7
5 changed files with 168 additions and 20 deletions

View file

@ -17,6 +17,10 @@ class Context(ABC):
def __exit__(self): def __exit__(self):
pass pass
@abstractmethod
def exposed_methods(self):
pass
@abstractmethod @abstractmethod
def instantiate(self, type_name: String, instance_name: String): def instantiate(self, type_name: String, instance_name: String):
pass pass

View file

@ -5,6 +5,7 @@ from core.context.bottom import BottomContext
class GenericContext(Context): class GenericContext(Context):
def __init__(self, state: State, model: Element, metamodel: Element): def __init__(self, state: State, model: Element, metamodel: Element):
super().__init__(state, model, metamodel) super().__init__(state, model, metamodel)
self.bottom = BottomContext(state, model) self.bottom = BottomContext(state, model)
@ -15,13 +16,24 @@ class GenericContext(Context):
def __exit__(self): def __exit__(self):
pass pass
def exposed_methods(self):
yield from [
self.instantiate,
self.instantiate_value,
self.instantiate_link,
self.retype_element,
self.list_elements,
self.delete_element,
self.verify,
]
def _type_exists(self, type_name: String, instantiate_link: bool) -> bool: def _type_exists(self, type_name: String, instantiate_link: bool) -> bool:
metamodel_root = self.state.read_dict(self.metamodel.id, "Model") metamodel_root = self.state.read_dict(self.metamodel.id, "Model")
type_element = self.state.read_dict(metamodel_root, type_name.value) type_element = self.state.read_dict(metamodel_root, type_name.value)
if type_element is None: if type_element is None:
return False return False
else: else:
element_is_edge = self.state.read_edge(type_element) is not None element_is_edge = self.state.read_edge(type_element) != (None, None)
return element_is_edge == instantiate_link return element_is_edge == instantiate_link
def instantiate(self, type_name: String, name: String): def instantiate(self, type_name: String, name: String):

View file

@ -1,4 +1,4 @@
from core.element import Element from core.element import Element, String, Integer, Boolean
from state.base import State from state.base import State
from core.context.generic import GenericContext from core.context.generic import GenericContext
@ -7,25 +7,26 @@ class SCDContext(GenericContext):
def __init__(self, state: State, model: Element, metamodel: Element): def __init__(self, state: State, model: Element, metamodel: Element):
super().__init__(state, model, metamodel) super().__init__(state, model, metamodel)
def exposed_methods(self):
yield from super().exposed_methods()
yield from [
self.create_class,
self.create_class_attribute,
self.create_association,
self.create_inheritance
]
def main(): def create_class(self, name: String, lower_cardinality: Integer = Element(), upper_cardinality: Integer = Element()):
from state.devstate import DevState pass
s = DevState() def create_class_attribute(self, class_name: String, name: String, optional: Boolean = Element(value=False)):
scd = SCDContext(s, Element(), Element()) pass
bootstrap = scd._bootstrap_scd()
model = s.read_dict(bootstrap.id, "Model")
x = []
for e in s.read_outgoing(model):
label_node_edge, = s.read_outgoing(e)
_, label_node = s.read_edge(label_node_edge)
type_node = s.read_dict(label_node, "Type")
x.append(f"{s.read_value(label_node)} : {s.read_value(type_node)}")
for t in sorted(x):
print(t)
# s.dump("out/scd.dot", "out/scd.png") def create_association(self, source_class_name: String, target_class_name: String, name: String,
source_lower_cardinality: Integer = Element(), target_lower_cardinality: Integer = Element(),
source_upper_cardinality: Integer = Element(), target_upper_cardinality: Integer = Element()
):
pass
def create_inheritance(self, parent_class_name: String, child_class_name: String):
if __name__ == '__main__': pass
main()

View file

@ -6,6 +6,16 @@ class Manager:
def __init__(self, state: State): def __init__(self, state: State):
self.state = state self.state = state
def exposed_methods(self):
yield from [
self.new_model,
self.get_model,
self.rename_model,
self.retype_model,
self.delete_model,
self.list_models,
]
def new_model(self, name: String, type_model_name: String) -> Element: def new_model(self, name: String, type_model_name: String) -> Element:
root = self.state.read_root() root = self.state.read_root()
mm_bottom = self.state.read_dict(root, type_model_name.value) mm_bottom = self.state.read_dict(root, type_model_name.value)

121
main.py Normal file
View file

@ -0,0 +1,121 @@
from core.element import Element
from core.manager import Manager
from core.context.bottom import BottomContext
from core.context.generic import GenericContext
from core.context import custom_contexts
from state.devstate import DevState
from bootstrap.simple_class_diagrams import bootstrap_scd
import inspect
from ast import literal_eval
import sys
import signal
signal.signal(signal.SIGINT, signal.default_int_handler)
def params(method):
annotations = {
"core.element.Element[str]": "String",
"core.element.Element[int]": "Integer",
"core.element.Element[float]": "Float",
"core.element.Element[bool]": "Boolean"
}
sign = inspect.signature(method)
for param in sign.parameters.values():
param_type = annotations.get(str(param.annotation), "Element")
if param.default is param.empty:
yield param.name, param_type
else:
yield param.name, param_type, param.default
def input_args(method):
args = []
for param_tuple in params(method):
if len(param_tuple) == 3:
param_name, param_type, param_default = param_tuple
arg = input(f"{param_type} {param_name} (default = {param_default.value})? ")
if arg == '':
arg = param_default.value
else:
param_name, param_type = param_tuple
while True:
arg = input(f"{param_type} {param_name}? ")
if arg == '':
print("This arguments is non-optional, please provide a value.")
else:
break
if arg is None:
arg = Element()
elif param_type in {"Boolean", "Integer", "Float"}:
arg = Element(value=literal_eval(arg))
else:
arg = Element(value=arg)
args.append(arg)
return args
def model_management_loop(manager: Manager):
try:
print("\nCurrently no model is loaded. Following model management operations are available:")
for m in manager.exposed_methods():
print(f"\t* {m.__name__}")
while True:
command = input("\nPlease enter a command: ")
try:
method = next(m for m in manager.exposed_methods() if m.__name__ == command)
user_args = input_args(method)
model = method(*user_args)
if model is not None and not model.is_none():
metamodel = Element(id=manager.state.read_dict(model.id, "Metamodel"))
modelling_loop(manager, model, metamodel)
break
except StopIteration:
print("Invalid command, please try again.")
except KeyboardInterrupt:
print("\nBye!")
sys.exit()
def modelling_loop(manager: Manager, model: Element, metamodel: Element):
model_name = manager.state.read_value(model.id)
metamodel_name = manager.state.read_value(metamodel.id)
if metamodel.is_none():
context = BottomContext(manager.state, model)
print(f"No metamodel found. Model {model_name} has been loaded in context Bottom.")
else:
context = custom_contexts.get(metamodel_name, GenericContext)(manager.state, model, metamodel)
print(type(context))
print(f"Model {model_name} has been loaded in context {metamodel_name}.")
print(f"To return to the model management interface press CTRL + C.")
print(f"The following operations are available in this context:")
for m in context.exposed_methods():
print(f"\t* {m.__name__}")
try:
while True:
command = input("\nPlease enter a command: ")
try:
method = next(m for m in context.exposed_methods() if m.__name__ == command)
user_args = input_args(method)
model = method(*user_args)
if model is not None and not model.is_none():
metamodel = Element(id=manager.state.read_dict(model.id, "Metamodel"))
modelling_loop(manager, model, metamodel)
break
except StopIteration:
print("Invalid command, please try again.")
except KeyboardInterrupt:
pass
if __name__ == '__main__':
state = DevState()
bootstrap_scd(state)
man = Manager(state)
print("Welcome to MV2!")
while True:
model_management_loop(man)