From 6320ecb3f75e3a29ed620ca5425ca22ef88a5496 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Fri, 21 Sep 2018 15:28:44 +0300 Subject: [PATCH] Property following functions value and possibleValue to ontology modules gitlab #131 Change-Id: I407c7ab8a0c1a7e547c240ea36ab9b8c53298cfe --- .../modeling/internal/Activator.java | 2 +- .../scl/GraphModuleSourceRepository.java | 1 + .../{ => ontologymodule}/GraphEntityType.java | 2 +- .../GraphPropertyRelation.java | 2 +- .../{ => ontologymodule}/GraphRelation.java | 2 +- .../GraphRequestDuringSCLCompilation.java | 18 ++ .../{ => ontologymodule}/OntologyModule.java | 181 ++++++++++++++++-- .../OntologyModuleSourceRepository.java | 2 +- .../scl/ontologymodule/SCLRelationInfo.java | 13 ++ .../SCLRelationInfoRequest.java | 79 ++++++++ ...servedWordsEscapingChildMapOfResource.java | 59 ++++++ .../elaboration/expressions/EConstant.java | 9 + .../elaboration/macros/MacroRule.java | 8 +- .../org.simantics.scl.db/scl/Simantics/DB.scl | 9 + .../scl/Simantics/Variables.scl | 3 + .../db/SCLCompilationRequestProcessor.java | 15 ++ 16 files changed, 383 insertions(+), 22 deletions(-) rename bundles/org.simantics.modeling/src/org/simantics/modeling/scl/{ => ontologymodule}/GraphEntityType.java (98%) rename bundles/org.simantics.modeling/src/org/simantics/modeling/scl/{ => ontologymodule}/GraphPropertyRelation.java (99%) rename bundles/org.simantics.modeling/src/org/simantics/modeling/scl/{ => ontologymodule}/GraphRelation.java (99%) create mode 100644 bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java rename bundles/org.simantics.modeling/src/org/simantics/modeling/scl/{ => ontologymodule}/OntologyModule.java (58%) rename bundles/org.simantics.modeling/src/org/simantics/modeling/scl/{ => ontologymodule}/OntologyModuleSourceRepository.java (97%) create mode 100644 bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java create mode 100644 bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java create mode 100644 bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java create mode 100644 bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java index 3fc0d46fa..b55bed028 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java @@ -5,7 +5,7 @@ import java.util.Hashtable; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.simantics.modeling.scl.GraphModuleSourceRepository; -import org.simantics.modeling.scl.OntologyModuleSourceRepository; +import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository; import org.simantics.scl.compiler.source.repository.ModuleSourceRepository; public class Activator implements BundleActivator { diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index f3f5b9170..8eed51aca 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -15,6 +15,7 @@ import org.simantics.db.request.Read; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingUtils; import org.simantics.modeling.internal.Activator; +import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.module.repository.UpdateListener.Observable; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java similarity index 98% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java index d59ea605c..8ea51cfd0 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.externalConstant; import gnu.trove.map.hash.THashMap; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java similarity index 99% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java index a4c1c4b2a..3275656bc 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import org.simantics.db.Resource; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java similarity index 99% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java index f1c8a79f8..5a4598ce3 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import org.simantics.db.Resource; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java new file mode 100644 index 000000000..54533ad29 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java @@ -0,0 +1,18 @@ +package org.simantics.modeling.scl.ontologymodule; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.scl.runtime.SCLContext; + +public class GraphRequestDuringSCLCompilation { + + public static RequestProcessor getRequestProcessor() { + ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph"); + if(graph != null) + return graph; + else + return Simantics.getSession(); + } + +} 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/OntologyModule.java similarity index 58% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java index 39cf2f765..ec698e670 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java @@ -1,8 +1,9 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -16,29 +17,48 @@ 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.constants.StringConstant; +import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; +import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; +import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.macros.MacroRule; 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.errors.Locations; 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.TVar; 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.compiler.types.kinds.Kinds; import org.simantics.scl.runtime.SCLContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectProcedure; public class OntologyModule extends LazyModule { - + private static final Logger LOGGER = LoggerFactory.getLogger(OntologyModule.class); + private static final String DB_MODULE = "Simantics/DB"; + private static final String VARIABLE_MODULE = "Simantics/Variable"; private static final Collection DEPENDENCIES = Arrays.asList( - new ImportDeclaration(DB_MODULE, null) + new ImportDeclaration(DB_MODULE, null), + new ImportDeclaration(VARIABLE_MODULE, null) ); private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource"); + private static final TCon BROWSABLE = Types.con(DB_MODULE, "Browsable"); + private static final TCon VARIABLE = Types.con(VARIABLE_MODULE, "Variable"); Resource ontology; String defaultLocalName; @@ -69,26 +89,55 @@ public class OntologyModule extends LazyModule { return Collections.emptyList(); } - private Resource getResource(String name) { + private static interface ResourceSearchResult {} + private static class JustResource implements ResourceSearchResult { + public final Resource resource; + public JustResource(Resource resource) { + this.resource = resource; + } + } + private static class ResourceAndSuffix implements ResourceSearchResult { + public final Resource resource; + public final String suffix; + public ResourceAndSuffix(Resource resource, String suffix) { + this.resource = resource; + this.suffix = suffix; + } + } + + private ResourceSearchResult getResourceOrSuffixedResource(String name) { Map localMap = childMaps.get(ontology); if(localMap == null) return null; + Resource parent = ontology; while(true) { int p = name.indexOf('.'); if(p < 0) break; String localName = name.substring(0, p); - Resource newParent = localMap.get(localName); - if(newParent == null) + parent = localMap.get(localName); + if(parent == null) return null; name = name.substring(p+1); // Get new local map - localMap = getLocalMap(newParent); + localMap = getLocalMap(parent); if(localMap == null) return null; } - return localMap.get(name); + Resource child = localMap.get(name); + if(child != null) + return new JustResource(child); + else + return new ResourceAndSuffix(parent, name); + } + + private Resource getResource(String name) { + ResourceSearchResult searchResult = getResourceOrSuffixedResource(name); + if(searchResult instanceof JustResource) + return ((JustResource)searchResult).resource; + else + return null; } private Map getLocalMap(Resource parent) { @@ -129,16 +178,116 @@ public class OntologyModule extends LazyModule { } } + @FunctionalInterface + private static interface ResourceFunctionGenerator { + SCLValue createValue(Name name, Resource resource); + } + + private static class RelatedValueMacroRule implements MacroRule { + private final Resource relation; + private final SCLRelationInfo relationInfo; + private final boolean optionalValue; + + public RelatedValueMacroRule(Resource relation, SCLRelationInfo relationInfo, boolean optionalValue) { + this.relation = relation; + this.relationInfo = relationInfo; + this.optionalValue = optionalValue; + } + + private Expression applyWithSubject(SimplificationContext context, Type subjectType, Expression evidence, Expression subject) { + if(Types.equals(subjectType, RESOURCE)) + return new EApply( + Locations.NO_LOCATION, + Types.READ_GRAPH, + context.getConstant(Name.create(DB_MODULE, optionalValue ? "possibleRelatedValue2" : "relatedValue2"), relationInfo.rangeType), + subject, + new EExternalConstant(relation, RESOURCE)); + else if(Types.equals(subjectType, VARIABLE)) + return new EApply( + Locations.NO_LOCATION, + Types.READ_GRAPH, + context.getConstant(Name.create(DB_MODULE, optionalValue ? "untypedPossiblePropertyValue" : "untypedPropertyValue"), relationInfo.rangeType), + subject, + new ELiteral(new StringConstant(relationInfo.name))); + else + return new EApply( + Locations.NO_LOCATION, + Types.READ_GRAPH, + context.getConstant(Name.create(DB_MODULE, optionalValue ? "genericPossibleRelatedValue" : "genericRelatedValue"), subjectType, relationInfo.rangeType), + evidence, + subject, + new EExternalConstant(relation, RESOURCE)); + } + + @Override + public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) { + Type subjectType = typeParameters[0]; + if(apply.parameters.length == 1) { + Variable subject = new Variable("subject", subjectType); + return new ESimpleLambda(subject, applyWithSubject(context, subjectType, apply.parameters[0], new EVariable(subject))); + } + else if(apply.parameters.length >= 2) { + Expression valueReplacement = applyWithSubject(context, subjectType, apply.parameters[0], apply.parameters[1]); + if(apply.parameters.length == 2) + return valueReplacement; + else { + apply.set(valueReplacement, Arrays.copyOfRange(apply.parameters, 2, apply.parameters.length)); + return apply; + } + } + else { + LOGGER.error("Application of relation following functions should have at least one parameter (the evidence of Browsable)."); + return null; + } + } + } + + private final static HashMap VALUE_GENERATOR_MAP = new HashMap<>(); + static { + TVar A = Types.var(Kinds.STAR); + VALUE_GENERATOR_MAP.put("value", (name, resource) -> { + SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource); + if(relationInfo == null) + return null; + + SCLValue value = new SCLValue(name); + value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, relationInfo.rangeType)))); + value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, false)); + return value; + }); + VALUE_GENERATOR_MAP.put("possibleValue", (name, resource) -> { + SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource); + if(relationInfo == null) + return null; + + SCLValue value = new SCLValue(name); + value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, Types.apply(Types.MAYBE, relationInfo.rangeType))))); + value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, true)); + return value; + }); + } + @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; + ResourceSearchResult searchResult = getResourceOrSuffixedResource(name); + if(searchResult instanceof JustResource) { + Resource resource = ((JustResource)searchResult).resource; + SCLValue value = new SCLValue(Name.create(getName(), name)); + value.setType(RESOURCE); + value.setExpression(new EExternalConstant(resource, RESOURCE)); + value.setInlineInSimplification(true); + return value; + } + else if(searchResult instanceof ResourceAndSuffix){ + ResourceAndSuffix resourceAndSuffix = (ResourceAndSuffix)searchResult; + ResourceFunctionGenerator generator = VALUE_GENERATOR_MAP.get(resourceAndSuffix.suffix); + if(generator == null) + return null; + else + return generator.createValue(Name.create(getName(), name), resourceAndSuffix.resource); + } + else + return null; } @Override diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java similarity index 97% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java index b91e90d61..134b2b3d7 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import java.util.Collection; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java new file mode 100644 index 000000000..451a83ecf --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java @@ -0,0 +1,13 @@ +package org.simantics.modeling.scl.ontologymodule; + +import org.simantics.scl.compiler.types.Type; + +public class SCLRelationInfo { + public final Type rangeType; + public final String name; + + public SCLRelationInfo(Type rangeType, String name) { + this.rangeType = rangeType; + this.name = name; + } +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java new file mode 100644 index 000000000..6662463c5 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java @@ -0,0 +1,79 @@ +package org.simantics.modeling.scl.ontologymodule; + +import java.util.Collection; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +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.db.SCLCompilationRequestProcessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SCLRelationInfoRequest extends UnaryRead { + private static final Logger LOGGER = LoggerFactory.getLogger(SCLRelationInfoRequest.class); + + private SCLRelationInfoRequest(Resource resource) { + super(resource); + } + + @Override + public SCLRelationInfo perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + if(!graph.isSubrelationOf(parameter, L0.HasProperty)) + return null; + + String name = graph.getPossibleRelatedValue(parameter, L0.HasName); + if(name == null) + return null; + + String valueType = graph.getPossibleRelatedValue(parameter, L0.RequiresValueType); + if(valueType == null) { + Collection rangeTypes = graph.getObjects(parameter, L0.HasRange); + if(rangeTypes.size() != 1) { + LOGGER.warn("Couldn't find SCLtype for {} because it has multiple range types.", graph.getURI(parameter)); + return null; + } + + Resource range = rangeTypes.iterator().next(); + Collection assertedValueTypes = graph.getAssertedObjects(range, L0.HasValueType); + if(assertedValueTypes.size() != 1) { + LOGGER.warn("Couldn't find SCL type for {} because its range {} has multiple asserted value types.", graph.getURI(parameter), graph.getURI(range)); + return null; + } + + Resource assertedValueType = assertedValueTypes.iterator().next(); + valueType = graph.getPossibleValue(assertedValueType, Bindings.STRING); + if(valueType == null) { + LOGGER.warn("Couldn't find SCL type for {} because value type assertion of {} is missing a value.", graph.getURI(parameter), graph.getURI(range)); + return null; + } + } + + Type type; + try { + type = Types.parseType(valueType); + } catch (SCLTypeParseException e) { + LOGGER.warn("Couldn't parse the value type of relation {}. Definition was '{}'.", graph.getURI(parameter), valueType); + return null; + } + + return new SCLRelationInfo(type, name); + } + + public static SCLRelationInfo getRelationInfo(Resource resource) { + try { + return SCLCompilationRequestProcessor.getRequestProcessor().syncRequest(new SCLRelationInfoRequest(resource), TransientCacheListener.instance()); + } catch(DatabaseException e) { + LOGGER.error("SCLRelationInfoRequest failed.", e); + return null; + } + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java new file mode 100644 index 000000000..6e674e41c --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.scl.ontologymodule; + +import java.util.Collection; +import java.util.Map; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.CollectionSupport; +import org.simantics.layer0.Layer0; +import org.simantics.scl.compiler.common.names.SCLReservedWords; +import org.simantics.utils.Development; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SCLReservedWordsEscapingChildMapOfResource extends ResourceRead> { + + private static final Logger LOGGER = LoggerFactory.getLogger(SCLReservedWordsEscapingChildMapOfResource.class); + + public SCLReservedWordsEscapingChildMapOfResource(Resource resource) { + super(resource); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Collection objects = graph.getObjects(resource, L0.ConsistsOf); + CollectionSupport cs = graph.getService(CollectionSupport.class); + Map result = cs.createObjectResourceMap(String.class, objects.size()); + for(Resource r : objects) { + String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); + if(name != null) { + if(SCLReservedWords.RESERVED_WORDS_SET.contains(name)) + name = name + "_"; + Resource old = result.put(name, r); + if (old != null) + LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ")."); + } else { + if(Development.DEVELOPMENT) + LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ")."); + } + } + return result; + } + +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java index eb3f5ca4a..25cc96019 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java @@ -16,6 +16,7 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs; import org.simantics.scl.compiler.elaboration.java.DynamicConstructor; +import org.simantics.scl.compiler.elaboration.macros.MacroRule; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; @@ -125,6 +126,14 @@ public class EConstant extends Expression { else return value.getExpression().copy().simplify(context); } + else { + MacroRule macroRule = value.getMacroRule(); + if(macroRule != null) { + Expression newExpression = macroRule.inline(context, typeParameters); + if(newExpression != null) + return newExpression; + } + } return this; } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java index 60d53acd2..21b836871 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java @@ -7,6 +7,12 @@ import org.simantics.scl.compiler.types.Type; public interface MacroRule { - Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply); + default Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) { + return null; + } + + default Expression inline(SimplificationContext context, Type[] typeParameters) { + return null; + } } diff --git a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl index a400659ee..2ff2f51ac 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl @@ -108,6 +108,9 @@ importJava "org.simantics.db.ReadGraph" where @JavaName getRelatedValue2 relatedValue2 :: Resource -> Resource -> a + @JavaName getPossibleRelatedValue2 + possibleRelatedValue2 :: Resource -> Resource -> Maybe a + @JavaName getRelatedVariantValue2 relatedVariantValue2 :: Resource -> Resource -> Variant @@ -187,6 +190,9 @@ class Browsable a where valueOf :: Serializable v => a -> v + genericRelatedValue :: a -> Resource -> t + genericPossibleRelatedValue :: a -> Resource -> Maybe t + variantValueOf :: a -> Variant children :: a -> [a] @@ -206,6 +212,9 @@ instance Browsable Resource where valueOf r = valueOf_ r binding variantValueOf = variantValueOf_ + genericRelatedValue = relatedValue2 + genericPossibleRelatedValue = possibleRelatedValue2 + children r = r # L0.ConsistsOf parent r = singleObject r L0.PartOf possibleParent r = possibleObject r L0.PartOf diff --git a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl index 43be6defb..436e0a173 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl @@ -421,6 +421,9 @@ instance Browsable Variable where variantValueOf v = createVariant (datatype v) (untypedValue v :: Dynamic) child = child_ possibleChild = possibleChild_ + + genericRelatedValue v rel = untypedPropertyValue v (nameOf rel) + genericPossibleRelatedValue v rel = untypedPossiblePropertyValue v (nameOf rel) propertiesClassified :: Variable -> Resource -> [Variable] propertiesClassified parent classified = do diff --git a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java new file mode 100644 index 000000000..b793b2128 --- /dev/null +++ b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java @@ -0,0 +1,15 @@ +package org.simantics.scl.db; + +import org.simantics.Simantics; +import org.simantics.db.RequestProcessor; +import org.simantics.scl.runtime.SCLContext; + +public class SCLCompilationRequestProcessor { + public static RequestProcessor getRequestProcessor() { + Object graph = SCLContext.getCurrent().get("graph"); + if(graph != null) + return (RequestProcessor)graph; + else + return Simantics.getSession(); + } +} -- 2.47.1