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