]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileValueRequest.java
1eb01aa393b688d0809f95dbef56d3f2d848fda2
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / scl / CompileValueRequest.java
1 package org.simantics.db.layer0.scl;
2
3 import org.simantics.databoard.Bindings;
4 import org.simantics.db.ReadGraph;
5 import org.simantics.db.Resource;
6 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
7 import org.simantics.db.common.request.IndexRoot;
8 import org.simantics.db.exception.DatabaseException;
9 import org.simantics.db.layer0.scl.CompileValueRequest.CompilationContext;
10 import org.simantics.db.layer0.util.RuntimeEnvironmentRequest;
11 import org.simantics.db.layer0.variable.Variable;
12 import org.simantics.layer0.Layer0;
13 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
14 import org.simantics.scl.compiler.elaboration.expressions.Expression;
15 import org.simantics.scl.compiler.environment.Environments;
16 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
17 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
18 import org.simantics.scl.compiler.types.Type;
19 import org.simantics.scl.runtime.SCLContext;
20 import org.simantics.scl.runtime.function.Function1;
21
22 /**
23  * Compiles an SCL expression that is attached to a literal
24  * whose parent is a component that is a part of a component type.
25  * 
26  * @author Tuukka Lehtonen
27  */
28 public class CompileValueRequest extends AbstractExpressionCompilationRequest<CompilationContext, Object> {
29
30     public static class CompilationContext extends AbstractExpressionCompilationContext {
31         public CompilationContext(RuntimeEnvironment runtimeEnvironment) {
32             super(runtimeEnvironment);
33         }
34     }
35
36     protected final Resource relation;
37     protected final Resource component;
38     protected final Resource literal;
39
40     public CompileValueRequest(Resource component, Resource literal, Resource relation) {
41         this.relation = relation;
42         this.component = component;
43         this.literal = literal;
44     }
45
46     public CompileValueRequest(ReadGraph graph, Variable context) throws DatabaseException {
47         this(context.getParent(graph).getRepresents(graph),
48                 context.getRepresents(graph),
49                 context.getPredicateResource(graph));
50     }
51
52     public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
53         SCLContext sclContext = SCLContext.getCurrent();
54         Object oldGraph = sclContext.get("graph");
55         try {
56             Function1<Object,Object> exp = graph.syncRequest(new CompileValueRequest(graph, context),
57                     TransientCacheListener.instance());
58             sclContext.put("graph", graph);
59             return exp.apply(context);
60         } catch (DatabaseException e) {
61             throw (DatabaseException)e;
62         } catch (Throwable t) {
63             throw new DatabaseException(t);
64         } finally {
65             sclContext.put("graph", oldGraph);
66         }
67     }
68
69     public static Function1<Object,Object> compile(ReadGraph graph, Resource component, Resource literal, Resource predicate) throws DatabaseException {
70         SCLContext sclContext = SCLContext.getCurrent();
71         Object oldGraph = sclContext.get("graph");
72         try {
73             Function1<Object,Object> exp = graph.syncRequest(new CompileValueRequest(component, literal, predicate),
74                     TransientCacheListener.instance());
75             sclContext.put("graph", graph);
76             return exp;
77         } catch (DatabaseException e) {
78             throw (DatabaseException)e;
79         } catch (Throwable t) {
80             throw new DatabaseException(t);
81         } finally {
82             sclContext.put("graph", oldGraph);
83         }
84     }
85
86     @Override
87     protected String getExpressionText(ReadGraph graph)
88             throws DatabaseException {
89         Layer0 L0 = Layer0.getInstance(graph);
90         return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
91     }
92
93     protected Resource getIndexRoot(ReadGraph graph) throws DatabaseException {
94         return graph.syncRequest(new IndexRoot(literal));
95     }
96
97     @Override
98     protected Type getExpectedType(ReadGraph graph, CompilationContext context)
99             throws DatabaseException {
100         Layer0 L0 = Layer0.getInstance(graph);
101         String valueType = graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);
102         if(valueType != null) {
103             try {
104                 return Environments.getType(context.runtimeEnvironment.getEnvironment(), valueType);
105             } catch (SCLExpressionCompilationException e) {
106                 e.printStackTrace();
107             }
108         }
109         return super.getExpectedType(graph, context);
110     }
111
112     @Override
113     protected CompilationContext getCompilationContext(ReadGraph graph)
114             throws DatabaseException {
115         Resource indexRoot = getIndexRoot(graph);
116         RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot));
117         return new CompilationContext(runtimeEnvironment);
118     }
119
120     @Override
121     protected Type getContextVariableType() {
122         return VARIABLE; 
123     }
124
125     @Override
126     protected Expression getVariableAccessExpression(
127             ReadGraph graph,
128             CompilationContext context,
129             org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
130             String name) throws DatabaseException {
131         if(name.equals("self"))
132             return new EVariable(contextVariable);
133         else
134             return null;
135     }
136
137 }