package org.simantics.district.network.profile; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.function.FunctionImpl1; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class VertexSymbolStyle extends ThrottledStyleBase { private static final Logger LOGGER = LoggerFactory.getLogger(VertexSymbolStyle.class); @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public String calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { // Prevent PendingVariableExceptions from coming through boolean wasSynchronous = graph.setSynchronous(true); try { Function symbolFunction = getSymbolFunction(graph, entry); if (symbolFunction == null) return null; try { return (String) Simantics.applySCLRead(graph, symbolFunction, groupItem); } catch (Exception e) { LOGGER.error("Getting dynamic symbol for " + groupItem + " (" + graph.getPossibleRelatedValue(groupItem, Layer0.getInstance(graph).HasName) + ") failed", e); return null; } } finally { graph.setSynchronous(wasSynchronous); } } @SuppressWarnings("rawtypes") protected static Function getSymbolFunction(ReadGraph graph, Resource entry) throws DatabaseException { // Cache function read for profile entry return graph.syncRequest(new SymbolFunctionRequest(entry), TransientCacheListener.instance()); } @Override public void applyThrottledStyleForNode(EvaluationContext observer, INode node, String value) { SingleElementNode n = (SingleElementNode) node; for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "SVG", value, observer); } @Override protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) { ((G2DSceneGraph)node.getRootNode()).clearPending(node); SingleElementNode n = (SingleElementNode) node; for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "SVG", null, evaluationContext); } @SuppressWarnings("rawtypes") protected static final class SymbolFunctionRequest extends ResourceRead { protected static final Function CONST_NULL = new FunctionImpl1() { @Override public String apply(Resource p0) { return null; } }; public SymbolFunctionRequest(Resource entry) { super(entry); } @Override public Function perform(ReadGraph graph) throws DatabaseException { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); Function symbolFunction = (Function) graph.getPossibleRelatedValue2(resource, DN.HasSymbolFunction, resource); if (symbolFunction == null) symbolFunction = CONST_NULL; return symbolFunction; } } }