package org.simantics.district.network.visualisations; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.simantics.NameLabelUtil; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.NamedResource; import org.simantics.db.common.request.ObjectsWithSupertype; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.district.network.visualisations.model.DynamicArrowContribution; import org.simantics.district.network.visualisations.model.DynamicColorContribution; import org.simantics.district.network.visualisations.model.DynamicColorMap; import org.simantics.district.network.visualisations.model.DynamicSizeContribution; import org.simantics.district.network.visualisations.model.DynamicSizeMap; import org.simantics.district.network.visualisations.model.DynamicSymbolContribution; import org.simantics.district.network.visualisations.model.StaticInformationContribution; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.top.ValueNotFound; import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.tuple.Tuple0; import org.simantics.structural.stubs.StructuralResource2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DynamicVisualisationsContributions { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsContributions.class); private static final String COMMON_DYNAMIC_VISUALISATIONS_MODULE = "CommonDynamicVisualisations"; private static final String COLOR_MAP_CONTRIBUTION = "colorMapContribution"; private static final String SIZE_MAP_CONTRIBUTION = "sizeMapContribution"; private static final String DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE = "DynamicVisualisationsContribution"; private static final String COLOR_CONTRIBUTION = "colorContribution"; private static final String SIZE_CONTRIBUTION = "sizeContribution"; private static final String ARROW_CONTRIBUTION = "arrowContribution"; private static final String STATIC_INFORMATION_CONTRIBUTION = "staticInformationContribution"; private static final String DYNAMIC_SYMBOL_CONTRIBUTION = "symbolContribution"; public static Map dynamicColorMaps(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); Map results = new HashMap<>(); Layer0 L0 = Layer0.getInstance(graph); for (Resource sharedOntology : sharedOntologies) { Resource sclModule = Layer0Utils.getPossibleChild(graph, sharedOntology, L0.SCLModule, COMMON_DYNAMIC_VISUALISATIONS_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); Object oldGraph = SCLContext.getCurrent().get("graph"); try { // let's put the graph to SCLContext for resolving the color maps SCLContext.getCurrent().put("graph", graph); @SuppressWarnings("unchecked") List result = (List) SCLOsgi.MODULE_REPOSITORY.getValue(moduleURI, COLOR_MAP_CONTRIBUTION); for (DynamicColorMap colorMap : result) { results.put(colorMap.getLabel(), colorMap); } } catch (ValueNotFound e) { // ignore LOGGER.debug("Dynamic color maps not found for {}", sclModule, e); } finally { SCLContext.getCurrent().put("graph", oldGraph); } } } return results; } public static Map dynamicSizeMaps(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); Map results = new HashMap<>(); Layer0 L0 = Layer0.getInstance(graph); for (Resource sharedOntology : sharedOntologies) { Resource sclModule = Layer0Utils.getPossibleChild(graph, sharedOntology, L0.SCLModule, COMMON_DYNAMIC_VISUALISATIONS_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); Object oldGraph = SCLContext.getCurrent().get("graph"); try { // let's put the graph to SCLContext for resolving the color maps SCLContext.getCurrent().put("graph", graph); @SuppressWarnings("unchecked") List result = (List) SCLOsgi.MODULE_REPOSITORY.getValue(moduleURI, SIZE_MAP_CONTRIBUTION); for (DynamicSizeMap sizeMap : result) { results.put(sizeMap.getLabel(), sizeMap); } } catch (ValueNotFound e) { // ignore LOGGER.debug("Dynamic size maps not found for {}", sclModule, e); } finally { SCLContext.getCurrent().put("graph", oldGraph); } } } return results; } public static Collection dynamicColoringObjects(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); List results = new ArrayList<>(); for (Resource sharedOntology : sharedOntologies) { Collection findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component)); //Collection findByType = QueryIndexUtils.searchByType(graph, sharedOntology, ); for (Resource find : findByType) { NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find); DynamicColoringObject dynamicColoringObject = dynamicColoringObject(graph, moduleType); if (dynamicColoringObject != null) results.add(dynamicColoringObject); } } return results; } public static Collection dynamicSizingObjects(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); List results = new ArrayList<>(); for (Resource sharedOntology : sharedOntologies) { Collection findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component)); //Collection findByType = QueryIndexUtils.searchByType(graph, sharedOntology, ); for (Resource find : findByType) { NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find); DynamicSizingObject dynamicSizingObject = dynamicSizingObject(graph, moduleType); if (dynamicSizingObject != null) results.add(dynamicSizingObject); } } return results; } private static DynamicColoringObject dynamicColoringObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); return new DynamicColoringObject(moduleType, getContributionSupplier(moduleURI, COLOR_CONTRIBUTION)); } return null; } private static DynamicSizingObject dynamicSizingObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); return new DynamicSizingObject(moduleType, getContributionSupplier(moduleURI, SIZE_CONTRIBUTION)); } return null; } public static Collection dynamicEdgeArrowObjects(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); List results = new ArrayList<>(); for (Resource sharedOntology : sharedOntologies) { Collection findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component)); //Collection findByType = QueryIndexUtils.searchByType(graph, sharedOntology, ); for (Resource find : findByType) { NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find); DynamicArrowObject dynamicarrowObject = dynamicEdgeArrowObject(graph, moduleType); if (dynamicarrowObject != null) results.add(dynamicarrowObject); } } return results; } private static DynamicArrowObject dynamicEdgeArrowObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); return new DynamicArrowObject(moduleType, getContributionSupplier(moduleURI, ARROW_CONTRIBUTION)); } return null; } private static Supplier> getContributionSupplier(String uri, String expressionText) { return () -> { try { @SuppressWarnings("unchecked") List result = (List) SCLOsgi.MODULE_REPOSITORY.getValue(uri, expressionText); return result.stream();//result.stream().map(DynamicColorContribution::fromTuple9); } catch (ValueNotFound e) { LOGGER.trace("Could not find contributions for module {} and expression {}", uri, expressionText, e); //throw new RuntimeException(e); return Stream.empty(); } }; } public static Collection staticInformationContributionObjects(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); List results = new ArrayList<>(); for (Resource sharedOntology : sharedOntologies) { Collection findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component)); //Collection findByType = QueryIndexUtils.searchByType(graph, sharedOntology, ); for (Resource find : findByType) { NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find); StaticInformationContributionObject staticInformationContributionObject = staticInformationContributionObject(graph, moduleType); if (staticInformationContributionObject != null) results.add(staticInformationContributionObject); } } return results; } private static StaticInformationContributionObject staticInformationContributionObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); return new StaticInformationContributionObject(moduleType, getContributionSupplier(moduleURI, STATIC_INFORMATION_CONTRIBUTION)); } return null; } public static Collection dynamicSymbolContributionObjects(ReadGraph graph) throws DatabaseException { List sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); List results = new ArrayList<>(); for (Resource sharedOntology : sharedOntologies) { Collection findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component)); //Collection findByType = QueryIndexUtils.searchByType(graph, sharedOntology, ); for (Resource find : findByType) { NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find); DynamicSymbolContributionObject dynamicSymbolContributionObject = dynamicSymbolContributionObject(graph, moduleType); if (dynamicSymbolContributionObject != null) results.add(dynamicSymbolContributionObject); } } return results; } private static DynamicSymbolContributionObject dynamicSymbolContributionObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE); if (sclModule != null) { String moduleURI = graph.getURI(sclModule); return new DynamicSymbolContributionObject(moduleType, getContributionSupplier(moduleURI, DYNAMIC_SYMBOL_CONTRIBUTION)); } return null; } public static class DynamicArrowObject { private final NamedResource arrowObject; private final Supplier> arrowContributionSupplier; private Map arrowContributions; public DynamicArrowObject(NamedResource coloringObject, Supplier> arrowContributionSupplier) { this.arrowObject = coloringObject; this.arrowContributionSupplier = arrowContributionSupplier; } public NamedResource getArrowObject() { return arrowObject; } public Map getArrowContributions() { if (arrowContributions == null) arrowContributions = arrowContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c)); return arrowContributions; } } public static class StaticInformationContributionObject { private final NamedResource staticInformationContributionObject; private final Supplier> staticInformationContributionSupplier; private Map staticInformationContributions; public StaticInformationContributionObject(NamedResource staticInformationContributionObject, Supplier> staticInformationContributionSupplier) { this.staticInformationContributionObject = staticInformationContributionObject; this.staticInformationContributionSupplier = staticInformationContributionSupplier; } public NamedResource getStaticInformationContributionObject() { return staticInformationContributionObject; } public Map getStaticInformationContributions() { if (staticInformationContributions == null) staticInformationContributions = staticInformationContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c)); return staticInformationContributions; } } public static class DynamicSymbolContributionObject { private final NamedResource dynamicSymbolContributionObject; private final Supplier> dynamicSymbolContributionSupplier; private DynamicSymbolContribution dynamicSymbolContribution; public DynamicSymbolContributionObject(NamedResource dynamicSymbolContributionObject, Supplier> dynamicSymbolContributionSupplier) { this.dynamicSymbolContributionObject = dynamicSymbolContributionObject; this.dynamicSymbolContributionSupplier = dynamicSymbolContributionSupplier; } public NamedResource getDynamicSymbolContributionObject() { return dynamicSymbolContributionObject; } public DynamicSymbolContribution getDynamicSymbolContribution() { if (dynamicSymbolContribution == null) { Optional findFirst = dynamicSymbolContributionSupplier.get().findFirst(); findFirst.ifPresent(dsc -> { dynamicSymbolContribution = dsc; }); } return dynamicSymbolContribution; } public void resolveSymbols(ReadGraph graph) { SCLContext current = SCLContext.getCurrent(); Object oldGraph = current.put("graph", graph); try { DynamicSymbolContribution dsc = getDynamicSymbolContribution(); if (dsc != null) dsc.resolveSymbolMap(); } finally { current.put("graph", oldGraph); } } } public static class DynamicColoringObject { private final NamedResource coloringObject; private final Supplier> colorContributionSupplier; private Map colorContributions; public DynamicColoringObject(NamedResource coloringObject, Supplier> colorContributionSupplier) { this.coloringObject = coloringObject; this.colorContributionSupplier = colorContributionSupplier; } public NamedResource getColoringObject() { return coloringObject; } public Map getColorContributions() { if (colorContributions == null) colorContributions = colorContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c)); return colorContributions; } @Override public String toString() { return getClass().getSimpleName() + " [" + coloringObject.getName() + " (" + coloringObject.getResource() + "), contributions=" + colorContributionsToString() + "]"; } private String colorContributionsToString() { return colorContributions.keySet().stream().map(key -> { DynamicColorContribution dynamicColorContribution = colorContributions.get(key); return key + "=" + dynamicColorContribution.getLabel(); }).collect(Collectors.joining(", ", "{", "}")); } } public static class DynamicColoringMap { private final NamedResource coloringObject; private final Supplier> colorContributionSupplier; private Map colorContributions; public DynamicColoringMap(NamedResource coloringObject, Supplier> colorContributionSupplier) { this.coloringObject = coloringObject; this.colorContributionSupplier = colorContributionSupplier; } public NamedResource getColoringObject() { return coloringObject; } public Map getColorContributions() { if (colorContributions == null) colorContributions = colorContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c)); return colorContributions; } } public static class DynamicSizingObject { private final NamedResource sizingObject; private final Supplier> sizeContributionSupplier; private Map sizeContributions; public DynamicSizingObject(NamedResource coloringObject, Supplier> sizeContributionSupplier) { this.sizingObject = coloringObject; this.sizeContributionSupplier = sizeContributionSupplier; } public NamedResource getSizingObject() { return sizingObject; } public Map getSizeContributions() { if (sizeContributions == null) sizeContributions = sizeContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c)); return sizeContributions; } } }