]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileProceduralSCLMonitorRequest.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / CompileProceduralSCLMonitorRequest.java
1 package org.simantics.modeling.scl;\r
2 \r
3 import gnu.trove.map.hash.THashMap;\r
4 \r
5 import org.simantics.databoard.Bindings;\r
6 import org.simantics.db.ReadGraph;\r
7 import org.simantics.db.Resource;\r
8 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
9 import org.simantics.db.common.request.IndexRoot;\r
10 import org.simantics.db.exception.DatabaseException;\r
11 import org.simantics.db.layer0.request.VariableRead;\r
12 import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext;\r
13 import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest;\r
14 import org.simantics.db.layer0.util.RuntimeEnvironmentRequest;\r
15 import org.simantics.db.layer0.variable.Variable;\r
16 import org.simantics.layer0.Layer0;\r
17 import org.simantics.modeling.ProceduralSubstructureMapRequest;\r
18 import org.simantics.modeling.scl.CompileProceduralSCLMonitorRequest.CompilationContext;\r
19 import org.simantics.scl.compiler.common.names.Name;\r
20 import org.simantics.scl.compiler.constants.StringConstant;\r
21 import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
22 import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
23 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
24 import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
25 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
26 import org.simantics.scl.compiler.environment.Environment;\r
27 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
28 import org.simantics.scl.compiler.types.Type;\r
29 import org.simantics.scl.runtime.SCLContext;\r
30 import org.simantics.scl.runtime.function.Function1;\r
31 import org.simantics.utils.datastructures.Pair;\r
32 \r
33 public class CompileProceduralSCLMonitorRequest extends AbstractExpressionCompilationRequest<CompilationContext, Variable> {\r
34     \r
35     protected static Name BROWSE = Name.create("Simantics/Variables", "browse");\r
36     protected static Name VALUE = Name.create("Simantics/Variables", "value");\r
37     \r
38     private final Resource componentType;\r
39     private final Resource literal;\r
40     private final Variable componentVariable;\r
41     \r
42     public static class CompilationContext extends AbstractExpressionCompilationContext {\r
43         public final THashMap<String, Pair<String,Type>> propertyMap;\r
44         \r
45         public CompilationContext(RuntimeEnvironment runtimeEnvironment,\r
46                 THashMap<String, Pair<String,Type>> propertyMap) {\r
47             super(runtimeEnvironment);\r
48             this.propertyMap = propertyMap;\r
49         }\r
50     }\r
51     \r
52     public CompileProceduralSCLMonitorRequest(ReadGraph graph, Variable context)\r
53             throws DatabaseException {\r
54         this.componentType = context.getParent(graph).getType(graph);\r
55         this.literal = context.getRepresents(graph);\r
56         this.componentVariable = context.getParent(graph);\r
57     }\r
58 \r
59     public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {\r
60         SCLContext sclContext = SCLContext.getCurrent();\r
61         Object oldGraph = sclContext.get("graph");\r
62         try {\r
63             Function1<Variable,Object> exp = graph.syncRequest(new CompileProceduralSCLMonitorRequest(graph, context),\r
64                     TransientCacheListener.<Function1<Variable,Object>>instance());\r
65             sclContext.put("graph", graph);\r
66             return exp.apply(context.getParent(graph));\r
67         } catch (DatabaseException e) {\r
68             throw (DatabaseException)e;\r
69         } catch (Throwable t) {\r
70             throw new DatabaseException(t);\r
71         } finally {\r
72             sclContext.put("graph", oldGraph);\r
73         }\r
74     }\r
75 \r
76     @Override\r
77     protected String getExpressionText(ReadGraph graph)\r
78             throws DatabaseException {\r
79         Layer0 L0 = Layer0.getInstance(graph);\r
80         return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);\r
81     }\r
82 \r
83     @Override\r
84     protected CompilationContext getCompilationContext(ReadGraph graph)\r
85             throws DatabaseException {\r
86         return graph.syncRequest(new VariableRead<CompilationContext>(componentVariable) {\r
87             @Override\r
88             public CompilationContext perform(ReadGraph graph)\r
89                     throws DatabaseException {\r
90                 Resource indexRoot = graph.syncRequest(new IndexRoot(componentType));\r
91                 RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot));\r
92                 THashMap<String, Pair<String,Type>> propertyMap =\r
93                         graph.sync(new ProceduralSubstructureMapRequest(componentVariable));\r
94                 return new CompilationContext(runtimeEnvironment, propertyMap);\r
95             }\r
96         });\r
97     }\r
98 \r
99     @Override\r
100     protected Type getContextVariableType() {\r
101         return VARIABLE;\r
102     }\r
103 \r
104     @Override\r
105     protected Expression getVariableAccessExpression(\r
106             ReadGraph graph,\r
107             CompilationContext context,\r
108             org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,\r
109             String name) throws DatabaseException {\r
110         Pair<String,Type> entry = context.propertyMap.get(name);\r
111         if(entry == null)\r
112             return null;\r
113         Environment environment = context.runtimeEnvironment.getEnvironment();\r
114         Expression propertyVariable = new EApply(\r
115                 new EConstant(environment.getValue(BROWSE)),\r
116                 new EVariable(contextVariable),\r
117                 new ELiteral(new StringConstant(entry.first))\r
118                 );\r
119         return new EApply(\r
120                 new EConstant(environment.getValue(VALUE), entry.second),\r
121                 propertyVariable\r
122                 );\r
123     }\r
124     \r
125     @Override\r
126     public int hashCode() {\r
127         return 31*componentVariable.hashCode() + literal.hashCode();\r
128     }\r
129     \r
130     @Override\r
131     public boolean equals(Object obj) {\r
132         if(this == obj)\r
133             return true;\r
134         if(obj == null || obj.getClass() != getClass())\r
135             return false;\r
136         CompileProceduralSCLMonitorRequest other = (CompileProceduralSCLMonitorRequest)obj;\r
137         return literal.equals(other.literal) && componentVariable.equals(other.componentVariable);\r
138     }\r
139 }\r
140 \r