X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.document.server%2Fsrc%2Forg%2Fsimantics%2Fdocument%2Fserver%2Frequest%2FServerSCLValueRequest.java;h=e6cdf6ff5b43712b098594d172a91b7595de63cb;hp=246acfdec72236a9640e7c3b3f0d27ded78b29f8;hb=41d461afeab1da2a4e10b726c5f2b14996706dcd;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java index 246acfdec..e6cdf6ff5 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java @@ -1,210 +1,236 @@ -package org.simantics.document.server.request; - -import java.util.Map; - -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.IndexRoot; -import org.simantics.db.common.request.UnaryRead; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; -import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.document.server.request.ServerSCLValueRequest.CompilationContext; -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.expressions.EApply; -import org.simantics.scl.compiler.elaboration.expressions.EConstant; -import org.simantics.scl.compiler.elaboration.expressions.ELiteral; -import org.simantics.scl.compiler.elaboration.expressions.EVariable; -import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.modules.SCLValue; -import org.simantics.scl.compiler.environment.Environment; -import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; -import org.simantics.scl.compiler.runtime.RuntimeEnvironment; -import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.compiler.types.Types; -import org.simantics.scl.compiler.types.kinds.Kinds; -import org.simantics.scl.runtime.SCLContext; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.structural2.scl.ComponentTypeProperty; -import org.simantics.structural2.scl.FindPossibleComponentTypeRequest; -import org.simantics.structural2.scl.ReadComponentTypeInterfaceRequest; -import org.simantics.utils.datastructures.Pair; - -public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest { - - private final Pair componentTypeAndRoot; - private final Resource literal; - - public static class CompilationContext extends AbstractExpressionCompilationContext { - public final Map propertyMap; - - public CompilationContext(RuntimeEnvironment runtimeEnvironment, - Map propertyMap) { - super(runtimeEnvironment); - this.propertyMap = propertyMap; - } - } - - private ServerSCLValueRequest(Pair componentTypeAndRoot, Resource literal) { - assert(literal != null); - this.literal = literal; - this.componentTypeAndRoot = componentTypeAndRoot; - } - - public ServerSCLValueRequest(ReadGraph graph, Variable context) throws DatabaseException { - this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph)); - } - - private static Pair getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException { - Variable parent = property.getParent(graph); - Resource represents = parent.getRepresents(graph); - if(represents != null) { - Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(represents)); - if(type != null) { - Resource root = graph.syncRequest(new IndexRoot(type)); - return Pair.make(type, root); - } - } - parent = parent.getParent(graph); - Resource root = graph.syncRequest(new IndexRoot(property.getRepresents(graph))); - return Pair.make(parent.getType(graph), root); - } - - public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException { - SCLContext sclContext = SCLContext.getCurrent(); - Object oldGraph = sclContext.get("graph"); - try { - Function1 exp = graph.syncRequest(new ServerSCLValueRequest(graph, context), - TransientCacheListener.>instance()); - sclContext.put("graph", graph); - return exp.apply(context); - } catch (DatabaseException e) { - throw (DatabaseException)e; - } catch (Throwable t) { - throw new DatabaseException(t); - } finally { - sclContext.put("graph", oldGraph); - } - } - - @Override - protected String getExpressionText(ReadGraph graph) - throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); - } - - protected RuntimeEnvironmentRequest getRuntimeEnvironmentRequest(Resource indexRoot) { - return new RuntimeEnvironmentRequest(indexRoot) { - @Override - protected void fillEnvironmentSpecification( - EnvironmentSpecification environmentSpecification) { - } - }; - } - - @Override - protected CompilationContext getCompilationContext(ReadGraph graph) - throws DatabaseException { - return graph.syncRequest(new UnaryRead,CompilationContext>(componentTypeAndRoot) { - @Override - public CompilationContext perform(ReadGraph graph) - throws DatabaseException { - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.second)); - Map propertyMap = - graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), - TransientCacheListener.>instance()); - return new CompilationContext(runtimeEnvironment, propertyMap); - } - }); - } - - @Override - protected Type getContextVariableType() { - return VARIABLE; - } - - private static Expression accessInputVariable(Environment environment, - org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) { - SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT); - return new EApply(new EConstant(variableParentFunction), - new EApply(new EConstant(variableParentFunction), - new EVariable(contextVariable))); - } - - protected static Name PROPERTY_VALUE_CACHED = Name.create("Document/All", "propertyValueCached"); - - protected static Expression getProperty(Environment environment, Expression variable, String propertyName, Type type) { - return new EApply( - new EConstant(environment.getValue(FROM_DYNAMIC), type), - new EApply( - new EConstant(environment.getValue(PROPERTY_VALUE_CACHED), Types.DYNAMIC), - variable, - new ELiteral(new StringConstant(propertyName)))); - } - - protected static Expression getPropertyFlexible(Environment environment, Expression variable, String propertyName, Type type) { - return makeTypeFlexible(environment, getProperty(environment, variable, propertyName, type), type); - } - - protected static Expression standardGetProperty( - Environment environment, - org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, - String name, - Type type) { - return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type); - } - - - @Override - protected Expression getVariableAccessExpression( - ReadGraph graph, - CompilationContext context, - org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, - String name) throws DatabaseException { - ComponentTypeProperty property = context.propertyMap.get(name); - if(property != null) - return standardGetProperty( - context.runtimeEnvironment.getEnvironment(), - contextVariable, - name, - property.type == null ? Types.metaVar(Kinds.STAR) : property.type); - else - return getSpecialVariableAccessExpression(graph, context, contextVariable, name); - } - - protected Expression getSpecialVariableAccessExpression(ReadGraph graph, - CompilationContext context, - org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, - String name) throws DatabaseException { - if(name.equals("input")) { - Environment environment = context.runtimeEnvironment.getEnvironment(); - return accessInputVariable(environment, contextVariable); - } - else if(name.equals("self")) - return new EVariable(contextVariable); - else - return null; - } - - @Override - public int hashCode() { - return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(this == obj) - return true; - if(obj == null || obj.getClass() != getClass()) - return false; - ServerSCLValueRequest other = (ServerSCLValueRequest)obj; - return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); - } -} +package org.simantics.document.server.request; + +import java.util.ArrayList; +import java.util.Map; + +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.IndexRoot; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; +import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.document.server.request.ServerSCLValueRequest.CompilationContext; +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.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; +import org.simantics.scl.compiler.runtime.RuntimeEnvironment; +import org.simantics.scl.compiler.top.SCLExpressionCompilationException; +import org.simantics.scl.compiler.types.TMetaVar; +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.kinds.Kinds; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.structural2.scl.ComponentTypeProperty; +import org.simantics.structural2.scl.FindPossibleComponentTypeRequest; +import org.simantics.structural2.scl.ReadComponentTypeInterfaceRequest; +import org.simantics.utils.datastructures.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ServerSCLValueRequest.class); + + private final Pair componentTypeAndRoot; + private final Resource literal; + protected String possibleExpectedValueType; + + public static class CompilationContext extends AbstractExpressionCompilationContext { + public final Map propertyMap; + + public CompilationContext(RuntimeEnvironment runtimeEnvironment, + Map propertyMap) { + super(runtimeEnvironment); + this.propertyMap = propertyMap; + } + } + + private ServerSCLValueRequest(Pair componentTypeAndRoot, Resource literal, String possibleExpectedValueType) { + assert(literal != null); + this.literal = literal; + this.componentTypeAndRoot = componentTypeAndRoot; + this.possibleExpectedValueType = possibleExpectedValueType; + } + + public ServerSCLValueRequest(ReadGraph graph, Variable context) throws DatabaseException { + this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context)); + } + + private static Pair getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException { + Variable parent = property.getParent(graph); + Resource represents = parent.getRepresents(graph); + if(represents != null) { + Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(represents)); + if(type != null) { + Resource root = graph.syncRequest(new IndexRoot(type)); + return Pair.make(type, root); + } + } + parent = parent.getParent(graph); + Resource root = graph.syncRequest(new IndexRoot(property.getRepresents(graph))); + return Pair.make(parent.getType(graph), root); + } + + public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + Function1 exp = graph.syncRequest(new ServerSCLValueRequest(graph, context), + TransientCacheListener.>instance()); + sclContext.put("graph", graph); + return exp.apply(context); + } catch (DatabaseException e) { + throw (DatabaseException)e; + } catch (Throwable t) { + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + } + + @Override + protected String getExpressionText(ReadGraph graph) + throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); + } + + protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) { + return new RuntimeEnvironmentRequest2(componentType, indexRoot) { + @Override + protected void fillEnvironmentSpecification( + EnvironmentSpecification environmentSpecification) { + } + }; + } + + @Override + protected CompilationContext getCompilationContext(ReadGraph graph) + throws DatabaseException { + return graph.syncRequest(new UnaryRead,CompilationContext>(componentTypeAndRoot) { + @Override + public CompilationContext perform(ReadGraph graph) + throws DatabaseException { + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); + Map propertyMap = + graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), + TransientCacheListener.>instance()); + return new CompilationContext(runtimeEnvironment, propertyMap); + } + }); + } + + @Override + protected Type getContextVariableType() { + return VARIABLE; + } + + private static Expression accessInputVariable(Environment environment, + org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) { + SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT); + return new EApply(new EConstant(variableParentFunction), + new EApply(new EConstant(variableParentFunction), + new EVariable(contextVariable))); + } + + protected static Name PROPERTY_VALUE_CACHED = Name.create("Document/All", "propertyValueCached"); + + protected static Expression getProperty(Environment environment, Expression variable, String propertyName, Type type) { + return new EApply( + new EConstant(environment.getValue(FROM_DYNAMIC), type), + new EApply( + new EConstant(environment.getValue(PROPERTY_VALUE_CACHED), Types.DYNAMIC), + variable, + new ELiteral(new StringConstant(propertyName)))); + } + + protected static Expression getPropertyFlexible(Environment environment, Expression variable, String propertyName, Type type) { + return makeTypeFlexible(environment, getProperty(environment, variable, propertyName, type), type); + } + + protected static Expression standardGetProperty( + Environment environment, + org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, + String name, + Type type) { + return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type); + } + + + @Override + protected Expression getVariableAccessExpression( + ReadGraph graph, + CompilationContext context, + org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, + String name) throws DatabaseException { + ComponentTypeProperty property = context.propertyMap.get(name); + if(property != null) + return standardGetProperty( + context.runtimeEnvironment.getEnvironment(), + contextVariable, + name, + property.type == null ? Types.metaVar(Kinds.STAR) : property.type); + else + return getSpecialVariableAccessExpression(graph, context, contextVariable, name); + } + + protected Expression getSpecialVariableAccessExpression(ReadGraph graph, + CompilationContext context, + org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable, + String name) throws DatabaseException { + if(name.equals("input")) { + Environment environment = context.runtimeEnvironment.getEnvironment(); + return accessInputVariable(environment, contextVariable); + } + else if(name.equals("self")) + return new EVariable(contextVariable); + else + return null; + } + + @Override + protected Type getExpectedType(ReadGraph graph, CompilationContext context) throws DatabaseException { + if(possibleExpectedValueType != null) { + try { + Type type = Environments.getType(context.runtimeEnvironment.getEnvironment(), possibleExpectedValueType); + type = Types.instantiate(Types.forAll(Types.freeVars(type).toArray(new TVar[0]), type), new ArrayList()); + return type; + } catch (SCLExpressionCompilationException e) { + LOGGER.error("Could not get type for " + String.valueOf(possibleExpectedValueType), e); + } + } + return super.getExpectedType(graph, context); + } + + + @Override + public int hashCode() { + return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) + return true; + if(obj == null || obj.getClass() != getClass()) + return false; + ServerSCLValueRequest other = (ServerSCLValueRequest)obj; + return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); + } +}