]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / OntologyModule.java
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java
new file mode 100644 (file)
index 0000000..bede92d
--- /dev/null
@@ -0,0 +1,310 @@
+package org.simantics.modeling.scl;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.function.Consumer;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
+import org.simantics.scl.compiler.module.ImportDeclaration;\r
+import org.simantics.scl.compiler.module.LazyModule;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;\r
+import org.simantics.scl.runtime.SCLContext;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectProcedure;\r
+\r
+public class OntologyModule extends LazyModule {\r
+\r
+    private static final String DB_MODULE = "Simantics/DB";\r
+    private static final Collection<ImportDeclaration> DEPENDENCIES = Arrays.asList(\r
+            new ImportDeclaration(DB_MODULE, null)\r
+            );\r
+    private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");\r
+    \r
+    Resource ontology;\r
+    THashMap<Resource,Map<String,Resource>> childMaps = new THashMap<Resource,Map<String,Resource>>();\r
+    \r
+    public OntologyModule(ReadGraph graph, String moduleName) throws DatabaseException {\r
+        super(moduleName);\r
+        ontology = graph.getResource(moduleName);\r
+        childMaps.put(ontology, createLocalMap(graph, ontology));\r
+    }\r
+\r
+    @Override\r
+    public List<ImportDeclaration> getDependencies() {\r
+        //return DEPENDENCIES;\r
+        return Collections.emptyList();\r
+    }\r
+    \r
+    private Resource getResource(String name) {\r
+        Map<String,Resource> localMap = childMaps.get(ontology); \r
+        if(localMap == null)\r
+            return null;\r
+        while(true) {\r
+            int p = name.indexOf('.');\r
+            if(p < 0)\r
+                break;\r
+            String localName = name.substring(0, p);\r
+            Resource newParent = localMap.get(localName);\r
+            if(newParent == null)\r
+                return null;\r
+            name = name.substring(p+1);\r
+            \r
+            // Get new local map\r
+            localMap = getLocalMap(newParent);\r
+            if(localMap == null)\r
+                return null;\r
+        }\r
+        return localMap.get(name);\r
+    }\r
+    \r
+    private Map<String, Resource> getLocalMap(Resource parent) {\r
+        Map<String, Resource> localMap = childMaps.get(parent);\r
+        if(localMap == null) {\r
+            if(childMaps.contains(parent))\r
+                return null;\r
+            localMap = createLocalMap(parent);\r
+            childMaps.put(parent, localMap);\r
+        }\r
+        return localMap;\r
+    }\r
+\r
+    private static Map<String, Resource> createLocalMap(final Resource parent) {\r
+        ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
+        if(graph != null)\r
+            return createLocalMap(graph, parent);\r
+        else\r
+            try {\r
+                return Simantics.getSession().syncRequest(new Read<Map<String, Resource>>() {\r
+                    @Override\r
+                    public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                        return createLocalMap(graph, parent);\r
+                    }\r
+                });\r
+            } catch(DatabaseException e) {\r
+                e.printStackTrace();\r
+                return null;\r
+            }   \r
+    }\r
+\r
+    private static Map<String, Resource> createLocalMap(ReadGraph graph, Resource parent) {\r
+        try {\r
+            return graph.syncRequest(new UnescapedChildMapOfResource(parent));\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected SCLValue createValue(String name) {\r
+        Resource resource = getResource(name);\r
+        if(resource == null)\r
+            return null;        \r
+        SCLValue value = new SCLValue(Name.create(getName(), name));\r
+        value.setType(RESOURCE);\r
+        value.setExpression(new EExternalConstant(resource, RESOURCE));\r
+        value.setInlineInSimplification(true);\r
+        return value;\r
+    }\r
+    \r
+    @Override\r
+    protected SCLRelation createRelation(String name) {\r
+        final Resource resource = getResource(name);\r
+        if(resource == null)\r
+            return null;\r
+        ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
+        if(graph != null)\r
+            return createRelation(graph, resource);\r
+        else\r
+            try {\r
+                return Simantics.getSession().syncRequest(new Read<SCLRelation>() {\r
+                    @Override\r
+                    public SCLRelation perform(ReadGraph graph) throws DatabaseException {\r
+                        return createRelation(graph, resource);\r
+                    }\r
+                });\r
+            } catch(DatabaseException e) {\r
+                e.printStackTrace();\r
+                return null;\r
+            }   \r
+    }\r
+    \r
+    public static SCLRelation createRelation(ReadGraph graph, Resource relation) {\r
+        try {\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            if(!graph.isInstanceOf(relation, L0.Relation))\r
+                return null;\r
+            if(graph.isInstanceOf(relation, L0.PropertyRelation) && graph.isInstanceOf(relation, L0.FunctionalRelation)) {\r
+                Type valueType = getValueType(graph, relation);\r
+                if(valueType != null)\r
+                    return new GraphPropertyRelation(relation, valueType);\r
+            }\r
+            \r
+            Resource inverseRelation = graph.getPossibleInverse(relation);\r
+            return new GraphRelation(relation, getSelectivity(graph, relation),\r
+                    inverseRelation, getSelectivity(graph, inverseRelation));\r
+        } catch(DatabaseException e) {\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected SCLEntityType createEntityType(String name) {\r
+        final Resource resource = getResource(name);\r
+        if(resource == null)\r
+            return null;\r
+        ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
+        if(graph != null)\r
+            return createEntityType(graph, resource);\r
+        else\r
+            try {\r
+                return Simantics.getSession().syncRequest(new Read<SCLEntityType>() {\r
+                    @Override\r
+                    public SCLEntityType perform(ReadGraph graph) throws DatabaseException {\r
+                        return createEntityType(graph, resource);\r
+                    }\r
+                });\r
+            } catch(DatabaseException e) {\r
+                e.printStackTrace();\r
+                return null;\r
+            }   \r
+    }\r
+    \r
+    private SCLEntityType createEntityType(ReadGraph graph, Resource type) {\r
+        try {\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            if(!graph.isInstanceOf(type, L0.Type))\r
+                return null;\r
+            return new GraphEntityType(graph, type);\r
+        } catch(DatabaseException e) {\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    private static double getSelectivity(ReadGraph graph, Resource relation) throws DatabaseException {\r
+        if(relation == null)\r
+            return Double.POSITIVE_INFINITY;\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        if(graph.isInstanceOf(relation, L0.FunctionalRelation))\r
+            return 1.0;\r
+        else\r
+            return 10.0;\r
+    }\r
+\r
+    private static Type getValueType(ReadGraph graph, Resource relation) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Type valueType = parseValueType((String)graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING));\r
+        if(valueType != null)\r
+            return valueType;\r
+        Resource range = graph.getPossibleObject(relation, L0.HasRange);\r
+        if(range != null) {\r
+            for(Resource valueTypeLiteral : graph.getAssertedObjects(range, L0.HasValueType)) {\r
+                valueType = parseValueType((String)graph.getValue(valueTypeLiteral, Bindings.STRING));\r
+                if(valueType != null)\r
+                    return valueType;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    private static Type parseValueType(String valueTypeString) {\r
+        if(valueTypeString == null)\r
+            return null;\r
+        try {\r
+            return Types.parseType(valueTypeString);\r
+        } catch (SCLTypeParseException e) {\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public void findValuesForPrefix(String prefix,\r
+            NamespaceFilter filter,\r
+            TObjectProcedure<SCLValue> proc) {\r
+        Map<String,Resource> localMap = childMaps.get(ontology); \r
+        if(localMap == null)\r
+            return;\r
+        String namePrefix = "";\r
+        while(true) {\r
+            int p = prefix.indexOf('.');\r
+            if(p < 0)\r
+                break;\r
+            String localName = prefix.substring(0, p);\r
+            Resource newParent = localMap.get(localName);\r
+            if(newParent == null)\r
+                return;\r
+            prefix = prefix.substring(p+1);\r
+            namePrefix = namePrefix + localName + ".";\r
+            \r
+            // Get new local map\r
+            localMap = getLocalMap(newParent);\r
+            if(localMap == null)\r
+                return;\r
+        }\r
+        for(String name : localMap.keySet())\r
+            if(name.startsWith(prefix) && filter.isValueIncluded(name))\r
+                proc.execute(getValue(namePrefix+name));\r
+    }\r
+    \r
+    @Override\r
+    public void findValuesForPrefix(String prefix, NamespaceFilter filter, Consumer<SCLValue> consumer) {\r
+        Map<String,Resource> localMap = childMaps.get(ontology); \r
+        if(localMap == null)\r
+            return;\r
+        String namePrefix = "";\r
+        while(true) {\r
+            int p = prefix.indexOf('.');\r
+            if(p < 0)\r
+                break;\r
+            String localName = prefix.substring(0, p);\r
+            Resource newParent = localMap.get(localName);\r
+            if(newParent == null)\r
+                return;\r
+            prefix = prefix.substring(p+1);\r
+            namePrefix = namePrefix + localName + ".";\r
+            \r
+            // Get new local map\r
+            localMap = getLocalMap(newParent);\r
+            if(localMap == null)\r
+                return;\r
+        }\r
+        for(String name : localMap.keySet())\r
+            if(name.startsWith(prefix) && filter.isValueIncluded(name))\r
+                consumer.accept(getValue(namePrefix+name));\r
+    }\r
+\r
+    @Override\r
+    public void findTypesForPrefix(String prefix, NamespaceFilter instance, Consumer<TCon> consumer) {\r
+        \r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        childMaps.clear();\r
+        childMaps = null;\r
+        ontology = null;\r
+    }\r
+}\r