-package org.simantics.structural2;\r
-\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.adapter.AdaptException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.error.DatatypeConstructionException;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.util.URIStringUtils;\r
-import org.simantics.db.Issue;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.issue.StandardIssue;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.PossibleIndexRoot;\r
-import org.simantics.db.common.request.ResourceRead;\r
-import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.function.All;\r
-import org.simantics.db.layer0.function.StandardChildDomainChildren;\r
-import org.simantics.db.layer0.request.PropertyInfo;\r
-import org.simantics.db.layer0.request.PropertyInfoRequest;\r
-import org.simantics.db.layer0.request.VariableRead;\r
-import org.simantics.db.layer0.variable.AbstractChildVariable;\r
-import org.simantics.db.layer0.variable.AbstractPropertyVariable;\r
-import org.simantics.db.layer0.variable.LazyPropertyVariable;\r
-import org.simantics.db.layer0.variable.NodeSupport;\r
-import org.simantics.db.layer0.variable.StandardGraphChildVariable;\r
-import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
-import org.simantics.db.layer0.variable.ValueAccessor;\r
-import org.simantics.db.layer0.variable.ValueAccessorWithBinding;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.layer0.variable.VariableMap;\r
-import org.simantics.db.layer0.variable.VariableMapImpl;\r
-import org.simantics.db.layer0.variable.VariableNode;\r
-import org.simantics.issues.common.IssueUtils;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.scl.reflection.annotations.SCLValue;\r
-import org.simantics.scl.runtime.SCLContext;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.simulator.variable.NodeManager;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.structural2.procedural.Component;\r
-import org.simantics.structural2.procedural.ConnectionPoint;\r
-import org.simantics.structural2.procedural.Interface;\r
-import org.simantics.structural2.procedural.SubstructureElement;\r
-import org.simantics.structural2.procedural.Terminal;\r
-import org.simantics.structural2.queries.ConnectionComponents;\r
-import org.simantics.structural2.queries.ConnectionJoinComponents;\r
-import org.simantics.structural2.queries.ConnectionPointMapOfResource;\r
-import org.simantics.structural2.queries.PossibleConnectionPointInfo;\r
-import org.simantics.structural2.scl.CompileStructuralValueRequest;\r
-import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest;\r
-import org.simantics.structural2.variables.Connection;\r
-import org.simantics.structural2.variables.ConnectionBrowser;\r
-import org.simantics.structural2.variables.StandardProceduralChildVariable;\r
-import org.simantics.structural2.variables.VariableConnectionPointDescriptor;\r
-import org.simantics.utils.datastructures.MapList;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public class Functions {\r
- \r
- @SCLValue(type="ValueAccessor")\r
- public static final ValueAccessor expressionValueAccessor = new ValueAccessorWithBinding() {\r
-\r
- public Binding getBinding() {\r
- return Bindings.STRING;\r
- }\r
- \r
- @Override\r
- public void setValue(WriteGraph graph, Variable context, Object value)\r
- throws DatabaseException {\r
- if(value == null) {\r
- if(getValue(graph, context) != null)\r
- clearExpression(graph, context);\r
- return;\r
- }\r
- \r
- // Get all necessary data\r
- String expression = (String)value;\r
- Variable parent = context.getParent(graph);\r
- if(!(parent instanceof AbstractPropertyVariable)) return;\r
- AbstractPropertyVariable property = (AbstractPropertyVariable)parent; \r
- Resource propertyResource = property.getRepresents(graph);\r
- if(propertyResource == null) return;\r
- Resource container = property.getContainerResource(graph);\r
- if(container == null) return;\r
- Resource predicate = property.getPossiblePredicateResource(graph);\r
- if(predicate == null) return; \r
- Statement stat = graph.getPossibleStatement(container, predicate); \r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- \r
- // Write \r
- boolean createNew = false;\r
- if(stat.isAsserted(container))\r
- createNew = true;\r
- else if(!graph.isInstanceOf(propertyResource, STR.SCLValue)) {\r
- graph.deny(propertyResource);\r
- createNew = true;\r
- }\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- if(createNew) {\r
- propertyResource = graph.newResource();\r
- graph.claim(container, predicate, propertyResource);\r
- graph.claim(propertyResource, L0.InstanceOf, STR.SCLValue); \r
- }\r
- graph.claimLiteral(propertyResource, L0.SCLValue_expression, expression, Bindings.STRING);\r
- }\r
-\r
- private void clearExpression(WriteGraph graph, Variable context) throws DatabaseException {\r
- Variable parent = context.getParent(graph);\r
- if(!(parent instanceof AbstractPropertyVariable)) return;\r
- AbstractPropertyVariable property = (AbstractPropertyVariable)parent;\r
- Resource container = property.getContainerResource(graph);\r
- if(container == null) return;\r
- Resource predicate = property.getPossiblePredicateResource(graph);\r
- if(predicate == null) return; \r
- graph.deny(container, predicate); \r
- }\r
-\r
- @Override\r
- public Object getValue(ReadGraph graph, Variable context)\r
- throws DatabaseException {\r
- Variable parent = context.getParent(graph);\r
- if(!(parent instanceof AbstractPropertyVariable))\r
- return null;\r
- AbstractPropertyVariable property = (AbstractPropertyVariable)parent;\r
- Resource propertyResource = property.getPossibleRepresents(graph);\r
- if(propertyResource == null) return null;\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- if(!graph.isInstanceOf(propertyResource, STR.SCLValue))\r
- return null;\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- return graph.getPossibleRelatedValue(propertyResource, L0.SCLValue_expression);\r
- }\r
- \r
- };\r
- \r
- static class ConnectionImpl implements Connection {\r
-\r
- final private StandardGraphPropertyVariable connectionPoint;\r
- \r
- public ConnectionImpl(StandardGraphPropertyVariable connectionPoint) {\r
- this.connectionPoint = connectionPoint;\r
- }\r
- \r
- @Override\r
- public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {\r
- Set<Variable> result = new THashSet<Variable>();\r
- for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {\r
- result.add(desc.getVariable(graph));\r
- }\r
- return result;\r
- }\r
- \r
- @Override\r
- public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {\r
- Set<String> result = new THashSet<String>();\r
- for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {\r
- result.add(desc.getURI(graph));\r
- }\r
- return result;\r
- }\r
-\r
- @Override\r
- public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {\r
- return ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType);\r
- }\r
-\r
- }\r
- \r
- @SCLValue(type="ValueAccessor")\r
- public static final ValueAccessor connectionValueAccessor = new ValueAccessor() {\r
-\r
- @Override\r
- public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
- throw new UnsupportedOperationException();\r
- }\r
- \r
- public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
- throw new UnsupportedOperationException();\r
- }\r
-\r
- public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
- try {\r
- Object value = getValue(graph, context);\r
- Binding srcBinding = Bindings.OBJECT.getContentBinding(value);\r
- return Bindings.adapt(value, srcBinding, binding);\r
- } catch (AdaptException e) {\r
- throw new DatabaseException(e);\r
- } catch (BindingException e) {\r
- throw new DatabaseException(e);\r
- }\r
- }\r
-\r
- @Override\r
- public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
- StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; \r
- return new ConnectionImpl(variable);\r
- }\r
-\r
- @Override\r
- public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
- try {\r
- return Datatypes.getDatatype(Connection.class);\r
- } catch (DatatypeConstructionException e) {\r
- throw new DatabaseException(e);\r
- }\r
- }\r
- \r
- }; \r
-\r
-\r
- @SCLValue(type = "VariableMap")\r
- public static VariableMap structuralChildDomainProperties = new VariableMapImpl() {\r
- \r
- public Variable getPossibleConnectionPointFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {\r
-\r
- Map<String, Resource> connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());\r
- Resource cp = connectionPoints.get(name);\r
- if(cp == null) return null;\r
- else return new StandardGraphPropertyVariable(graph, variable, cp);\r
- \r
- }\r
- \r
- public Map<String, Variable> collectConnectionPointsFromContext(ReadGraph graph, StructuralResource2 STR, Variable variable, Resource context, Map<String, Variable> map, boolean needSynchronized) throws DatabaseException {\r
- \r
- if(graph.isImmutable(context)) {\r
-\r
- Map<String, Resource> cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());\r
- if(cps.size() == 0) return map;\r
- \r
- if(map == null) map = new THashMap<String,Variable>(cps.size());\r
- \r
- for(Map.Entry<String, Resource> entry : cps.entrySet()) {\r
- String name = entry.getKey();\r
- Resource cp = entry.getValue();\r
- if(needSynchronized && !graph.isInstanceOf(cp, STR.SynchronizedConnectionRelation)) continue;\r
- map.put(name, new StandardGraphPropertyVariable(graph, variable, cp));\r
- }\r
- \r
- return map;\r
-\r
- } else {\r
- \r
- Collection<Resource> predicates = graph.getPredicates(context);\r
- \r
- for(Resource predicate : predicates) {\r
- \r
- PropertyInfo info = graph.isImmutable(predicate) ?\r
- graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :\r
- graph.syncRequest(new PossibleConnectionPointInfo(predicate));\r
- \r
- if(info != null) {\r
- if(map == null) map = new THashMap<String,Variable>(4);\r
- if(needSynchronized && !graph.isInstanceOf(predicate, STR.SynchronizedConnectionRelation)) continue;\r
- map.put(info.name, new StandardGraphPropertyVariable(graph, variable, predicate));\r
- }\r
- \r
- }\r
-\r
- return map;\r
-\r
- }\r
- \r
- }\r
-\r
- @Override\r
- public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
- final StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
- Variable cp = getPossibleConnectionPointFromContext(graph, variable, variable.resource, name);\r
- if(cp != null) return cp;\r
- return All.getStandardChildDomainPropertyVariable(graph, context, name);\r
- }\r
-\r
- @Override\r
- public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
- StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- map = collectConnectionPointsFromContext(graph, STR, variable, variable.resource, map, false);\r
- return All.getStandardChildDomainPropertyVariables(graph, context, map);\r
- }\r
- \r
- public Map<String,Variable> getVariables(ReadGraph graph, Variable context, String classification, Map<String,Variable> map) throws DatabaseException {\r
- if (StructuralResource2.URIs.SynchronizedRelation.equals(classification)) {\r
- return All.getStandardChildDomainPropertyVariables(graph, context, classification, map);\r
- } else if (StructuralResource2.URIs.SynchronizedConnectionRelation.equals(classification)) {\r
- StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
- return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, true);\r
- } else if(StructuralResource2.URIs.ConnectionRelation.equals(classification)) {\r
- StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
- return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, false);\r
- }\r
- return super.getVariables(graph, context, classification, map);\r
- }\r
- \r
- };\r
-\r
- static class StructuralChildMapOfResource extends ResourceRead<Map<String, Resource>> {\r
-\r
- public StructuralChildMapOfResource(Resource resource) {\r
- super(resource);\r
- }\r
-\r
- @Override\r
- public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- Resource type = graph.getPossibleType(resource, STR.Component);\r
- if(type != null) {\r
- Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy);\r
- if(definition != null) {\r
- Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));\r
- if (!map.isEmpty())\r
- return map;\r
- } \r
- }\r
- Map<String, Resource> directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));\r
- return directChildren;\r
- }\r
-\r
- }\r
-\r
- static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {\r
-\r
- public StructuralChildMapOfResourceT(Resource resource) {\r
- super(resource);\r
- }\r
-\r
- @Override\r
- public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);\r
- if(definition != null) {\r
- Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));\r
- if (!map.isEmpty())\r
- return map;\r
- } \r
- return Collections.emptyMap();\r
- }\r
-\r
- }\r
-\r
- static class StructuralRunChildMapOfResource extends ResourceRead<Map<String, Resource>> {\r
-\r
- public StructuralRunChildMapOfResource(Resource resource) {\r
- super(resource);\r
- }\r
-\r
- public Map<String, Resource> fromContext(ReadGraph graph, Resource context) throws DatabaseException {\r
- return graph.sync(new StructuralChildMapOfResource(context));\r
- }\r
- \r
- @Override\r
- public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- SimulationResource SIMU = SimulationResource.getInstance(graph);\r
- Resource model = graph.sync(new PossibleIndexRoot(resource));\r
- if(graph.isInstanceOf(model, L0.RVIContext)) {\r
- return fromContext(graph, model);\r
- }\r
- Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
- if(configuration != null) {\r
- if(graph.isInstanceOf(configuration, L0.RVIContext)) {\r
- return fromContext(graph, configuration);\r
- }\r
- }\r
- \r
- return Collections.emptyMap();\r
- \r
- }\r
- \r
- }\r
- \r
- private static class SubstructureRequest extends VariableRead<List<SubstructureElement>> {\r
- public SubstructureRequest(Variable context) {\r
- super(context);\r
- }\r
-\r
- @Override\r
- public List<SubstructureElement> perform(ReadGraph graph) {\r
- try {\r
- Resource type = variable.getPossibleType(graph);\r
- if(type == null)\r
- return null;\r
- return CompileProceduralComponentTypeRequest.compileAndEvaluate(graph, type, variable);\r
- } catch (Throwable t) {\r
- t.printStackTrace();\r
- return null;\r
- }\r
- }\r
- }\r
-\r
- public static List<SubstructureElement> getProceduralDesc(ReadGraph graph, final Variable context) throws DatabaseException {\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- final Resource type = context.getPossibleType(graph);\r
- if(type != null) {\r
- if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {\r
- return graph.syncRequest(new SubstructureRequest(context));\r
- }\r
- }\r
- return null;\r
- } \r
- \r
- public static Map<String,Variable> getProcedural(ReadGraph graph, Variable context, List<SubstructureElement> elements, Map<String,Variable> map) throws DatabaseException {\r
- \r
- if(map == null) map = new THashMap<String,Variable>();\r
- \r
- MapList<String,org.simantics.structural2.procedural.Connection> conns = new MapList<String,org.simantics.structural2.procedural.Connection>();\r
- for(SubstructureElement sub : elements) {\r
- if(sub instanceof org.simantics.structural2.procedural.Connection) {\r
- org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)sub;\r
- for(ConnectionPoint cp : conn.connectionPoints) {\r
- if(cp instanceof Terminal) {\r
- Terminal t = (Terminal)cp;\r
- conns.add(t.component, conn);\r
- }\r
- }\r
- }\r
- }\r
- \r
- Map<String,Component> proceduralChildren = new THashMap<String, Component>();\r
- for(SubstructureElement sub : elements) {\r
- if(sub instanceof Component) {\r
- Component comp = (Component)sub;\r
- proceduralChildren.put(comp.name, comp);\r
- }\r
- }\r
- \r
- Collection<Object> nodeChildren = All.getPossibleNodeChildren(graph, (AbstractChildVariable)context);\r
- Set<String> used = new HashSet<String>(nodeChildren.size());\r
- for(Object nodeChild : nodeChildren) {\r
- @SuppressWarnings("rawtypes")\r
- NodeSupport support = ((AbstractChildVariable)context).node.support;\r
- @SuppressWarnings("rawtypes")\r
- NodeManager manager = support.manager;\r
- @SuppressWarnings("unchecked")\r
- String name = manager.getName(nodeChild);\r
- used.add(name);\r
- Component proceduralChild = proceduralChildren.get(name); \r
- if(proceduralChild != null) {\r
- map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, new VariableNode(support, nodeChild), proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));\r
- }\r
- }\r
- \r
- for(Map.Entry<String, Component> entry : proceduralChildren.entrySet()) {\r
- String name = entry.getKey();\r
- if(used.contains(name)) continue;\r
- Component proceduralChild = entry.getValue();\r
- map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, null, proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));\r
- }\r
- \r
- return map;\r
- \r
- } \r
- \r
- private static class ProceduralSubstructureRequest extends VariableRead<Map<String,Variable>> {\r
-\r
- public ProceduralSubstructureRequest(Variable variable) {\r
- super(variable);\r
- }\r
-\r
- @Override\r
- public Map<String, Variable> perform(ReadGraph graph)\r
- throws DatabaseException {\r
- List<SubstructureElement> elements = getProceduralDesc(graph, variable);\r
- if(elements != null)\r
- return getProcedural(graph, variable, elements, null);\r
- else\r
- return null;\r
- }\r
- }\r
- \r
- \r
- @SCLValue(type = "VariableMap")\r
- public static VariableMap structuralChildDomainChildren = new VariableMapImpl() {\r
- \r
- @Override\r
- public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
- \r
- final Resource type = context.getPossibleType(graph);\r
- if(type != null) {\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {\r
- Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),\r
- TransientCacheListener.<Map<String,Variable>>instance());\r
- if(map != null) return map.get(name);\r
- }\r
- }\r
-\r
- Resource represents = context.getPossibleRepresents(graph);\r
- if(represents == null) {\r
- Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));\r
- Resource child = children.get(name);\r
- return All.getStandardChildDomainChildVariable(graph, context, child, name);\r
- }\r
- Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));\r
- Resource child = children.get(name);\r
- return All.getStandardChildDomainChildVariable(graph, context, child, name);\r
- }\r
-\r
- @Override\r
- public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
- \r
- final Resource type = context.getPossibleType(graph);\r
- if(type != null) {\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {\r
- Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),\r
- TransientCacheListener.<Map<String,Variable>>instance());\r
- if(mapPrime != null) {\r
- if(map != null) {\r
- map.putAll(mapPrime);\r
- return map;\r
- }\r
- else\r
- return mapPrime;\r
- }\r
- }\r
- }\r
- Resource represents = context.getPossibleRepresents(graph);\r
- if(represents == null) {\r
- Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));\r
- return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);\r
- }\r
- Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));\r
- return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);\r
- }\r
- \r
- };\r
- \r
- @SCLValue(type = "VariableMap")\r
- public static VariableMap structuralRunDomainChildren = new VariableMapImpl() {\r
- \r
- @Override\r
- public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
- Map<String, Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph)));\r
- Resource child = children.get(name);\r
- return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);\r
- }\r
-\r
- @Override\r
- public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
- StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
- Map<String,Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource));\r
- return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);\r
- }\r
- \r
- };\r
-\r
- @SCLValue(type = "ReadGraph -> [Resource] -> [Resource]")\r
- public static List<Resource> connectionExtension(ReadGraph graph, List<Resource> rs) throws DatabaseException {\r
-\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- HashSet<Resource> extension = new HashSet<Resource>(8);\r
- for(Resource r : rs) {\r
- if(graph.isInstanceOf(r, STR.Connection)) {\r
- extension.addAll(graph.syncRequest(new ConnectionComponents(r), TransientCacheListener.<Collection<Resource>>instance()));\r
- }\r
- if(graph.isInstanceOf(r, STR.ConnectionJoin)) {\r
- extension.addAll(graph.syncRequest(new ConnectionJoinComponents(r), TransientCacheListener.<Collection<Resource>>instance()));\r
- }\r
- }\r
-\r
- HashSet<Resource> components = new HashSet<Resource>(8);\r
- for(Resource r : extension) {\r
- components.addAll(graph.sync(new ObjectsWithType(r, STR.Connects, STR.Component)));\r
- }\r
- \r
- if(!extension.isEmpty()) {\r
- ArrayList<Resource> result = new ArrayList<Resource>(rs.size() + extension.size());\r
- result.addAll(rs);\r
- result.addAll(extension);\r
- result.addAll(components);\r
- rs = result;\r
- }\r
- \r
- return rs;\r
- \r
- }\r
-\r
- @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
- public static List<Issue> connectionValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
- \r
- if(!graph.hasStatement(component)) return Collections.emptyList();\r
-\r
- ArrayList<Issue> result = new ArrayList<Issue>();\r
- \r
- Layer0 L0 = Layer0.getInstance(graph);\r
- StructuralResource2 sr = StructuralResource2.getInstance(graph);\r
-\r
- Resource type = graph.getSingleType(component, sr.Component);\r
- \r
- Set<Resource> requiredConnections = new HashSet<Resource>();\r
- for(Resource connectionRelation : graph.sync(new ObjectsWithType(type, L0.ConsistsOf, sr.ConnectionRelation))) {\r
- Boolean required = graph.getPossibleRelatedValue(connectionRelation, sr.ConnectionRelation_connectionRequired, Bindings.BOOLEAN);\r
- if(required != null && required)\r
- requiredConnections.add(connectionRelation);\r
- }\r
- \r
- Set<Resource> connections = new HashSet<Resource>();\r
-\r
- for(Statement stm : graph.getStatements(component, sr.IsConnectedTo)) {\r
- connections.add(stm.getPredicate());\r
- connections.addAll(graph.getSuperrelations(stm.getPredicate()));\r
- }\r
-\r
- for(Resource req : requiredConnections) {\r
- if(!connections.contains(req)) {\r
- result.add(new StandardIssue(sr.ConnectionConstraint_ErrorIssue, component, req));\r
- }\r
- }\r
-\r
- return result;\r
- \r
- }\r
-\r
- @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
- public static String connectionIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
- List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
- String attributeName = graph.getRelatedValue(contexts.get(1), Layer0.getInstance(graph).HasName);\r
- return "'" + attributeName + "' should be connected.";\r
- }\r
-\r
- public static class InterfacePathMap extends VariableRead<GraphMap<Map<String,InterfaceResolution>>> {\r
-\r
- public InterfacePathMap(Variable context) {\r
- super(context);\r
- }\r
-\r
- @Override\r
- public GraphMap<Map<String,InterfaceResolution>> perform(ReadGraph graph) throws DatabaseException {\r
-\r
- return new GraphMap<Map<String,InterfaceResolution>>() {\r
-\r
- @Override\r
- Map<String, InterfaceResolution> get(ReadGraph graph, String key) throws DatabaseException {\r
- \r
- Variable child = variable.getChild(graph, key);\r
- \r
- Map<String,InterfaceResolution> childMap = new THashMap<String,InterfaceResolution>();\r
- Collection<InterfaceResolution> paths = computeInterfacePaths(graph, child);//child.getPossiblePropertyValue(graph, "proceduralConnectionPointPath");\r
- if(paths != null) {\r
- for(InterfaceResolution r : paths) {\r
- childMap.put(r.interfaceName, r);\r
- }\r
- }\r
- return childMap;\r
-\r
- }\r
- \r
- };\r
- \r
- }\r
- \r
- }\r
- \r
- public static String resolveInterfacePath(ReadGraph graph, Variable context, String component, Resource relation) throws DatabaseException {\r
- \r
- GraphMap<Map<String,InterfaceResolution>> map = graph.syncRequest(new InterfacePathMap(context), TransientCacheListener.<GraphMap<Map<String,InterfaceResolution>>>instance());\r
- Map<String,InterfaceResolution> childMap = map.get(graph, component);\r
- if(childMap == null) return "";\r
-\r
- PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheListener.<PropertyInfo>instance());\r
-\r
- InterfaceResolution match = childMap.get(info.name);\r
- if(match != null) {\r
- String comp = URIStringUtils.escape(component);\r
- Variable newContext = context.getChild(graph, component);\r
- return "/" + comp + resolveInterfacePath(graph, newContext, match.componentName, match.connectionPoint);\r
- } else {\r
- return "/" + URIStringUtils.escape(component) + "#" + URIStringUtils.escape(info.name); \r
- }\r
- \r
- }\r
- \r
- public static class InterfaceResolution {\r
- \r
- public Resource interfaceConnectionPoint;\r
- public String interfaceName;\r
- public String componentName;\r
- public Resource connectionPoint;\r
- \r
- public InterfaceResolution(Resource interfaceConnectionPoint, String interfaceName, String componentName, Resource connectionPoint) {\r
- this.interfaceConnectionPoint = interfaceConnectionPoint;\r
- this.interfaceName = interfaceName;\r
- this.componentName = componentName;\r
- this.connectionPoint = connectionPoint;\r
- }\r
- \r
- }\r
- \r
- public static Collection<InterfaceResolution> computeInterfacePaths(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- Resource type = variable.getPossibleType(graph);\r
- if(type != null) {\r
- if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {\r
- ArrayList<InterfaceResolution> result = new ArrayList<InterfaceResolution>();\r
- List<SubstructureElement> elements = getProceduralDesc(graph, variable); \r
- if(elements != null) {\r
- for(SubstructureElement e : elements) {\r
- if(e instanceof org.simantics.structural2.procedural.Connection) {\r
- org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)e;\r
- Interface inf = null;\r
- for(ConnectionPoint cp : conn.connectionPoints) {\r
- if(cp instanceof Interface) {\r
- if(inf != null) throw new DatabaseException("Multiple interfaces referenced in procedural connection.");\r
- inf = (Interface)cp;\r
- }\r
- }\r
- if(inf != null && conn.connectionPoints.size() > 1) {\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- String cpName = URIStringUtils.escape( graph.<String>getRelatedValue(inf.relation, L0.HasName, Bindings.STRING) );\r
- for(ConnectionPoint cp : conn.connectionPoints) {\r
- if(cp == inf) continue;\r
- Terminal t = (Terminal)cp;\r
- result.add(new InterfaceResolution(inf.relation, cpName, t.component, t.relation));\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return result;\r
- \r
- }\r
-\r
- final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(type));\r
- if(interfaces != null) return interfaces;\r
-\r
- }\r
- \r
- return BUILTIN_STRUCTURAL_CPS;\r
- \r
- }\r
- \r
- static class InterfacePathRequest extends VariableRead<Collection<InterfaceResolution>> {\r
-\r
- public InterfacePathRequest(Variable variable) {\r
- super(variable);\r
- }\r
- \r
- @Override\r
- public Collection<InterfaceResolution> perform(ReadGraph graph) throws DatabaseException {\r
- return computeInterfacePaths(graph, variable);\r
- }\r
- \r
- }\r
- \r
- static class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {\r
-\r
- public DefinedUCInterfaceMap(Resource resource) {\r
- super(resource);\r
- }\r
-\r
- @Override\r
- public Collection<InterfaceResolution> perform(ReadGraph graph)\r
- throws DatabaseException {\r
-\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);\r
- if(definition != null) {\r
- Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) {\r
- String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);\r
- for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) {\r
- Statement stm = graph.getPossibleStatement(conn, STR.Connects);\r
- if(stm == null) continue;\r
- Resource component = stm.getObject();\r
- String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);\r
- result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate())));\r
- }\r
- }\r
- return result;\r
- }\r
- return null;\r
- }\r
-\r
- }\r
- \r
- public static final Collection<InterfaceResolution> BUILTIN_STRUCTURAL_CPS = new ArrayList<InterfaceResolution>();\r
-\r
- @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
- public static Object computeExpression(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {\r
- return CompileStructuralValueRequest.compileAndEvaluate(graph, context);\r
- }\r
-\r
- public static Object computeExpressionInContext(ReadGraph graph, Variable context, final String expression) throws DatabaseException {\r
- SCLContext sclContext = SCLContext.getCurrent();\r
- Object oldGraph = sclContext.get("graph");\r
- try {\r
- Function1<Variable,Object> exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) {\r
- protected String getExpressionText(ReadGraph graph) throws DatabaseException {\r
- return expression;\r
- }\r
- },\r
- TransientCacheListener.<Function1<Variable,Object>>instance());\r
- sclContext.put("graph", graph);\r
- return exp.apply(context);\r
- } catch (DatabaseException e) {\r
- throw (DatabaseException)e;\r
- } catch (Throwable t) {\r
- throw new DatabaseException(t);\r
- } finally {\r
- sclContext.put("graph", oldGraph);\r
- }\r
- } \r
- \r
- static abstract class InterfacePathProperty extends LazyPropertyVariable {\r
- \r
- public InterfacePathProperty(Variable parent) {\r
- super(parent, "proceduralConnectionPointPath", Bindings.STRING_ARRAY);\r
- }\r
- \r
- @Override\r
- public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
- return getValue(graph);\r
- }\r
- \r
- }\r
- \r
- static abstract class GraphMap<Value> {\r
- \r
- abstract Value get(ReadGraph graph, String key) throws DatabaseException;\r
- \r
- }\r
- \r
-}\r
+package org.simantics.structural2;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.error.DatatypeConstructionException;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.issue.StandardIssue;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.uri.UnescapedChildMapOfResource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.function.All;
+import org.simantics.db.layer0.function.StandardChildDomainChildren;
+import org.simantics.db.layer0.request.PropertyInfo;
+import org.simantics.db.layer0.request.PropertyInfoRequest;
+import org.simantics.db.layer0.request.VariableRead;
+import org.simantics.db.layer0.variable.AbstractChildVariable;
+import org.simantics.db.layer0.variable.AbstractPropertyVariable;
+import org.simantics.db.layer0.variable.LazyPropertyVariable;
+import org.simantics.db.layer0.variable.NodeSupport;
+import org.simantics.db.layer0.variable.StandardGraphChildVariable;
+import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
+import org.simantics.db.layer0.variable.ValueAccessor;
+import org.simantics.db.layer0.variable.ValueAccessorWithBinding;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.VariableMap;
+import org.simantics.db.layer0.variable.VariableMapImpl;
+import org.simantics.db.layer0.variable.VariableNode;
+import org.simantics.issues.common.IssueUtils;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.reflection.annotations.SCLValue;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.simulation.ontology.SimulationResource;
+import org.simantics.simulator.variable.NodeManager;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.procedural.Component;
+import org.simantics.structural2.procedural.ConnectionPoint;
+import org.simantics.structural2.procedural.Interface;
+import org.simantics.structural2.procedural.SubstructureElement;
+import org.simantics.structural2.procedural.Terminal;
+import org.simantics.structural2.queries.ConnectionComponents;
+import org.simantics.structural2.queries.ConnectionJoinComponents;
+import org.simantics.structural2.queries.ConnectionPointMapOfResource;
+import org.simantics.structural2.queries.PossibleConnectionPointInfo;
+import org.simantics.structural2.scl.CompileStructuralValueRequest;
+import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest;
+import org.simantics.structural2.variables.Connection;
+import org.simantics.structural2.variables.ConnectionBrowser;
+import org.simantics.structural2.variables.StandardProceduralChildVariable;
+import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
+import org.simantics.utils.datastructures.MapList;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+public class Functions {
+
+ @SCLValue(type="ValueAccessor")
+ public static final ValueAccessor expressionValueAccessor = new ValueAccessorWithBinding() {
+
+ public Binding getBinding() {
+ return Bindings.STRING;
+ }
+
+ @Override
+ public void setValue(WriteGraph graph, Variable context, Object value)
+ throws DatabaseException {
+ if(value == null) {
+ if(getValue(graph, context) != null)
+ clearExpression(graph, context);
+ return;
+ }
+
+ // Get all necessary data
+ String expression = (String)value;
+ Variable parent = context.getParent(graph);
+ if(!(parent instanceof AbstractPropertyVariable)) return;
+ AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
+ Resource propertyResource = property.getRepresents(graph);
+ if(propertyResource == null) return;
+ Resource container = property.getContainerResource(graph);
+ if(container == null) return;
+ Resource predicate = property.getPossiblePredicateResource(graph);
+ if(predicate == null) return;
+ Statement stat = graph.getPossibleStatement(container, predicate);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ // Write
+ boolean createNew = false;
+ if(stat.isAsserted(container))
+ createNew = true;
+ else if(!graph.isInstanceOf(propertyResource, STR.SCLValue)) {
+ graph.deny(propertyResource);
+ createNew = true;
+ }
+ Layer0 L0 = Layer0.getInstance(graph);
+ if(createNew) {
+ propertyResource = graph.newResource();
+ graph.claim(container, predicate, propertyResource);
+ graph.claim(propertyResource, L0.InstanceOf, STR.SCLValue);
+ }
+ graph.claimLiteral(propertyResource, L0.SCLValue_expression, expression, Bindings.STRING);
+ }
+
+ private void clearExpression(WriteGraph graph, Variable context) throws DatabaseException {
+ Variable parent = context.getParent(graph);
+ if(!(parent instanceof AbstractPropertyVariable)) return;
+ AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
+ Resource container = property.getContainerResource(graph);
+ if(container == null) return;
+ Resource predicate = property.getPossiblePredicateResource(graph);
+ if(predicate == null) return;
+ graph.deny(container, predicate);
+ }
+
+ @Override
+ public Object getValue(ReadGraph graph, Variable context)
+ throws DatabaseException {
+ Variable parent = context.getParent(graph);
+ if(!(parent instanceof AbstractPropertyVariable))
+ return null;
+ AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
+ Resource propertyResource = property.getPossibleRepresents(graph);
+ if(propertyResource == null) return null;
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ if(!graph.isInstanceOf(propertyResource, STR.SCLValue))
+ return null;
+ Layer0 L0 = Layer0.getInstance(graph);
+ return graph.getPossibleRelatedValue(propertyResource, L0.SCLValue_expression);
+ }
+
+ };
+
+ static class ConnectionImpl implements Connection {
+
+ final private StandardGraphPropertyVariable connectionPoint;
+
+ public ConnectionImpl(StandardGraphPropertyVariable connectionPoint) {
+ this.connectionPoint = connectionPoint;
+ }
+
+ @Override
+ public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
+ Set<Variable> result = new THashSet<Variable>();
+ for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
+ result.add(desc.getVariable(graph));
+ }
+ return result;
+ }
+
+ @Override
+ public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
+ Set<String> result = new THashSet<String>();
+ for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
+ result.add(desc.getURI(graph));
+ }
+ return result;
+ }
+
+ @Override
+ public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
+ return ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType);
+ }
+
+ }
+
+ @SCLValue(type="ValueAccessor")
+ public static final ValueAccessor connectionValueAccessor = new ValueAccessor() {
+
+ @Override
+ public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
+ try {
+ Object value = getValue(graph, context);
+ Binding srcBinding = Bindings.OBJECT.getContentBinding(value);
+ return Bindings.adapt(value, srcBinding, binding);
+ } catch (AdaptException e) {
+ throw new DatabaseException(e);
+ } catch (BindingException e) {
+ throw new DatabaseException(e);
+ }
+ }
+
+ @Override
+ public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
+ StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;
+ return new ConnectionImpl(variable);
+ }
+
+ @Override
+ public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
+ try {
+ return Datatypes.getDatatype(Connection.class);
+ } catch (DatatypeConstructionException e) {
+ throw new DatabaseException(e);
+ }
+ }
+
+ };
+
+
+ @SCLValue(type = "VariableMap")
+ public static VariableMap structuralChildDomainProperties = new VariableMapImpl() {
+
+ public Variable getPossibleConnectionPointFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {
+
+ Map<String, Resource> connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
+ Resource cp = connectionPoints.get(name);
+ if(cp == null) return null;
+ else return new StandardGraphPropertyVariable(graph, variable, cp);
+
+ }
+
+ public Map<String, Variable> collectConnectionPointsFromContext(ReadGraph graph, StructuralResource2 STR, Variable variable, Resource context, Map<String, Variable> map, boolean needSynchronized) throws DatabaseException {
+
+ if(graph.isImmutable(context)) {
+
+ Map<String, Resource> cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
+ if(cps.size() == 0) return map;
+
+ if(map == null) map = new THashMap<String,Variable>(cps.size());
+
+ for(Map.Entry<String, Resource> entry : cps.entrySet()) {
+ String name = entry.getKey();
+ Resource cp = entry.getValue();
+ if(needSynchronized && !graph.isInstanceOf(cp, STR.SynchronizedConnectionRelation)) continue;
+ map.put(name, new StandardGraphPropertyVariable(graph, variable, cp));
+ }
+
+ return map;
+
+ } else {
+
+ Collection<Resource> predicates = graph.getPredicates(context);
+
+ for(Resource predicate : predicates) {
+
+ PropertyInfo info = graph.isImmutable(predicate) ?
+ graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :
+ graph.syncRequest(new PossibleConnectionPointInfo(predicate));
+
+ if(info != null) {
+ if(map == null) map = new THashMap<String,Variable>(4);
+ if(needSynchronized && !graph.isInstanceOf(predicate, STR.SynchronizedConnectionRelation)) continue;
+ map.put(info.name, new StandardGraphPropertyVariable(graph, variable, predicate));
+ }
+
+ }
+
+ return map;
+
+ }
+
+ }
+
+ @Override
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+ final StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
+ Variable cp = getPossibleConnectionPointFromContext(graph, variable, variable.resource, name);
+ if(cp != null) return cp;
+ return All.getStandardChildDomainPropertyVariable(graph, context, name);
+ }
+
+ @Override
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+ StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ map = collectConnectionPointsFromContext(graph, STR, variable, variable.resource, map, false);
+ return All.getStandardChildDomainPropertyVariables(graph, context, map);
+ }
+
+ public Map<String,Variable> getVariables(ReadGraph graph, Variable context, String classification, Map<String,Variable> map) throws DatabaseException {
+ if (StructuralResource2.URIs.SynchronizedRelation.equals(classification)) {
+ return All.getStandardChildDomainPropertyVariables(graph, context, classification, map);
+ } else if (StructuralResource2.URIs.SynchronizedConnectionRelation.equals(classification)) {
+ StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
+ return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, true);
+ } else if(StructuralResource2.URIs.ConnectionRelation.equals(classification)) {
+ StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
+ return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, false);
+ }
+ return super.getVariables(graph, context, classification, map);
+ }
+
+ };
+
+ static class StructuralChildMapOfResource extends ResourceRead<Map<String, Resource>> {
+
+ public StructuralChildMapOfResource(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ Resource type = graph.getPossibleType(resource, STR.Component);
+ if(type != null) {
+ Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy);
+ if(definition != null) {
+ Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
+ if (!map.isEmpty())
+ return map;
+ }
+ }
+ Map<String, Resource> directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));
+ return directChildren;
+ }
+
+ }
+
+ static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {
+
+ public StructuralChildMapOfResourceT(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
+ if(definition != null) {
+ Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
+ if (!map.isEmpty())
+ return map;
+ }
+ return Collections.emptyMap();
+ }
+
+ }
+
+ static class StructuralRunChildMapOfResource extends ResourceRead<Map<String, Resource>> {
+
+ public StructuralRunChildMapOfResource(Resource resource) {
+ super(resource);
+ }
+
+ public Map<String, Resource> fromContext(ReadGraph graph, Resource context) throws DatabaseException {
+ return graph.sync(new StructuralChildMapOfResource(context));
+ }
+
+ @Override
+ public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ SimulationResource SIMU = SimulationResource.getInstance(graph);
+ Resource model = graph.sync(new PossibleIndexRoot(resource));
+ if(graph.isInstanceOf(model, L0.RVIContext)) {
+ return fromContext(graph, model);
+ }
+ Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);
+ if(configuration != null) {
+ if(graph.isInstanceOf(configuration, L0.RVIContext)) {
+ return fromContext(graph, configuration);
+ }
+ }
+
+ return Collections.emptyMap();
+
+ }
+
+ }
+
+ private static class SubstructureRequest extends VariableRead<List<SubstructureElement>> {
+ public SubstructureRequest(Variable context) {
+ super(context);
+ }
+
+ @Override
+ public List<SubstructureElement> perform(ReadGraph graph) {
+ try {
+ Resource type = variable.getPossibleType(graph);
+ if(type == null)
+ return null;
+ return CompileProceduralComponentTypeRequest.compileAndEvaluate(graph, type, variable);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return null;
+ }
+ }
+ }
+
+ public static List<SubstructureElement> getProceduralDesc(ReadGraph graph, final Variable context) throws DatabaseException {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ final Resource type = context.getPossibleType(graph);
+ if(type != null) {
+ if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
+ return graph.syncRequest(new SubstructureRequest(context));
+ }
+ }
+ return null;
+ }
+
+ public static Map<String,Variable> getProcedural(ReadGraph graph, Variable context, List<SubstructureElement> elements, Map<String,Variable> map) throws DatabaseException {
+
+ if(map == null) map = new THashMap<String,Variable>();
+
+ MapList<String,org.simantics.structural2.procedural.Connection> conns = new MapList<String,org.simantics.structural2.procedural.Connection>();
+ for(SubstructureElement sub : elements) {
+ if(sub instanceof org.simantics.structural2.procedural.Connection) {
+ org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)sub;
+ for(ConnectionPoint cp : conn.connectionPoints) {
+ if(cp instanceof Terminal) {
+ Terminal t = (Terminal)cp;
+ conns.add(t.component, conn);
+ }
+ }
+ }
+ }
+
+ Map<String,Component> proceduralChildren = new THashMap<String, Component>();
+ for(SubstructureElement sub : elements) {
+ if(sub instanceof Component) {
+ Component comp = (Component)sub;
+ proceduralChildren.put(comp.name, comp);
+ }
+ }
+
+ Collection<Object> nodeChildren = All.getPossibleNodeChildren(graph, (AbstractChildVariable)context);
+ Set<String> used = new HashSet<String>(nodeChildren.size());
+ for(Object nodeChild : nodeChildren) {
+ @SuppressWarnings("rawtypes")
+ NodeSupport support = ((AbstractChildVariable)context).node.support;
+ @SuppressWarnings("rawtypes")
+ NodeManager manager = support.manager;
+ @SuppressWarnings("unchecked")
+ String name = manager.getName(nodeChild);
+ used.add(name);
+ Component proceduralChild = proceduralChildren.get(name);
+ if(proceduralChild != null) {
+ map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, new VariableNode(support, nodeChild), proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));
+ }
+ }
+
+ for(Map.Entry<String, Component> entry : proceduralChildren.entrySet()) {
+ String name = entry.getKey();
+ if(used.contains(name)) continue;
+ Component proceduralChild = entry.getValue();
+ map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, null, proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));
+ }
+
+ return map;
+
+ }
+
+ private static class ProceduralSubstructureRequest extends VariableRead<Map<String,Variable>> {
+
+ public ProceduralSubstructureRequest(Variable variable) {
+ super(variable);
+ }
+
+ @Override
+ public Map<String, Variable> perform(ReadGraph graph)
+ throws DatabaseException {
+ List<SubstructureElement> elements = getProceduralDesc(graph, variable);
+ if(elements != null)
+ return getProcedural(graph, variable, elements, null);
+ else
+ return null;
+ }
+ }
+
+
+ @SCLValue(type = "VariableMap")
+ public static VariableMap structuralChildDomainChildren = new VariableMapImpl() {
+
+ @Override
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+
+ final Resource type = context.getPossibleType(graph);
+ if(type != null) {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
+ Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
+ TransientCacheListener.<Map<String,Variable>>instance());
+ if(map != null) return map.get(name);
+ }
+ }
+
+ Resource represents = context.getPossibleRepresents(graph);
+ if(represents == null) {
+ Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
+ Resource child = children.get(name);
+ return All.getStandardChildDomainChildVariable(graph, context, child, name);
+ }
+ Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
+ Resource child = children.get(name);
+ return All.getStandardChildDomainChildVariable(graph, context, child, name);
+ }
+
+ @Override
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+
+ final Resource type = context.getPossibleType(graph);
+ if(type != null) {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
+ Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
+ TransientCacheListener.<Map<String,Variable>>instance());
+ if(mapPrime != null) {
+ if(map != null) {
+ map.putAll(mapPrime);
+ return map;
+ }
+ else
+ return mapPrime;
+ }
+ }
+ }
+ Resource represents = context.getPossibleRepresents(graph);
+ if(represents == null) {
+ Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
+ return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
+ }
+ Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
+ return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
+ }
+
+ };
+
+ @SCLValue(type = "VariableMap")
+ public static VariableMap structuralRunDomainChildren = new VariableMapImpl() {
+
+ @Override
+ public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+ Map<String, Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph)));
+ Resource child = children.get(name);
+ return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
+ }
+
+ @Override
+ public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+ StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
+ Map<String,Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource));
+ return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
+ }
+
+ };
+
+ @SCLValue(type = "ReadGraph -> [Resource] -> [Resource]")
+ public static List<Resource> connectionExtension(ReadGraph graph, List<Resource> rs) throws DatabaseException {
+
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ HashSet<Resource> extension = new HashSet<Resource>(8);
+ for(Resource r : rs) {
+ if(graph.isInstanceOf(r, STR.Connection)) {
+ extension.addAll(graph.syncRequest(new ConnectionComponents(r), TransientCacheListener.<Collection<Resource>>instance()));
+ }
+ if(graph.isInstanceOf(r, STR.ConnectionJoin)) {
+ extension.addAll(graph.syncRequest(new ConnectionJoinComponents(r), TransientCacheListener.<Collection<Resource>>instance()));
+ }
+ }
+
+ HashSet<Resource> components = new HashSet<Resource>(8);
+ for(Resource r : extension) {
+ components.addAll(graph.sync(new ObjectsWithType(r, STR.Connects, STR.Component)));
+ }
+
+ if(!extension.isEmpty()) {
+ ArrayList<Resource> result = new ArrayList<Resource>(rs.size() + extension.size());
+ result.addAll(rs);
+ result.addAll(extension);
+ result.addAll(components);
+ rs = result;
+ }
+
+ return rs;
+
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> [Issue]")
+ public static List<Issue> connectionValidator(ReadGraph graph, Resource component) throws DatabaseException {
+
+ if(!graph.hasStatement(component)) return Collections.emptyList();
+
+ ArrayList<Issue> result = new ArrayList<Issue>();
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ StructuralResource2 sr = StructuralResource2.getInstance(graph);
+
+ Resource type = graph.getSingleType(component, sr.Component);
+
+ Set<Resource> requiredConnections = new HashSet<Resource>();
+ for(Resource connectionRelation : graph.sync(new ObjectsWithType(type, L0.ConsistsOf, sr.ConnectionRelation))) {
+ Boolean required = graph.getPossibleRelatedValue(connectionRelation, sr.ConnectionRelation_connectionRequired, Bindings.BOOLEAN);
+ if(required != null && required)
+ requiredConnections.add(connectionRelation);
+ }
+
+ Set<Resource> connections = new HashSet<Resource>();
+
+ for(Statement stm : graph.getStatements(component, sr.IsConnectedTo)) {
+ connections.add(stm.getPredicate());
+ connections.addAll(graph.getSuperrelations(stm.getPredicate()));
+ }
+
+ for(Resource req : requiredConnections) {
+ if(!connections.contains(req)) {
+ result.add(new StandardIssue(sr.ConnectionConstraint_ErrorIssue, component, req));
+ }
+ }
+
+ return result;
+
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
+ public static String connectionIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
+ List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);
+ String attributeName = graph.getRelatedValue(contexts.get(1), Layer0.getInstance(graph).HasName);
+ return "'" + attributeName + "' should be connected.";
+ }
+
+ public static class InterfacePathMap extends VariableRead<GraphMap<Map<String,InterfaceResolution>>> {
+
+ public InterfacePathMap(Variable context) {
+ super(context);
+ }
+
+ @Override
+ public GraphMap<Map<String,InterfaceResolution>> perform(ReadGraph graph) throws DatabaseException {
+
+ return new GraphMap<Map<String,InterfaceResolution>>() {
+
+ @Override
+ Map<String, InterfaceResolution> get(ReadGraph graph, String key) throws DatabaseException {
+
+ Variable child = variable.getChild(graph, key);
+
+ Map<String,InterfaceResolution> childMap = new THashMap<String,InterfaceResolution>();
+ Collection<InterfaceResolution> paths = computeInterfacePaths(graph, child);//child.getPossiblePropertyValue(graph, "proceduralConnectionPointPath");
+ if(paths != null) {
+ for(InterfaceResolution r : paths) {
+ childMap.put(r.interfaceName, r);
+ }
+ }
+ return childMap;
+
+ }
+
+ };
+
+ }
+
+ }
+
+ public static String resolveInterfacePath(ReadGraph graph, Variable context, String component, Resource relation) throws DatabaseException {
+
+ GraphMap<Map<String,InterfaceResolution>> map = graph.syncRequest(new InterfacePathMap(context), TransientCacheListener.<GraphMap<Map<String,InterfaceResolution>>>instance());
+ Map<String,InterfaceResolution> childMap = map.get(graph, component);
+ if(childMap == null) return "";
+
+ PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheListener.<PropertyInfo>instance());
+
+ InterfaceResolution match = childMap.get(info.name);
+ if(match != null) {
+ String comp = URIStringUtils.escape(component);
+ Variable newContext = context.getChild(graph, component);
+ return "/" + comp + resolveInterfacePath(graph, newContext, match.componentName, match.connectionPoint);
+ } else {
+ return "/" + URIStringUtils.escape(component) + "#" + URIStringUtils.escape(info.name);
+ }
+
+ }
+
+ public static class InterfaceResolution {
+
+ public Resource interfaceConnectionPoint;
+ public String interfaceName;
+ public String componentName;
+ public Resource connectionPoint;
+
+ public InterfaceResolution(Resource interfaceConnectionPoint, String interfaceName, String componentName, Resource connectionPoint) {
+ this.interfaceConnectionPoint = interfaceConnectionPoint;
+ this.interfaceName = interfaceName;
+ this.componentName = componentName;
+ this.connectionPoint = connectionPoint;
+ }
+
+ }
+
+ public static Collection<InterfaceResolution> computeInterfacePaths(ReadGraph graph, Variable variable) throws DatabaseException {
+
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ Resource type = variable.getPossibleType(graph);
+ if(type != null) {
+ if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
+ ArrayList<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
+ List<SubstructureElement> elements = getProceduralDesc(graph, variable);
+ if(elements != null) {
+ for(SubstructureElement e : elements) {
+ if(e instanceof org.simantics.structural2.procedural.Connection) {
+ org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)e;
+ Interface inf = null;
+ for(ConnectionPoint cp : conn.connectionPoints) {
+ if(cp instanceof Interface) {
+ if(inf != null) throw new DatabaseException("Multiple interfaces referenced in procedural connection.");
+ inf = (Interface)cp;
+ }
+ }
+ if(inf != null && conn.connectionPoints.size() > 1) {
+ Layer0 L0 = Layer0.getInstance(graph);
+ String cpName = URIStringUtils.escape( graph.<String>getRelatedValue(inf.relation, L0.HasName, Bindings.STRING) );
+ for(ConnectionPoint cp : conn.connectionPoints) {
+ if(cp == inf) continue;
+ Terminal t = (Terminal)cp;
+ result.add(new InterfaceResolution(inf.relation, cpName, t.component, t.relation));
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+
+ }
+
+ final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(type));
+ if(interfaces != null) return interfaces;
+
+ }
+
+ return BUILTIN_STRUCTURAL_CPS;
+
+ }
+
+ static class InterfacePathRequest extends VariableRead<Collection<InterfaceResolution>> {
+
+ public InterfacePathRequest(Variable variable) {
+ super(variable);
+ }
+
+ @Override
+ public Collection<InterfaceResolution> perform(ReadGraph graph) throws DatabaseException {
+ return computeInterfacePaths(graph, variable);
+ }
+
+ }
+
+ static class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {
+
+ public DefinedUCInterfaceMap(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Collection<InterfaceResolution> perform(ReadGraph graph)
+ throws DatabaseException {
+
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
+ if(definition != null) {
+ Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
+ Layer0 L0 = Layer0.getInstance(graph);
+ for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) {
+ String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
+ for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) {
+ Statement stm = graph.getPossibleStatement(conn, STR.Connects);
+ if(stm == null) continue;
+ Resource component = stm.getObject();
+ String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
+ result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate())));
+ }
+ }
+ return result;
+ }
+ return null;
+ }
+
+ }
+
+ public static final Collection<InterfaceResolution> BUILTIN_STRUCTURAL_CPS = new ArrayList<InterfaceResolution>();
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+ public static Object computeExpression(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {
+ return CompileStructuralValueRequest.compileAndEvaluate(graph, context);
+ }
+
+ public static Object computeExpressionInContext(ReadGraph graph, Variable context, final String expression) throws DatabaseException {
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ Function1<Variable,Object> exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) {
+ protected String getExpressionText(ReadGraph graph) throws DatabaseException {
+ return expression;
+ }
+ },
+ TransientCacheListener.<Function1<Variable,Object>>instance());
+ sclContext.put("graph", graph);
+ return exp.apply(context);
+ } catch (DatabaseException e) {
+ throw (DatabaseException)e;
+ } catch (Throwable t) {
+ throw new DatabaseException(t);
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+
+ static abstract class InterfacePathProperty extends LazyPropertyVariable {
+
+ public InterfacePathProperty(Variable parent) {
+ super(parent, "proceduralConnectionPointPath", Bindings.STRING_ARRAY);
+ }
+
+ @Override
+ public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
+ return getValue(graph);
+ }
+
+ }
+
+ static abstract class GraphMap<Value> {
+
+ abstract Value get(ReadGraph graph, String key) throws DatabaseException;
+
+ }
+
+}