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 String defaultLocalName;
45 THashMap<Resource,Map<String,Resource>> childMaps = new THashMap<Resource,Map<String,Resource>>();
47 public OntologyModule(ReadGraph graph, String moduleName) throws DatabaseException {
49 ontology = graph.getResource(moduleName);
50 readDefaultLocalName(graph);
51 childMaps.put(ontology, createLocalMap(graph, ontology));
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 = "";
62 public String getDefaultLocalName() {
63 return defaultLocalName;
67 public List<ImportDeclaration> getDependencies() {
68 //return DEPENDENCIES;
69 return Collections.emptyList();
72 private Resource getResource(String name) {
73 Map<String,Resource> localMap = childMaps.get(ontology);
77 int p = name.indexOf('.');
80 String localName = name.substring(0, p);
81 Resource newParent = localMap.get(localName);
84 name = name.substring(p+1);
87 localMap = getLocalMap(newParent);
91 return localMap.get(name);
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))
99 localMap = createLocalMap(parent);
100 childMaps.put(parent, localMap);
105 private static Map<String, Resource> createLocalMap(final Resource parent) {
106 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
108 return createLocalMap(graph, parent);
111 return Simantics.getSession().syncRequest(new Read<Map<String, Resource>>() {
113 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
114 return createLocalMap(graph, parent);
117 } catch(DatabaseException e) {
123 private static Map<String, Resource> createLocalMap(ReadGraph graph, Resource parent) {
125 return graph.syncRequest(new UnescapedChildMapOfResource(parent));
126 } catch (DatabaseException e) {
133 protected SCLValue createValue(String name) {
134 Resource resource = getResource(name);
137 SCLValue value = new SCLValue(Name.create(getName(), name));
138 value.setType(RESOURCE);
139 value.setExpression(new EExternalConstant(resource, RESOURCE));
140 value.setInlineInSimplification(true);
145 protected SCLRelation createRelation(String name) {
146 final Resource resource = getResource(name);
149 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
151 return createRelation(graph, resource);
154 return Simantics.getSession().syncRequest(new Read<SCLRelation>() {
156 public SCLRelation perform(ReadGraph graph) throws DatabaseException {
157 return createRelation(graph, resource);
160 } catch(DatabaseException e) {
166 public static SCLRelation createRelation(ReadGraph graph, Resource relation) {
168 Layer0 L0 = Layer0.getInstance(graph);
169 if(!graph.isInstanceOf(relation, L0.Relation))
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);
177 Resource inverseRelation = graph.getPossibleInverse(relation);
178 return new GraphRelation(relation, getSelectivity(graph, relation),
179 inverseRelation, getSelectivity(graph, inverseRelation));
180 } catch(DatabaseException e) {
187 protected SCLEntityType createEntityType(String name) {
188 final Resource resource = getResource(name);
191 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
193 return createEntityType(graph, resource);
196 return Simantics.getSession().syncRequest(new Read<SCLEntityType>() {
198 public SCLEntityType perform(ReadGraph graph) throws DatabaseException {
199 return createEntityType(graph, resource);
202 } catch(DatabaseException e) {
208 private SCLEntityType createEntityType(ReadGraph graph, Resource type) {
210 Layer0 L0 = Layer0.getInstance(graph);
211 if(!graph.isInstanceOf(type, L0.Type))
213 return new GraphEntityType(graph, type);
214 } catch(DatabaseException e) {
220 private static double getSelectivity(ReadGraph graph, Resource relation) throws DatabaseException {
222 return Double.POSITIVE_INFINITY;
223 Layer0 L0 = Layer0.getInstance(graph);
224 if(graph.isInstanceOf(relation, L0.FunctionalRelation))
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)
235 Resource range = graph.getPossibleObject(relation, L0.HasRange);
237 for(Resource valueTypeLiteral : graph.getAssertedObjects(range, L0.HasValueType)) {
238 valueType = parseValueType((String)graph.getValue(valueTypeLiteral, Bindings.STRING));
239 if(valueType != null)
246 private static Type parseValueType(String valueTypeString) {
247 if(valueTypeString == null)
250 return Types.parseType(valueTypeString);
251 } catch (SCLTypeParseException e) {
258 public void findValuesForPrefix(String prefix,
259 NamespaceFilter filter,
260 TObjectProcedure<SCLValue> proc) {
261 Map<String,Resource> localMap = childMaps.get(ontology);
264 String namePrefix = "";
266 int p = prefix.indexOf('.');
269 String localName = prefix.substring(0, p);
270 Resource newParent = localMap.get(localName);
271 if(newParent == null)
273 prefix = prefix.substring(p+1);
274 namePrefix = namePrefix + localName + ".";
277 localMap = getLocalMap(newParent);
281 for(String name : localMap.keySet())
282 if(name.startsWith(prefix) && filter.isValueIncluded(name))
283 proc.execute(getValue(namePrefix+name));
287 public void findValuesForPrefix(String prefix, NamespaceFilter filter, Consumer<SCLValue> consumer) {
288 Map<String,Resource> localMap = childMaps.get(ontology);
291 String namePrefix = "";
293 int p = prefix.indexOf('.');
296 String localName = prefix.substring(0, p);
297 Resource newParent = localMap.get(localName);
298 if(newParent == null)
300 prefix = prefix.substring(p+1);
301 namePrefix = namePrefix + localName + ".";
304 localMap = getLocalMap(newParent);
308 for(String name : localMap.keySet())
309 if(name.startsWith(prefix) && filter.isValueIncluded(name))
310 consumer.accept(getValue(namePrefix+name));
314 public void findTypesForPrefix(String prefix, NamespaceFilter instance, Consumer<TCon> consumer) {
319 public void dispose() {
326 public String toString() {
327 return new StringBuilder().append("OntologyModule ").append(getName()).toString();
331 public ClassLoader getParentClassLoader() {
332 return getClass().getClassLoader();