1 package org.simantics.modeling.scl;
3 import java.util.Arrays;
4 import java.util.Collection;
5 import java.util.Collections;
8 import java.util.function.Consumer;
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;
32 import gnu.trove.map.hash.THashMap;
33 import gnu.trove.procedure.TObjectProcedure;
35 public class OntologyModule extends LazyModule {
37 private static final String DB_MODULE = "Simantics/DB";
38 private static final Collection<ImportDeclaration> DEPENDENCIES = Arrays.asList(
39 new ImportDeclaration(DB_MODULE, null)
41 private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");
44 THashMap<Resource,Map<String,Resource>> childMaps = new THashMap<Resource,Map<String,Resource>>();
46 public OntologyModule(ReadGraph graph, String moduleName) throws DatabaseException {
48 ontology = graph.getResource(moduleName);
49 childMaps.put(ontology, createLocalMap(graph, ontology));
53 public List<ImportDeclaration> getDependencies() {
54 //return DEPENDENCIES;
55 return Collections.emptyList();
58 private Resource getResource(String name) {
59 Map<String,Resource> localMap = childMaps.get(ontology);
63 int p = name.indexOf('.');
66 String localName = name.substring(0, p);
67 Resource newParent = localMap.get(localName);
70 name = name.substring(p+1);
73 localMap = getLocalMap(newParent);
77 return localMap.get(name);
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))
85 localMap = createLocalMap(parent);
86 childMaps.put(parent, localMap);
91 private static Map<String, Resource> createLocalMap(final Resource parent) {
92 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
94 return createLocalMap(graph, parent);
97 return Simantics.getSession().syncRequest(new Read<Map<String, Resource>>() {
99 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
100 return createLocalMap(graph, parent);
103 } catch(DatabaseException e) {
109 private static Map<String, Resource> createLocalMap(ReadGraph graph, Resource parent) {
111 return graph.syncRequest(new UnescapedChildMapOfResource(parent));
112 } catch (DatabaseException e) {
119 protected SCLValue createValue(String name) {
120 Resource resource = getResource(name);
123 SCLValue value = new SCLValue(Name.create(getName(), name));
124 value.setType(RESOURCE);
125 value.setExpression(new EExternalConstant(resource, RESOURCE));
126 value.setInlineInSimplification(true);
131 protected SCLRelation createRelation(String name) {
132 final Resource resource = getResource(name);
135 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
137 return createRelation(graph, resource);
140 return Simantics.getSession().syncRequest(new Read<SCLRelation>() {
142 public SCLRelation perform(ReadGraph graph) throws DatabaseException {
143 return createRelation(graph, resource);
146 } catch(DatabaseException e) {
152 public static SCLRelation createRelation(ReadGraph graph, Resource relation) {
154 Layer0 L0 = Layer0.getInstance(graph);
155 if(!graph.isInstanceOf(relation, L0.Relation))
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);
163 Resource inverseRelation = graph.getPossibleInverse(relation);
164 return new GraphRelation(relation, getSelectivity(graph, relation),
165 inverseRelation, getSelectivity(graph, inverseRelation));
166 } catch(DatabaseException e) {
173 protected SCLEntityType createEntityType(String name) {
174 final Resource resource = getResource(name);
177 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
179 return createEntityType(graph, resource);
182 return Simantics.getSession().syncRequest(new Read<SCLEntityType>() {
184 public SCLEntityType perform(ReadGraph graph) throws DatabaseException {
185 return createEntityType(graph, resource);
188 } catch(DatabaseException e) {
194 private SCLEntityType createEntityType(ReadGraph graph, Resource type) {
196 Layer0 L0 = Layer0.getInstance(graph);
197 if(!graph.isInstanceOf(type, L0.Type))
199 return new GraphEntityType(graph, type);
200 } catch(DatabaseException e) {
206 private static double getSelectivity(ReadGraph graph, Resource relation) throws DatabaseException {
208 return Double.POSITIVE_INFINITY;
209 Layer0 L0 = Layer0.getInstance(graph);
210 if(graph.isInstanceOf(relation, L0.FunctionalRelation))
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)
221 Resource range = graph.getPossibleObject(relation, L0.HasRange);
223 for(Resource valueTypeLiteral : graph.getAssertedObjects(range, L0.HasValueType)) {
224 valueType = parseValueType((String)graph.getValue(valueTypeLiteral, Bindings.STRING));
225 if(valueType != null)
232 private static Type parseValueType(String valueTypeString) {
233 if(valueTypeString == null)
236 return Types.parseType(valueTypeString);
237 } catch (SCLTypeParseException e) {
244 public void findValuesForPrefix(String prefix,
245 NamespaceFilter filter,
246 TObjectProcedure<SCLValue> proc) {
247 Map<String,Resource> localMap = childMaps.get(ontology);
250 String namePrefix = "";
252 int p = prefix.indexOf('.');
255 String localName = prefix.substring(0, p);
256 Resource newParent = localMap.get(localName);
257 if(newParent == null)
259 prefix = prefix.substring(p+1);
260 namePrefix = namePrefix + localName + ".";
263 localMap = getLocalMap(newParent);
267 for(String name : localMap.keySet())
268 if(name.startsWith(prefix) && filter.isValueIncluded(name))
269 proc.execute(getValue(namePrefix+name));
273 public void findValuesForPrefix(String prefix, NamespaceFilter filter, Consumer<SCLValue> consumer) {
274 Map<String,Resource> localMap = childMaps.get(ontology);
277 String namePrefix = "";
279 int p = prefix.indexOf('.');
282 String localName = prefix.substring(0, p);
283 Resource newParent = localMap.get(localName);
284 if(newParent == null)
286 prefix = prefix.substring(p+1);
287 namePrefix = namePrefix + localName + ".";
290 localMap = getLocalMap(newParent);
294 for(String name : localMap.keySet())
295 if(name.startsWith(prefix) && filter.isValueIncluded(name))
296 consumer.accept(getValue(namePrefix+name));
300 public void findTypesForPrefix(String prefix, NamespaceFilter instance, Consumer<TCon> consumer) {
305 public void dispose() {
312 public String toString() {
313 return new StringBuilder().append("OntologyModule ").append(getName()).toString();