Przeglądaj źródła

- Adding relationship between different versions of the same artifact
- Adding the selection of the input control port when starting
activitites.

Lucas Albertins 2 lat temu
rodzic
commit
c6c7dfff4c

+ 55 - 23
src/main/java/ua/be/wee/controller/EnactementControllerMVC.java

@@ -4,6 +4,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.sql.Timestamp;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -20,10 +21,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import ua.be.wee.model.EnactmentController;
+import ua.be.wee.model.NamedElement;
 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.ControlInputPort;
 import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.pm.PM;
 import ua.be.wee.model.pt.EndActivityEvent;
@@ -31,6 +34,7 @@ import ua.be.wee.model.pt.Event;
 import ua.be.wee.model.pt.PT;
 import ua.be.wee.model.pt.TraceArtifact;
 import ua.be.wee.model.repository.FusekiWrapper;
+import ua.be.wee.model.util.Pair;
 import ua.be.wee.service.FileStorageService;
 
 @Controller
@@ -87,11 +91,8 @@ public class EnactementControllerMVC {
 		} else {
 			PM pm = controller.getPM(pmiri);			
 			PT trace = controller.createTrace(pm);
-			List<String> iris = controller.findNextNodes(pm.getInitial().getIri());
-			List<Node> acts = new ArrayList<Node>();
-			for (String iri : iris) {
-				acts.add(pm.getNode(iri));
-			}
+			List<Pair<String,String>> iris = controller.findNextNodes(pm.getInitial().getIri());
+			List<PMTrigger> acts = findElements(pm, iris);
 			model.addAttribute("error", false);
 			request.getSession().setAttribute("pm", pm);
 			request.getSession().setAttribute("trace", trace);
@@ -103,19 +104,42 @@ public class EnactementControllerMVC {
 	        return "enact";
 		}
     }
+
+	private List<PMTrigger> findElements(PM pm, List<Pair<String, String>> iris) {
+		List<PMTrigger> acts = new ArrayList<PMTrigger>();
+		for (Pair<String,String> pair : iris) {
+			PMTrigger tr = new PMTrigger();
+			if (pair.getSnd() != null) {
+				List<ControlInputPort> ctrlInPorts = ((Activity)pm.getNode(pair.getSnd())).getCtrlInPorts();
+				ControlInputPort port = null;
+				for (ControlInputPort ctr : ctrlInPorts) {
+					if (ctr.getIri().equals(pair.getFst())) {
+						port = ctr;
+						break;
+					}
+				}
+				tr.setPort(port);
+
+			} else {
+				tr.setNode((FinalNode)pm.getNode(pair.getFst()));
+			}
+			acts.add(tr);
+		}
+		return acts;
+	}
     
     @PostMapping("/startAct")
     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");
