Browse Source

- Fixing bugs in generated RDF triples for traces
- adding service to return the traces that are still active (no
EndTraceEvent)

Lucas Albertins 2 years ago
parent
commit
f2deffcf2b

+ 12 - 7
src/main/java/ua/be/wee/controller/rest/PTController.java

@@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RestController;
 
 import ua.be.wee.model.pt.Event;
-import ua.be.wee.model.pt.PT;
+import ua.be.wee.model.pt.StartTraceEvent;
 import ua.be.wee.model.repository.PTRepository;
 
 @RestController
@@ -17,18 +17,23 @@ public class PTController {
 	@Autowired
 	private PTRepository ptRepository;
 	
+	@GetMapping("/traces")
+	List<StartTraceEvent> allPTs() {
+		return ptRepository.getStartTraceEvents();
+	}
 	
 	
-	@GetMapping("/startTraceEvents")
-	List<PT> allPTs() {
-		return ptRepository.getStartTraceEvents();
+	@GetMapping("/events/{traceiri}")
+	List<Event> getEvents(@PathVariable String traceiri) throws Exception {
+		return ptRepository.getEvents(traceiri);
 	}
 	
 	
-	@GetMapping("/events/{id}")
-	List<Event> getEvents(@PathVariable String id) throws Exception {
-		return ptRepository.getEvents(id);
+	@GetMapping("/activetraces/{pmiri}")
+	List<StartTraceEvent> getActiveTraces(@PathVariable String pmiri) throws Exception {
+		return ptRepository.getActiveTraces(pmiri);
 	}
+	
 
 
 	

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

@@ -1,8 +1,6 @@
 package ua.be.wee.model.pt;
 
 
-import java.sql.Timestamp;
-import java.text.SimpleDateFormat;
 import java.util.List;
 
 import javax.persistence.Entity;
@@ -28,8 +26,6 @@ public class PT {
 	
 	@OneToOne
 	private PM pmEnacted;
-	
-	private Timestamp timestamp;
 
 	public PM getPmEnacted() {
 		return pmEnacted;
@@ -39,14 +35,6 @@ public class PT {
 		this.pmEnacted = pmEnacted;
 	}
 
-	public Timestamp getTimestamp() {
-		return timestamp;
-	}
-
-	public void setTimestamp(Timestamp timestamp) {
-		this.timestamp = timestamp;
-	}
-
 	public String getIri() {
 		return iri;
 	}
@@ -59,10 +47,6 @@ public class PT {
 	public String getName() {
 		return name;
 	}
-	
-	public String getTimestampF() {
-		return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(timestamp);
-	}
 
 	public List<Event> getEvents() {
 		return events;

+ 90 - 35
src/main/java/ua/be/wee/model/repository/PTRepository.java

@@ -57,7 +57,8 @@ public class PTRepository {
 			PT pt = new PT();
 			pt.setPmEnacted(pm);
 			pt.setIri(traceiri);
-			pt.setEvents(new ArrayList<Event>());
+			
+			
 			
 			query = "PREFIX tr: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
 					+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
@@ -70,7 +71,14 @@ public class PTRepository {
 			if (results.hasNext()) {
 				QuerySolution next = results.next();
 				RDFNode rdfNode = next.get("?ts");
-				pt.setTimestamp(DateTimeConverter.convertSPARQLDateTimeToTimestamp(rdfNode.toString()));
+				
+				StartTraceEvent ev = new StartTraceEvent();
+				ev.setIri(traceiri);
+				ev.setPmEnacted(pm);
+				ev.setTimestamp(DateTimeConverter.convertSPARQLDateTimeToTimestamp(rdfNode.toString()));
+				List<Event> list = new ArrayList<Event>();
+				list.add(ev);
+				pt.setEvents(list);
 			}
 			return pt;
 		} else {
@@ -95,7 +103,7 @@ public class PTRepository {
 	}
 
 	public void createStartEvent(PT pt, ControlInputPort port, Activity act, List<TraceArtifact> arts) throws Exception {
-		int index = pt.getLastEvent() == null ? 0 : (Integer.parseInt(""+pt.getLastEvent().getIri().charAt(pt.getLastEvent().getIri().length()-1))+1); 
+		int index = pt.getEvents().size() == 1 ? 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;
@@ -109,7 +117,6 @@ public class PTRepository {
 				+ "INSERT {\n"
 				+ "	<" + iri + "> rdf:type <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#StartActivityEvent> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#element> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#Event> , owl:Thing , <http://ua.be/sdo2l/vocabulary/base/acyclic#element> ;\n"
 				+ "    base:acyclicForward <" + endiri + "> ;\n"
-				+ "    tr:isFollowedBy <" + endiri + "> ;\n"
 				+ "    tr:hasTimestamp ?now ; \n"
 				+ "    tr:isPrecededBy <" + preiri + "> ;\n"
 				+ "    tr:relatesTo <" + portiri + "> ;\n";
@@ -172,7 +179,11 @@ public class PTRepository {
 	public void updatePT(PT pt) throws Exception {
 		String transitive = "";
 		for (Event ev : pt.getEvents()) {
-			transitive += "<" + ev.getIri()+">,";
+			if (ev instanceof StartTraceEvent) {
+				continue;
+			} else {
+				transitive += "<" + ev.getIri()+">,";
+			}
 		}
 		transitive = transitive.substring(0, transitive.length()-1);
 		
@@ -188,10 +199,10 @@ public class PTRepository {
 				+ "};\n"
 				+ "INSERT DATA {\n"
 				+ "	<" + pt.getIri() + "> rdf:type    <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#Event> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#StartTraceEvent> , owl:Thing , <http://ua.be/sdo2l/vocabulary/base/acyclic#element> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#element> ;\n"
-				+ "    base:acyclicForward <" + pt.getEvents().get(0).getIri() + "> ;\n"
+				+ "    base:acyclicForward <" + pt.getEvents().get(1).getIri() + "> ;\n"
 				+ "    base:transitiveForward "+ transitive + " ;\n"
-				+ "    tr:isFollowedBy <" + pt.getEvents().get(0).getIri() + "> ;\n"
-				+ "    tr:hasTimestamp " + DateTimeConverter.convertTimestampToSPARQLdateTime(pt.getTimestamp()) + " ; \n "
+				+ "    tr:isFollowedBy <" + pt.getEvents().get(1).getIri() + "> ;\n"
+				+ "    tr:hasTimestamp " + DateTimeConverter.convertTimestampToSPARQLdateTime(pt.getEvents().get(0).getTimestamp()) + " ; \n "
 				+ "    tr:relatesTo <" + pt.getPmEnacted().getIri() + "> ;\n"
 				+ "    owl:sameAs <"+ pt.getIri() + "> .\n"
 				+ "};";
@@ -214,9 +225,10 @@ public class PTRepository {
 				break;
 			}
 		}
+		String preiri = pt.getLastEvent() != null ? pt.getLastEvent().getIri() : pt.getIri();
 		int index = (Integer.parseInt(""+source.getIri().charAt(source.getIri().length()-1)));
 		
-		String startiri = pt.getIri().replace('#', '/') + "#" + "start_activity" + index;
+		//String startiri = pt.getIri().replace('#', '/') + "#" + "start_activity" + index;
 		String endiri = pt.getIri().replace('#', '/') + "#" + "end_activity" + index;
 		
 		List<String> artifactsIRI = new ArrayList<String>();
@@ -224,7 +236,7 @@ public class PTRepository {
 			String artifactIRI = pt.getIri().replace('#', '/') + "#" + art.getGUID();
 			art.setIri(artifactIRI);
 			artifactsIRI.add(artifactIRI);
-			createTraceArtifact(endiri,startiri, art, pt);
+			createTraceArtifact(endiri,preiri, art, pt);
 		}
 		
 	
@@ -234,7 +246,7 @@ public class PTRepository {
 				+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base/acyclic#>\n"
 				+ "INSERT {\n"
 				+ "	<" + endiri + "> rdf:type <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#EndActivityEvent> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#element> , <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#Event> , owl:Thing , <http://ua.be/sdo2l/vocabulary/base/acyclic#element> ;\n"
-				+ "    tr:isPrecededBy <" + startiri + "> ;\n"
+				+ "    tr:isPrecededBy <" + preiri + "> ;\n"
 				+ "    tr:relatesTo <" + p.getIri() + "> ;\n"
 				+ "    tr:hasTimestamp ?now ; \n";
 				
@@ -242,7 +254,7 @@ public class PTRepository {
 			query += "    tr:produces <" + iri + "> ;\n" ;
 		}
 		query += "    owl:sameAs <" + endiri + "> .\n"
-			  + " <"+ startiri + "> tr:isFollowedBy <" + endiri + "> .\n"
+			  + " <"+ preiri + "> tr:isFollowedBy <" + endiri + "> .\n"
 			  + "} WHERE {"
 				+ "	SELECT ?now\n"
 				+ "    WHERE\n"
@@ -450,8 +462,8 @@ public class PTRepository {
 	}
 
 	
-	public List<PT> getStartTraceEvents() {
-		List<PT> list = new ArrayList<PT>();
+	public List<StartTraceEvent> getStartTraceEvents() {
+		List<StartTraceEvent> list = new ArrayList<StartTraceEvent>();
 		String query = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
 				+ "PREFIX tr: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
 				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
@@ -466,7 +478,7 @@ public class PTRepository {
 			RDFNode trace = next.get("?trace");
 			RDFNode pm = next.get("?pm");
 			RDFNode ts = next.get("?ts");
-			PT pt = new PT();
+			StartTraceEvent pt = new StartTraceEvent();
 			pt.setIri(trace.toString());
 			pt.setTimestamp(DateTimeConverter.convertSPARQLDateTimeToTimestamp(ts.toString()));
 			pt.setPmEnacted(pmRepo.getPM(pm.toString()));
@@ -503,19 +515,19 @@ public class PTRepository {
 			stev.setPmEnacted(pm2);
 			stev.setTimestamp(DateTimeConverter.convertSPARQLDateTimeToTimestamp(ts.toString()));
 			list.add(stev);
-			String next = nextQ.toString();
-			String nexttype = nexttypeQ.toString();
 			
-			while (next != null && !next.toString().equals("")) {
-				
+			String next = nextQ != null ? nextQ.toString() : null;
+			String nexttype = nexttypeQ != null ? nexttypeQ.toString() : null;
+			
+			while (next!= null && !next.toString().equals("")) {
 				if (nexttype.toString().equals(Event.START_ACTIVITY_IRI)) {
 					Pair<String,String> p = getStartActivityEvent(next.toString(), pm2, list);
-					next = p.getFst();
-					nexttype = p.getSnd();
+					next = p != null ? p.getFst() : null;
+					nexttype = p != null ? p.getSnd() : null;
 				} else if (nexttype.toString().equals(Event.END_ACTIVITY_IRI)) {
 					Pair<String,String> p = getEndActivityEvent(next.toString(), pm2, list);
-					next = p.getFst();
-					nexttype = p.getSnd();
+					next = p != null ? p.getFst() : null;
+					nexttype = p != null ? p.getSnd() : null;
 				} else if (nexttype.toString().equals(Event.END_TRACE_IRI)) {
 					getEndTraceEvent(next.toString(), pm2, list);
 					next = null;
@@ -540,7 +552,6 @@ public class PTRepository {
 		if (rs.hasNext()) {
 			QuerySolution sol = rs.next();
 			RDFNode trace = sol.get("?trace");
-			RDFNode pm = sol.get("?pm");
 			RDFNode ts = sol.get("?ts");
 			
 			EndTraceEvent ev = new EndTraceEvent();
@@ -560,11 +571,13 @@ public class PTRepository {
 				+ "SELECT ?trace ?port ?act ?ts ?next ?nexttype WHERE {\n"
 				+ "	?trace owl:sameAs <" + iri + "> ;\n"
 				+ "    	tr:relatesTo ?port ;\n"
-				+ "	 	tr:hasTimestamp ?ts ;\n"
-				+ "   	tr:isFollowedBy ?next .\n"
-				+ "		?next a ?nexttype .\n"
-				+ "     FILTER (?nexttype IN (tr:StartActivityEvent, tr:EndActivityEvent, tr:EndTraceEvent)) ."
+				+ "	 	tr:hasTimestamp ?ts .\n"
 				+ " ?act pm:hasPort ?port .\n"
+				+ "   OPTIONAL {\n"
+				+ "    ?trace tr:isFollowedBy ?next .\n"
+				+ "	   ?next a ?nexttype .\n"
+				+ "    FILTER (?nexttype IN (tr:StartActivityEvent, tr:EndActivityEvent, tr:EndTraceEvent)) . \n"
+				+ "  }\n"
 				+ "}";
 		ResultSet rs = FusekiWrapper.getInstance().execQuery(query);
 		if (rs.hasNext()) {
@@ -594,7 +607,12 @@ public class PTRepository {
 			
 			list.add(stev);
 			
-			return new Pair<String, String>(sol.get("?next").toString(), sol.get("?nexttype").toString());
+			RDFNode next = sol.get("?next");
+			if (next == null) {
+				return null;
+			} else {
+				return new Pair<String, String>(next.toString(),sol.get("?nexttype").toString());
+			}
 		} else {
 			throw new Exception("No data returned by query: \n" + query );
 		}
@@ -645,12 +663,14 @@ public class PTRepository {
 				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
 				+ "SELECT ?trace ?port ?act ?ts ?next ?nexttype WHERE {\n"
 				+ "	?trace owl:sameAs <" + iri + "> ;\n"
-				+ "    	tr:relatesTo ?port ;\n"
-				+ "	 	tr:hasTimestamp ?ts ;\n"
-				+ "   	tr:isFollowedBy ?next .\n"
-				+ "		?next a ?nexttype .\n"
-				+ "     FILTER (?nexttype IN (tr:StartActivityEvent, tr:EndActivityEvent, tr:EndTraceEvent)) ."
+				+ "     tr:relatesTo ?port ;\n"
+				+ "	 	tr:hasTimestamp ?ts .\n"
 				+ " ?act pm:hasPort ?port .\n"
+				+ "   OPTIONAL {\n"
+				+ "    ?trace tr:isFollowedBy ?next .\n"
+				+ "	?next a ?nexttype .\n"
+				+ "    FILTER (?nexttype IN (tr:StartActivityEvent, tr:EndActivityEvent, tr:EndTraceEvent)) . \n"
+				+ "  }\n"
 				+ "}";
 		ResultSet rs = FusekiWrapper.getInstance().execQuery(query);
 		if (rs.hasNext()) {
@@ -679,12 +699,47 @@ public class PTRepository {
 						
 			list.add(ev);
 			
-			return new Pair<String, String>(sol.get("?next").toString(),sol.get("?nexttype").toString());
+			RDFNode next = sol.get("?next");
+			if (next == null) {
+				return null;
+			} else {
+				return new Pair<String, String>(next.toString(),sol.get("?nexttype").toString());
+			}
+			
 		} else {
 			throw new Exception("No data returned by query: \n" + query );
 		}
 	}
 
+	public List<StartTraceEvent> getActiveTraces(String pm) {
+		List<StartTraceEvent> list = new ArrayList<StartTraceEvent>();
+		String query = "PREFIX tr: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
+				+ "SELECT ?trace ?ts ?next WHERE {\n"
+				+ "  ?trace a tr:StartTraceEvent ;\n"
+				+ "	   	tr:isFollowedBy+ ?next .\n"
+				+ "	 ?trace tr:relatesTo <" + pm + "> ."	
+				+ "  ?next a ?nexttype .\n"
+				+ "  ?trace tr:hasTimestamp ?ts ."
+				+ "  FILTER (?trace != ?next)\n"
+				+ "  FILTER NOT EXISTS {?next tr:isFollowedBy ?other  } .\n"
+				+ "  FILTER (?nexttype IN (tr:StartActivityEvent, tr:EndActivityEvent)) . \n"
+				+ "}";
+		ResultSet rs = FusekiWrapper.getInstance().execQuery(query);
+		while (rs.hasNext()) {
+			QuerySolution next = rs.next();
+			RDFNode trace = next.get("?trace");
+			RDFNode ts = next.get("?ts");
+			StartTraceEvent ev = new StartTraceEvent();
+			ev.setIri(trace.toString());
+			ev.setTimestamp(DateTimeConverter.convertSPARQLDateTimeToTimestamp(ts.toString()));
+			PM pmo = new PM();
+			pmo.setIri(pm);
+			ev.setPmEnacted(pmo);
+			list.add(ev);
+		}
+		return list;		
+	}
+
 	
 
 }

+ 2 - 2
src/main/resources/templates/enact.html

@@ -56,11 +56,11 @@
 
       <div class="details">
         <p th:inline="text"><strong>Trace: </strong><span class="accent">[[${session.trace.name}]]</span></p>
-        <p th:inline="text"><strong>Started at: </strong><span class="accent">[[${session.trace.timestampF}]]</span></p>
+        <p th:inline="text"><strong>Started at: </strong><span class="accent">[[${session.trace.events[0].timestampF}]]</span></p>
         <th:block th:each="ev : ${session.trace.events}">
           <p th:if="${ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}"><strong>Begin: </strong><span class="accent" th:text="${ev.relatesTo.activity.name}"></span></p>
           <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent'}"><strong>End: </strong><span class="accent" th:text="${ev.relatesTo.activity.name}"></span></p>
-          <p><strong>Port: </strong><span class="accent">[[${ev.relatesTo.name}]]</span></p>
+          <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent' || ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}"><strong>Port: </strong><span class="accent">[[${ev.relatesTo.name}]]</span></p>
         </th:block>
       </div>
 

+ 2 - 2
src/main/resources/templates/enactEnd.html

@@ -60,11 +60,11 @@
 
       <div class="details">
         <p th:inline="text"><strong>Trace: </strong><span class="accent">[[${session.trace.name}]]</span></p>
-        <p th:inline="text"><strong>Started at: </strong><span class="accent">[[${session.trace.timestampF}]]</span></p>
+        <p th:inline="text"><strong>Started at: </strong><span class="accent">[[${session.trace.events[0].timestampF}]]</span></p>
         <th:block th:each="ev : ${session.trace.events}">
           <p th:if="${ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}"><strong>Begin: </strong><span class="accent" th:text="${ev.relatesTo.activity.name}"></span></p>
           <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent'}"><strong>End: </strong><span class="accent" th:text="${ev.relatesTo.activity.name}"></span></p>
-          <p><strong>Port: </strong><span class="accent">[[${ev.relatesTo.name}]]</span></p>
+          <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent' || ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}"><strong>Port: </strong><span class="accent">[[${ev.relatesTo.name}]]</span></p>
         </th:block>
       </div>
     </div>

+ 3 - 3
src/main/resources/templates/endEnactment.html

@@ -10,14 +10,14 @@
     <p th:inline="text">Enactment of the Process Model: [[${session.pm.name}]] has ended!</p>
     <a th:href="@{/}">HOME</a>
     <p th:inline="text">Trace: [[${session.trace.name}]]</p>
-    <p th:inline="text">Started at: [[${session.trace.timestampF}]]</p>
+    <p th:inline="text">Started at: [[${session.trace.events[0].timestampF}]]</p>
     <th:block th:each="ev : ${session.trace.events}">
       <p th:if="${ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}">Begin:</p>
       <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent'}">End:</p>
-      <p th:if="${ev.class.name != 'ua.be.wee.model.pt.EndTraceEvent'}" th:text="${ev.relatesTo.activity.name}"></p>
+      <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent' || ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}" th:text="${ev.relatesTo.activity.name}"></p>
       <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndTraceEvent'}">End of Trace at:</p>
       <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndTraceEvent'}" th:text="${ev.timestampF}"></p>
-      <p th:if="${ev.class.name != 'ua.be.wee.model.pt.EndTraceEvent'}">port: [[${ev.relatesTo.name}]]</p>
+      <p th:if="${ev.class.name == 'ua.be.wee.model.pt.EndActivityEvent' || ev.class.name == 'ua.be.wee.model.pt.StartActivityEvent'}">port: [[${ev.relatesTo.name}]]</p>
     </th:block>
   </section>
 </main>