-package org.simantics.db.layer0.genericrelation;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
-import org.simantics.db.common.request.IndexRoots;\r
-import org.simantics.db.common.request.PossibleIndexRoot;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.Change;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.ChangeType;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentAddition;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentModification;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentRemoval;\r
-import org.simantics.db.layer0.genericrelation.DependencyChanges.LinkChange;\r
-import org.simantics.db.service.CollectionSupport;\r
-import org.simantics.layer0.Layer0;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-public class DependencyChangesWriter {\r
- ReadGraph g;\r
- Layer0 l0;\r
-\r
- THashMap<Resource, Change> changesByResource = new THashMap<>();\r
- ArrayList<ComponentRemoval> removals = new ArrayList<>();\r
-\r
- public DependencyChangesWriter(ReadGraph g) {\r
- this.g = g;\r
- this.l0 = Layer0.getInstance(g);\r
- }\r
-\r
- public void addComponentModification(Resource component) throws DatabaseException {\r
- if (!component.isPersistent())\r
- return;\r
- if(!changesByResource.contains(component))\r
- changesByResource.put(component, new ComponentModification(component));\r
- }\r
-\r
- public void addLinkChange(Resource component) throws DatabaseException {\r
- if (!component.isPersistent())\r
- return;\r
- //if(!changesByResource.contains(component))\r
- changesByResource.put(component, new LinkChange(component));\r
- }\r
-\r
- public void addComponentAddition(Resource parent, Resource component) throws DatabaseException {\r
- if (!component.isPersistent())\r
- return;\r
- changesByResource.put(component, new ComponentAddition(component, parent));\r
- }\r
-\r
- public void addComponentRemoval(Resource parent, Resource component) throws DatabaseException {\r
-// System.err.println("addComponentRemoval " + component);\r
- // NOTE: removals are registered by their parent resource because the\r
- // (component, PartOf, parent) link no longer exists and the model cannot\r
- // be found otherwise.\r
-// changesByResource.put(parent, new ComponentRemoval(component, parent));\r
- if (!component.isPersistent())\r
- return;\r
- removals.add(new ComponentRemoval(component, parent));\r
- }\r
-\r
- public DependencyChanges getResult() throws DatabaseException {\r
- THashMap<Resource, ArrayList<Change>> changes = new THashMap<>();\r
- CollectionSupport cs = g.getService(CollectionSupport.class);\r
- List<Resource> keys = cs.asSortedList(changesByResource.keySet());\r
- boolean hasUnresolved = false;\r
- for(Resource key : keys) {\r
- Change change = changesByResource.get(key);\r
- // Default logic with simpler index root resolution.\r
- Resource model = g.syncRequest(new PossibleIndexRoot(key), TransientCacheListener.<Resource>instance());\r
- boolean modelFound = model != null;\r
- if (model != null) {\r
- addChange(model, change, changes);\r
- } else {\r
- // Very heavy fallback logic\r
- Collection<Resource> models = g.syncRequest(new IndexRoots(key), TransientCacheListener.<Collection<Resource>>instance());\r
- for(Resource m : models)\r
- addChange(m, change, changes);\r
- modelFound = !models.isEmpty();\r
- }\r
- if (modelFound && change.getType() == ChangeType.COMPONENT_ADDITION) {\r
- hasUnresolved = true;\r
- }\r
- }\r
- if (!removals.isEmpty()) {\r
- THashMap<Resource, ComponentRemoval> removedComponents = new THashMap<>(removals.size());\r
- for(ComponentRemoval removal : removals)\r
- removedComponents.put(removal.component, removal);\r
- for(ComponentRemoval removal : removals) {\r
- Resource parent = removal.parent;\r
- Collection<Resource> models = getModelsForRemoved(g, parent, removedComponents); \r
- for(Resource model : models) {\r
- ArrayList<Change> modelChanges = changes.get(model);\r
- if(modelChanges == null) {\r
- modelChanges = new ArrayList<>();\r
- changes.put(model, modelChanges);\r
- }\r
- modelChanges.add(removal);\r
- }\r
- if(models.isEmpty() && !removedComponents.contains(parent)) {\r
- hasUnresolved = true;\r
- }\r
- }\r
- }\r
-\r
- return new DependencyChanges(changes, hasUnresolved);\r
- }\r
-\r
- private void addChange(Resource model, Change change, Map<Resource, ArrayList<Change>> changes) {\r
- ArrayList<Change> modelChanges = changes.get(model);\r
- if(modelChanges == null) {\r
- modelChanges = new ArrayList<>();\r
- changes.put(model, modelChanges);\r
- }\r
- modelChanges.add(change);\r
- }\r
-\r
- private Collection<Resource> getModelsForRemoved(ReadGraph graph, Resource resource, THashMap<Resource, ComponentRemoval> removedComponents) throws DatabaseException {\r
- ComponentRemoval removal = removedComponents.get(resource);\r
- if(removal == null) {\r
- Resource model = g.syncRequest(new PossibleIndexRoot(resource), TransientCacheListener.<Resource>instance());\r
- if (model != null)\r
- return Collections.singleton(model);\r
- return graph.syncRequest(new IndexRoots(resource), TransientCacheListener.<Collection<Resource>>instance());\r
- }\r
- return getModelsForRemoved(graph, removal.parent, removedComponents);\r
- }\r
- \r
-}\r
+package org.simantics.db.layer0.genericrelation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.IndexRoots;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.Change;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ChangeType;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentAddition;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentModification;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentRemoval;
+import org.simantics.db.layer0.genericrelation.DependencyChanges.LinkChange;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.layer0.Layer0;
+
+import gnu.trove.map.hash.THashMap;
+
+public class DependencyChangesWriter {
+ ReadGraph g;
+ Layer0 l0;
+
+ THashMap<Resource, Change> changesByResource = new THashMap<>();
+ ArrayList<ComponentRemoval> removals = new ArrayList<>();
+
+ public DependencyChangesWriter(ReadGraph g) {
+ this.g = g;
+ this.l0 = Layer0.getInstance(g);
+ }
+
+ public void addComponentModification(Resource component) throws DatabaseException {
+ if (!component.isPersistent())
+ return;
+ if(!changesByResource.contains(component))
+ changesByResource.put(component, new ComponentModification(component));
+ }
+
+ public void addLinkChange(Resource component) throws DatabaseException {
+ if (!component.isPersistent())
+ return;
+ //if(!changesByResource.contains(component))
+ changesByResource.put(component, new LinkChange(component));
+ }
+
+ public void addComponentAddition(Resource parent, Resource component) throws DatabaseException {
+ if (!component.isPersistent())
+ return;
+ changesByResource.put(component, new ComponentAddition(component, parent));
+ }
+
+ public void addComponentRemoval(Resource parent, Resource component) throws DatabaseException {
+// System.err.println("addComponentRemoval " + component);
+ // NOTE: removals are registered by their parent resource because the
+ // (component, PartOf, parent) link no longer exists and the model cannot
+ // be found otherwise.
+// changesByResource.put(parent, new ComponentRemoval(component, parent));
+ if (!component.isPersistent())
+ return;
+ removals.add(new ComponentRemoval(component, parent));
+ }
+
+ public DependencyChanges getResult() throws DatabaseException {
+ THashMap<Resource, ArrayList<Change>> changes = new THashMap<>();
+ CollectionSupport cs = g.getService(CollectionSupport.class);
+ List<Resource> keys = cs.asSortedList(changesByResource.keySet());
+ boolean hasUnresolved = false;
+ for(Resource key : keys) {
+ Change change = changesByResource.get(key);
+ // Default logic with simpler index root resolution.
+ Resource model = g.syncRequest(new PossibleIndexRoot(key), TransientCacheListener.<Resource>instance());
+ boolean modelFound = model != null;
+ if (model != null) {
+ addChange(model, change, changes);
+ } else {
+ // Very heavy fallback logic
+ Collection<Resource> models = g.syncRequest(new IndexRoots(key), TransientCacheListener.<Collection<Resource>>instance());
+ for(Resource m : models)
+ addChange(m, change, changes);
+ modelFound = !models.isEmpty();
+ }
+ if (modelFound && change.getType() == ChangeType.COMPONENT_ADDITION) {
+ hasUnresolved = true;
+ }
+ }
+ if (!removals.isEmpty()) {
+ THashMap<Resource, ComponentRemoval> removedComponents = new THashMap<>(removals.size());
+ for(ComponentRemoval removal : removals)
+ removedComponents.put(removal.component, removal);
+ for(ComponentRemoval removal : removals) {
+ Resource parent = removal.parent;
+ Collection<Resource> models = getModelsForRemoved(g, parent, removedComponents);
+ for(Resource model : models) {
+ ArrayList<Change> modelChanges = changes.get(model);
+ if(modelChanges == null) {
+ modelChanges = new ArrayList<>();
+ changes.put(model, modelChanges);
+ }
+ modelChanges.add(removal);
+ }
+ if(models.isEmpty() && !removedComponents.contains(parent)) {
+ hasUnresolved = true;
+ }
+ }
+ }
+
+ return new DependencyChanges(changes, hasUnresolved);
+ }
+
+ private void addChange(Resource model, Change change, Map<Resource, ArrayList<Change>> changes) {
+ ArrayList<Change> modelChanges = changes.get(model);
+ if(modelChanges == null) {
+ modelChanges = new ArrayList<>();
+ changes.put(model, modelChanges);
+ }
+ modelChanges.add(change);
+ }
+
+ private Collection<Resource> getModelsForRemoved(ReadGraph graph, Resource resource, THashMap<Resource, ComponentRemoval> removedComponents) throws DatabaseException {
+ ComponentRemoval removal = removedComponents.get(resource);
+ if(removal == null) {
+ Resource model = g.syncRequest(new PossibleIndexRoot(resource), TransientCacheListener.<Resource>instance());
+ if (model != null)
+ return Collections.singleton(model);
+ return graph.syncRequest(new IndexRoots(resource), TransientCacheListener.<Collection<Resource>>instance());
+ }
+ return getModelsForRemoved(graph, removal.parent, removedComponents);
+ }
+
+}