package org.simantics.structural2; import java.util.Collection; import java.util.LinkedList; import org.simantics.databoard.Databoard; import org.simantics.databoard.binding.Binding; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.Instances; import org.simantics.db.layer0.exception.MissingVariableException; import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.RVI.GuidRVIPart; import org.simantics.db.layer0.variable.RVI.RVIPart; import org.simantics.db.layer0.variable.RVIBuilder; import org.simantics.db.layer0.variable.StandardRVIResolver; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.layer0.Layer0; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.structural.stubs.StructuralResource2; public class StructuralRVIResolver extends StandardRVIResolver { protected boolean isRVIBase(ReadGraph graph, Variable variable) throws DatabaseException { if (Variables.isContext(graph, variable)) return true; StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource represents = variable.getRepresents(graph); if (represents == null) return false; if (graph.isInstanceOf(represents, STR.Composite)) return false; return true; } @Override public RVI getRVI(ReadGraph graph, Variable variable) throws DatabaseException { if (Variables.isContext(graph, variable)) { Databoard databoard = graph.getService( Databoard.class ); Binding rviBinding = databoard.getBindingUnchecked( RVI.class ); return RVI.empty(rviBinding); } else { Variable base = variable.getParent(graph); while(!isRVIBase(graph, base)) base = base.getParent(graph); RVIPart part = getRVIPart(graph, variable); return new RVIBuilder(base.getRVI(graph)).append(part).toRVI(); } } @Override public RVI getPossibleRVI(ReadGraph graph, Variable variable) throws DatabaseException { if (Variables.isContext(graph, variable)) { Databoard databoard = graph.getService( Databoard.class ); Binding rviBinding = databoard.getBindingUnchecked( RVI.class ); return RVI.empty(rviBinding); } else { Variable base = variable.getParent(graph); if(base == null) return null; while(!isRVIBase(graph, base)) { base = base.getParent(graph); if(base == null) return null; } RVIPart part = getRVIPart(graph, variable); if(part == null) return null; RVI baseRVI = base.getPossibleRVI(graph); if(baseRVI == null) return null; return new RVIBuilder(baseRVI).append(part).toRVI(); } } protected boolean isPartOfComponentType(ReadGraph graph, Resource resource) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource container = graph.getPossibleObject(resource, L0.PartOf); if(container != null && graph.isInstanceOf(container, STR.Composite)) { return graph.hasStatement(container, STR.Defines); } return false; } protected Resource getBase(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); SimulationResource SIMU = SimulationResource.getInstance(graph); Resource represents = variable.getPossibleRepresents(graph); if(represents != null && graph.isInstanceOf(represents, SIMU.Run)) return Variables.getPossibleConfigurationContextResource(graph, represents); else if(isPartOfComponentType(graph, resource)) return graph.getPossibleObject(resource, L0.PartOf); return represents; } protected Collection getRVIPath(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException { Resource base = getBase(graph, variable, resource); if (base == null) return null; LinkedList result = new LinkedList(); result.add(resource); Layer0 L0 = Layer0.getInstance(graph); resource = graph.getPossibleObject(resource, L0.PartOf); if(resource == null) return null; while(!base.equals(resource)) { result.addFirst(resource); resource = graph.getPossibleObject(resource, L0.PartOf); if(resource == null) return null; } return result; } protected Collection getRVIPath(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { if(part.resource != null) { return getRVIPath(graph, variable, part.resource); } else { Resource indexRoot = variable.getIndexRoot(graph); Instances instances = graph.adapt(Layer0.getInstance(graph).Entity, Instances.class); GUID guid = new GUID(part.mostSignificant, part.leastSignificant); Collection queryResult = instances.find(graph, indexRoot, "GUID:"+guid.indexString()); if(queryResult.size() != 1) return null; return getRVIPath(graph, variable, queryResult.iterator().next()); } } @Override protected Variable resolveChild(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException { Collection path = getRVIPath(graph, variable, resource); if (path == null) throw new MissingVariableException("Didn't find a variable related to " + resource + ".", resource); for (Resource r : path) variable = variable.browse(graph, r); return variable; } @Override protected Variable resolveChild(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { Collection path = getRVIPath(graph, variable, part); if (path == null) throw new MissingVariableException("Didn't find a variable related to " + part + ".", variable.getPossibleRepresents(graph)); for (Resource r : path) variable = variable.browse(graph, r); return variable; } }