فهرست منبع

Try to lazily stay in the same model in between modify operations

Yentl Van Tendeloo 8 سال پیش
والد
کامیت
263cf37bf1
2فایلهای تغییر یافته به همراه157 افزوده شده و 269 حذف شده
  1. 0 5
      bootstrap/mini_modify.alc
  2. 157 264
      wrappers/modelverse.py

+ 0 - 5
bootstrap/mini_modify.alc

@@ -324,11 +324,6 @@ Element function modify(model : Element, write : Boolean):
 	String cmd
 
 	output("Model loaded, ready for commands!")
-	if (write):
-		output("Mode: r/w")
-	else:
-		output("Mode: r")
-	output("Use 'help' command for a list of possible commands")
 
 	while (True):
 		cmd = input()

+ 157 - 264
wrappers/modelverse.py

@@ -68,9 +68,29 @@ address = None
 last_output = None
 mode = MODE_UNCONNECTED
 prev_mode = None
+current_model = None
+
+def _goto_mode(new_mode, model_name=None):
+    global mode
+
+    if mode == MODE_MODELLING and new_mode == MODE_MODIFY:
+        # Are in root view, but want to modify a model
+        model_modify(model_name)
+    elif mode == MODE_MODIFY and new_mode == MODE_MODIFY and model_name != None and current_model != model_name:
+        # Are in modify mode, but want to modify a different model
+        model_exit()
+        model_modify(model_name)
+    elif mode == MODE_MODIFY and new_mode == MODE_MODELLING:
+        model_exit()
+    elif mode == new_mode:
+        return
+    else:
+        # Go to a mode that we have no automatic transfer to: raise exception
+        raise InvalidMode()
 
 def _input(value):
     # Ugly json encoding of primitives
+    print("[IN] %s" % value)
     if isinstance(value, type([])):
         value = json.dumps(value)
         urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": value, "taskname": taskname}))).read()
@@ -120,6 +140,7 @@ def _output(expected=None):
     try:
         global last_output
         last_output = json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "taskname": taskname}))).read())
+        print("[OUT] %s" % last_output)
     except:
         raise UnknownError()
     if expected is not None and last_output != expected:
@@ -187,8 +208,8 @@ def login(username, password):
     # raises PermissionDenied
     # raises InterfaceMismatch
     global mode
-    if mode != MODE_UNAUTHORIZED:
-        raise InvalidMode()
+    _goto_mode(MODE_UNAUTHORIZED)
+
     _output("Log on as which user?")
     _input(username)
     if _output() == "Password for existing user?":
@@ -226,9 +247,7 @@ def model_add(model_name, metamodel_name, model_code=None):
     # raises UnknownError
     # raises PermissionDenied
     # raises CompilationError
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     # Do this before creating the model, as otherwise compilation errors would make us inconsistent
     if model_code is not None:
