소스 검색

Allow manual activities with empty activity signature to be executed

Yentl Van Tendeloo 7 년 전
부모
커밋
81aadde81f
4개의 변경된 파일78개의 추가작업 그리고 29개의 파일을 삭제
  1. 23 26
      bootstrap/core_algorithm.alc
  2. 36 1
      unit/test_all.py
  3. 6 0
      wrappers/classes/modelverse.xml
  4. 13 2
      wrappers/modelverse_SCCD.py

+ 23 - 26
bootstrap/core_algorithm.alc

@@ -620,7 +620,6 @@ Element function execute_operation(operation_id : String, input_models : Element
 				cmd_model_add(input_metamodels[key], input_models[key], "")
 			mm = get_full_model(get_entry_id(input_models[key]), get_entry_id(input_metamodels[key]))
 			if (element_eq(mm, read_root())):
-				log("Signature mismatch in operation for tag " + key)
 				output("Signature mismatch in operation for tag " + key)
 				return read_root()!
 			set_add_node(model_tuples, create_tuple(key, mm))
@@ -628,7 +627,6 @@ Element function execute_operation(operation_id : String, input_models : Element
 		Element merged_metamodel
 		merged_metamodel = get_full_model(merged_metamodel_id, get_entry_id("formalisms/SimpleClassDiagrams"))
 		if (element_eq(merged_metamodel, read_root())):
-			log("Merged metamodel in operation is not of type formalisms/SimpleClassDiagrams")
 			output("Type cannot be typed as formalisms/SimpleClassDiagrams: 'merged'")
 			return read_root()!
 
@@ -639,14 +637,12 @@ Element function execute_operation(operation_id : String, input_models : Element
 			Element m
 			m = get_full_model(get_entry_id(input_models[set_pop(dict_keys(input_models))]), get_entry_id(input_metamodels[set_pop(dict_keys(input_metamodels))]))
 			if (element_eq(m, read_root())):
-				log("Signature mismatch in operation for tag " + cast_value(set_pop(dict_keys(input_models))))
 				output("Signature mismatch in operation for tag " + cast_value(set_pop(dict_keys(input_models))))
 				return read_root()!
 			merged_model = model_copy(m)
 		elif (bool_and(dict_len(input_models) == 0, dict_len(output_metamodels) == 0)):
 			merged_model = read_root()
 		else:
-			log("Could not resolve intermediate merged metamodel")
 			output("Could not resolve intermediate merged metamodel")
 			return read_root()!
 
@@ -663,34 +659,35 @@ Element function execute_operation(operation_id : String, input_models : Element
 		Element operation
 		operation = get_full_model(operation_id, ramified_metamodel_id)
 		if (element_eq(operation, read_root())):
-			log("Operation could not be typed by specified RAMified metamodel!")
 			output("Operation could not be typed by specified RAMified metamodel!")
 			return read_root()!
 		result = transform(merged_model, operation)
 	elif (exact_type == "ManualOperation"):
 		output("Please perform manual operation " + cast_value(full_name(operation_id)))
-		String model_name
-		model_name = ""
-		while (get_entry_id(model_name) != ""):
-			model_name = "tmp/" + random_string(20)
-		model_create(merged_model, model_name, merged_metamodel_id, "Model")
-		// We want to modify, so modify
-		do_spawn_modify(model_name, True)
-		merged_model = get_full_model(get_entry_id(model_name), merged_metamodel_id)
-		//model_delete(get_entry_id(model_name))
-		result = True
+		if (element_neq(merged_model, read_root())):
+			String model_name
+			model_name = ""
+			while (get_entry_id(model_name) != ""):
+				model_name = "tmp/" + random_string(20)
+			model_create(merged_model, model_name, merged_metamodel_id, "Model")
+			// We want to modify, so modify
+			do_spawn_modify(model_name, True)
+			merged_model = get_full_model(get_entry_id(model_name), merged_metamodel_id)
+			//model_delete(get_entry_id(model_name))
+			result = True
+		else:
+			output("Nothing to modify")
+			return True!
 	elif (exact_type == "ActionLanguage"):
 		Element func
 		Element al
 		al = get_full_model(operation_id, get_entry_id("formalisms/ActionLanguage"))
 		if (element_eq(al, read_root())):
-			log("Action Language operation not typed by ActionLanguage metamodel!")
 			output("Action Language operation not typed by ActionLanguage metamodel!")
 			return read_root()!
 		func = get_func_AL_model(al)
 		result = func(merged_model)
 	else:
-		log("Unknown type of operation: " + exact_type)
 		output("Unknown type of operation: " + exact_type)
 		return read_root()!
 
@@ -709,7 +706,6 @@ Element function execute_operation(operation_id : String, input_models : Element
 			Element mm
 			mm = get_full_model(get_entry_id(output_metamodels[key]), get_entry_id("formalisms/SimpleClassDiagrams"))
 			if (element_eq(mm, read_root())):
-				log("Output metamodel cannot be interpreted using formalisms/SimpleClassDiagrams: " + key)
 				output("Type cannot be typed as formalisms/SimpleClassDiagrams: " + key)
 				return read_root()!
 			set_add_node(model_tuples, create_tuple(key, mm))
@@ -726,7 +722,6 @@ Element function execute_operation(operation_id : String, input_models : Element
 
 		return result!
 	else:
-		log("Negative result of execution")
 		return read_root()!
 
 Boolean function enact_action(pm : Element, element : String, mapping : Element):
@@ -1915,17 +1910,15 @@ String function cmd_transformation_add_MT(source_models : Element, target_models
 		if (model_id != ""):
 			if (allow_read(current_user_id, model_id)):
 				// Check whether or not it is formalisms/SimpleClassDiagrams
-				if (is_typed_by(model_id, get_entry_id("formalisms/SimpleClassDiagrams"))):
+				mm = get_full_model(model_id, get_entry_id("formalisms/SimpleClassDiagrams"))
+				if (element_neq(mm, read_root())):
 					if (bool_not(dict_in(source, key))):
 						dict_add(source, key, model_id)
-						mm = get_full_model(model_id, get_entry_id("formalisms/SimpleClassDiagrams"))
-						if (element_eq(mm, read_root())):
-							return "Type cannot be typed as formalisms/SimpleClassDiagrams: " + name!
 						set_add_node(to_ramify, create_tuple(key, mm))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
-					return "Model not supported for RAMification: " + name!
+					return "Type cannot be typed as formalisms/SimpleClassDiagrams: " + name!
 			else:
 				return "Read permission denied to: " + name!
 		else:
@@ -1938,7 +1931,8 @@ String function cmd_transformation_add_MT(source_models : Element, target_models
 		model_id = get_entry_id(name)
 		if (model_id != ""):
 			if (allow_read(current_user_id, model_id)):
-				if (is_typed_by(model_id, get_entry_id("formalisms/SimpleClassDiagrams"))):
+				mm = get_full_model(model_id, get_entry_id("formalisms/SimpleClassDiagrams"))
+				if (element_neq(mm, read_root())):
 					if (bool_not(dict_in(target, key))):
 						if (dict_in(source, key)):
 							if (value_eq(model_id, source[key])):
@@ -1946,10 +1940,13 @@ String function cmd_transformation_add_MT(source_models : Element, target_models
 								// Don't add to to_ramify, as it is already in there!
 							else:
 								return "Input and output signature differ for same key: " + key!
+						else:
+							dict_add(target, key, model_id)
+							set_add_node(to_ramify, create_tuple(key, mm))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
-					return "Model not supported for RAMification: " + name!
+					return "Type cannot be typed as formalisms/SimpleClassDiagrams: " + name!
 			else:
 				return "Read permission denied to: " + name!
 		else:

+ 36 - 1
unit/test_all.py

@@ -4175,10 +4175,45 @@ class TestModelverse(unittest.TestCase):
         # Try to create activity that already exists
         sig = transformation_signature("users/user/test/c")
         try:
-            transformation_add_MT({}, {}, "users/user/test/c", default_function)
+            transformation_add_MT({"MODEL_A": "users/user/test/A"}, {}, "users/user/test/c", default_function)
+            self.fail()
         except ModelExists:
             assert sig == transformation_signature("users/user/test/c")
 
+        # Compilation error
+        try:
+            transformation_add_MT({"MODEL_A": "users/user/test/A"}, {}, "users/user/test/o", "adfa")
+            self.fail()
+        except CompilationError:
+            pass
+
+    def test_op_transformation_execute_MANUAL(self):
+        # Add models for transformation
+        model_add("users/user/test/A", "formalisms/SimpleClassDiagrams", """
+            SimpleAttribute String {}
+            Class A {
+                name = "A"
+                name : String
+            }
+            """)
+        model_add("users/user/test/B", "formalisms/SimpleClassDiagrams", """
+            SimpleAttribute String {}
+            Class B {
+                name = "B"
+                name : String
+            }
+            """)
+        model_add("users/user/test/a", "users/user/test/A", "A {}")
+        model_add("users/user/test/b", "users/user/test/B", "B {}")
+
+        # Add some activity to execute
+        transformation_add_MANUAL({}, {}, "users/user/test/c")
+
+        def operation(model):
+            print("Executing")
+
+        transformation_execute_MANUAL("users/user/test/c", {}, {}, operation)
+
     """
     def test_op_model_render(self):
     def test_op_transformation_execute_MT(self):

+ 6 - 0
wrappers/classes/modelverse.xml

@@ -1680,6 +1680,12 @@
                                     </raise>
                                 </transition>
 
+                                <transition cond="self.expect_response_partial('Nothing to modify', pop=True)" target=".">
+                                    <raise event="result">
+                                        <parameter expr="None"/>
+                                    </raise>
+                                </transition>
+
                                 <transition cond="self.inputs" target="../../../history">
                                     <script>
                                         self.inputs.pop(0)

+ 13 - 2
wrappers/modelverse_SCCD.py

@@ -1410,11 +1410,16 @@ class Modelverse(RuntimeClassBase):
         _initialized_behaviour_wait_for_action_activity_OP_forwarding_1.setTrigger(None)
         _initialized_behaviour_wait_for_action_activity_OP_forwarding_1.setGuard(self._initialized_behaviour_wait_for_action_activity_OP_forwarding_1_guard)
         self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"].addTransition(_initialized_behaviour_wait_for_action_activity_OP_forwarding_1)
-        _initialized_behaviour_wait_for_action_activity_OP_forwarding_2 = Transition(self, self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"], [self.states["/initialized/behaviour/wait_for_action/history"]])
+        _initialized_behaviour_wait_for_action_activity_OP_forwarding_2 = Transition(self, self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"], [self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"]])
         _initialized_behaviour_wait_for_action_activity_OP_forwarding_2.setAction(self._initialized_behaviour_wait_for_action_activity_OP_forwarding_2_exec)
         _initialized_behaviour_wait_for_action_activity_OP_forwarding_2.setTrigger(None)
         _initialized_behaviour_wait_for_action_activity_OP_forwarding_2.setGuard(self._initialized_behaviour_wait_for_action_activity_OP_forwarding_2_guard)
         self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"].addTransition(_initialized_behaviour_wait_for_action_activity_OP_forwarding_2)
+        _initialized_behaviour_wait_for_action_activity_OP_forwarding_3 = Transition(self, self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"], [self.states["/initialized/behaviour/wait_for_action/history"]])
+        _initialized_behaviour_wait_for_action_activity_OP_forwarding_3.setAction(self._initialized_behaviour_wait_for_action_activity_OP_forwarding_3_exec)
+        _initialized_behaviour_wait_for_action_activity_OP_forwarding_3.setTrigger(None)
+        _initialized_behaviour_wait_for_action_activity_OP_forwarding_3.setGuard(self._initialized_behaviour_wait_for_action_activity_OP_forwarding_3_guard)
+        self.states["/initialized/behaviour/wait_for_action/activity/OP/forwarding"].addTransition(_initialized_behaviour_wait_for_action_activity_OP_forwarding_3)
         
         # transition /initialized/behaviour/wait_for_action/megamodelling
         _initialized_behaviour_wait_for_action_megamodelling_0 = Transition(self, self.states["/initialized/behaviour/wait_for_action/megamodelling"], [self.states["/initialized/behaviour/operations/model_list"]])
@@ -3333,10 +3338,16 @@ class Modelverse(RuntimeClassBase):
         return self.expect_response_partial('Please edit this model before sending next input: ', pop=False)
     
     def _initialized_behaviour_wait_for_action_activity_OP_forwarding_2_exec(self, parameters):
+        self.raiseInternalEvent(Event("result", None, [None]))
+    
+    def _initialized_behaviour_wait_for_action_activity_OP_forwarding_2_guard(self, parameters):
+        return self.expect_response_partial('Nothing to modify', pop=True)
+    
+    def _initialized_behaviour_wait_for_action_activity_OP_forwarding_3_exec(self, parameters):
         self.inputs.pop(0)
         self.raiseInternalEvent(Event("request", None, [0]))
     
-    def _initialized_behaviour_wait_for_action_activity_OP_forwarding_2_guard(self, parameters):
+    def _initialized_behaviour_wait_for_action_activity_OP_forwarding_3_guard(self, parameters):
         return self.inputs
     
     def _initialized_behaviour_wait_for_action_megamodelling_0_exec(self, parameters):