From 2e5e6f18c3d1182386e69f86b78e5a4179dde18a Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Tue, 29 May 2018 16:44:48 +0300 Subject: [PATCH] Added support for filtering changes gitlab #1 Change-Id: I765d0bdad5c304321bd3c82e77c386da890eb02e --- .../scl/Interop/Update.scl | 6 + .../interop/update/model/ModelUpdate.java | 191 ++++++++++++++---- .../simantics/interop/update/model/NopOp.java | 6 + .../interop/update/model/PropertyChange.java | 8 + .../interop/update/model/UpdateList.java | 1 + .../interop/update/model/UpdateNode.java | 11 + .../interop/update/model/UpdateOp.java | 14 ++ 7 files changed, 197 insertions(+), 40 deletions(-) diff --git a/org.simantics.interop.update/scl/Interop/Update.scl b/org.simantics.interop.update/scl/Interop/Update.scl index 31eaff2..f9974ea 100644 --- a/org.simantics.interop.update/scl/Interop/Update.scl +++ b/org.simantics.interop.update/scl/Interop/Update.scl @@ -110,6 +110,9 @@ importJava "org.simantics.interop.update.model.PropertyChange" where @JavaName getSecond getSecond :: PropertyChange -> Maybe Statement + @JavaName isVisible + pcVisible :: PropertyChange -> Boolean + importJava "org.simantics.interop.update.model.UpdateNode" where data UpdateNode @@ -129,6 +132,9 @@ importJava "org.simantics.interop.update.model.UpdateNode" where @JavaName getChildren getNodeChildren :: UpdateNode -> [UpdateNode] + @JavaName isVisible + isNodeVisible :: UpdateNode -> Boolean + importJava "org.simantics.interop.update.model.UpdateStatus" where 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 46bf79e..2149fc5 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 @@ -1,6 +1,9 @@ package org.simantics.interop.update.model; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; import java.util.List; import java.util.Map.Entry; @@ -15,6 +18,7 @@ import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.request.Read; import org.simantics.interop.test.GraphChanges; import org.simantics.interop.test.GraphComparator; +import org.simantics.utils.datastructures.BijectionMap; import org.simantics.utils.datastructures.Pair; public abstract class ModelUpdate { @@ -36,6 +40,7 @@ public abstract class ModelUpdate { private UpdateList updateList3; private List filters = new ArrayList(); + private List userFilters = new ArrayList(); boolean init = false; @@ -55,7 +60,7 @@ public abstract class ModelUpdate { this.oldModel = oldModel; this.newModel = newModel; this.originalModel = originalModel; - addFilters(filters); +// addFilters(filters); if (originalModel != null) { // tree way comparison // compare the original and the old model @@ -65,7 +70,7 @@ public abstract class ModelUpdate { showWarning(result2.second); comparator2.test(getSession()); changes2 = comparator2.getChanges(); - changes2 = getSession().syncRequest(new FilterChangesRead(changes2)); + changes2 = getSession().syncRequest(new FilterChangesRead(changes2, filters)); updateTree2 = getUpdateTree(changes2); updateList2 = getUpdateList(changes2); @@ -76,7 +81,7 @@ public abstract class ModelUpdate { showWarning(result3.second); comparator3.test(getSession()); changes3 = comparator3.getChanges(); - changes3 = getSession().syncRequest(new FilterChangesRead(changes3)); + changes3 = getSession().syncRequest(new FilterChangesRead(changes3, filters)); } Pair result = getChanges(oldModel,newModel); @@ -118,9 +123,12 @@ public abstract class ModelUpdate { } comparator.test(getSession()); changes = comparator.getChanges(); - changes = getSession().syncRequest(new FilterChangesRead(changes)); + changes = getSession().syncRequest(new FilterChangesRead(changes, filters)); updateTree = getUpdateTree(changes); updateList = getUpdateList(changes); + if (userFilters.size() != 0) { + refreshUserFilters(); + } if (originalModel != null) { @@ -130,7 +138,110 @@ public abstract class ModelUpdate { init = true; } + public void addFilter(ChangeFilter filter) { + if (init) + throw new IllegalStateException("ModelUpdate has been initialized, adjusting filters is no longer possible."); + filters.add(filter); + + } + + /** + * Adds an user filter. Use refreshUserFilters() to apply the changes. + * @param filter + */ + public void addUserFilter(ChangeFilter filter) { + userFilters.add(filter); + } + + /** + * Removes an user filter. Use refreshUserFilters() to apply the changes. + * @param filter + */ + public void removeUserFilter(ChangeFilter filter) { + userFilters.remove(filter); + } + + /** + * Clears user filters. Use refreshUserFilters() to apply the changes. + */ + public void clearUserFilters() { + userFilters.clear(); + } + + public void refreshUserFilters() throws DatabaseException{ + // use user filters to set visible flags of changes. + // First, set all changes visible. + Deque stack = new ArrayDeque<>(); + stack.push(updateTree.getRootNode()); + while (!stack.isEmpty()) { + UpdateNode n = stack.pop(); + n.setVisible(true); + stack.addAll(n.getChildren()); + } + for (PropertyChange pc : updateList.getChanges()) { + pc.setVisible(true); + } + if (userFilters.size() > 0) { + // Create filtered changes + List combined = new ArrayList<>(filters); + combined.addAll(userFilters); + GraphChanges filteredChanges = getSession().syncRequest(new FilterChangesRead(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()); + } + } + + 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); + } + } + } + for (PropertyChange lc : l) { + if (!comparable.containsLeft(lc)) + lc.setVisible(false); + } + + } protected abstract Pair getChanges(Resource r1, Resource r2) throws DatabaseException; protected abstract UpdateTree getUpdateTree(GraphChanges changes) throws DatabaseException; @@ -138,10 +249,6 @@ public abstract class ModelUpdate { return new UpdateList(changes, changes.getModifications()); } - protected void addFilters(List filters) { - - } - public Resource getOldModel() { return oldModel; } @@ -226,46 +333,50 @@ public abstract class ModelUpdate { private class FilterChangesRead implements Read { private GraphChanges changes; - public FilterChangesRead(GraphChanges changes) { + private List filters; + + public FilterChangesRead(GraphChanges changes, List filters) { this.changes = changes; + this.filters = filters; } @Override public GraphChanges perform(ReadGraph graph) throws DatabaseException { return filterChanges(graph, changes); } - } - - /** - * Filters changes: - * 1. Changes that are not essential for model update (changes that can be found when the models are axcatly the same) - * 2. Runs custom filters for value changes. - * - * @param g - * @param changes - * @return - * @throws DatabaseException - */ - protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException - { - - List> modifications = new ArrayList>(); - for (Pair mod : changes.getModifications()) { - - boolean accept = true; - for (ChangeFilter filter : filters) { - if (!filter.accept(g, mod)) { - accept = false; - break; - } - } - if (accept) - modifications.add(mod); - } - GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable()); - return newChanges; - } + /** + * Filters changes: + * 1. Changes that are not essential for model update (changes that can be found when the models are axcatly the same) + * 2. Runs custom filters for value changes. + * + * @param g + * @param changes + * @return + * @throws DatabaseException + */ + protected GraphChanges filterChanges(ReadGraph g, GraphChanges changes) throws DatabaseException + { + + List> modifications = new ArrayList>(); + + for (Pair mod : changes.getModifications()) { + + boolean accept = true; + for (ChangeFilter filter : filters) { + if (!filter.accept(g, mod)) { + accept = false; + break; + } + } + if (accept) + modifications.add(mod); + } + GraphChanges newChanges = new GraphChanges(changes.getResource1(),changes.getResource2(),changes.getDeletions(), changes.getAdditions(), modifications, changes.getComparable()); + return newChanges; + } + } + public interface ChangeFilter { public boolean accept(ReadGraph g, Pair change) throws DatabaseException; diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/NopOp.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/NopOp.java index 2dfb30f..f2316d5 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/NopOp.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/NopOp.java @@ -1,6 +1,7 @@ package org.simantics.interop.update.model; 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; @@ -34,6 +35,11 @@ public class NopOp extends UpdateOp{ return r; } + @Override + public Statement getStatement() { + return null; + } + @Override public boolean isAdd() { return false; diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/PropertyChange.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/PropertyChange.java index 9867a39..25d4359 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/PropertyChange.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/PropertyChange.java @@ -12,6 +12,7 @@ public class PropertyChange { protected Pair pair; protected boolean applied = false; protected boolean selected = false; + protected boolean visible = true; public PropertyChange(GraphChanges changes, Statement first, Statement second) { @@ -87,5 +88,12 @@ public class PropertyChange { return applied; } + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } } diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateList.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateList.java index 6f66ba3..beb0e43 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateList.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateList.java @@ -10,6 +10,7 @@ import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.exception.DatabaseException; import org.simantics.interop.test.GraphChanges; +import org.simantics.interop.update.model.ModelUpdate.ChangeFilter; import org.simantics.utils.datastructures.Pair; public class UpdateList { diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateNode.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateNode.java index 486b3a1..3a79531 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateNode.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateNode.java @@ -16,6 +16,7 @@ public class UpdateNode { private UpdateOp op; private Resource r; private String label; + private boolean visible = true; private Collection children = new ArrayList(); @@ -101,5 +102,15 @@ public class UpdateNode { public UpdateOp getOp() { return op; } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + if (op != null) + op.visible = visible; + } } diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOp.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOp.java index 6809ea7..00d1139 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOp.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOp.java @@ -4,6 +4,7 @@ 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; @@ -21,6 +22,7 @@ public abstract class UpdateOp { private boolean selected = false; private boolean manualSelection = false; protected boolean applied = false; + protected boolean visible = true; private Collection parentOps = new ArrayList(); private Collection subOps = new ArrayList(); @@ -142,6 +144,12 @@ public abstract class UpdateOp { public boolean applied() { return applied; } + + public boolean isVisible() { + return visible; + } + + public void apply(WriteGraph g) throws DatabaseException { if (applied) return; @@ -164,6 +172,12 @@ public abstract class UpdateOp { */ 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 -- 2.47.1