@@ -246,16 +265,13 @@ def model_add(model_name, metamodel_name, model_code=None):
 
 def model_delete(model_name):
     """Delete an existing model."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["model_delete", model_name])
     _handle_output("Success")
 
 def model_modify(model_name):
     """Modify an existing model."""
-    # return is_write
     # raises UnknownModel
     # raises PermissionDenied
     # raises UnknownError
@@ -267,28 +283,22 @@ def model_modify(model_name):
         mode = MODE_MODIFY
         return None
 
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     prev_mode = MODE_MODELLING
 
     _input(["model_modify", model_name])
     _handle_output("Success")
+    global current_model
+    current_model = model_name
     # Mode has changed
     mode = MODE_MODIFY
     _output("Model loaded, ready for commands!")
-    if ("r/w" in _output()):
-        write = True
-    else:
-        write = False
-    _output("Use 'help' command for a list of possible commands")
-    return write
 
 def model_list():
     """List all models."""
     # return [(model1, metamodel1), (model2, metamodel2), ...]
     # raises UnknownError
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     _input("model_list")
     output = _handle_output("Success: ", split=" ")
     if output == "":
@@ -308,8 +318,7 @@ def model_list_full():
     """List full information on all models."""
     # return [(model1, metamodel1, owner1, group1, permissions1), (model2, metamodel2, owner2, group2, permissions2), ...]
     # raises UnknownError
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     _input("model_list_full")
     output = _handle_output("Success: ", split=" ")
     if output == "":
@@ -331,8 +340,7 @@ def verify(model):
     # return "verification_result"
     # raises UnknownError
     # raises UnknownModel
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     _input(["verify", model])
     return _handle_output("Success: ", split=" ")
 
@@ -370,8 +378,7 @@ def user_logout():
     # return None
     # raises UnknownError
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     _input("exit")
     mode = MODE_UNCONNECTED
 
@@ -380,8 +387,7 @@ def user_delete():
     # return None
     # raises UnknownError
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
     _input("self-destruct")
     mode = MODE_UNCONNECTED
 
@@ -391,17 +397,13 @@ def model_render(model, mapper):
     # raises UnknownError
     # raises UnknownIdentifier
     # raises InterfaceMismatch
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["model_render", model, mapper])
     return _handle_output("Success: ", split=" ")
 
 def transformation_between(source, target):
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["transformation_between", source, target])
     output = _handle_output("Success: ", split=" ")
@@ -411,18 +413,14 @@ def transformation_between(source, target):
 
 def transformation_add_MT_language(metamodels, RAMified_name):
     """Create a new Model Transformation language out of a set of metamodels."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["transformation_add_MT_language"] + metamodels + ["", RAMified_name])
     _handle_output("Success")
 
 def transformation_add_MT(RAMified_metamodel, source_metamodels, target_metamodels, operation_name, code):
     """Create a new model transformation."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     try:
         compiled = _compile_model(code)
@@ -436,9 +434,7 @@ def transformation_add_MT(RAMified_metamodel, source_metamodels, target_metamode
 
 def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code):
     """Create a new action language model, which can be executed."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     try:
         compiled = _compile_AL(code)
@@ -452,9 +448,7 @@ def transformation_add_AL(source_metamodels, target_metamodels, operation_name,
 
 def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name):
     """Create a new manual model operation."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["transformation_add_MANUAL"] + source_metamodels + [""] + target_metamodels + [""] + [operation_name])
     _handle_output("Success")
@@ -462,8 +456,7 @@ def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_na
 def transformation_execute_AL(operation_name, input_models_dict, output_models_dict, callback=lambda i: None):
     """Execute an existing model operation."""
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     mv_dict_rep = []
     for key, value in input_models_dict.items():
@@ -493,8 +486,7 @@ def transformation_execute_AL(operation_name, input_models_dict, output_models_d
 def transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=lambda i: None):
     """Execute an existing model operation."""
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     mv_dict_rep = []
     for key, value in input_models_dict.items():
@@ -529,8 +521,7 @@ def transformation_execute_MANUAL(operation_name, input_models_dict, output_mode
 def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, callback=lambda i: None):
     """Execute an existing model operation."""
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     mv_dict_rep = []
     for key, value in input_models_dict.items():
@@ -559,9 +550,7 @@ def transformation_execute_MT(operation_name, input_models_dict, output_models_d
 
 def transformation_list():
     """List existing model operations."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input("transformation_list")
     output = _handle_output("Success: ", split=" ")
@@ -578,15 +567,9 @@ def transformation_list():
 
     return lst
 
-def transformation_detail():
-    """List full details of a a model operation."""
-    raise NotImplementedError()
-
 def transformation_RAMify(metamodel_name, RAMified_metamodel_name):
     """Ramify an existing metamodel."""
-    global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["transformation_RAMify", metamodel_name, RAMified_metamodel_name])
     _handle_output("Success")
@@ -594,8 +577,7 @@ def transformation_RAMify(metamodel_name, RAMified_metamodel_name):
 def process_execute(process_name, prefix, callbacks):
     """Execute a process model."""
     global mode
-    if mode != MODE_MODELLING:
-        raise InvalidMode()
+    _goto_mode(MODE_MODELLING)
 
     _input(["process_execute", process_name, prefix])
     _handle_output("Success")
