--- /dev/null
+package org.simantics.interop.update.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.interop.test.GraphChanges;
+
+/**
+ * Base class for update operations (adding and deleting objects)
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public abstract class UpdateOp {
+
+ private GraphChanges changes;
+
+ private boolean selected = false;
+ private boolean manualSelection = false;
+ protected boolean applied = false;
+
+ private Collection<UpdateOp> parentOps = new ArrayList<UpdateOp>();
+ private Collection<UpdateOp> subOps = new ArrayList<UpdateOp>();
+
+
+ public UpdateOp(GraphChanges changes) {
+ this.changes = changes;
+ }
+
+ public Collection<UpdateOp> getParentOps() {
+ return parentOps;
+ }
+
+ public Collection<UpdateOp> getSubOps() {
+ return subOps;
+ }
+
+ public void addParentOp(UpdateOp op) {
+ assert (!op.equals(this));
+ parentOps.add(op);
+ }
+
+ public void addSubOp(UpdateOp op) {
+ assert (!op.equals(this));
+ subOps.add(op);
+ }
+
+ public void removeParentOp(UpdateOp op) {
+ parentOps.remove(op);
+ }
+
+ public void removeSubOp(UpdateOp op) {
+ subOps.remove(op);
+ }
+
+ public GraphChanges getChanges() {
+ return changes;
+ }
+
+ public abstract boolean isAdd();
+ public abstract boolean isDelete();
+
+ public abstract boolean requiresParentOps();
+ public abstract boolean requiresSubOps();
+
+ public boolean select(boolean select) {
+ boolean b = _select(select);
+ if (b)
+ manualSelection = true;
+ return b;
+ }
+
+ private boolean _select(boolean select) {
+ if (select == selected)
+ return true;
+ if (select) {
+ if (requiresParentOps()) {
+ for (UpdateOp op : parentOps)
+ op._select(true);
+ }
+
+ selected = true;
+ manualSelection = false;
+ if (requiresSubOps()) {
+ for (UpdateOp op : subOps)
+ op._select(true);
+ }
+
+ } else {
+ selected = false;
+ manualSelection = false;
+ for (UpdateOp op : subOps) {
+ if (op.requiresParentOps())
+ op._select(false);
+ else if (!op.manualSelection)
+ op._select(false);
+ }
+ for (UpdateOp op : parentOps)
+ if (op.requiresSubOps())
+ op._select(false);
+ return true;
+ }
+ return false;
+ }
+ public boolean selected() {
+ return selected;
+ }
+
+ public boolean applied() {
+ return applied;
+ }
+ public void apply(WriteGraph g) throws DatabaseException {
+ if (applied)
+ return;
+ _apply(g);
+ applied = true;
+
+ }
+
+ protected abstract void _apply(WriteGraph g) throws DatabaseException;
+
+ /**
+ * Returns resource that this operation is changing.
+ * @return
+ */
+ public abstract Resource getResource();
+
+ /**
+ * Returns resource that this operation created during apply operation. If operation did not add anything, this returns null.
+ * @return
+ */
+ public abstract Resource getCreatedResource();
+
+}