--- /dev/null
+package org.simantics.modeling.utils;\r
+\r
+import java.util.Collections;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.MetadataI;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.UndoMetadata;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.genericrelation.DependencyChanges;\r
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentAddition;\r
+import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentModification;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.service.CollectionSupport;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.modeling.adapters.ChangeHistoryUpdated;\r
+import org.simantics.modeling.adapters.SkipChangeHistoryUpdate;\r
+\r
+/**\r
+ * @author Antti Villberg\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class OntologicalRequirementTracker {\r
+\r
+ private static final boolean DEBUG = false;\r
+ private static final boolean DEBUG_MODIFICATIONS = false;\r
+ private static final boolean DEBUG_PROPAGATE = false;\r
+\r
+ private Layer0 L0;\r
+ private DiagramResource DIA;\r
+\r
+ private void propagate(ReadGraph graph, Resource r, Set<Resource> rs) throws DatabaseException {\r
+ if (!r.isPersistent()) return;\r
+ if (!rs.add(r)) return;\r
+ if (DEBUG_PROPAGATE)\r
+ System.out.println("propagated to: " + NameUtils.getURIOrSafeNameInternal(graph, r));\r
+ if (graph.isInstanceOf(r, L0.IndexRoot)) return;\r
+ Resource owner = graph.getPossibleObject(r, L0.IsOwnedBy);\r
+ if (owner == null)\r
+ return;\r
+ if (graph.isInstanceOf(r, DIA.DiagramContainer)) {\r
+ // Diagram changes do not touch the composite - but do propagate from folder\r
+ owner = graph.getPossibleObject(owner, L0.PartOf);\r
+ if (owner == null) return;\r
+ }\r
+ propagate(graph, owner, rs);\r
+ }\r
+\r
+ public void update(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {\r
+ \r
+ if (metadata != null) {\r
+ boolean isUndo = metadata.getMetadata().containsKey(UndoMetadata.class.getName());\r
+ boolean wasHistoryUpdate = metadata.getMetadata().containsKey(ChangeHistoryUpdated.class.getName());\r
+ boolean skipUpdate = metadata.getMetadata().containsKey(SkipChangeHistoryUpdate.class.getName());\r
+ if (isUndo || wasHistoryUpdate || skipUpdate) {\r
+ if (DEBUG)\r
+ System.out.println("skipping change history update: isUndo=" + isUndo + ", wasHistoryUpdate=" + wasHistoryUpdate + ", skipUpdate=" + skipUpdate);\r
+ return;\r
+ }\r
+ }\r
+\r
+ L0 = Layer0.getInstance(graph);\r
+ DIA = DiagramResource.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+ \r
+ CollectionSupport cs = graph.getService(CollectionSupport.class);\r
+\r
+ Set<Resource> work = cs.createSet();\r
+ Set<Resource> creates = cs.createSet();\r
+ Set<Resource> ids = cs.createSet();\r
+\r
+ for (Resource model : event.modelChanges.keySet()) {\r
+ DependencyChanges.Change[] changes = event.modelChanges.get(model);\r
+ if (changes == null || changes.length == 0)\r
+ continue;\r
+\r
+ for (DependencyChanges.Change c : changes) {\r
+ if (c instanceof ComponentModification) {\r
+ Resource r = ((ComponentModification) c).component;\r
+ if (DEBUG)\r
+ System.out.println("ComponentModification: " + NameUtils.getURIOrSafeNameInternal(graph, r));\r
+ propagate(graph, r, work);\r
+ }\r
+ if (c instanceof ComponentAddition) {\r
+ Resource r = ((ComponentAddition) c).component;\r
+ boolean hasChangeInformation = graph.hasStatement(r, MOD.changeInformation);\r
+ if (!hasChangeInformation && ModelingUtils.needsModificationInfo(graph, r)) {\r
+ creates.add(r);\r
+ if (DEBUG)\r
+ System.out.println("ComponentAddition(true): " + NameUtils.getURIOrSafeNameInternal(graph, r));\r
+ } else {\r
+ if (DEBUG)\r
+ System.out.println("ComponentAddition(false): " + NameUtils.getURIOrSafeNameInternal(graph, r));\r
+ }\r
+ boolean hasGUID = graph.hasStatement(r, L0.identifier);\r
+ if (!hasGUID && ModelingUtils.needsIdentifier(graph, r)) {\r
+ ids.add(r);\r
+ }\r
+ propagate(graph, r, work);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (work.isEmpty())\r
+ return;\r
+\r
+ if (DEBUG_MODIFICATIONS) {\r
+ for (Resource w : creates)\r
+ System.out.println("created: " + NameUtils.getURIOrSafeNameInternal(graph, w));\r
+ }\r
+\r
+ Set<Resource> modis = cs.createSet();\r
+ for (Resource r : Layer0Utils.sortByCluster(graph, work))\r
+ if (!creates.contains(r) && ModelingUtils.needsModificationInfo(graph, r))\r
+ modis.add(r);\r
+\r
+ if (DEBUG_MODIFICATIONS) {\r
+ for (Resource w : modis)\r
+ System.out.println("modified: " + NameUtils.getURIOrSafeNameInternal(graph, w));\r
+ }\r
+\r
+ if (!modis.isEmpty() || !creates.isEmpty() || !ids.isEmpty()) {\r
+ graph.asyncRequest(new OntologicalRequirementEnforceRequest(creates, modis, ids));\r
+ }\r
+ \r
+ }\r
+\r
+}\r