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%2FServerSCLHandlerValueRequest.java;h=7283cf26b36a5786c1212f6bc7d6405042cae882;hp=ca82be6c94ee53d624fdcb539573186602cb962e;hb=41d461afeab1da2a4e10b726c5f2b14996706dcd;hpb=fdbe87627e92805701d0672fbe8f1dc60b7f7b00 diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java index ca82be6c9..7283cf26b 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java @@ -1,269 +1,289 @@ -package org.simantics.document.server.request; - -import java.util.HashMap; -import java.util.List; -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.exception.DatabaseException; -import org.simantics.db.layer0.request.VariableRead; -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.Functions; -import org.simantics.document.server.bean.DataDefinition; -import org.simantics.document.server.request.ServerSCLHandlerValueRequest.CompilationContext; -import org.simantics.layer0.Layer0; -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.EVar; -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.TCon; -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 ServerSCLHandlerValueRequest extends AbstractExpressionCompilationRequest { - - private final Variable context; - 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 ServerSCLHandlerValueRequest(Variable context, Pair componentTypeAndRoot, Resource literal) { - assert(literal != null); - this.context = context; - this.literal = literal; - this.componentTypeAndRoot = componentTypeAndRoot; - } - - public ServerSCLHandlerValueRequest(ReadGraph graph, Variable context) throws DatabaseException { - this(context, 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 List getEffects(ReadGraph graph, Variable context) throws DatabaseException { - try { - ServerSCLHandlerValueRequest req = new ServerSCLHandlerValueRequest(graph, context); - return req.getExpressionEffects(graph); - } catch (DatabaseException e) { - throw (DatabaseException)e; - } catch (Throwable t) { - throw new DatabaseException(t); - } - } - - 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 ServerSCLHandlerValueRequest(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); - String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); - return "\\context -> " + exp; - } - - 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 VariableRead(context) { - - @Override - public CompilationContext perform(ReadGraph graph) throws DatabaseException { - - Pair parameter = getComponentTypeAndRoot(graph, variable); - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.second)); - - Map propertyMap = - graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), - TransientCacheListener.>instance()); - -// Map result = new HashMap(propertyMap); -// for(DataDefinition dd : Functions.dataDefinitions(graph, variable)) { -// result.put(dd.target, null); -// } - - 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 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 { - -// if(context.propertyMap.containsKey(name)) { -// -// org.simantics.scl.compiler.elaboration.expressions.Variable parametersVariable = new org.simantics.scl.compiler.elaboration.expressions.Variable("context", COMMAND_CONTEXT); -// -// Environment environment = context.runtimeEnvironment.getEnvironment(); -// -//// return new EApply( -//// new EConstant(environment.getValue(FROM_DYNAMIC), Types.STRING), -// return new EApply( -// new EConstant(environment.getValue(CONTEXT_VARIABLE), Types.DYNAMIC), -// new EVariable(parametersVariable), -// new ELiteral(new StringConstant(name))); -// -// } - - 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() { - final int prime = 31; - int result = 1; - result = prime * result + ((context == null) ? 0 : context.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest) obj; - if (context == null) { - if (other.context != null) - return false; - } else if (!context.equals(other.context)) - return false; - return true; - } - -// @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; -// ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest)obj; -// return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); -// } - -} +package org.simantics.document.server.request; + +import java.util.ArrayList; +import java.util.List; +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.exception.DatabaseException; +import org.simantics.db.layer0.request.VariableRead; +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.ServerSCLHandlerValueRequest.CompilationContext; +import org.simantics.layer0.Layer0; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +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.TCon; +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 ServerSCLHandlerValueRequest extends AbstractExpressionCompilationRequest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ServerSCLHandlerValueRequest.class); + + private final Variable context; + 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 ServerSCLHandlerValueRequest(Variable context, Pair componentTypeAndRoot, Resource literal, String possibleExpectedValueType) { + assert(literal != null); + this.context = context; + this.literal = literal; + this.componentTypeAndRoot = componentTypeAndRoot; + this.possibleExpectedValueType = possibleExpectedValueType; + } + + public ServerSCLHandlerValueRequest(ReadGraph graph, Variable context) throws DatabaseException { + this(context, 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 List getEffects(ReadGraph graph, Variable context) throws DatabaseException { + try { + ServerSCLHandlerValueRequest req = new ServerSCLHandlerValueRequest(graph, context); + return req.getExpressionEffects(graph); + } catch (DatabaseException e) { + throw (DatabaseException)e; + } catch (Throwable t) { + throw new DatabaseException(t); + } + } + + 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 ServerSCLHandlerValueRequest(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); + String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); + return "\\context -> " + exp; + } + + 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 VariableRead(context) { + + @Override + public CompilationContext perform(ReadGraph graph) throws DatabaseException { + + Pair parameter = getComponentTypeAndRoot(graph, variable); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); + + Map propertyMap = + graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), + TransientCacheListener.>instance()); + +// Map result = new HashMap(propertyMap); +// for(DataDefinition dd : Functions.dataDefinitions(graph, variable)) { +// result.put(dd.target, null); +// } + + 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 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 { + +// if(context.propertyMap.containsKey(name)) { +// +// org.simantics.scl.compiler.elaboration.expressions.Variable parametersVariable = new org.simantics.scl.compiler.elaboration.expressions.Variable("context", COMMAND_CONTEXT); +// +// Environment environment = context.runtimeEnvironment.getEnvironment(); +// +//// return new EApply( +//// new EConstant(environment.getValue(FROM_DYNAMIC), Types.STRING), +// return new EApply( +// new EConstant(environment.getValue(CONTEXT_VARIABLE), Types.DYNAMIC), +// new EVariable(parametersVariable), +// new ELiteral(new StringConstant(name))); +// +// } + + 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() { + final int prime = 31; + int result = 1; + result = prime * result + ((context == null) ? 0 : context.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest) obj; + if (context == null) { + if (other.context != null) + return false; + } else if (!context.equals(other.context)) + return false; + return true; + } + +// @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; +// ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest)obj; +// return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); +// } + +}