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