1 package org.simantics.modeling.scl;
\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
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
32 import gnu.trove.map.hash.THashMap;
\r
33 import gnu.trove.procedure.TObjectProcedure;
\r
35 public class OntologyModule extends LazyModule {
\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
41 private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");
\r
44 THashMap<Resource,Map<String,Resource>> childMaps = new THashMap<Resource,Map<String,Resource>>();
\r
46 public OntologyModule(ReadGraph graph, String moduleName) throws DatabaseException {
\r
48 ontology = graph.getResource(moduleName);
\r
49 childMaps.put(ontology, createLocalMap(graph, ontology));
\r
53 public List<ImportDeclaration> getDependencies() {
\r
54 //return DEPENDENCIES;
\r
55 return Collections.emptyList();
\r
58 private Resource getResource(String name) {
\r
59 Map<String,Resource> localMap = childMaps.get(ontology);
\r
60 if(localMap == null)
\r
63 int p = name.indexOf('.');
\r
66 String localName = name.substring(0, p);
\r
67 Resource newParent = localMap.get(localName);
\r
68 if(newParent == null)
\r
70 name = name.substring(p+1);
\r
72 // Get new local map
\r
73 localMap = getLocalMap(newParent);
\r
74 if(localMap == null)
\r
77 return localMap.get(name);
\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
85 localMap = createLocalMap(parent);
\r
86 childMaps.put(parent, localMap);
\r
91 private static Map<String, Resource> createLocalMap(final Resource parent) {
\r
92 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
\r
94 return createLocalMap(graph, parent);
\r
97 return Simantics.getSession().syncRequest(new Read<Map<String, Resource>>() {
\r
99 public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
\r
100 return createLocalMap(graph, parent);
\r
103 } catch(DatabaseException e) {
\r
104 e.printStackTrace();
\r
109 private static Map<String, Resource> createLocalMap(ReadGraph graph, Resource parent) {
\r
111 return graph.syncRequest(new UnescapedChildMapOfResource(parent));
\r
112 } catch (DatabaseException e) {
\r
113 e.printStackTrace();
\r
119 protected SCLValue createValue(String name) {
\r
120 Resource resource = getResource(name);
\r
121 if(resource == 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
131 protected SCLRelation createRelation(String name) {
\r
132 final Resource resource = getResource(name);
\r
133 if(resource == null)
\r
135 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
\r
137 return createRelation(graph, resource);
\r
140 return Simantics.getSession().syncRequest(new Read<SCLRelation>() {
\r
142 public SCLRelation perform(ReadGraph graph) throws DatabaseException {
\r
143 return createRelation(graph, resource);
\r
146 } catch(DatabaseException e) {
\r
147 e.printStackTrace();
\r
152 public static SCLRelation createRelation(ReadGraph graph, Resource relation) {
\r
154 Layer0 L0 = Layer0.getInstance(graph);
\r
155 if(!graph.isInstanceOf(relation, L0.Relation))
\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
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
173 protected SCLEntityType createEntityType(String name) {
\r
174 final Resource resource = getResource(name);
\r
175 if(resource == null)
\r
177 ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
\r
179 return createEntityType(graph, resource);
\r
182 return Simantics.getSession().syncRequest(new Read<SCLEntityType>() {
\r
184 public SCLEntityType perform(ReadGraph graph) throws DatabaseException {
\r
185 return createEntityType(graph, resource);
\r
188 } catch(DatabaseException e) {
\r
189 e.printStackTrace();
\r
194 private SCLEntityType createEntityType(ReadGraph graph, Resource type) {
\r
196 Layer0 L0 = Layer0.getInstance(graph);
\r
197 if(!graph.isInstanceOf(type, L0.Type))
\r
199 return new GraphEntityType(graph, type);
\r
200 } catch(DatabaseException e) {
\r
201 e.printStackTrace();
\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
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
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
232 private static Type parseValueType(String valueTypeString) {
\r
233 if(valueTypeString == null)
\r
236 return Types.parseType(valueTypeString);
\r
237 } catch (SCLTypeParseException e) {
\r
238 e.printStackTrace();
\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
250 String namePrefix = "";
\r
252 int p = prefix.indexOf('.');
\r
255 String localName = prefix.substring(0, p);
\r
256 Resource newParent = localMap.get(localName);
\r
257 if(newParent == null)
\r
259 prefix = prefix.substring(p+1);
\r
260 namePrefix = namePrefix + localName + ".";
\r
262 // Get new local map
\r
263 localMap = getLocalMap(newParent);
\r
264 if(localMap == null)
\r
267 for(String name : localMap.keySet())
\r
268 if(name.startsWith(prefix) && filter.isValueIncluded(name))
\r
269 proc.execute(getValue(namePrefix+name));
\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
277 String namePrefix = "";
\r
279 int p = prefix.indexOf('.');
\r
282 String localName = prefix.substring(0, p);
\r
283 Resource newParent = localMap.get(localName);
\r
284 if(newParent == null)
\r
286 prefix = prefix.substring(p+1);
\r
287 namePrefix = namePrefix + localName + ".";
\r
289 // Get new local map
\r
290 localMap = getLocalMap(newParent);
\r
291 if(localMap == null)
\r
294 for(String name : localMap.keySet())
\r
295 if(name.startsWith(prefix) && filter.isValueIncluded(name))
\r
296 consumer.accept(getValue(namePrefix+name));
\r
300 public void findTypesForPrefix(String prefix, NamespaceFilter instance, Consumer<TCon> consumer) {
\r
305 public void dispose() {
\r
312 public String toString() {
\r
313 return new StringBuilder().append("OntologyModule ").append(getName()).toString();
\r