package org.simantics.interop.update.model; import java.util.ArrayList; import java.util.Collection; import org.simantics.db.Resource; import org.simantics.db.Statement; 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 * */ public abstract class UpdateOp { private GraphChanges changes; private boolean selected = false; private boolean manualSelection = false; protected boolean applied = false; protected boolean visible = true; protected boolean enabled = true; private Collection parentOps = new ArrayList(); private Collection subOps = new ArrayList(); public UpdateOp(GraphChanges changes) { this.changes = changes; } public Collection getParentOps() { return parentOps; } public Collection 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 boolean isChange() { return isAdd() || isDelete(); } /** * Is parent operation applied before this. * @return */ public abstract boolean requiresParentOps(); /** * Is child operation applied before this. * @return */ public abstract boolean requiresSubOps(); /** * Is parent operation selected when this is selected * @return */ public boolean selectParentOps() { return requiresParentOps(); } /** * Is child operation selected when this is selected * @return */ public boolean selectSubOps() { return requiresSubOps(); } public boolean select(boolean select) { if (!enabled) return false; if (!isChange()) return false; boolean b = _select(select); if (b) manualSelection = true; return b; } private boolean _select(boolean select) { if (select == selected) return true; if (applied) return false; if (!isChange()) return false; if (select) { if (selectParentOps()) { for (UpdateOp op : parentOps) op._select(true); } selected = true; manualSelection = false; if (selectSubOps()) { for (UpdateOp op : subOps) op._select(true); } } else { selected = false; manualSelection = false; for (UpdateOp op : subOps) { if (op.selectParentOps()) op._select(false); else if (!op.manualSelection) op._select(false); } for (UpdateOp op : parentOps) if (op.selectSubOps()) op._select(false); return true; } return false; } public boolean selected() { return selected; } public boolean applied() { return applied; } public boolean isVisible() { return visible; } /** * Is change enabled. Disabled changes do not allow changing selected state. * @return */ public boolean enabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public void apply(WriteGraph g) throws DatabaseException { if (applied) return; _apply(g); applied = true; } /** * Applies the changes into the database. * * @param g * @throws DatabaseException */ 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 is changing. * @return */ public abstract Statement getStatement(); /** * Returns resource that this operation created during apply operation. If operation did not add anything, this returns null. * @return */ public abstract Resource getCreatedResource(); }