Browse Source

Commiting a version where basic flows without artifacts can be enacted.

Lucas Albertins 2 years ago
parent
commit
fac0129d73

+ 60 - 12
src/main/java/ua/be/wee/controller/EnactementControllerMVC.java

@@ -20,7 +20,11 @@ import org.springframework.web.bind.annotation.RequestParam;
 import ua.be.wee.model.EnactmentController;
 import ua.be.wee.model.nodes.Activity;
 import ua.be.wee.model.nodes.Artifact;
+import ua.be.wee.model.nodes.FinalNode;
+import ua.be.wee.model.nodes.Node;
+import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.pm.PM;
+import ua.be.wee.model.pt.Event;
 import ua.be.wee.model.pt.PT;
 import ua.be.wee.model.repository.FusekiWrapper;
 
@@ -47,6 +51,8 @@ public class EnactementControllerMVC {
 		if (!env.getProperty("endpoint").equals("")) {
 			model.addAttribute("savedEndpoint", env.getProperty("endpoint"));
 			model.addAttribute("hasEndpoint", true);
+		} else {
+			model.addAttribute("hasEndpoint", false);
 		}
         return "index";
     }
@@ -74,13 +80,19 @@ public class EnactementControllerMVC {
 		} else {
 			PM pm = controller.getPM(pmiri);			
 			PT trace = controller.createTrace(pm);
-			List<Activity> acts = controller.findFirstActivity(pm);
+			List<String> iris = controller.findNextNodes(pm.getInitial().getIri());
+			List<Node> acts = new ArrayList<Node>();
+			for (String iri : iris) {
+				acts.add(pm.getNode(iri));
+			}
 			model.addAttribute("error", false);
 			request.getSession().setAttribute("pm", pm);
 			request.getSession().setAttribute("trace", trace);
+			request.getSession().setAttribute("previous", pm.getInitial().getIri());
 			model.addAttribute("acts",acts);
 			model.addAttribute("arts", null);
 			model.addAttribute("current", "1");
+			model.addAttribute("hidden_iri",pm.getInitial().getIri());
 	        return "enact";
 		}
     }