-    	List<Node> acts = (List<Node>) request.getSession().getAttribute("acts");
+    	List<PMTrigger> acts = (List<PMTrigger>) request.getSession().getAttribute("acts");
     	List<Node> endacts = (List<Node>) request.getSession().getAttribute("endacts");
     	Node node = pm.getNode(activity);
     	Object arts = request.getSession().getAttribute("arts");
     	if (node instanceof Activity) {
 
         	controller.addStartEvent(pt,(Activity)node,((List<TraceArtifact>)arts));
-        	acts.remove(node);
+        	removeElement(acts,node);
         	endacts.add(node);
         	request.getSession().removeAttribute("arts");
         	return "enact";
@@ -132,10 +156,20 @@ public class EnactementControllerMVC {
     	
     }
     
-    @PostMapping("/endAct")
+    private void removeElement(List<PMTrigger> acts, Node node) {
+		for (PMTrigger pmTrigger : acts) {
+			if (pmTrigger.getIri().equals(node.getIri())) {
+				acts.remove(pmTrigger);
+				break;
+			}
+		}
+		
+	}
+
+	@PostMapping("/endAct")
     public String endActivity(Model model, @RequestParam String port, @RequestParam String activity, HttpServletRequest request) throws Exception {
     	PM pm = (PM)request.getSession().getAttribute("pm");
-    	List<Node> acts = (List<Node>)request.getSession().getAttribute("acts");
+    	List<PMTrigger> acts = (List<PMTrigger>)request.getSession().getAttribute("acts");
     	List<Node> endacts = (List<Node>)request.getSession().getAttribute("endacts");
     	PT pt = (PT)request.getSession().getAttribute("trace");
     	Activity act = (Activity)pm.getNode(activity);
@@ -147,13 +181,11 @@ public class EnactementControllerMVC {
 				break;
 			}
 		}
-    	List<String> iris = controller.findNextNodes(p.getIri());
-		for (String iri : iris) {
-			acts.add(pm.getNode(iri));
-		}
+    	List<Pair<String,String>> iris = controller.findNextNodes(p.getIri());
+		acts.addAll(findElements(pm, iris));
     	List<TraceArtifact> arts = new ArrayList<TraceArtifact>();
     	
-    	controller.addEndEvent(pt,act,arts,p);
+    	controller.addEndEvent(pt,arts,p);
     	endacts.remove(act);
  
     	
@@ -167,7 +199,7 @@ public class EnactementControllerMVC {
     @PostMapping("/endActArt")
     public String endActivityWithArtifacts(Model model, @RequestParam String port, @RequestParam String activity, HttpServletRequest request) throws Exception {
     	PM pm = (PM)request.getSession().getAttribute("pm");
-    	List<Node> acts = (List<Node>)request.getSession().getAttribute("acts");
+    	List<PMTrigger> acts = (List<PMTrigger>)request.getSession().getAttribute("acts");
     	List<Node> endacts = (List<Node>)request.getSession().getAttribute("endacts");
     	PT pt = (PT)request.getSession().getAttribute("trace");
     	Activity act = (Activity)pm.getNode(activity);
@@ -188,7 +220,7 @@ public class EnactementControllerMVC {
 				if (part.getName().equals(artifact.getName())) {
 					TraceArtifact tArt = new TraceArtifact();
 					tArt.setLocation(part.getSubmittedFileName());
-					tArt.setTag("v1"); //TODO fix the tag generation
+					//tArt.setTag("v1"); //TODO fix the tag generation
 					tArt.setGUID(part.getSubmittedFileName()+"-" +tArt.getTag());
 					tArt.setRelatesTo(artifact);
 					traceArts.add(tArt);
@@ -198,15 +230,16 @@ public class EnactementControllerMVC {
 			}  
 		}
     	
-    	List<String> iris = controller.findNextNodes(p.getIri());
-		for (String iri : iris) {
-			acts.add(pm.getNode(iri));
-		}
-    	
-    	controller.addEndEvent(pt,act,traceArts,p);
+    	controller.addEndEvent(pt,traceArts,p);
     	endacts.remove(act);
     	
     	
+    	List<Pair<String,String>> iris = controller.findNextNodes(p.getIri());
+		acts.addAll(findElements(pm, iris));
+    	
+    	
+    	
+    	
     	
     	request.getSession().setAttribute("trace", pt);
     	request.getSession().setAttribute("previous", p.getIri());
@@ -259,7 +292,6 @@ public class EnactementControllerMVC {
         			if (chosen != null) {
         				arts.add(chosen);
 					}
-					
 				}
             	//model.addAttribute("arts", arts);
             	request.getSession().setAttribute("arts", arts);

+ 44 - 0
src/main/java/ua/be/wee/controller/PMTrigger.java

@@ -0,0 +1,44 @@
+package ua.be.wee.controller;
+
+import ua.be.wee.model.nodes.FinalNode;
+import ua.be.wee.model.nodes.ports.ControlInputPort;
+
+public class PMTrigger {
+	
+	private FinalNode node;
+	
+	public FinalNode getNode() {
+		return node;
+	}
+
+	public void setNode(FinalNode node) {
+		this.node = node;
+	}
+
+	public ControlInputPort getPort() {
+		return port;
+	}
+
+	public void setPort(ControlInputPort port) {
+		this.port = port;
+	}
+
+	private ControlInputPort port;
+	
+	public String getName() {
+		if (port != null) {
+			return port.getActivity().getName() + " VIA PORT: " + port.getName();
+		} else {
+			return "END TRACE";
+		}
+	}
+	
+	public String getIri() {
+		if (port != null) {
+			return port.getActivity().getIri();
+		} else {
+			return node.getIri();
+		}
+	}
+
+}

+ 4 - 3
src/main/java/ua/be/wee/model/EnactmentController.java

@@ -15,6 +15,7 @@ import ua.be.wee.model.pt.Event;
 import ua.be.wee.model.pt.PT;
 import ua.be.wee.model.pt.PTRepository;
 import ua.be.wee.model.pt.TraceArtifact;
+import ua.be.wee.model.util.Pair;
 
 @Component
 public class EnactmentController {
@@ -38,7 +39,7 @@ public class EnactmentController {
 		return pm;
 	}
 
-	public List<String> findNextNodes(String iri) {
+	public List<Pair<String,String>> findNextNodes(String iri) {
 		return pmRepo.findNextNodes(iri); 
 	}
 
@@ -50,8 +51,8 @@ public class EnactmentController {
 		traceRepo.createStartEvent(pt,act,arts);
 	}
 
-	public void addEndEvent(PT pt, Activity act, List<TraceArtifact> arts, ControlOutputPort p) throws Exception {
-		traceRepo.createEndEvent(pt,act,arts,p);
+	public void addEndEvent(PT pt, List<TraceArtifact> arts, ControlOutputPort p) throws Exception {
+		traceRepo.createEndEvent(pt,arts,p);
 		
 	}
 

+ 1 - 1
src/main/java/ua/be/wee/model/nodes/NodeRespository.java

@@ -227,7 +227,7 @@ public class NodeRespository {
 			ControlOutputPort cout = new ControlOutputPort();
 			cout.setIri(iri.toString());
 			cout.setName(name.toString());
-			cout.setAct(act);
+			cout.setActivity(act);
 			list.add(cout);
 		}
 		return list;

+ 5 - 6
src/main/java/ua/be/wee/model/nodes/ports/ControlInputPort.java

@@ -4,14 +4,13 @@ import ua.be.wee.model.nodes.Activity;
 
 public class ControlInputPort extends Port {
 
-	private Activity act;
+	private Activity activity;
 
-	public Activity getAct() {
-		return act;
+	public Activity getActivity() {
+		return activity;
 	}
 
-	public void setAct(Activity act) {
-		this.act = act;
+	public void setAct(Activity activity) {
+		this.activity = activity;
 	}
-	
 }

+ 5 - 5
src/main/java/ua/be/wee/model/nodes/ports/ControlOutputPort.java

@@ -4,13 +4,13 @@ import ua.be.wee.model.nodes.Activity;
 
 public class ControlOutputPort extends Port {
 	
-	private Activity act;
+	private Activity activity;
 
-	public Activity getAct() {
-		return act;
+	public Activity getActivity() {
+		return activity;
 	}
 
-	public void setAct(Activity act) {
-		this.act = act;
+	public void setActivity(Activity activity) {
+		this.activity = activity;
 	}
 }

+ 3 - 0
src/main/java/ua/be/wee/model/nodes/ports/Port.java

@@ -1,11 +1,14 @@
 package ua.be.wee.model.nodes.ports;
 
+import javax.persistence.Id;
+
 import ua.be.wee.model.NamedElement;
 
 public abstract class Port implements NamedElement {
 	
 	private String name;
 	
+	@Id
 	private String iri;
 
 	public String getName() {

+ 7 - 8
src/main/java/ua/be/wee/model/pm/PMRepository.java

@@ -8,10 +8,9 @@ import org.apache.jena.query.ResultSet;
 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;
+import ua.be.wee.model.util.Pair;
 
 @Component
 public class PMRepository {
@@ -57,8 +56,8 @@ public class PMRepository {
 		return pm;
 	}
 
-	public List<String> findNextNodes(String iri) {
-		List<String> list = new ArrayList<String>();
+	public List<Pair<String,String>> findNextNodes(String iri) {
+		List<Pair<String,String>> list = new ArrayList<Pair<String,String>>();
 		String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
 				+ "PREFIX pm: <http://ua.be/sdo2l/vocabulary/formalisms/pm#>\n"
 				+ "SELECT ?e ?nodetype ?act WHERE {\n"
@@ -74,13 +73,13 @@ public class PMRepository {
 		while (results.hasNext()) {
 			QuerySolution soln = results.nextSolution();
 			RDFNode type = soln.get("?nodetype");
-			RDFNode iriRDF;
+			Pair<String,String> pair;
 			if (type.toString().equals(Node.CTRL_INPUT_PORT_IRI)) {
-				iriRDF = soln.get("?act");
+				pair = new Pair<String,String>(soln.get("?e").toString(),soln.get("?act").toString());
 			} else {
-				iriRDF = soln.get("?e");
+				pair = new Pair<String,String>(soln.get("?e").toString(), null);
 			}
-			list.add(iriRDF.toString());
+			list.add(pair);
 			
 		}
 		return list;

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

@@ -18,6 +18,8 @@ public class PT {
 	private String name;
 	
 	private List<Event> events;
+	
+	private List<TraceArtifact> inputs;
 
 	public PM getPmEnacted() {
 		return pmEnacted;
@@ -71,4 +73,12 @@ public class PT {
 		events.add(ev);
 	}
 
+	public List<TraceArtifact> getInputs() {
+		return inputs;
+	}
+
+	public void setInputs(List<TraceArtifact> inputs) {
+		this.inputs = inputs;
+	}
+
 }

+ 108 - 26
src/main/java/ua/be/wee/model/pt/PTRepository.java

@@ -5,11 +5,12 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.jena.query.QuerySolution;
 import org.apache.jena.query.ResultSet;
+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.Artifact;
 import ua.be.wee.model.nodes.ports.ControlOutputPort;
 import ua.be.wee.model.pm.PM;
 import ua.be.wee.model.repository.FusekiWrapper;
@@ -140,7 +141,7 @@ public class PTRepository {
 		
 	}
 
-	public void createEndEvent(PT pt, Activity act, List<TraceArtifact> arts, ControlOutputPort p) throws Exception {
+	public void createEndEvent(PT pt, List<TraceArtifact> arts, ControlOutputPort p) throws Exception {
 		//TODO: this won't work with concurrent flows (solution: send the start activity event in the request)
 		List<Event> events = pt.getEvents();
 		Event aux = null;
@@ -148,7 +149,7 @@ public class PTRepository {
 		for (int i = (events.size()-1); i >= 0; i--) {
 			aux = events.get(i); 
 			if (aux instanceof StartActivityEvent && 
-					(((StartActivityEvent) aux).getRelatesTo().getAct().getIri().equals(act.getIri()))) {
+					(((StartActivityEvent) aux).getRelatesTo().getActivity().getIri().equals(p.getActivity().getIri()))) {
 				source = aux;
 				break;
 			}
@@ -163,28 +164,7 @@ public class PTRepository {
 			String artifactIRI = pt.getIri().replace('#', '/') + "#" + art.getGUID();
 			art.setIri(artifactIRI);
 			artifactsIRI.add(artifactIRI);
-			String query = "PREFIX pt: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
-					+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
-					+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
-					+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base/base#>\n"
-					+ "INSERT DATA { \n"
-					+ " <" + artifactIRI + "> rdf:type base:Versionable , pt:Artifact , owl:Thing , pt:element , base:ImmutableThing ;\n"
-					+ "        base:hasGUID \"" + art.getGUID() + "\" ;\n"
-					+ "        base:hasTag \"" + art.getTag() + "\" ;\n"
-					+ "        pt:hasLocation \"" + art.getLocation() + "\" ;\n"
-					//+ "        pt:isConsumedBy <http://ua.be/sdo2l/description/traces/my_pt#start_activity1> ;\n"
-					//+ "        pt:isModel <http://ua.be/sdo2l/description/artifacts/my_xopp#model> ;\n"
-					+ "        pt:isProducedBy <" + endiri + "> ;\n"
-					+ "        pt:relatesTo <" + art.getRelatesTo().getIri() + "> ;\n"
-					+ "        owl:sameAs  <" + artifactIRI + "> .\n"
-					+ "}";
-			if (FusekiWrapper.getInstance().updateQuery(query) ) {
-				artifactsIRI.add(artifactIRI);
-				art.setTimestamp(Timestamp.from(Instant.now()));
-			} else {
-				throw new Exception("Error inserting data.");
-			}
-			
+			createTraceArtifact(endiri,startiri, art, pt);
 		}
 		
 	
@@ -201,7 +181,8 @@ public class PTRepository {
 			query += "    tr:produces <" + iri + "> ;\n" ;
 		}
 		query += "    owl:sameAs <" + endiri + "> .\n"
-				+ "}";
+			  + " <"+ startiri + "> tr:isFollowedBy <" + endiri + "> .\n"
+			  + "}";
 		
 		if (FusekiWrapper.getInstance().updateQuery(query) ) {
 			EndActivityEvent ev = new EndActivityEvent();
@@ -217,7 +198,107 @@ public class PTRepository {
 			throw new Exception("Error inserting data.");
 		}		
 	}
+
+	private void createTraceArtifact(String endEvIRI, String startEvIRI, TraceArtifact art, PT pt)
+			throws Exception {
+		
+		TraceArtifact latest = getLastestVersion(startEvIRI,art);
+		
+		String query = "PREFIX pt: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
+				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
+				+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+				+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base/base#>\n"
+				+ "INSERT DATA { \n"
+				+ " <" + art.getIri() + "> rdf:type base:Versionable , pt:Artifact , owl:Thing , pt:element , base:ImmutableThing ;\n"
+				+ "        pt:hasLocation \"" + art.getLocation() + "\" ;\n"
+				+ "        pt:isProducedBy <" + endEvIRI + "> ;\n"
+				+ "        pt:relatesTo <" + art.getRelatesTo().getIri() + "> ;\n"
+				+ "        owl:sameAs  <" + art.getIri() + "> ;\n";
+				if (latest != null) {
+					String newTag = (Integer.parseInt(latest.getTag().substring(1))+1)+"";
+					art.setTag(newTag);
+					art.setGUID(art.getRelatesTo().getName()+"-"+art.getTag());
+					query += "        base:nextVersionOf \"" + latest.getIri() + "\" ;\n"
+					+ "        base:hasGUID \"" + art.getGUID() + "\" ;\n"
+					+ "        base:hasTag \"" + art.getTag() + "\" ;\n"
+					+ "  <" +latest.getIri() + "> base:previousVersionOf <" + art.getIri() +  "> .\n" 
+					+ "}";
+				} else {
+					art.setTag("v1");
+					art.setGUID(art.getRelatesTo().getName()+"-"+art.getTag());
+					query += "        base:hasGUID \"" + art.getGUID() + "\" ;\n"
+					+ "        base:hasTag \"" + art.getTag() + "\" .\n"
+					+ "}";
+				} 
+				
+		if (FusekiWrapper.getInstance().updateQuery(query) ) {
+			art.setTimestamp(Timestamp.from(Instant.now()));
+			if (latest != null) {
+				List<TraceArtifact> inputs = pt.getInputs();
+				boolean found = false;
+				if (inputs != null) {
+					for (TraceArtifact traceArtifact : inputs) {
+						if (traceArtifact.getIri().equals(latest.getIri())) {
+							traceArtifact.setNextVersion(art);
+							found = true;
+							break;
+						}
+					}
+				}
+				
+				if (!found) {
+					List<Event> events = pt.getEvents();
+					for (Event event : events) {
+						if (event instanceof StartActivityEvent && ((StartActivityEvent)event).getArtifact(latest.getIri()) != null) {
+							((StartActivityEvent)event).getArtifact(latest.getIri()).setNextVersion(art);
+							break;
+						} else if (event instanceof EndActivityEvent && ((EndActivityEvent)event).getArtifact(latest.getIri()) != null) {
+							((EndActivityEvent)event).getArtifact(latest.getIri()).setNextVersion(art);
+							break;
+						}  
+					}
+				}
+			}
+		} else {
+			throw new Exception("Error inserting data.");
+		}
+	}
 	
+	private TraceArtifact getLastestVersion(String startEvIRI, TraceArtifact art) {
+		String query = "PREFIX pt: <http://ua.be/sdo2l/vocabulary/formalisms/processtraces#>\n"
+				+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base/base#>\n"
+				+ "SELECT DISTINCT ?art ?version\n"
+				+ "WHERE { \n"
+				+ "  ?art a pt:Artifact .\n"
+				+ "  ?art pt:relatesTo <" + art.getRelatesTo().getIri() + "> .\n"
+				+ "  ?art base:hasTag ?version .\n"
+				+ "  {\n"
+				+ "    {?art pt:isProducedBy ?endEv .\n"
+				+ "    <"+ startEvIRI+ "> pt:isPrecededBy+ ?endEv .} \n"
+				+ "    UNION \n"
+				+ "    {?art pt:isConsumedBy ?startEv .\n"
+				+ "     <"+ startEvIRI+ "> pt:isPrecededBy+ ?startEv .}\n"
+				+ "  }  \n"
+				+ "  FILTER NOT EXISTS {\n"
+				+ "  	?art base:previousVersionOf ?newArt .\n"
+				+ "    FILTER (?art != ?newArt) \n"
+				+ "  }\n"
+				+ "}";
+		ResultSet rs = FusekiWrapper.getInstance().execQuery(query);
+		if (rs.hasNext()) {
+			QuerySolution next = rs.next();
+			RDFNode lastestIRI = next.get("?art");
+			RDFNode latestVersion = next.get("?version");
+			if (lastestIRI != null) {
+				TraceArtifact result = new TraceArtifact();
+				result.setIri(latestVersion.toString());
+				result.setGUID(latestVersion.toString());
+				return result;
+			}
+		}
+		return null;
+	}
+
 	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"
@@ -228,6 +309,7 @@ public class PTRepository {
 				+ " 	tr:isPrecededBy <" + previous + "> ;\n"
 				+ "    	tr:relatesTo <" + pmIRI + "> ;\n"
 				+ "     owl:sameAs  <" + traceiri + "> .\n"
+				+ " <" + previous + "> tr:isFollowedBy <" + traceiri + "> .\n"				
 				+ "}";
 		if (FusekiWrapper.getInstance().updateQuery(query) ) {
 			EndTraceEvent ev = new EndTraceEvent();

+ 11 - 0
src/main/java/ua/be/wee/model/pt/TraceArtifact.java

@@ -22,6 +22,9 @@ public class TraceArtifact {
 	
 	private Timestamp timestamp;
 	
+	private TraceArtifact nextVersion;
+	
+	
 	public Timestamp getTimestamp() {
 		return timestamp;
 	}
@@ -85,4 +88,12 @@ public class TraceArtifact {
 	public void setRelatesTo(Artifact relatesTo) {
 		this.relatesTo = relatesTo;
 	}
+
+	public TraceArtifact getNextVersion() {
+		return nextVersion;
+	}
+
+	public void setNextVersion(TraceArtifact nextVersion) {
+		this.nextVersion = nextVersion;
+	}
 }

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

@@ -116,7 +116,7 @@
     <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:text="${ev.relatesTo.act.name}">...</td>
+        <td style="color: #5e9ca0;" colspan="2" th:text="${ev.relatesTo.activity.name}">...</td>
     </tr>
     <tr>
         <td style="color: #5e9ca0;font-weight: bold;" colspan="2" >port:</td>

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

@@ -118,7 +118,7 @@
     <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:text="${ev.relatesTo.act.name}">...</td>
+        <td style="color: #5e9ca0;" colspan="2" th:text="${ev.relatesTo.activity.name}">...</td>
     </tr>
     <tr>
         <td style="color: #5e9ca0;font-weight: bold;" colspan="2" >port:</td>

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

@@ -68,7 +68,7 @@
     <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;" colspan="2" th:if="${ev.class.name != 'ua.be.wee.model.pt.EndTraceEvent'}" th:text="${ev.relatesTo.activity.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>