@@ -678,141 +660,106 @@ def element_list(model_name):
     """Return a list of all IDs and the type of the element"""
     # return [(name1, type1), (name2, type2), ...]
     # raises UnknownError
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input("list_full")
-        lst = set([])
-        output = _handle_output("Success: ", split=" ")
-        if output == "":
-            return set([])
-        for v in output.split("\n"):
-            m, mm = v.split(":")
-            m = m.strip()
-            mm = mm.strip()
-            lst.add((m, mm))
-        return lst
-
-    finally:
-        model_exit()
+    _input("list_full")
+    lst = set([])
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
+        m, mm = v.split(":")
+        m = m.strip()
+        mm = mm.strip()
+        lst.add((m, mm))
+    return lst
 
 def types(model_name):
     """Return a list of all types usable in the model"""
     # return [type1, type2, ...]
     # raises UnknownError
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input("types")
-        lst = set([])
-        output = _handle_output("Success: ", split=" ")
-        if output == "":
-            return set([])
-        for v in output.split("\n"):
-            m, mm = v.split(":")
-            m = m.strip()
-            lst.add(m)
-        return lst
-
-    finally:
-        model_exit()
+    _input("types")
+    lst = set([])
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
+        m, mm = v.split(":")
+        m = m.strip()
+        lst.add(m)
+    return lst
 
 def types_full(model_name):
     """Return a list of full types usable in the model"""
     # return [(type1, typetype1), (type2, typetype2), ...]
     # raises UnknownError
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input("types")
-        lst = set([])
-        output = _handle_output("Success: ", split=" ")
-        if output == "":
-            return set([])
-        for v in output.split("\n"):
-            m, mm = v.split(":")
-            m = m.strip()
-            mm = mm.strip()
-            lst.add((m, mm))
-        return lst
-
-    finally:
-        model_exit()
+    _input("types")
+    lst = set([])
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
+        m, mm = v.split(":")
+        m = m.strip()
+        mm = mm.strip()
+        lst.add((m, mm))
+    return lst
 
 def read(model_name, ID):
     """Return a tuple of information on the element: its type and source/target (None if not an edge)"""
     # return (type, (source, target))
     # raises UnknownError
     # raises UnknownIdentifier
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input(["read", ID])
-        output = _handle_output("Success: ", split=" ")
-        v = output.split("\n")
-        t = v[1].split(":")[1].strip()
-        if (not v[0].startswith("Source:")):
-            rval = (t, None)
-        else:
-            src = v[0].split(":")[1].strip()
-            trg = v[1].split(":")[1].strip()
-            rval = (t, (src, trg))
-        return rval
-
-    finally:
-        model_exit()
+    _input(["read", ID])
+    output = _handle_output("Success: ", split=" ")
+    v = output.split("\n")
+    t = v[1].split(":")[1].strip()
+    if (not v[0].startswith("Source:")):
+        rval = (t, None)
+    else:
+        src = v[0].split(":")[1].strip()
+        trg = v[1].split(":")[1].strip()
+        rval = (t, (src, trg))
+    return rval
 
 def read_attrs(model_name, ID):
     """Return a dictionary of attribute value pairs"""
     # return {attr1: value1, attr2: value2, ...}
     # raises UnknownError
     # raises UnknownIdentifier
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input(["read", ID])
-        output = _handle_output("Success: ", split=" ")
-        v = output.split("\n")
-        searching = True
-        rval = {}
-        for r in v:
-            if searching:
-                if r == "Attributes:":
-                    # Start working on attributes
-                    searching = False
+    _input(["read", ID])
+    output = _handle_output("Success: ", split=" ")
+    v = output.split("\n")
+    searching = True
+    rval = {}
+    for r in v:
+        if searching:
+            if r == "Attributes:":
+                # Start working on attributes
+                searching = False
+        else:
+            key, value = r.split(":", 1)
+            _, value = value.split("=", 1)
+            key = json.loads(key.strip())
+            value = value.strip()
+            if value == "None":
+                value = None
+            elif value == "True":
+                value = True
+            elif value == "False":
+                value = False
             else:
-                key, value = r.split(":", 1)
-                _, value = value.split("=", 1)
-                key = json.loads(key.strip())
-                value = value.strip()
-                if value == "None":
-                    value = None
-                elif value == "True":
-                    value = True
-                elif value == "False":
-                    value = False
-                else:
-                    value = json.loads(value)
-                rval[key] = value
-        return rval
-
-    finally:
-        model_exit()
+                value = json.loads(value)
+            rval[key] = value
+    return rval
 
 def instantiate(model_name, typename, edge=None, ID=""):
     """Create a new instance of the specified typename, between the selected elements (if not None), and with the provided ID (if any)"""
