+package org.simantics.interop.update.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.interop.test.GraphChanges;
+import org.simantics.interop.update.model.UpdateNode.Status;
+
+
+public abstract class UpdateTree {
+
+ private UpdateNode rootNode;
+ private Map<Resource,UpdateNode> nodes;
+ private GraphChanges changes;
+ private UpdateOperations updateOps;
+
+
+ public UpdateTree(ReadGraph g, GraphChanges changes, UpdateOperations updateOps) throws DatabaseException {
+ this.changes = changes;
+ this.nodes = new HashMap<Resource, UpdateNode>();
+ this.rootNode = createNode(Status.EXIST, changes.getResource1());
+ nodes.put(changes.getResource1(), rootNode);
+ nodes.put(changes.getResource2(), rootNode);
+ this.updateOps = updateOps;
+ this.updateOps.populate(g);
+ populate(g);
+ }
+
+ public UpdateOperations getUpdateOps() {
+ return updateOps;
+ }
+
+ public UpdateNode getRootNode() {
+ return rootNode;
+ }
+
+ protected abstract UpdateNode createNode(Status staus, Resource r);
+ protected abstract UpdateNode createNode(Status staus, UpdateOp op);
+
+ private UpdateNode createNode(Resource r1, Resource r2) {
+ UpdateNode node = null;
+ if (r1 != null && r2 != null) {
+ node = createNode(Status.EXIST, r1);
+ nodes.put(r1, node);
+ nodes.put(r2, node);
+ } else if (r1 != null) {
+ node = createNode(Status.DELETED ,updateOps.getUpdateOp(r1));
+ nodes.put(r1, node);
+ } else if (r2 != null) {
+ node = createNode(Status.NEW, updateOps.getUpdateOp(r2));
+ nodes.put(r2, node);
+ }
+ return node;
+ }
+
+ public UpdateNode addNode(ReadGraph g, Resource r1, Resource r2) throws DatabaseException {
+ if (r1 != null && r2 != null) {
+ return null;
+ }
+ if (nodes.containsKey(r1))
+ return nodes.get(r1);
+ if (nodes.containsKey(r2))
+ return nodes.get(r2);
+
+ UpdateNode node = createNode(r1, r2);
+ connectParent(g,node);
+ return node;
+
+ }
+
+ private boolean connectParent(ReadGraph g, UpdateNode node) throws DatabaseException {
+ UpdateNode parent = null;
+ while (true) {
+ Resource parentResource = node.getParentResource(g);
+ parent = nodes.get(parentResource);
+ if (parent == null) {
+ if (changes.getComparable().containsLeft(parentResource)) {
+ parent = createNode(parentResource, changes.getComparable().getRight(parentResource));
+ } else if (changes.getComparable().containsRight(parentResource)) {
+ parent = createNode(changes.getComparable().getLeft(parentResource) ,parentResource);
+ } else {
+ return false;
+ }
+ //parent.setStatus(Status.CONTAINS);
+ parent.addChild(node);
+ node = parent;
+ parent = null;
+ } else {
+ parent.addChild(node);
+ return true;
+ }
+
+ }
+ }
+
+ protected abstract boolean handleCustom(ReadGraph g, UpdateOp op) throws DatabaseException;
+
+ private void populate(ReadGraph g) throws DatabaseException{
+
+ for (UpdateOp op : updateOps.getOperations()) {
+ if (!handleCustom(g, op)) {
+ if (op.isAdd()) {
+ addNode(g, null,op.getResource());
+ } else {
+ addNode(g, op.getResource(), null);
+ }
+ }
+ }
+
+ }
+
+}