X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.interop.update%2Fsrc%2Forg%2Fsimantics%2Finterop%2Fupdate%2Fmodel%2FModelUpdate.java;h=32da62bb523bcc67c72baaddf0fac74fe305687d;hb=92b414c8ba889933a493d10b3c609edbb8aab95e;hp=cbdfc8f48f5cefe15c5b2ffe570b0201b269c509;hpb=3c9703b0855a8d19d515ae38fa16b4d2bea645df;p=simantics%2Finterop.git diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java index cbdfc8f..32da62b 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java @@ -2,24 +2,26 @@ package org.simantics.interop.update.model; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Deque; import java.util.List; import java.util.Map.Entry; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.request.Read; import org.simantics.interop.test.GraphChanges; +import org.simantics.interop.test.GraphChanges.Modification; import org.simantics.interop.test.GraphComparator; -import org.simantics.utils.datastructures.BijectionMap; import org.simantics.utils.datastructures.Pair; public abstract class ModelUpdate { @@ -40,8 +42,10 @@ public abstract class ModelUpdate { private UpdateTree updateTree3; private UpdateList updateList3; + private UpdateNode3 updateNode3; + private List filters = new ArrayList(); - private List userFilters = new ArrayList(); + private List userFilters = new ArrayList(); boolean init = false; @@ -58,9 +62,16 @@ public abstract class ModelUpdate { * @throws DatabaseException */ public void setInput(Resource oldModel, Resource newModel, Resource originalModel, boolean newDistinct) throws DatabaseException{ + this.setInput(oldModel, newModel, originalModel, newDistinct, null); + } + public void setInput(Resource oldModel, Resource newModel, Resource originalModel, boolean newDistinct, IProgressMonitor monitor) throws DatabaseException{ + this.oldModel = oldModel; this.newModel = newModel; this.originalModel = originalModel; + + if (monitor == null) + monitor = new NullProgressMonitor(); // addFilters(filters); if (originalModel != null) { // tree way comparison @@ -69,21 +80,26 @@ public abstract class ModelUpdate { GraphComparator comparator2 = result2.first; if (result2.second != null) showWarning(result2.second); - comparator2.test(getSession()); + comparator2.test(getSession(), monitor); changes2 = comparator2.getChanges(); + if (monitor.isCanceled()) + return; changes2 = getSession().syncRequest(createFilterRead(changes2, filters)); - updateTree2 = getUpdateTree(changes2); - updateList2 = getUpdateList(changes2); + Pair chg2 = createChangeObjects(changes2, null); + updateTree2 = chg2.first; + updateList2 = chg2.second; // compare the original and the new model Pair result3 = getChanges(originalModel,newModel); GraphComparator comparator3 = result3.first; if (result3.second != null) showWarning(result3.second); - comparator3.test(getSession()); + comparator3.test(getSession(), monitor); changes3 = comparator3.getChanges(); changes3 = getSession().syncRequest(createFilterRead(changes3, filters)); } + if (monitor.isCanceled()) + return; Pair result = getChanges(oldModel,newModel); GraphComparator comparator = result.first; @@ -122,11 +138,16 @@ public abstract class ModelUpdate { } } } - comparator.test(getSession()); + if (monitor.isCanceled()) + return; + comparator.test(getSession(), monitor); + monitor.setTaskName("Processing changes..."); + monitor.subTask(""); changes = comparator.getChanges(); changes = getSession().syncRequest(createFilterRead(changes, filters)); - updateTree = getUpdateTree(changes); - updateList = getUpdateList(changes); + Pair chg = createChangeObjects(changes, monitor); + updateTree = chg.first; + updateList = chg.second; if (userFilters.size() != 0) { refreshUserFilters(); } @@ -135,7 +156,6 @@ public abstract class ModelUpdate { if (originalModel != null) { defaultSelections(); } - init = true; } @@ -154,7 +174,7 @@ public abstract class ModelUpdate { * Adds an user filter. Use refreshUserFilters() to apply the changes. * @param filter */ - public void addUserFilter(ChangeFilter filter) { + public void addUserFilter(ChangeFilter2 filter) { userFilters.add(filter); } @@ -162,7 +182,7 @@ public abstract class ModelUpdate { * Removes an user filter. Use refreshUserFilters() to apply the changes. * @param filter */ - public void removeUserFilter(ChangeFilter filter) { + public void removeUserFilter(ChangeFilter2 filter) { userFilters.remove(filter); } @@ -173,7 +193,7 @@ public abstract class ModelUpdate { userFilters.clear(); } - public List getUserFilters() { + public List getUserFilters() { return userFilters; } @@ -191,74 +211,87 @@ public abstract class ModelUpdate { pc.setVisible(true); } if (userFilters.size() > 0) { - // Create filtered changes - List combined = new ArrayList<>(filters); - combined.addAll(userFilters); - GraphChanges filteredChanges = getSession().syncRequest(createFilterRead(changes, combined)); - UpdateTree updateTreeF = getUpdateTree(filteredChanges); - UpdateList updateListF = getUpdateList(filteredChanges); - // hide changes that are not contained within the filtered changes. - applyVisibleFlags(updateTree.getRootNode(), updateTreeF.getRootNode()); - applyVisibleFlags(updateList.getChanges(), updateListF.getChanges()); + if (changes2 != null && changes3 != null) { + getUpdateTree3(); + } + getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + for (PropertyChange change : updateList.getChanges()) { + boolean visible = true; + for (ChangeFilter2 filter : userFilters) { + if (!filter.accept(graph, change)) { + visible = false; + break; + } + } + change.setVisible(visible); + } + if (updateTree3 != null) { + Deque stack = new ArrayDeque<>(); + stack.add(getUpdateNode3()); + while (!stack.isEmpty()) { + UpdateNode3 n = stack.pop(); + boolean visible = true; + for (ChangeFilter2 filter : userFilters) { + if (!filter.accept(graph, n)) { + visible = false; + break; + } + } + n.setVisible(visible); + for (UpdateNode3 c : n.getChildren()) + stack.push(c); + } + } else { + + Deque stack = new ArrayDeque<>(); + stack.add(updateTree.getRootNode()); + while (!stack.isEmpty()) { + UpdateNode n = stack.pop(); + boolean visible = true; + for (ChangeFilter2 filter : userFilters) { + if (!filter.accept(graph, n)) { + visible = false; + break; + } + } + n.setVisible(visible); + for (UpdateNode c : n.getChildren()) + stack.push(c); + } + } + } + }); } } - private void applyVisibleFlags(UpdateNode l, UpdateNode r) { - BijectionMap comparable = new BijectionMap<>(); - for (UpdateNode lc : l.getChildren()) { - for (UpdateNode rc : r.getChildren()) { - if (comparable.containsRight(rc)) - continue; - if (lc.getResource() != null) { - if (lc.getResource().equals(rc.getResource())) { - - comparable.map(lc, rc); - break; - } - } else if (rc.getResource() == null){ - UpdateOp lop = lc.getOp(); - UpdateOp rop = rc.getOp(); - if (lop.getStatement() != null && lop.getStatement().equals(rop.getStatement())) { - comparable.map(lc, rc); - break; - } - } - } - } - for (UpdateNode lc : l.getChildren()) { - if (!comparable.containsLeft(lc)) - lc.setVisible(false); - } - for (Entry entry : comparable.getEntries()) { - applyVisibleFlags(entry.getKey(), entry.getValue()); - } - } - - private void applyVisibleFlags(Collection l, Collection r) { - BijectionMap comparable = new BijectionMap<>(); - for (PropertyChange lc : l) { - for (PropertyChange rc : r) { - if (comparable.containsRight(rc)) - continue; - if (lc.getFirst().equals(rc.getFirst())) { - comparable.map(lc, rc); - break; - } - } - } - for (PropertyChange lc : l) { - if (!comparable.containsLeft(lc)) - lc.setVisible(false); - } - + protected abstract Pair getChanges(Resource r1, Resource r2) throws DatabaseException; + + protected Pair createChangeObjects(GraphChanges changes, IProgressMonitor monitor) throws DatabaseException{ + if (monitor != null) + monitor.subTask("Processing structural changes"); + UpdateTree updateTree = getUpdateTree(changes); + if (monitor != null) + monitor.subTask("Processing property changes"); + UpdateList updateList = getUpdateList(changes); + if (monitor != null) + monitor.subTask("Postprocessing changes"); + postProcess(updateTree, updateList); + return new Pair(updateTree, updateList); } - protected abstract Pair getChanges(Resource r1, Resource r2) throws DatabaseException; protected abstract UpdateTree getUpdateTree(GraphChanges changes) throws DatabaseException; protected UpdateList getUpdateList(GraphChanges changes) throws DatabaseException { return new UpdateList(changes, changes.getModifications()); } + + protected void postProcess(UpdateTree updateTree, UpdateList updateList) throws DatabaseException{ + + } + public Resource getOldModel() { return oldModel; } @@ -300,15 +333,28 @@ public abstract class ModelUpdate { } public UpdateTree getUpdateTree3() throws DatabaseException{ - if (updateTree3 == null && changes3 != null) - updateTree3 = getUpdateTree(changes3); + if (updateTree3 == null && changes3 != null) { + Pair chg3 = createChangeObjects(changes3, null); + updateTree3 = chg3.first; + updateList3 = chg3.second; + } return updateTree3; } public UpdateList getUpdateList3() throws DatabaseException { - if (updateList3 == null && changes3 != null) - updateList3 = getUpdateList(changes3); + if (updateList3 == null && changes3 != null) { + Pair chg3 = createChangeObjects(changes3, null); + updateTree3 = chg3.first; + updateList3 = chg3.second; + } return updateList3; } + + public UpdateNode3 getUpdateNode3() throws DatabaseException { + if (updateNode3 == null && changes2 != null && changes3 != null) { + updateNode3 = UpdateNode3.getCombinedTree(this); + } + return updateNode3; + } public void applyAll(WriteGraph graph) throws DatabaseException { @@ -324,12 +370,13 @@ public abstract class ModelUpdate { public void applySelected(WriteGraph graph) throws DatabaseException { Layer0Utils.addCommentMetadata(graph, "Apply selected model updates"); graph.markUndoPoint(); + + updateTree.getUpdateOps().applySelected(graph); + for (PropertyChange mod : updateList.getChanges()) { if (mod.selected()) mod.apply(graph); } - - updateTree.getUpdateOps().applySelected(graph); } @@ -372,9 +419,9 @@ public abstract class ModelUpdate { protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException { - List> modifications = new ArrayList>(); + List modifications = new ArrayList(); - for (Pair mod : changes.getModifications()) { + for (Modification mod : changes.getModifications()) { boolean accept = true; for (ChangeFilter filter : filters) { @@ -386,14 +433,61 @@ public abstract class ModelUpdate { if (accept) modifications.add(mod); } - GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable()); + List deletions = new ArrayList(); + for (Statement del : changes.getDeletions()) { + + boolean accept = true; + for (ChangeFilter filter : filters) { + if (!filter.acceptDeletion(g, del)) { + accept = false; + break; + } + } + if (accept) + deletions.add(del); + } + List additions = new ArrayList(); + for (Statement del : changes.getAdditions()) { + + boolean accept = true; + for (ChangeFilter filter : filters) { + if (!filter.acceptAddition(g, del)) { + accept = false; + break; + } + } + if (accept) + additions.add(del); + } + + GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),deletions, additions, modifications, changes.getComparable()); return newChanges; } } - + /** + * Interface for built-in filters that are used for processing raw change data before forming UpdateTree + UpdateList + * @author luukkainen + * + */ public interface ChangeFilter { - public boolean accept(ReadGraph g, Pair change) throws DatabaseException; + public boolean accept(ReadGraph g, Modification change) throws DatabaseException; + public boolean acceptAddition(ReadGraph g, Statement addition) throws DatabaseException; + public boolean acceptDeletion(ReadGraph g, Statement deletion) throws DatabaseException; + } + + /** + * Interface for user defined filters. + * + * This filter only affects visible flags. + * + * @author luukkainen + * + */ + public interface ChangeFilter2 { + public boolean accept(ReadGraph g, PropertyChange change) throws DatabaseException; + public boolean accept(ReadGraph g, UpdateNode change) throws DatabaseException; + public boolean accept(ReadGraph g, UpdateNode3 change) throws DatabaseException; } @@ -417,12 +511,14 @@ public abstract class ModelUpdate { } @Override - public boolean accept(ReadGraph g, Pair change) throws DatabaseException { + public boolean accept(ReadGraph g, Modification change) throws DatabaseException { //filter floating point values that have less than 1% difference. - if (!g.hasValue(change.first.getObject()) || !g.hasValue(change.second.getObject())) + if (change.getLeftStm() == null || change.getRightStm() == null) + return true; + if (!g.hasValue(change.getLeftStm().getObject()) || !g.hasValue(change.getRightStm().getObject())) return true; - Object v1 = g.getValue(change.first.getObject()); - Object v2 = g.getValue(change.second.getObject()); + Object v1 = g.getValue(change.getLeftStm().getObject()); + Object v2 = g.getValue(change.getRightStm().getObject()); if (v1 instanceof Double && v2 instanceof Double) { double d1 = (Double)v1; @@ -438,6 +534,16 @@ public abstract class ModelUpdate { return true; } + + @Override + public boolean acceptAddition(ReadGraph g, Statement addition) throws DatabaseException { + return true; + } + + @Override + public boolean acceptDeletion(ReadGraph g, Statement deletion) throws DatabaseException { + return true; + } } public void defaultSelections() { @@ -471,7 +577,7 @@ public abstract class ModelUpdate { if (pair.getFirst() != null) { boolean found = false; for (PropertyChange pair2 : updateList2.getChanges()) { - if (pair.getFirst().equals(pair2.getSecond())) { + if (pair.getFirst() != null && pair.getFirst().equals(pair2.getSecond())) { found = true; break; } @@ -502,4 +608,19 @@ public abstract class ModelUpdate { public void removeListener(WarningListener listener) { warningListeners.remove(listener); } + + public void dispose() { + changes = null; + changes2 = null; + changes3 = null; + filters = null; + userFilters = null; + updateList = null; + updateList2 = null; + updateList3 = null; + updateTree = null; + updateTree2 = null; + updateTree3 = null; + updateNode3 = null; + } }