package org.simantics.issues.common; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.simantics.db.Issue; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.ResourceRead2; import org.simantics.db.common.request.ResourceRead3; import org.simantics.db.common.utils.Functions; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.issues.ontology.IssueResource; import org.simantics.layer0.Layer0; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DependencyIssueValidator2 extends ResourceRead3 { private static final Logger LOGGER = LoggerFactory.getLogger(DependencyIssueValidator2.class); public static final boolean DEBUG = false; public DependencyIssueValidator2(Resource resource, Resource model, Resource source) { super(resource, model, source); } static class DependencyIssueDescriptions extends ResourceRead2> { public DependencyIssueDescriptions(Resource source, Resource context0) { super(source, context0); } @Override public Set perform(ReadGraph graph) throws DatabaseException { HashSet result = new HashSet(); for(Resource issue : graph.syncRequest(new ManagedIssues(resource))) { Issue desc = graph.sync(new StandardIssueDescription(issue)); if(desc == null) continue; if(resource2.equals(desc.getMainContext())) result.add(desc); } return result; } } static class Contexts extends ResourceRead2> { public Contexts(Resource source, Resource resource) { super(source, resource); } @Override public Set perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); IssueResource IR = IssueResource.getInstance(graph); Resource constraint = graph.getSingleObject(resource, IR.Sources_DependencyTracker_HasConstraint); Resource function = graph.getSingleObject(constraint, L0.Constraint_Validator); try { @SuppressWarnings("unchecked") Set contexts = new HashSet((List)Functions.exec(graph, function, graph, resource2)); if(DEBUG) System.err.println("Validator found: " + contexts.size() + " issues (" + contexts + ")"); return contexts; } catch (DatabaseException e) { LOGGER.error("Reading a constraint validator failed", e); return Collections.emptySet(); } } @Override public String toString() { return "DependencyIssueValidators2$Contexts[resource=" + resource2 + " source=" + resource + "]"; } } @Override public Boolean perform(ReadGraph graph) throws DatabaseException { if(DEBUG) System.err.println("Running DependencyValidator for " + NameUtils.getSafeName(graph, resource) + " " + NameUtils.getSafeName(graph, resource3)); Set existing = graph.syncRequest(new DependencyIssueDescriptions(resource3, resource), TransientCacheListener.>instance()); if(DEBUG) System.err.println("Existing: " + existing.size() + " issues (" + existing + ")"); // Removed resources do not have issues if(!graph.hasStatement(resource)) { if(DEBUG) System.err.println("No statements"); return existing.isEmpty(); } Set contexts = graph.syncRequest(new Contexts(resource3, resource), TransientCacheListener.>instance()); if(DEBUG) System.err.println("Current: " + contexts.size() + " issues (" + contexts + ")"); return existing.equals(contexts); } }