1 package org.simantics.modeling;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.Collections;
\r
6 import java.util.Map;
\r
8 import org.simantics.db.ReadGraph;
\r
9 import org.simantics.db.RequestProcessor;
\r
10 import org.simantics.db.Resource;
\r
11 import org.simantics.db.common.request.ResourceRead;
\r
12 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
\r
13 import org.simantics.db.exception.DatabaseException;
\r
14 import org.simantics.db.layer0.request.PropertyInfo;
\r
15 import org.simantics.db.layer0.request.PropertyInfoRequest;
\r
16 import org.simantics.layer0.Layer0;
\r
17 import org.simantics.scl.compiler.types.Type;
\r
18 import org.simantics.structural.stubs.StructuralResource2;
\r
19 import org.simantics.utils.datastructures.Pair;
\r
22 * Contains necessary information about a component type to represent its
\r
25 * @author Hannu Niemistö
\r
27 public class ComponentTypeSubstructure {
\r
29 public final THashMap<String, Type> properties;
\r
30 public final Map<String, ComponentTypeSubstructure> children;
\r
32 private ComponentTypeSubstructure(THashMap<String, Type> properties,
\r
33 Map<String, ComponentTypeSubstructure> children) {
\r
34 this.properties = properties;
\r
35 this.children = children;
\r
38 public Pair<String,Type> possibleTypedRVI(String name) {
\r
39 StringBuilder b = new StringBuilder();
\r
41 ComponentTypeSubstructure substructure = this;
\r
43 // Find the children
\r
45 while( (p = name.indexOf('.', namePos)) >= 0 ) {
\r
46 String childName = name.substring(namePos, p);
\r
47 ComponentTypeSubstructure childSubstructure = substructure.children.get(childName);
\r
48 if(childSubstructure == null)
\r
50 b.append('/').append(childName);
\r
52 substructure = childSubstructure;
\r
55 // Find the property
\r
56 String propertyName = name.substring(namePos);
\r
57 Type type = substructure.properties.get(propertyName);
\r
60 b.append('#').append(propertyName);
\r
61 return Pair.make(b.toString(), type);
\r
64 public static ComponentTypeSubstructure forType(RequestProcessor processor, Resource componentType) throws DatabaseException {
\r
65 return processor.syncRequest(new ResourceRead<ComponentTypeSubstructure>(componentType) {
\r
67 public ComponentTypeSubstructure perform(ReadGraph graph)
\r
68 throws DatabaseException {
\r
70 THashMap<String, Type> properties = new THashMap<String, Type>();
\r
71 collect(graph, resource, properties);
\r
72 for(Resource t : graph.getSupertypes(resource)) collect(graph, t, properties);
\r
75 Map<String, ComponentTypeSubstructure> children;
\r
77 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
78 Resource composite = graph.getPossibleObject(resource, STR.IsDefinedBy);
\r
79 if(composite == null)
\r
80 children = Collections.<String, ComponentTypeSubstructure>emptyMap();
\r
82 Map<String, Resource> childMap = graph.syncRequest(new UnescapedChildMapOfResource(composite));
\r
83 children = new THashMap<String, ComponentTypeSubstructure>(childMap.size());
\r
84 for(Map.Entry<String,Resource> entry : childMap.entrySet()) {
\r
85 Resource component = entry.getValue();
\r
86 Resource type = graph.getPossibleType(component, STR.Component);
\r
88 children.put(entry.getKey(), forType(graph, type));
\r
92 // Return the result
\r
93 return new ComponentTypeSubstructure(properties, children);
\r
98 private static void collect(ReadGraph graph, Resource t, THashMap<String, Type> result) throws DatabaseException {
\r
99 Layer0 L0 = Layer0.getInstance(graph);
\r
100 for(Resource relation : graph.getObjects(t, L0.DomainOf)) {
\r
101 if(graph.isSubrelationOf(relation, L0.HasProperty)) {
\r
102 PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(relation));
\r
103 result.put(propertyInfo.name, SCLTypeUtils.getType(propertyInfo));
\r