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; public class UpdateTree { private UpdateNode rootNode; private Map nodes; private GraphChanges changes; private UpdateOperations updateOps; public UpdateTree(ReadGraph g, GraphChanges changes, UpdateOperations updateOps) throws DatabaseException { this.changes = changes; this.nodes = new HashMap(); this.rootNode = createNode(g, UpdateStatus.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; } public GraphChanges getChanges() { return changes; } protected UpdateNode createNode(ReadGraph g, UpdateStatus status, Resource r) throws DatabaseException { return new UpdateNode(g,status, r); } protected UpdateNode createNode(ReadGraph g, UpdateStatus status, UpdateOp op) throws DatabaseException{ return new UpdateNode(g,status, op); } private UpdateNode createNode(ReadGraph g, Resource r1, Resource r2) throws DatabaseException { UpdateNode node = null; if (r1 != null && r2 != null) { UpdateOp op = updateOps.getUpdateOp(r1); if (op == null) op = updateOps.getUpdateOp(r2); if (op == null) node = createNode(g, UpdateStatus.EXIST, r1); else node = createNode(g, UpdateStatus.EXIST, op); nodes.put(r1, node); nodes.put(r2, node); } else if (r1 != null) { node = createNode(g,UpdateStatus.DELETED ,updateOps.getUpdateOp(r1)); nodes.put(r1, node); } else if (r2 != null) { node = createNode(g,UpdateStatus.NEW, updateOps.getUpdateOp(r2)); nodes.put(r2, node); } return node; } public UpdateNode addNode(ReadGraph g, Resource r1, Resource r2) throws DatabaseException { if (nodes.containsKey(r1)) return nodes.get(r1); if (nodes.containsKey(r2)) return nodes.get(r2); UpdateNode node = createNode(g, r1, r2); connectParent(g,node); return node; } public UpdateNode getNode(Resource r) { return nodes.get(r); } protected 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) { parent = getOrCreate(g, parentResource); if (parent == null) return false; //parent.setStatus(Status.CONTAINS); parent.addChild(node); node = parent; parent = null; } else { parent.addChild(node); return true; } } } protected UpdateNode getOrCreate(ReadGraph g, Resource parentResource) throws DatabaseException { UpdateNode parent = nodes.get(parentResource); if (parent == null) { if (changes.getComparable().containsLeft(parentResource)) { parent = createNode(g, parentResource, changes.getComparable().getRight(parentResource)); } else if (changes.getComparable().containsRight(parentResource)) { parent = createNode(g, changes.getComparable().getLeft(parentResource) ,parentResource); } else { return null; } //parent.setStatus(Status.CONTAINS } return parent; } protected boolean handleCustom(ReadGraph g, UpdateOp op) throws DatabaseException { return false; } 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 if (op.isDelete()){ addNode(g, op.getResource(), null); } else if (op.isChange()) { Resource l = getChanges().getComparable().containsLeft(op.getResource()) ? op.getResource() :getChanges().getComparable().getLeft(op.getResource()); Resource r = getChanges().getComparable().containsRight(op.getResource()) ? op.getResource() :getChanges().getComparable().getRight(op.getResource()); addNode(g, l, r); } } } } }