]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeSubstructure.java
Layer0Utils.addL0Identifier to prevent possible differentiation of code
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / ComponentTypeSubstructure.java
1 package org.simantics.modeling;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import java.util.Collections;
6 import java.util.Map;
7
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;
20
21 /**
22  * Contains necessary information about a component type to represent its
23  * variable space.
24  * 
25  * @author Hannu Niemistö
26  */
27 public class ComponentTypeSubstructure {
28     
29     public final THashMap<String, Type> properties;
30     public final Map<String, ComponentTypeSubstructure> children;
31     
32     private ComponentTypeSubstructure(THashMap<String, Type> properties,
33             Map<String, ComponentTypeSubstructure> children) {
34         this.properties = properties;
35         this.children = children;
36     }
37     
38     public Pair<String,Type> possibleTypedRVI(String name) {
39         StringBuilder b = new StringBuilder();
40         int namePos = 0;
41         ComponentTypeSubstructure substructure = this;
42         
43         // Find the children
44         int p;
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)
49                 return null;
50             b.append('/').append(childName);
51             namePos = p+1;
52             substructure = childSubstructure;
53         }
54         
55         // Find the property
56         String propertyName = name.substring(namePos);
57         Type type = substructure.properties.get(propertyName);
58         if(type == null)
59             return null;
60         b.append('#').append(propertyName);
61         return Pair.make(b.toString(), type);
62     }
63
64     public static ComponentTypeSubstructure forType(RequestProcessor processor, Resource componentType) throws DatabaseException {
65         return processor.syncRequest(new ResourceRead<ComponentTypeSubstructure>(componentType) {
66             @Override
67             public ComponentTypeSubstructure perform(ReadGraph graph)
68                     throws DatabaseException {
69                 // Properties
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);
73                 
74                 // Children
75                 Map<String, ComponentTypeSubstructure> children;
76                 
77                 StructuralResource2 STR = StructuralResource2.getInstance(graph);
78                 Resource composite = graph.getPossibleObject(resource, STR.IsDefinedBy);
79                 if(composite == null)
80                     children = Collections.<String, ComponentTypeSubstructure>emptyMap();
81                 else {
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);
87                         if(type != null)
88                             children.put(entry.getKey(), forType(graph, type));
89                     }
90                 }
91                     
92                 // Return the result
93                 return new ComponentTypeSubstructure(properties, children);
94             }
95         });
96     }
97     
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));
104             }
105         }
106     }
107 }