]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java
Sync git svn branch with SVN repository r33144.
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / OntologyModule.java
1 package org.simantics.modeling.scl;\r
2 \r
3 import java.util.Arrays;\r
4 import java.util.Collection;\r
5 import java.util.Collections;\r
6 import java.util.List;\r
7 import java.util.Map;\r
8 import java.util.function.Consumer;\r
9 \r
10 import org.simantics.Simantics;\r
11 import org.simantics.databoard.Bindings;\r
12 import org.simantics.db.ReadGraph;\r
13 import org.simantics.db.Resource;\r
14 import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
15 import org.simantics.db.exception.DatabaseException;\r
16 import org.simantics.db.request.Read;\r
17 import org.simantics.layer0.Layer0;\r
18 import org.simantics.scl.compiler.common.names.Name;\r
19 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
20 import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
21 import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;\r
22 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
23 import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
24 import org.simantics.scl.compiler.module.ImportDeclaration;\r
25 import org.simantics.scl.compiler.module.LazyModule;\r
26 import org.simantics.scl.compiler.types.TCon;\r
27 import org.simantics.scl.compiler.types.Type;\r
28 import org.simantics.scl.compiler.types.Types;\r
29 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;\r
30 import org.simantics.scl.runtime.SCLContext;\r
31 \r
32 import gnu.trove.map.hash.THashMap;\r
33 import gnu.trove.procedure.TObjectProcedure;\r
34 \r
35 public class OntologyModule extends LazyModule {\r
36 \r
37     private static final String DB_MODULE = "Simantics/DB";\r
38     private static final Collection<ImportDeclaration> DEPENDENCIES = Arrays.asList(\r
39             new ImportDeclaration(DB_MODULE, null)\r
40             );\r
41     private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");\r
42     \r
43     Resource ontology;\r
44     THashMap<Resource,Map<String,Resource>> childMaps = new THashMap<Resource,Map<String,Resource>>();\r
45     \r
46     public OntologyModule(ReadGraph graph, String moduleName) throws DatabaseException {\r
47         super(moduleName);\r
48         ontology = graph.getResource(moduleName);\r
49         childMaps.put(ontology, createLocalMap(graph, ontology));\r
50     }\r
51 \r
52     @Override\r
53     public List<ImportDeclaration> getDependencies() {\r
54         //return DEPENDENCIES;\r
55         return Collections.emptyList();\r
56     }\r
57     \r
58     private Resource getResource(String name) {\r
59         Map<String,Resource> localMap = childMaps.get(ontology); \r
60         if(localMap == null)\r
61             return null;\r
62         while(true) {\r
63             int p = name.indexOf('.');\r
64             if(p < 0)\r
65                 break;\r
66             String localName = name.substring(0, p);\r
67             Resource newParent = localMap.get(localName);\r
68             if(newParent == null)\r
69                 return null;\r
70             name = name.substring(p+1);\r
71             \r
72             // Get new local map\r
73             localMap = getLocalMap(newParent);\r
74             if(localMap == null)\r
75                 return null;\r
76         }\r
77         return localMap.get(name);\r
78     }\r
79     \r
80     private Map<String, Resource> getLocalMap(Resource parent) {\r
81         Map<String, Resource> localMap = childMaps.get(parent);\r
82         if(localMap == null) {\r
83             if(childMaps.contains(parent))\r
84                 return null;\r
85             localMap = createLocalMap(parent);\r
86             childMaps.put(parent, localMap);\r
87         }\r
88         return localMap;\r
89     }\r
90 \r
91     private static Map<String, Resource> createLocalMap(final Resource parent) {\r
92         ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
93         if(graph != null)\r
94             return createLocalMap(graph, parent);\r
95         else\r
96             try {\r
97                 return Simantics.getSession().syncRequest(new Read<Map<String, Resource>>() {\r
98                     @Override\r
99                     public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
100                         return createLocalMap(graph, parent);\r
101                     }\r
102                 });\r
103             } catch(DatabaseException e) {\r
104                 e.printStackTrace();\r
105                 return null;\r
106             }   \r
107     }\r
108 \r
109     private static Map<String, Resource> createLocalMap(ReadGraph graph, Resource parent) {\r
110         try {\r
111             return graph.syncRequest(new UnescapedChildMapOfResource(parent));\r
112         } catch (DatabaseException e) {\r
113             e.printStackTrace();\r
114             return null;\r
115         }\r
116     }\r
117     \r
118     @Override\r
119     protected SCLValue createValue(String name) {\r
120         Resource resource = getResource(name);\r
121         if(resource == null)\r
122             return null;        \r
123         SCLValue value = new SCLValue(Name.create(getName(), name));\r
124         value.setType(RESOURCE);\r
125         value.setExpression(new EExternalConstant(resource, RESOURCE));\r
126         value.setInlineInSimplification(true);\r
127         return value;\r
128     }\r
129     \r
130     @Override\r
131     protected SCLRelation createRelation(String name) {\r
132         final Resource resource = getResource(name);\r
133         if(resource == null)\r
134             return null;\r
135         ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
136         if(graph != null)\r
137             return createRelation(graph, resource);\r
138         else\r
139             try {\r
140                 return Simantics.getSession().syncRequest(new Read<SCLRelation>() {\r
141                     @Override\r
142                     public SCLRelation perform(ReadGraph graph) throws DatabaseException {\r
143                         return createRelation(graph, resource);\r
144                     }\r
145                 });\r
146             } catch(DatabaseException e) {\r
147                 e.printStackTrace();\r
148                 return null;\r
149             }   \r
150     }\r
151     \r
152     public static SCLRelation createRelation(ReadGraph graph, Resource relation) {\r
153         try {\r
154             Layer0 L0 = Layer0.getInstance(graph);\r
155             if(!graph.isInstanceOf(relation, L0.Relation))\r
156                 return null;\r
157             if(graph.isInstanceOf(relation, L0.PropertyRelation) && graph.isInstanceOf(relation, L0.FunctionalRelation)) {\r
158                 Type valueType = getValueType(graph, relation);\r
159                 if(valueType != null)\r
160                     return new GraphPropertyRelation(relation, valueType);\r
161             }\r
162             \r
163             Resource inverseRelation = graph.getPossibleInverse(relation);\r
164             return new GraphRelation(relation, getSelectivity(graph, relation),\r
165                     inverseRelation, getSelectivity(graph, inverseRelation));\r
166         } catch(DatabaseException e) {\r
167             e.printStackTrace();\r
168             return null;\r
169         }\r
170     }\r
171     \r
172     @Override\r
173     protected SCLEntityType createEntityType(String name) {\r
174         final Resource resource = getResource(name);\r
175         if(resource == null)\r
176             return null;\r
177         ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
178         if(graph != null)\r
179             return createEntityType(graph, resource);\r
180         else\r
181             try {\r
182                 return Simantics.getSession().syncRequest(new Read<SCLEntityType>() {\r
183                     @Override\r
184                     public SCLEntityType perform(ReadGraph graph) throws DatabaseException {\r
185                         return createEntityType(graph, resource);\r
186                     }\r
187                 });\r
188             } catch(DatabaseException e) {\r
189                 e.printStackTrace();\r
190                 return null;\r
191             }   \r
192     }\r
193     \r
194     private SCLEntityType createEntityType(ReadGraph graph, Resource type) {\r
195         try {\r
196             Layer0 L0 = Layer0.getInstance(graph);\r
197             if(!graph.isInstanceOf(type, L0.Type))\r
198                 return null;\r
199             return new GraphEntityType(graph, type);\r
200         } catch(DatabaseException e) {\r
201             e.printStackTrace();\r
202             return null;\r
203         }\r
204     }\r
205     \r
206     private static double getSelectivity(ReadGraph graph, Resource relation) throws DatabaseException {\r
207         if(relation == null)\r
208             return Double.POSITIVE_INFINITY;\r
209         Layer0 L0 = Layer0.getInstance(graph);\r
210         if(graph.isInstanceOf(relation, L0.FunctionalRelation))\r
211             return 1.0;\r
212         else\r
213             return 10.0;\r
214     }\r
215 \r
216     private static Type getValueType(ReadGraph graph, Resource relation) throws DatabaseException {\r
217         Layer0 L0 = Layer0.getInstance(graph);\r
218         Type valueType = parseValueType((String)graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING));\r
219         if(valueType != null)\r
220             return valueType;\r
221         Resource range = graph.getPossibleObject(relation, L0.HasRange);\r
222         if(range != null) {\r
223             for(Resource valueTypeLiteral : graph.getAssertedObjects(range, L0.HasValueType)) {\r
224                 valueType = parseValueType((String)graph.getValue(valueTypeLiteral, Bindings.STRING));\r
225                 if(valueType != null)\r
226                     return valueType;\r
227             }\r
228         }\r
229         return null;\r
230     }\r
231     \r
232     private static Type parseValueType(String valueTypeString) {\r
233         if(valueTypeString == null)\r
234             return null;\r
235         try {\r
236             return Types.parseType(valueTypeString);\r
237         } catch (SCLTypeParseException e) {\r
238             e.printStackTrace();\r
239             return null;\r
240         }\r
241     }\r
242     \r
243     @Override\r
244     public void findValuesForPrefix(String prefix,\r
245             NamespaceFilter filter,\r
246             TObjectProcedure<SCLValue> proc) {\r
247         Map<String,Resource> localMap = childMaps.get(ontology); \r
248         if(localMap == null)\r
249             return;\r
250         String namePrefix = "";\r
251         while(true) {\r
252             int p = prefix.indexOf('.');\r
253             if(p < 0)\r
254                 break;\r
255             String localName = prefix.substring(0, p);\r
256             Resource newParent = localMap.get(localName);\r
257             if(newParent == null)\r
258                 return;\r
259             prefix = prefix.substring(p+1);\r
260             namePrefix = namePrefix + localName + ".";\r
261             \r
262             // Get new local map\r
263             localMap = getLocalMap(newParent);\r
264             if(localMap == null)\r
265                 return;\r
266         }\r
267         for(String name : localMap.keySet())\r
268             if(name.startsWith(prefix) && filter.isValueIncluded(name))\r
269                 proc.execute(getValue(namePrefix+name));\r
270     }\r
271     \r
272     @Override\r
273     public void findValuesForPrefix(String prefix, NamespaceFilter filter, Consumer<SCLValue> consumer) {\r
274         Map<String,Resource> localMap = childMaps.get(ontology); \r
275         if(localMap == null)\r
276             return;\r
277         String namePrefix = "";\r
278         while(true) {\r
279             int p = prefix.indexOf('.');\r
280             if(p < 0)\r
281                 break;\r
282             String localName = prefix.substring(0, p);\r
283             Resource newParent = localMap.get(localName);\r
284             if(newParent == null)\r
285                 return;\r
286             prefix = prefix.substring(p+1);\r
287             namePrefix = namePrefix + localName + ".";\r
288             \r
289             // Get new local map\r
290             localMap = getLocalMap(newParent);\r
291             if(localMap == null)\r
292                 return;\r
293         }\r
294         for(String name : localMap.keySet())\r
295             if(name.startsWith(prefix) && filter.isValueIncluded(name))\r
296                 consumer.accept(getValue(namePrefix+name));\r
297     }\r
298 \r
299     @Override\r
300     public void findTypesForPrefix(String prefix, NamespaceFilter instance, Consumer<TCon> consumer) {\r
301         \r
302     }\r
303 \r
304     @Override\r
305     public void dispose() {\r
306         childMaps.clear();\r
307         childMaps = null;\r
308         ontology = null;\r
309     }\r
310     \r
311     @Override\r
312     public String toString() {\r
313         return new StringBuilder().append("OntologyModule ").append(getName()).toString();\r
314     }\r
315 }\r