X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.issues.common%2Fsrc%2Forg%2Fsimantics%2Fissues%2Fcommon%2FDependencyIssueSource2.java;h=b11fd220ddff588650af40c443d00c017336e9a8;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=37669ab581ec74b6878da15cad9476287846b907;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/DependencyIssueSource2.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/DependencyIssueSource2.java index 37669ab58..b11fd220d 100644 --- a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/DependencyIssueSource2.java +++ b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/DependencyIssueSource2.java @@ -1,183 +1,183 @@ -package org.simantics.issues.common; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import org.simantics.Simantics; -import org.simantics.db.MetadataI; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.Indexing; -import org.simantics.db.common.changeset.GenericChangeListener; -import org.simantics.db.common.procedure.adapter.TransientCacheListener; -import org.simantics.db.common.request.PossibleTypedParent; -import org.simantics.db.common.utils.Functions; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.event.ChangeListener; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest; -import org.simantics.db.layer0.genericrelation.DependencyChanges; -import org.simantics.db.service.GraphChangeListenerSupport; -import org.simantics.issues.ontology.IssueResource; -import org.simantics.layer0.Layer0; -import org.simantics.scl.runtime.function.Function2; -import org.simantics.simulation.ontology.SimulationResource; - -public class DependencyIssueSource2 implements IssueSource { - - public static final boolean DEBUG = false; - - private Resource source; - private Resource model; - private Resource type; - private Set searchTypes; - private Resource base; - private Resource extensionFunction; - - private CopyOnWriteArraySet, Boolean>> listeners = new CopyOnWriteArraySet<>(); - private ConcurrentMap, Boolean>, ChangeListener> listenerMap = new ConcurrentHashMap<>(); - - public DependencyIssueSource2(ReadGraph graph, Resource source) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - IssueResource IR = IssueResource.getInstance(graph); - this.source = source; - this.model = graph.syncRequest(new PossibleTypedParent(source, SimulationResource.getInstance(graph).Model)); - this.extensionFunction = graph.getPossibleObject(source, IR.Sources_DependencyTracker_HasExtension); - this.type = graph.getSingleObject(source, IR.Sources_DependencyTracker_HasType); - HashSet _searchTypes = new HashSet<>(); - _searchTypes.addAll(graph.getObjects(source, IR.Sources_DependencyTracker_HasSearchType)); - _searchTypes.add(type); - this.searchTypes = new HashSet<>(_searchTypes); - Resource baseFunction = graph.getSingleObject(source, IR.Sources_DependencyTracker_HasBaseFunction); - this.base = Functions.exec(graph, baseFunction, graph, graph.getSingleObject(source, L0.PartOf)); - } - - private List resourcesToCheck(ReadGraph graph, DependencyChanges event) throws DatabaseException { - - HashSet depSet = new HashSet<>(); - - if(DEBUG) { - System.err.println("resourcesToCheck[" + NameUtils.getSafeName(graph, source) + "] - component changes for type " + NameUtils.getSafeName(graph, searchTypes)); - } - - depSet.addAll(IssueSourceUtils.getChangedDependencies(graph, model, base, searchTypes, event)); - depSet.addAll(IssueSourceUtils.getChangedDependencies(graph, source, model, base, searchTypes)); - - List deps = new ArrayList<>(depSet); - - if(DEBUG) { - System.err.println("resourcesToCheck[" + NameUtils.getSafeName(graph, source) + "] " + deps); - for(Resource r : deps) { - System.err.println("dep " + NameUtils.getSafeName(graph, r)); - } - } - - if(extensionFunction != null) { - try { - deps = Functions.exec(graph, extensionFunction, graph, deps); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - if(DEBUG) { - for(Resource r : deps) { - System.err.println("dep extension " + NameUtils.getSafeName(graph, r)); - } - } - - ArrayList result = new ArrayList<>(); - for(Resource dep : deps) { - // TODO: still not complete - e.g. someone can replace the InstanceOf - Set types = graph.getTypes(dep); - if(types.isEmpty() || types.contains(type)) result.add(dep); - } - return result; - - } - - class DependencyChangeListener extends GenericChangeListener { - - private boolean isValid(ReadGraph graph, List toCheck) throws DatabaseException { - for(Resource resource : toCheck) { - if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) { - return false; - } - } - return true; - } - - @Override - public boolean preEventRequest() { - return !Indexing.isDependenciesIndexingDisabled(); - } - - @Override - public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException { - - List toCheck = resourcesToCheck(graph, event); - if(!isValid(graph, toCheck)) { - for(Function2, Boolean> r : listeners) { - r.apply(graph, toCheck); - } - } - - if(graph instanceof WriteGraph) { - IssueSourceUtils.update((WriteGraph)graph, source); - } - } - - } - - @Override - public void addDirtyListener(Function2, Boolean> runnable) { - boolean added = listeners.add(runnable); - if (added) { - GraphChangeListenerSupport changeSupport = Simantics.getSession().getService(GraphChangeListenerSupport.class); - ChangeListener metadataListener = new DependencyChangeListener(); - listenerMap.put(runnable, metadataListener); - changeSupport.addMetadataListener(metadataListener); - } - } - - @Override - public void removeDirtyListener(Function2, Boolean> runnable) { - boolean removed = listeners.remove(runnable); - ChangeListener metadataListener = listenerMap.remove(runnable); - if (removed && metadataListener != null) { - GraphChangeListenerSupport changeSupport = Simantics.getSession().getService(GraphChangeListenerSupport.class); - changeSupport.removeMetadataListener(metadataListener); - } - } - - @Override - public void update(WriteGraph graph, List resources) throws DatabaseException { - - for(Resource resource : resources) { - if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) { - new DependencyIssueSynchronizer2(resource, source).perform(graph); - } - } - - IssueSourceUtils.update(graph, source); - - } - - @Override - public boolean needUpdate(ReadGraph graph, List resources) throws DatabaseException { - - for(Resource resource : resources) { - if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) return true; - } - - return false; - - } - -} +package org.simantics.issues.common; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.simantics.Simantics; +import org.simantics.db.MetadataI; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.Indexing; +import org.simantics.db.common.changeset.GenericChangeListener; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.PossibleTypedParent; +import org.simantics.db.common.utils.Functions; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.event.ChangeListener; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest; +import org.simantics.db.layer0.genericrelation.DependencyChanges; +import org.simantics.db.service.GraphChangeListenerSupport; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.scl.runtime.function.Function2; +import org.simantics.simulation.ontology.SimulationResource; + +public class DependencyIssueSource2 implements IssueSource { + + public static final boolean DEBUG = false; + + private Resource source; + private Resource model; + private Resource type; + private Set searchTypes; + private Resource base; + private Resource extensionFunction; + + private CopyOnWriteArraySet, Boolean>> listeners = new CopyOnWriteArraySet<>(); + private ConcurrentMap, Boolean>, ChangeListener> listenerMap = new ConcurrentHashMap<>(); + + public DependencyIssueSource2(ReadGraph graph, Resource source) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + IssueResource IR = IssueResource.getInstance(graph); + this.source = source; + this.model = graph.syncRequest(new PossibleTypedParent(source, SimulationResource.getInstance(graph).Model)); + this.extensionFunction = graph.getPossibleObject(source, IR.Sources_DependencyTracker_HasExtension); + this.type = graph.getSingleObject(source, IR.Sources_DependencyTracker_HasType); + HashSet _searchTypes = new HashSet<>(); + _searchTypes.addAll(graph.getObjects(source, IR.Sources_DependencyTracker_HasSearchType)); + _searchTypes.add(type); + this.searchTypes = new HashSet<>(_searchTypes); + Resource baseFunction = graph.getSingleObject(source, IR.Sources_DependencyTracker_HasBaseFunction); + this.base = Functions.exec(graph, baseFunction, graph, graph.getSingleObject(source, L0.PartOf)); + } + + private List resourcesToCheck(ReadGraph graph, DependencyChanges event) throws DatabaseException { + + HashSet depSet = new HashSet<>(); + + if(DEBUG) { + System.err.println("resourcesToCheck[" + NameUtils.getSafeName(graph, source) + "] - component changes for type " + NameUtils.getSafeName(graph, searchTypes)); + } + + depSet.addAll(IssueSourceUtils.getChangedDependencies(graph, model, base, searchTypes, event)); + depSet.addAll(IssueSourceUtils.getChangedDependencies(graph, source, model, base, searchTypes)); + + List deps = new ArrayList<>(depSet); + + if(DEBUG) { + System.err.println("resourcesToCheck[" + NameUtils.getSafeName(graph, source) + "] " + deps); + for(Resource r : deps) { + System.err.println("dep " + NameUtils.getSafeName(graph, r)); + } + } + + if(extensionFunction != null) { + try { + deps = Functions.exec(graph, extensionFunction, graph, deps); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + if(DEBUG) { + for(Resource r : deps) { + System.err.println("dep extension " + NameUtils.getSafeName(graph, r)); + } + } + + ArrayList result = new ArrayList<>(); + for(Resource dep : deps) { + // TODO: still not complete - e.g. someone can replace the InstanceOf + Set types = graph.getTypes(dep); + if(types.isEmpty() || types.contains(type)) result.add(dep); + } + return result; + + } + + class DependencyChangeListener extends GenericChangeListener { + + private boolean isValid(ReadGraph graph, List toCheck) throws DatabaseException { + for(Resource resource : toCheck) { + if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) { + return false; + } + } + return true; + } + + @Override + public boolean preEventRequest() { + return !Indexing.isDependenciesIndexingDisabled(); + } + + @Override + public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException { + + List toCheck = resourcesToCheck(graph, event); + if(!isValid(graph, toCheck)) { + for(Function2, Boolean> r : listeners) { + r.apply(graph, toCheck); + } + } + + if(graph instanceof WriteGraph) { + IssueSourceUtils.update((WriteGraph)graph, source); + } + } + + } + + @Override + public void addDirtyListener(Function2, Boolean> runnable) { + boolean added = listeners.add(runnable); + if (added) { + GraphChangeListenerSupport changeSupport = Simantics.getSession().getService(GraphChangeListenerSupport.class); + ChangeListener metadataListener = new DependencyChangeListener(); + listenerMap.put(runnable, metadataListener); + changeSupport.addMetadataListener(metadataListener); + } + } + + @Override + public void removeDirtyListener(Function2, Boolean> runnable) { + boolean removed = listeners.remove(runnable); + ChangeListener metadataListener = listenerMap.remove(runnable); + if (removed && metadataListener != null) { + GraphChangeListenerSupport changeSupport = Simantics.getSession().getService(GraphChangeListenerSupport.class); + changeSupport.removeMetadataListener(metadataListener); + } + } + + @Override + public void update(WriteGraph graph, List resources) throws DatabaseException { + + for(Resource resource : resources) { + if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) { + new DependencyIssueSynchronizer2(resource, source).perform(graph); + } + } + + IssueSourceUtils.update(graph, source); + + } + + @Override + public boolean needUpdate(ReadGraph graph, List resources) throws DatabaseException { + + for(Resource resource : resources) { + if(!graph.syncRequest(new DependencyIssueValidator2(resource, model, source), TransientCacheListener.instance())) return true; + } + + return false; + + } + +}