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