@@ -89,12 +101,24 @@ public class EnactementControllerMVC {
     public String startActivity(Model model, @RequestParam String activity, HttpServletRequest request) throws Exception {
     	PM pm = (PM)request.getSession().getAttribute("pm");
     	PT pt = (PT)request.getSession().getAttribute("trace");
-    	Activity act = (Activity)pm.getNode(activity);
-    	List<Artifact> arts = new ArrayList<>();
-    	controller.addStartEvent(pm,pt,act,arts);
-    	//request.getSession().setAttribute("trace", pt);
-    	model.addAttribute("act",act);
-    	return "enactEnd";
+    	Node node = pm.getNode(activity);
+    	if (node instanceof Activity) {
+    		List<Artifact> arts = new ArrayList<>();
+        	controller.addStartEvent(pt,(Activity)node,arts);
+        	//request.getSession().setAttribute("trace", pt);
+        	model.addAttribute("act",node);
+        	return "enactEnd";
+		} else if (node instanceof FinalNode) {
+			String previous = (String)request.getSession().getAttribute("previous");
+			Event endTraceEvent = controller.addEndTraceEvent(pt.getIri(), previous, pm.getIri());
+			pt.addEvent(endTraceEvent);
+			controller.updatePT(pt);
+			return "endEnactment";
+		} else {
+			return "error";
+		}
+    	
+    	
     }
     
     @PostMapping("/endAct")
@@ -102,10 +126,24 @@ public class EnactementControllerMVC {
     	PM pm = (PM)request.getSession().getAttribute("pm");
     	PT pt = (PT)request.getSession().getAttribute("trace");
     	Activity act = (Activity)pm.getNode(activity);
+    	List<ControlOutputPort> ctrlOutPorts = act.getCtrlOutPorts();
+    	ControlOutputPort p = null;
+    	for (ControlOutputPort out : ctrlOutPorts) {
+    		if (out.getIri().equals(port)) {
+				p = out;
+				break;
+			}
+		}
+    	List<String> iris = controller.findNextNodes(p.getIri());
+		List<Node> acts = new ArrayList<Node>();
+		for (String iri : iris) {
+			acts.add(pm.getNode(iri));
+		}
     	List<Artifact> arts = new ArrayList<>();
-    	controller.addEndEvent(pm,pt,act,arts);
+    	
+    	controller.addEndEvent(pt,act,arts,p);
     	request.getSession().setAttribute("trace", pt);
-    	List<Activity> acts = controller.findNextActivity(pm,act);
+    	request.getSession().setAttribute("previous", p.getIri());
     	model.addAttribute("acts",acts);
 		model.addAttribute("arts", null);
 		model.addAttribute("current", "1");
@@ -115,13 +153,23 @@ public class EnactementControllerMVC {
     @RequestMapping("/inarts")
     public String selectActivity(Model model, @RequestParam String iri, HttpServletRequest request) throws Exception {
     	PM pm = (PM)request.getSession().getAttribute("pm");
+    	String previous = (String)request.getSession().getAttribute("previous");
     	if (!iri.equals("1")) {
-        	Activity act = (Activity)pm.getNode(iri);
-        	model.addAttribute("arts", act.getInputs() == null ? (new ArrayList<Artifact>()) : act.getInputs());
+        	if (pm.getNode(iri) instanceof Activity) {
+        		Activity act = (Activity)pm.getNode(iri);
+            	model.addAttribute("arts", act.getInputs() == null ? (new ArrayList<Artifact>()) : act.getInputs());
+			} else { 
+				model.addAttribute("endBool", true);
+			}
+        	
 		} else {
 			model.addAttribute("arts", null);
 		}
-    	List<Activity> acts = controller.findFirstActivity(pm);
+    	List<String> iris = controller.findNextNodes(previous);
+		List<Node> acts = new ArrayList<Node>();
+		for (String iric : iris) {
+			acts.add(pm.getNode(iric));
+		}
     	model.addAttribute("acts",acts);
     	model.addAttribute("current", iri);
     	return "enact";

+ 17 - 9
src/main/java/ua/be/wee/model/EnactmentController.java

@@ -8,8 +8,10 @@ import org.springframework.stereotype.Component;
 import ua.be.wee.model.nodes.Activity;
 import ua.be.wee.model.nodes.Artifact;
 import ua.be.wee.model.nodes.NodeRespository;
+import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.pm.PM;
 import ua.be.wee.model.pm.PMRepository;
+import ua.be.wee.model.pt.Event;
 import ua.be.wee.model.pt.PT;
 import ua.be.wee.model.pt.PTRepository;
 
@@ -35,25 +37,31 @@ public class EnactmentController {
 		return pm;
 	}
 
-	public List<Activity> findFirstActivity(PM pm) {
-		return pmRepo.findFirstActivity(pm);
+	public List<String> findNextNodes(String initialNode) {
+		return pmRepo.findNextNodes(initialNode); 
 	}
 
 	public PT createTrace(PM pm) throws Exception {
 		return traceRepo.createTrace(pm);
 	}
 
-	public void addStartEvent(PM pm, PT pt, Activity act, List<Artifact> arts) throws Exception {
-		traceRepo.createStartEvent(pm,pt,act,arts);
+	public void addStartEvent(PT pt, Activity act, List<Artifact> arts) throws Exception {
+		traceRepo.createStartEvent(pt,act,arts);
 	}
 
-	public void addEndEvent(PM pm, PT pt, Activity act, List<Artifact> arts) {
-		// TODO Auto-generated method stub
+	public void addEndEvent(PT pt, Activity act, List<Artifact> arts, ControlOutputPort p) throws Exception {
+		traceRepo.createEndEvent(pt,act,arts,p);
 		
 	}
 
-	public List<Activity> findNextActivity(PM pm, Activity act) {
-		// TODO Auto-generated method stub
-		return null;
+	public Event addEndTraceEvent(String iri, String previous, String pmIRI) throws Exception {
+		return traceRepo.createEndTraceEvent(iri,previous, pmIRI);
+		
 	}
+
+	public void updatePT(PT pt) throws Exception {
+		traceRepo.updatePT(pt);
+		
+	}
+
 }

+ 4 - 0
src/main/java/ua/be/wee/model/nodes/FinalNode.java

@@ -11,5 +11,9 @@ public class FinalNode extends Node {
 	public void setPrevious(Node previous) {
 		this.previous = previous;
 	}
+	
+	public String getName() {
+		return "END TRACE";
+	}
 
 }

+ 2 - 0
src/main/java/ua/be/wee/model/nodes/Node.java

@@ -14,6 +14,8 @@ public abstract class Node implements NamedElement {
 	public static final String FINAL_IRI = "http://ua.be/sdo2l/vocabulary/formalisms/pm#Final";
 	public static final String FORKJOIN_IRI = "http://ua.be/sdo2l/vocabulary/formalisms/pm#ForkJoin";
 	public static final String ARTIFACT_IRI = "http://ua.be/sdo2l/vocabulary/formalisms/pm#Artifact";
+	public static final String CTRL_INPUT_PORT_IRI = "http://ua.be/sdo2l/vocabulary/formalisms/pm#CtrlInputPort";
+	public static final String CTRL_OUTPUT_PORT_IRI = "http://ua.be/sdo2l/vocabulary/formalisms/pm#CtrlOutputPort";
 		
 	@Id
 	private String iri;

+ 21 - 13
src/main/java/ua/be/wee/model/pm/PMRepository.java

@@ -9,6 +9,8 @@ import org.apache.jena.rdf.model.RDFNode;
 import org.springframework.stereotype.Component;
 
 import ua.be.wee.model.nodes.Activity;
+import ua.be.wee.model.nodes.Node;
+import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.repository.FusekiWrapper;
 
 @Component
@@ -55,27 +57,33 @@ public class PMRepository {
 		return pm;
 	}
 
-	public List<Activity> findFirstActivity(PM pm) {
-		List<Activity> list = new ArrayList<Activity>();
+	public List<String> findNextNodes(String iri) {
+		List<String> list = new ArrayList<String>();
 		String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
 				+ "PREFIX pm: <http://ua.be/sdo2l/vocabulary/formalisms/pm#>\n"
-				+ "SELECT ?act WHERE {\n"
-				+ "  ?node owl:sameAs <" + pm.getInitial().getIri() + "> .\n"
+				+ "SELECT ?e ?nodetype ?act WHERE {\n"
+				+ "  ?node owl:sameAs <" + iri + "> .\n"
 				+ "  ?node pm:ctrlTo+ ?e .\n"
-				+ "  ?e a pm:CtrlInputPort ;\n"
-				+ "		pm:ofActivity ?act .\n"
+				+ "  ?e a ?nodetype ;\n"
+				+ "  FILTER (?nodetype in (pm:CtrlInputPort, pm:Final)) \n"
+				+ "	 OPTIONAL {\n"
+				+ "		?e pm:ofActivity ?act .\n"
+				+ "	 }\n"
 				+ "}";
 		ResultSet results = FusekiWrapper.getInstance().execQuery(query);
 		while (results.hasNext()) {
 			QuerySolution soln = results.nextSolution();
-			RDFNode iri = soln.get("?act");
-			list.add((Activity)pm.getNode(iri.toString()));
+			RDFNode type = soln.get("?nodetype");
+			RDFNode iriRDF;
+			if (type.toString().equals(Node.CTRL_INPUT_PORT_IRI)) {
+				iriRDF = soln.get("?act");
+			} else {
+				iriRDF = soln.get("?e");
+			}
+			list.add(iriRDF.toString());
+			
 		}
-		
 		return list;
-	}
-
-	
-	
+	}	
 	
 }

+ 16 - 0
src/main/java/ua/be/wee/model/pt/EndTraceEvent.java

@@ -1,6 +1,22 @@
 package ua.be.wee.model.pt;
 
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+
 public class EndTraceEvent extends Event {
 	
+	private Timestamp timestamp;
+	
+	public Timestamp getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(Timestamp timestamp) {
+		this.timestamp = timestamp;
+	}
+	
+	public String getTimestampF() {
+		return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(timestamp);
+	}
 
 }

+ 69 - 15
src/main/java/ua/be/wee/model/pt/PTRepository.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
 
 import ua.be.wee.model.nodes.Activity;
 import ua.be.wee.model.nodes.Artifact;
+import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.pm.PM;
 import ua.be.wee.model.repository.FusekiWrapper;
 
@@ -56,14 +57,14 @@ public class PTRepository {
 		return index;
 	}
 
-	public void createStartEvent(PM pm, PT pt, Activity act, List<Artifact> arts) throws Exception {
-		String iri = pt.getIri().replace('#', '/') + "#" + "start_activity" + 
-				(pt.getLastEvent() != null ? pt.getLastEvent().getIri().charAt(pt.getLastEvent().getIri().length()-1) : "0");
-		String endiri = pt.getIri().replace('#', '/') + "#" + "end_activity" + 
-				(pt.getLastEvent() != null ? pt.getLastEvent().getIri().charAt(pt.getLastEvent().getIri().length()-1) : "0");
+	public void createStartEvent(PT pt, Activity act, List<Artifact> arts) throws Exception {
+		int index = pt.getLastEvent() == null ? 0 : (Integer.parseInt(""+pt.getLastEvent().getIri().charAt(pt.getLastEvent().getIri().length()-1))+1); 
+
+		String iri = pt.getIri().replace('#', '/') + "#" + "start_activity" + index;
+		String endiri = pt.getIri().replace('#', '/') + "#" + "end_activity" + index;
 		
 		String preiri = pt.getLastEvent() != null ? pt.getLastEvent().getIri() : pt.getIri();
-		String portiri = act.getCtrlInPorts().get(0).getIri();
+		String portiri = act.getCtrlInPorts().get(0).getIri(); //TODO:  change it later to consider multiple input ports
 		String query = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
 				+ "PREFIX tr: <http://ua.be/sdo2l/vocabulary/base/processtraces#>\n"
 				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
@@ -76,8 +77,6 @@ public class PTRepository {
 				+ "    tr:relatesTo <" + portiri + "> ;\n"
 				+ "    owl:sameAs <" + iri + "> .\n"
 				+ "}";
-		
-		System.out.println(query);
 		if (FusekiWrapper.getInstance().updateQuery(query) ) {
 			StartActivityEvent ev = new StartActivityEvent();
 			ev.setIri(iri);
@@ -90,7 +89,7 @@ public class PTRepository {
 		
 	}
 	
-	private void updatePT(PT pt) throws Exception {
+	public void updatePT(PT pt) throws Exception {
 		String transitive = "";
 		for (Event ev : pt.getEvents()) {
 			transitive += "<" + ev.getIri()+">,";
@@ -121,14 +120,69 @@ public class PTRepository {
 		
 	}
 
+	public void createEndEvent(PT pt, Activity act, List<Artifact> arts, ControlOutputPort p) throws Exception {
+		//TODO: this won't work with concurrent flows (solution: send the start activity event in the request)
+		int index = (Integer.parseInt(""+pt.getLastEvent().getIri().charAt(pt.getLastEvent().getIri().length()-1)));
+		
+		String startiri = pt.getIri().replace('#', '/') + "#" + "start_activity" + index;
+		String endiri = pt.getIri().replace('#', '/') + "#" + "end_activity" + index;
+		
+		String query = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+				+ "PREFIX tr: <http://ua.be/sdo2l/vocabulary/base/processtraces#>\n"
+				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
+				+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base/acyclic#>\n"
+				+ "INSERT DATA {\n"
+				+ "	<" + endiri + "> rdf:type <http://ua.be/sdo2l/vocabulary/base/processtraces#StartActivityEvent> , <http://ua.be/sdo2l/vocabulary/base/processtraces#element> , <http://ua.be/sdo2l/vocabulary/base/processtraces#Event> , owl:Thing , <http://ua.be/sdo2l/vocabulary/base/acyclic#element> ;\n"
+				//+ "    base:acyclicForward <" + endiri + "> ;\n"
+				//+ "    tr:isFollowedBy <" + endiri + "> ;\n"
+				+ "    tr:isPrecededBy <" + startiri + "> ;\n"
+				+ "    tr:relatesTo <" + p.getIri() + "> ;\n"
+				+ "    owl:sameAs <" + endiri + "> .\n"
+				+ "}";
+		if (FusekiWrapper.getInstance().updateQuery(query) ) {
+			EndActivityEvent ev = new EndActivityEvent();
+			ev.setIri(endiri);
+			ev.setRelatesTo(p);
+			pt.addEvent(ev);
+			updatePT(pt);
+		} else {
+			throw new Exception("Error inserting data.");
+		}
+		
+	}
+	
+	public Event createEndTraceEvent(String ptIRI, String previous, String pmIRI) throws Exception {
+		String traceiri = ptIRI + "_end";
+		String query = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+				+ "PREFIX tr: <http://ua.be/sdo2l/vocabulary/base/processtraces#>\n"
+				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
+				+ "INSERT DATA {\n"
+				+ "	<"+ traceiri + "> rdf:type <http://ua.be/sdo2l/vocabulary/base/acyclic#element> , <http://ua.be/sdo2l/vocabulary/base/processtraces#EndTraceEvent> , <http://ua.be/sdo2l/vocabulary/base/processtraces#Event> , <http://ua.be/sdo2l/vocabulary/base/processtraces#element> , owl:Thing ;\n"
+				+ " 	tr:isPrecededBy <" + previous + "> ;\n"
+				+ "    	tr:relatesTo <" + pmIRI + "> ;\n"
+				+ "     owl:sameAs  <" + traceiri + "> .\n"
+				+ "}";
+		if (FusekiWrapper.getInstance().updateQuery(query) ) {
+			EndTraceEvent ev = new EndTraceEvent();
+			ev.setIri(traceiri);
+			ev.setTimestamp(Timestamp.from(Instant.now()));
+//			ev.setRelatesTo(p);
+//			pt.addEvent(ev);
+//			updatePT(pt);
+			return ev;
+		} else {
+			throw new Exception("Error inserting data.");
+		}
+		
+	}
+	
 	public static void main(String[] args) {
-		String iri = "<http://ua.be/sdo2l/description/artifacts/my_pm#model>";
-		String ptIri = iri.split("#")[0] + "/traces#pt_1" ;
-		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		String iri = "http://ua.be/sdo2l/description/artifacts/MyPM_pm/traces/pt_1#start_activity0";
+		char charAt = iri.charAt(iri.length()-1);
+		System.out.println(Integer.parseInt(""+charAt)+1);
 		
-		System.out.println(iri.split("#")[0]);
-		System.out.println(timestamp.toString());
-		System.out.println(ptIri);
 	}
 
+	
+
 }

+ 7 - 3
src/main/resources/templates/enact.html

@@ -54,16 +54,20 @@
         <select class="form-control" id="activities" name="activity" th:onchange="'window.location.href = \'' + @{/inarts} + '?iri=\' + encodeURIComponent(this.value) ' " >
     			<option th:value="1" >select Activity</option>
 			    <option th:each="act: ${acts}" th:selected="${act.iri == current}" th:value="${act.iri}" th:text="${act.name}"></option>
-			</select>
+		</select>
+
 		</td>
     </tr>    
-</table>    
+</table>
+
+<input id="endEnactment" th:if="${endBool}" class="button button1" type="submit" value="End Enactment" />
+    
 <div id="hidden_div" th:if="${arts != null}"> 
 
 <table th:if="${arts != null && arts.size > 0}">
 	<tr> <td > Artifacts </td> </tr>
 </table>
-<input class="button button1" type="submit" value="Start Activity"/> 
+<input id="startActivity" class="button button1" type="submit" value="Start Activity"/> 
 
 </div>
 

+ 96 - 0
src/main/resources/templates/endEnactment.html

@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>New account</title>
+     <style>
+		.button {
+		  border: none;
+		  color: white;
+		  padding: 16px 32px;
+		  text-align: center;
+		  text-decoration: none;
+		  display: inline-block;
+		  font-size: 16px;
+		  margin: 4px 2px;
+		  transition-duration: 0.4s;
+		  cursor: pointer;
+		}
+		
+		.button1 {
+		  background-color: white; 
+		  color: black; 
+		  border: 2px solid #5e9ca0;
+		}
+		
+		.button1:hover {
+		  background-color: #5e9ca0;
+		  color: white;
+		}		
+	</style>
+	<script type="text/javascript">
+	function showDiv(select){
+	   if(select.value!=1){
+	    document.getElementById('hidden_div').style.display = "block";
+	   } else{
+	    document.getElementById('hidden_div').style.display = "none";
+	   }
+	} 
+</script>
+</head>
+
+<body>
+<div style="width:100%; height: 100px;background-color:white" class="bg-faded">
+  <!-- Main Div -->
+  <h1 style="color: #5e9ca0; text-align: center;">Wee: Workflow Enactment Engine</h1>
+</div>
+
+<div style="float:left;width:50%;" >
+
+<h3 style="color: #5e9ca0;" th:inline="text">Enactment of the Process Model: [[${session.pm.name}]] has ended!</h3>
+
+<a th:href="@{/}" class="button button1" > HOME </a>
+	
+
+
+</div>
+
+<div style="float:left; width:50%; background-color:white; ">
+
+<h3 style="color: #5e9ca0;" th:inline="text">Trace: [[${session.trace.name}]] </h3>
+<h4 style="color: #5e9ca0;" th:inline="text">Started at: [[${session.trace.timestampF}]] </h4>
+
+<table>
+  <th:block th:each="ev : ${session.trace.events}">
+    <tr>
+        <td style="color: #5e9ca0;font-weight: bold;" th:if="${ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}" >begin:</td>
+        <td style="color: #5e9ca0;font-weight: bold;" th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent'}" >end:</td>
+        <td style="color: #5e9ca0;" colspan="2" th:if="${ev.class.name != 'ua.be.wee.model.pt.EndTraceEvent'}" th:text="${ev.relatesTo.act.name}">...</td>
+        
+        <td style="color: #5e9ca0;font-weight: bold;" th:if="${ev.class.name == 'ua.be.wee.model.pt.EndTraceEvent'}" >End of Trace at: </td>
+        <td style="color: #5e9ca0;" colspan="2" th:if="${ev.class.name == 'ua.be.wee.model.pt.EndTraceEvent'}" th:text="${ev.timestampF}">...</td>
+    </tr>
+    <tr th:if="${ev.class.name != 'ua.be.wee.model.pt.EndTraceEvent'}">
+        <td style="color: #5e9ca0;font-weight: bold;" colspan="2" >port:</td>
+        <td style="color: #5e9ca0;"  >[[${ev.relatesTo.name}]]</td>
+    </tr>
+  </th:block>
+</table>
+
+</div>
+    
+
+     
+
+
+ 
+
+
+
+
+</body>
+
+</html>