1 package org.simantics.structural2;
\r
4 import java.util.ArrayList;
\r
5 import java.util.Collection;
\r
6 import java.util.Collections;
\r
7 import java.util.HashSet;
\r
8 import java.util.List;
\r
9 import java.util.Map;
\r
10 import java.util.Set;
\r
12 import org.simantics.databoard.Bindings;
\r
13 import org.simantics.databoard.Datatypes;
\r
14 import org.simantics.databoard.adapter.AdaptException;
\r
15 import org.simantics.databoard.binding.Binding;
\r
16 import org.simantics.databoard.binding.error.BindingException;
\r
17 import org.simantics.databoard.binding.error.DatatypeConstructionException;
\r
18 import org.simantics.databoard.type.Datatype;
\r
19 import org.simantics.databoard.util.URIStringUtils;
\r
20 import org.simantics.db.Issue;
\r
21 import org.simantics.db.ReadGraph;
\r
22 import org.simantics.db.Resource;
\r
23 import org.simantics.db.Statement;
\r
24 import org.simantics.db.WriteGraph;
\r
25 import org.simantics.db.common.issue.StandardIssue;
\r
26 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
\r
27 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
\r
28 import org.simantics.db.common.request.ObjectsWithType;
\r
29 import org.simantics.db.common.request.PossibleIndexRoot;
\r
30 import org.simantics.db.common.request.ResourceRead;
\r
31 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
\r
32 import org.simantics.db.exception.DatabaseException;
\r
33 import org.simantics.db.layer0.function.All;
\r
34 import org.simantics.db.layer0.function.StandardChildDomainChildren;
\r
35 import org.simantics.db.layer0.request.PropertyInfo;
\r
36 import org.simantics.db.layer0.request.PropertyInfoRequest;
\r
37 import org.simantics.db.layer0.request.VariableRead;
\r
38 import org.simantics.db.layer0.variable.AbstractChildVariable;
\r
39 import org.simantics.db.layer0.variable.AbstractPropertyVariable;
\r
40 import org.simantics.db.layer0.variable.LazyPropertyVariable;
\r
41 import org.simantics.db.layer0.variable.NodeSupport;
\r
42 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
\r
43 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
\r
44 import org.simantics.db.layer0.variable.ValueAccessor;
\r
45 import org.simantics.db.layer0.variable.ValueAccessorWithBinding;
\r
46 import org.simantics.db.layer0.variable.Variable;
\r
47 import org.simantics.db.layer0.variable.VariableMap;
\r
48 import org.simantics.db.layer0.variable.VariableMapImpl;
\r
49 import org.simantics.db.layer0.variable.VariableNode;
\r
50 import org.simantics.issues.common.IssueUtils;
\r
51 import org.simantics.layer0.Layer0;
\r
52 import org.simantics.scl.reflection.annotations.SCLValue;
\r
53 import org.simantics.scl.runtime.SCLContext;
\r
54 import org.simantics.scl.runtime.function.Function1;
\r
55 import org.simantics.simulation.ontology.SimulationResource;
\r
56 import org.simantics.simulator.variable.NodeManager;
\r
57 import org.simantics.structural.stubs.StructuralResource2;
\r
58 import org.simantics.structural2.procedural.Component;
\r
59 import org.simantics.structural2.procedural.ConnectionPoint;
\r
60 import org.simantics.structural2.procedural.Interface;
\r
61 import org.simantics.structural2.procedural.SubstructureElement;
\r
62 import org.simantics.structural2.procedural.Terminal;
\r
63 import org.simantics.structural2.queries.ConnectionComponents;
\r
64 import org.simantics.structural2.queries.ConnectionJoinComponents;
\r
65 import org.simantics.structural2.queries.ConnectionPointMapOfResource;
\r
66 import org.simantics.structural2.queries.PossibleConnectionPointInfo;
\r
67 import org.simantics.structural2.scl.CompileStructuralValueRequest;
\r
68 import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest;
\r
69 import org.simantics.structural2.variables.Connection;
\r
70 import org.simantics.structural2.variables.ConnectionBrowser;
\r
71 import org.simantics.structural2.variables.StandardProceduralChildVariable;
\r
72 import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
\r
73 import org.simantics.utils.datastructures.MapList;
\r
75 import gnu.trove.map.hash.THashMap;
\r
76 import gnu.trove.set.hash.THashSet;
\r
78 public class Functions {
\r
80 @SCLValue(type="ValueAccessor")
\r
81 public static final ValueAccessor expressionValueAccessor = new ValueAccessorWithBinding() {
\r
83 public Binding getBinding() {
\r
84 return Bindings.STRING;
\r
88 public void setValue(WriteGraph graph, Variable context, Object value)
\r
89 throws DatabaseException {
\r
91 if(getValue(graph, context) != null)
\r
92 clearExpression(graph, context);
\r
96 // Get all necessary data
\r
97 String expression = (String)value;
\r
98 Variable parent = context.getParent(graph);
\r
99 if(!(parent instanceof AbstractPropertyVariable)) return;
\r
100 AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
\r
101 Resource propertyResource = property.getRepresents(graph);
\r
102 if(propertyResource == null) return;
\r
103 Resource container = property.getContainerResource(graph);
\r
104 if(container == null) return;
\r
105 Resource predicate = property.getPossiblePredicateResource(graph);
\r
106 if(predicate == null) return;
\r
107 Statement stat = graph.getPossibleStatement(container, predicate);
\r
108 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
111 boolean createNew = false;
\r
112 if(stat.isAsserted(container))
\r
114 else if(!graph.isInstanceOf(propertyResource, STR.SCLValue)) {
\r
115 graph.deny(propertyResource);
\r
118 Layer0 L0 = Layer0.getInstance(graph);
\r
120 propertyResource = graph.newResource();
\r
121 graph.claim(container, predicate, propertyResource);
\r
122 graph.claim(propertyResource, L0.InstanceOf, STR.SCLValue);
\r
124 graph.claimLiteral(propertyResource, L0.SCLValue_expression, expression, Bindings.STRING);
\r
127 private void clearExpression(WriteGraph graph, Variable context) throws DatabaseException {
\r
128 Variable parent = context.getParent(graph);
\r
129 if(!(parent instanceof AbstractPropertyVariable)) return;
\r
130 AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
\r
131 Resource container = property.getContainerResource(graph);
\r
132 if(container == null) return;
\r
133 Resource predicate = property.getPossiblePredicateResource(graph);
\r
134 if(predicate == null) return;
\r
135 graph.deny(container, predicate);
\r
139 public Object getValue(ReadGraph graph, Variable context)
\r
140 throws DatabaseException {
\r
141 Variable parent = context.getParent(graph);
\r
142 if(!(parent instanceof AbstractPropertyVariable))
\r
144 AbstractPropertyVariable property = (AbstractPropertyVariable)parent;
\r
145 Resource propertyResource = property.getPossibleRepresents(graph);
\r
146 if(propertyResource == null) return null;
\r
147 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
148 if(!graph.isInstanceOf(propertyResource, STR.SCLValue))
\r
150 Layer0 L0 = Layer0.getInstance(graph);
\r
151 return graph.getPossibleRelatedValue(propertyResource, L0.SCLValue_expression);
\r
156 static class ConnectionImpl implements Connection {
\r
158 final private StandardGraphPropertyVariable connectionPoint;
\r
160 public ConnectionImpl(StandardGraphPropertyVariable connectionPoint) {
\r
161 this.connectionPoint = connectionPoint;
\r
165 public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
166 Set<Variable> result = new THashSet<Variable>();
\r
167 for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
\r
168 result.add(desc.getVariable(graph));
\r
174 public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
175 Set<String> result = new THashSet<String>();
\r
176 for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
\r
177 result.add(desc.getURI(graph));
\r
183 public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
184 return ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType);
\r
189 @SCLValue(type="ValueAccessor")
\r
190 public static final ValueAccessor connectionValueAccessor = new ValueAccessor() {
\r
193 public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
\r
194 throw new UnsupportedOperationException();
\r
197 public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
\r
198 throw new UnsupportedOperationException();
\r
201 public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
\r
203 Object value = getValue(graph, context);
\r
204 Binding srcBinding = Bindings.OBJECT.getContentBinding(value);
\r
205 return Bindings.adapt(value, srcBinding, binding);
\r
206 } catch (AdaptException e) {
\r
207 throw new DatabaseException(e);
\r
208 } catch (BindingException e) {
\r
209 throw new DatabaseException(e);
\r
214 public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
\r
215 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;
\r
216 return new ConnectionImpl(variable);
\r
220 public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
\r
222 return Datatypes.getDatatype(Connection.class);
\r
223 } catch (DatatypeConstructionException e) {
\r
224 throw new DatabaseException(e);
\r
231 @SCLValue(type = "VariableMap")
\r
232 public static VariableMap structuralChildDomainProperties = new VariableMapImpl() {
\r
234 public Variable getPossibleConnectionPointFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {
\r
236 Map<String, Resource> connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
\r
237 Resource cp = connectionPoints.get(name);
\r
238 if(cp == null) return null;
\r
239 else return new StandardGraphPropertyVariable(graph, variable, cp);
\r
243 public Map<String, Variable> collectConnectionPointsFromContext(ReadGraph graph, StructuralResource2 STR, Variable variable, Resource context, Map<String, Variable> map, boolean needSynchronized) throws DatabaseException {
\r
245 if(graph.isImmutable(context)) {
\r
247 Map<String, Resource> cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
\r
248 if(cps.size() == 0) return map;
\r
250 if(map == null) map = new THashMap<String,Variable>(cps.size());
\r
252 for(Map.Entry<String, Resource> entry : cps.entrySet()) {
\r
253 String name = entry.getKey();
\r
254 Resource cp = entry.getValue();
\r
255 if(needSynchronized && !graph.isInstanceOf(cp, STR.SynchronizedConnectionRelation)) continue;
\r
256 map.put(name, new StandardGraphPropertyVariable(graph, variable, cp));
\r
263 Collection<Resource> predicates = graph.getPredicates(context);
\r
265 for(Resource predicate : predicates) {
\r
267 PropertyInfo info = graph.isImmutable(predicate) ?
\r
268 graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :
\r
269 graph.syncRequest(new PossibleConnectionPointInfo(predicate));
\r
272 if(map == null) map = new THashMap<String,Variable>(4);
\r
273 if(needSynchronized && !graph.isInstanceOf(predicate, STR.SynchronizedConnectionRelation)) continue;
\r
274 map.put(info.name, new StandardGraphPropertyVariable(graph, variable, predicate));
\r
286 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
287 final StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
\r
288 Variable cp = getPossibleConnectionPointFromContext(graph, variable, variable.resource, name);
\r
289 if(cp != null) return cp;
\r
290 return All.getStandardChildDomainPropertyVariable(graph, context, name);
\r
294 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
295 StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
\r
296 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
297 map = collectConnectionPointsFromContext(graph, STR, variable, variable.resource, map, false);
\r
298 return All.getStandardChildDomainPropertyVariables(graph, context, map);
\r
301 public Map<String,Variable> getVariables(ReadGraph graph, Variable context, String classification, Map<String,Variable> map) throws DatabaseException {
\r
302 if (StructuralResource2.URIs.SynchronizedRelation.equals(classification)) {
\r
303 return All.getStandardChildDomainPropertyVariables(graph, context, classification, map);
\r
304 } else if (StructuralResource2.URIs.SynchronizedConnectionRelation.equals(classification)) {
\r
305 StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
\r
306 return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, true);
\r
307 } else if(StructuralResource2.URIs.ConnectionRelation.equals(classification)) {
\r
308 StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
\r
309 return collectConnectionPointsFromContext(graph, StructuralResource2.getInstance(graph), variable, variable.resource, map, false);
\r
311 return super.getVariables(graph, context, classification, map);
\r
316 static class StructuralChildMapOfResource extends ResourceRead<Map<String, Resource>> {
\r
318 public StructuralChildMapOfResource(Resource resource) {
\r
323 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
\r
324 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
325 Resource type = graph.getPossibleType(resource, STR.Component);
\r
327 Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy);
\r
328 if(definition != null) {
\r
329 Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
\r
330 if (!map.isEmpty())
\r
334 Map<String, Resource> directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));
\r
335 return directChildren;
\r
340 static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {
\r
342 public StructuralChildMapOfResourceT(Resource resource) {
\r
347 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
\r
348 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
349 Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
\r
350 if(definition != null) {
\r
351 Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
\r
352 if (!map.isEmpty())
\r
355 return Collections.emptyMap();
\r
360 static class StructuralRunChildMapOfResource extends ResourceRead<Map<String, Resource>> {
\r
362 public StructuralRunChildMapOfResource(Resource resource) {
\r
366 public Map<String, Resource> fromContext(ReadGraph graph, Resource context) throws DatabaseException {
\r
367 return graph.sync(new StructuralChildMapOfResource(context));
\r
371 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
\r
373 Layer0 L0 = Layer0.getInstance(graph);
\r
374 SimulationResource SIMU = SimulationResource.getInstance(graph);
\r
375 Resource model = graph.sync(new PossibleIndexRoot(resource));
\r
376 if(graph.isInstanceOf(model, L0.RVIContext)) {
\r
377 return fromContext(graph, model);
\r
379 Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);
\r
380 if(configuration != null) {
\r
381 if(graph.isInstanceOf(configuration, L0.RVIContext)) {
\r
382 return fromContext(graph, configuration);
\r
386 return Collections.emptyMap();
\r
392 private static class SubstructureRequest extends VariableRead<List<SubstructureElement>> {
\r
393 public SubstructureRequest(Variable context) {
\r
398 public List<SubstructureElement> perform(ReadGraph graph) {
\r
400 Resource type = variable.getPossibleType(graph);
\r
403 return CompileProceduralComponentTypeRequest.compileAndEvaluate(graph, type, variable);
\r
404 } catch (Throwable t) {
\r
405 t.printStackTrace();
\r
411 public static List<SubstructureElement> getProceduralDesc(ReadGraph graph, final Variable context) throws DatabaseException {
\r
412 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
413 final Resource type = context.getPossibleType(graph);
\r
415 if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
\r
416 return graph.syncRequest(new SubstructureRequest(context));
\r
422 public static Map<String,Variable> getProcedural(ReadGraph graph, Variable context, List<SubstructureElement> elements, Map<String,Variable> map) throws DatabaseException {
\r
424 if(map == null) map = new THashMap<String,Variable>();
\r
426 MapList<String,org.simantics.structural2.procedural.Connection> conns = new MapList<String,org.simantics.structural2.procedural.Connection>();
\r
427 for(SubstructureElement sub : elements) {
\r
428 if(sub instanceof org.simantics.structural2.procedural.Connection) {
\r
429 org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)sub;
\r
430 for(ConnectionPoint cp : conn.connectionPoints) {
\r
431 if(cp instanceof Terminal) {
\r
432 Terminal t = (Terminal)cp;
\r
433 conns.add(t.component, conn);
\r
439 Map<String,Component> proceduralChildren = new THashMap<String, Component>();
\r
440 for(SubstructureElement sub : elements) {
\r
441 if(sub instanceof Component) {
\r
442 Component comp = (Component)sub;
\r
443 proceduralChildren.put(comp.name, comp);
\r
447 Collection<Object> nodeChildren = All.getPossibleNodeChildren(graph, (AbstractChildVariable)context);
\r
448 Set<String> used = new HashSet<String>(nodeChildren.size());
\r
449 for(Object nodeChild : nodeChildren) {
\r
450 @SuppressWarnings("rawtypes")
\r
451 NodeSupport support = ((AbstractChildVariable)context).node.support;
\r
452 @SuppressWarnings("rawtypes")
\r
453 NodeManager manager = support.manager;
\r
454 @SuppressWarnings("unchecked")
\r
455 String name = manager.getName(nodeChild);
\r
457 Component proceduralChild = proceduralChildren.get(name);
\r
458 if(proceduralChild != null) {
\r
459 map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, new VariableNode(support, nodeChild), proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));
\r
463 for(Map.Entry<String, Component> entry : proceduralChildren.entrySet()) {
\r
464 String name = entry.getKey();
\r
465 if(used.contains(name)) continue;
\r
466 Component proceduralChild = entry.getValue();
\r
467 map.put(proceduralChild.name, new StandardProceduralChildVariable(graph, context, null, proceduralChild.name, proceduralChild.type, proceduralChild.properties, conns.getValues(proceduralChild.name)));
\r
474 private static class ProceduralSubstructureRequest extends VariableRead<Map<String,Variable>> {
\r
476 public ProceduralSubstructureRequest(Variable variable) {
\r
481 public Map<String, Variable> perform(ReadGraph graph)
\r
482 throws DatabaseException {
\r
483 List<SubstructureElement> elements = getProceduralDesc(graph, variable);
\r
484 if(elements != null)
\r
485 return getProcedural(graph, variable, elements, null);
\r
492 @SCLValue(type = "VariableMap")
\r
493 public static VariableMap structuralChildDomainChildren = new VariableMapImpl() {
\r
496 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
498 final Resource type = context.getPossibleType(graph);
\r
500 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
501 if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
\r
502 Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
\r
503 TransientCacheListener.<Map<String,Variable>>instance());
\r
504 if(map != null) return map.get(name);
\r
508 Resource represents = context.getPossibleRepresents(graph);
\r
509 if(represents == null) {
\r
510 Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
\r
511 Resource child = children.get(name);
\r
512 return All.getStandardChildDomainChildVariable(graph, context, child, name);
\r
514 Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
\r
515 Resource child = children.get(name);
\r
516 return All.getStandardChildDomainChildVariable(graph, context, child, name);
\r
520 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
522 final Resource type = context.getPossibleType(graph);
\r
524 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
525 if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
\r
526 Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
\r
527 TransientCacheListener.<Map<String,Variable>>instance());
\r
528 if(mapPrime != null) {
\r
530 map.putAll(mapPrime);
\r
538 Resource represents = context.getPossibleRepresents(graph);
\r
539 if(represents == null) {
\r
540 Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
\r
541 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
\r
543 Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
\r
544 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
\r
549 @SCLValue(type = "VariableMap")
\r
550 public static VariableMap structuralRunDomainChildren = new VariableMapImpl() {
\r
553 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
\r
554 Map<String, Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph)));
\r
555 Resource child = children.get(name);
\r
556 return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
\r
560 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
\r
561 StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
\r
562 Map<String,Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource));
\r
563 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
\r
568 @SCLValue(type = "ReadGraph -> [Resource] -> [Resource]")
\r
569 public static List<Resource> connectionExtension(ReadGraph graph, List<Resource> rs) throws DatabaseException {
\r
571 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
572 HashSet<Resource> extension = new HashSet<Resource>(8);
\r
573 for(Resource r : rs) {
\r
574 if(graph.isInstanceOf(r, STR.Connection)) {
\r
575 extension.addAll(graph.syncRequest(new ConnectionComponents(r), TransientCacheListener.<Collection<Resource>>instance()));
\r
577 if(graph.isInstanceOf(r, STR.ConnectionJoin)) {
\r
578 extension.addAll(graph.syncRequest(new ConnectionJoinComponents(r), TransientCacheListener.<Collection<Resource>>instance()));
\r
582 HashSet<Resource> components = new HashSet<Resource>(8);
\r
583 for(Resource r : extension) {
\r
584 components.addAll(graph.sync(new ObjectsWithType(r, STR.Connects, STR.Component)));
\r
587 if(!extension.isEmpty()) {
\r
588 ArrayList<Resource> result = new ArrayList<Resource>(rs.size() + extension.size());
\r
590 result.addAll(extension);
\r
591 result.addAll(components);
\r
599 @SCLValue(type = "ReadGraph -> Resource -> [Issue]")
\r
600 public static List<Issue> connectionValidator(ReadGraph graph, Resource component) throws DatabaseException {
\r
602 if(!graph.hasStatement(component)) return Collections.emptyList();
\r
604 ArrayList<Issue> result = new ArrayList<Issue>();
\r
606 Layer0 L0 = Layer0.getInstance(graph);
\r
607 StructuralResource2 sr = StructuralResource2.getInstance(graph);
\r
609 Resource type = graph.getSingleType(component, sr.Component);
\r
611 Set<Resource> requiredConnections = new HashSet<Resource>();
\r
612 for(Resource connectionRelation : graph.sync(new ObjectsWithType(type, L0.ConsistsOf, sr.ConnectionRelation))) {
\r
613 Boolean required = graph.getPossibleRelatedValue(connectionRelation, sr.ConnectionRelation_connectionRequired, Bindings.BOOLEAN);
\r
614 if(required != null && required)
\r
615 requiredConnections.add(connectionRelation);
\r
618 Set<Resource> connections = new HashSet<Resource>();
\r
620 for(Statement stm : graph.getStatements(component, sr.IsConnectedTo)) {
\r
621 connections.add(stm.getPredicate());
\r
622 connections.addAll(graph.getSuperrelations(stm.getPredicate()));
\r
625 for(Resource req : requiredConnections) {
\r
626 if(!connections.contains(req)) {
\r
627 result.add(new StandardIssue(sr.ConnectionConstraint_ErrorIssue, component, req));
\r
635 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
\r
636 public static String connectionIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
\r
637 List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);
\r
638 String attributeName = graph.getRelatedValue(contexts.get(1), Layer0.getInstance(graph).HasName);
\r
639 return "'" + attributeName + "' should be connected.";
\r
642 public static class InterfacePathMap extends VariableRead<GraphMap<Map<String,InterfaceResolution>>> {
\r
644 public InterfacePathMap(Variable context) {
\r
649 public GraphMap<Map<String,InterfaceResolution>> perform(ReadGraph graph) throws DatabaseException {
\r
651 return new GraphMap<Map<String,InterfaceResolution>>() {
\r
654 Map<String, InterfaceResolution> get(ReadGraph graph, String key) throws DatabaseException {
\r
656 Variable child = variable.getChild(graph, key);
\r
658 Map<String,InterfaceResolution> childMap = new THashMap<String,InterfaceResolution>();
\r
659 Collection<InterfaceResolution> paths = computeInterfacePaths(graph, child);//child.getPossiblePropertyValue(graph, "proceduralConnectionPointPath");
\r
660 if(paths != null) {
\r
661 for(InterfaceResolution r : paths) {
\r
662 childMap.put(r.interfaceName, r);
\r
675 public static String resolveInterfacePath(ReadGraph graph, Variable context, String component, Resource relation) throws DatabaseException {
\r
677 GraphMap<Map<String,InterfaceResolution>> map = graph.syncRequest(new InterfacePathMap(context), TransientCacheListener.<GraphMap<Map<String,InterfaceResolution>>>instance());
\r
678 Map<String,InterfaceResolution> childMap = map.get(graph, component);
\r
679 if(childMap == null) return "";
\r
681 PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheListener.<PropertyInfo>instance());
\r
683 InterfaceResolution match = childMap.get(info.name);
\r
684 if(match != null) {
\r
685 String comp = URIStringUtils.escape(component);
\r
686 Variable newContext = context.getChild(graph, component);
\r
687 return "/" + comp + resolveInterfacePath(graph, newContext, match.componentName, match.connectionPoint);
\r
689 return "/" + URIStringUtils.escape(component) + "#" + URIStringUtils.escape(info.name);
\r
694 public static class InterfaceResolution {
\r
696 public Resource interfaceConnectionPoint;
\r
697 public String interfaceName;
\r
698 public String componentName;
\r
699 public Resource connectionPoint;
\r
701 public InterfaceResolution(Resource interfaceConnectionPoint, String interfaceName, String componentName, Resource connectionPoint) {
\r
702 this.interfaceConnectionPoint = interfaceConnectionPoint;
\r
703 this.interfaceName = interfaceName;
\r
704 this.componentName = componentName;
\r
705 this.connectionPoint = connectionPoint;
\r
710 public static Collection<InterfaceResolution> computeInterfacePaths(ReadGraph graph, Variable variable) throws DatabaseException {
\r
712 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
713 Resource type = variable.getPossibleType(graph);
\r
715 if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
\r
716 ArrayList<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
\r
717 List<SubstructureElement> elements = getProceduralDesc(graph, variable);
\r
718 if(elements != null) {
\r
719 for(SubstructureElement e : elements) {
\r
720 if(e instanceof org.simantics.structural2.procedural.Connection) {
\r
721 org.simantics.structural2.procedural.Connection conn = (org.simantics.structural2.procedural.Connection)e;
\r
722 Interface inf = null;
\r
723 for(ConnectionPoint cp : conn.connectionPoints) {
\r
724 if(cp instanceof Interface) {
\r
725 if(inf != null) throw new DatabaseException("Multiple interfaces referenced in procedural connection.");
\r
726 inf = (Interface)cp;
\r
729 if(inf != null && conn.connectionPoints.size() > 1) {
\r
730 Layer0 L0 = Layer0.getInstance(graph);
\r
731 String cpName = URIStringUtils.escape( graph.<String>getRelatedValue(inf.relation, L0.HasName, Bindings.STRING) );
\r
732 for(ConnectionPoint cp : conn.connectionPoints) {
\r
733 if(cp == inf) continue;
\r
734 Terminal t = (Terminal)cp;
\r
735 result.add(new InterfaceResolution(inf.relation, cpName, t.component, t.relation));
\r
746 final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(type));
\r
747 if(interfaces != null) return interfaces;
\r
751 return BUILTIN_STRUCTURAL_CPS;
\r
755 static class InterfacePathRequest extends VariableRead<Collection<InterfaceResolution>> {
\r
757 public InterfacePathRequest(Variable variable) {
\r
762 public Collection<InterfaceResolution> perform(ReadGraph graph) throws DatabaseException {
\r
763 return computeInterfacePaths(graph, variable);
\r
768 static class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {
\r
770 public DefinedUCInterfaceMap(Resource resource) {
\r
775 public Collection<InterfaceResolution> perform(ReadGraph graph)
\r
776 throws DatabaseException {
\r
778 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
779 Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
\r
780 if(definition != null) {
\r
781 Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
\r
782 Layer0 L0 = Layer0.getInstance(graph);
\r
783 for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) {
\r
784 String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
\r
785 for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) {
\r
786 Statement stm = graph.getPossibleStatement(conn, STR.Connects);
\r
787 if(stm == null) continue;
\r
788 Resource component = stm.getObject();
\r
789 String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
\r
790 result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate())));
\r
800 public static final Collection<InterfaceResolution> BUILTIN_STRUCTURAL_CPS = new ArrayList<InterfaceResolution>();
\r
802 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
\r
803 public static Object computeExpression(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {
\r
804 return CompileStructuralValueRequest.compileAndEvaluate(graph, context);
\r
807 public static Object computeExpressionInContext(ReadGraph graph, Variable context, final String expression) throws DatabaseException {
\r
808 SCLContext sclContext = SCLContext.getCurrent();
\r
809 Object oldGraph = sclContext.get("graph");
\r
811 Function1<Variable,Object> exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) {
\r
812 protected String getExpressionText(ReadGraph graph) throws DatabaseException {
\r
816 TransientCacheListener.<Function1<Variable,Object>>instance());
\r
817 sclContext.put("graph", graph);
\r
818 return exp.apply(context);
\r
819 } catch (DatabaseException e) {
\r
820 throw (DatabaseException)e;
\r
821 } catch (Throwable t) {
\r
822 throw new DatabaseException(t);
\r
824 sclContext.put("graph", oldGraph);
\r
828 static abstract class InterfacePathProperty extends LazyPropertyVariable {
\r
830 public InterfacePathProperty(Variable parent) {
\r
831 super(parent, "proceduralConnectionPointPath", Bindings.STRING_ARRAY);
\r
835 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
836 return getValue(graph);
\r
841 static abstract class GraphMap<Value> {
\r
843 abstract Value get(ReadGraph graph, String key) throws DatabaseException;
\r