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