@@ -821,35 +768,23 @@ def instantiate(model_name, typename, edge=None, ID=""):
     # raises UnknownType
     # raises UnknownIdentifier
     # raises NotAnEdge
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        if edge is None:
-            _input(["instantiate_node", typename, ID])
-        else:
-            _input(["instantiate_edge", typename, ID, edge[0], edge[1]])
-        return _handle_output("Success: ", split=" ")
-    finally:
-        model_exit()
+    if edge is None:
+        _input(["instantiate_node", typename, ID])
+    else:
+        _input(["instantiate_edge", typename, ID, edge[0], edge[1]])
+    return _handle_output("Success: ", split=" ")
 
 def delete_element(model_name, ID):
     """Delete the element with the given ID"""
     # return None
     # raises UnknownError
     # raises UnknownIdentifier
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input(["delete", ID])
-        _handle_output("Success")
-    finally:
-        model_exit()
+    _input(["delete", ID])
+    _handle_output("Success")
 
 def attr_assign(model_name, ID, attr, value):
     """Assign a value to an attribute"""
@@ -858,16 +793,10 @@ def attr_assign(model_name, ID, attr, value):
     # raises UnknownIdentifier
     # raises NoSuchAttribute
     # raises UnsupportedValue
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input(["attr_add", ID, attr, value])
-        _handle_output("Success")
-    finally:
-        model_exit()
+    _input(["attr_add", ID, attr, value])
+    _handle_output("Success")
 
 def attr_assign_code(model_name, ID, attr, code):
     """Assign a piece of Action Language code to the attribute"""
@@ -881,51 +810,33 @@ def attr_assign_code(model_name, ID, attr, code):
     except Exception as e:
         raise CompilationError(e)
 
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input(["attr_add", ID, attr])
-        _handle_output("Waiting for code constructors...")
-        _input(compiled)
-        _output("Success")
-    finally:
-        model_exit()
+    _input(["attr_add", ID, attr])
+    _handle_output("Waiting for code constructors...")
+    _input(compiled)
+    _output("Success")
 
 def attr_delete(model_name, ID, attr):
     """Remove an attribute."""
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input(["attr_del", ID, attr])
-        _handle_output("Success")
-    finally:
-        model_exit()
+    _input(["attr_del", ID, attr])
+    _handle_output("Success")
 
 def read_outgoing(model_name, ID, typename):
     """Returns a list of all outgoing associations of a specific type ("" = all)"""
     # return [name1, name2, ...]
     # raises UnknownError
     # raises UnknownIdentifier
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input(["read_outgoing", ID, typename])
-        output = _handle_output("Success: ", split=" ")
-        if output == "":
-            return set([])
-        else:
-            return set(output.split("\n"))
-    finally:
-        model_exit()
+    _input(["read_outgoing", ID, typename])
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 def read_incoming(model_name, ID, typename):
     """Returns a list of all incoming associations of a specific type ("" = all)"""
@@ -933,20 +844,14 @@ def read_incoming(model_name, ID, typename):
     # raises UnknownError
     # raises UnknownIdentifier
     # raises UnknownType
-    model_modify(model_name)
+    _goto_mode(MODE_MODIFY, model_name)
 
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
-
-    try:
-        _input(["read_incoming", ID, typename])
-        output = _handle_output("Success: ", split=" ")
-        if output == "":
-            return set([])
-        else:
-            return set(output.split("\n"))
-    finally:
-        model_exit()
+    _input(["read_incoming", ID, typename])
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 def read_association_source(model_name, ID):
     """Returns the source of an association."""
@@ -954,16 +859,10 @@ def read_association_source(model_name, ID):
     # raises UnknownError
     # raises UnknownIdentifier
     # raises NotAnAssociation
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input(["read_association_source", ID])
-        return _handle_output("Success: ", split=" ")
-    finally:
-        model_exit()
+    _input(["read_association_source", ID])
+    return _handle_output("Success: ", split=" ")
 
 def read_association_destination(model_name, ID):
     """Returns the destination of an association."""
@@ -971,16 +870,10 @@ def read_association_destination(model_name, ID):
     # raises UnknownError
     # raises UnknownIdentifier
     # raises NotAnAssociation
-    model_modify(model_name)
-
-    if mode != MODE_MODIFY:
-        raise InvalidMode()
+    _goto_mode(MODE_MODIFY, model_name)
 
-    try:
-        _input(["read_association_destination", ID])
-        return _handle_output("Success: ", split=" ")
-    finally:
-        model_exit()
+    _input(["read_association_destination", ID])
+    return _handle_output("Success: ", split=" ")
 
 def model_exit():
     """Leave model modify mode."""