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