]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorExpressionVisitor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagram / monitor / MonitorExpressionVisitor.java
1 package org.simantics.modeling.ui.diagram.monitor;\r
2 \r
3 import java.util.HashMap;\r
4 import java.util.LinkedList;\r
5 import java.util.Map;\r
6 import java.util.Stack;\r
7 \r
8 import org.simantics.basicexpression.analysis.DepthFirstAdapter;\r
9 import org.simantics.basicexpression.analysis.EvaluationException;\r
10 import org.simantics.basicexpression.node.AAddressValue;\r
11 import org.simantics.basicexpression.node.AConstantValue;\r
12 import org.simantics.basicexpression.node.AFunctionPrimary;\r
13 import org.simantics.basicexpression.node.AMultMultiplicative;\r
14 import org.simantics.basicexpression.node.APlusExpression;\r
15 import org.simantics.basicexpression.node.ARangeValue;\r
16 import org.simantics.basicexpression.node.ARviValue;\r
17 import org.simantics.basicexpression.node.ASequenceArgList;\r
18 import org.simantics.basicexpression.node.ASingleArgList;\r
19 import org.simantics.basicexpression.node.ASingleRange;\r
20 import org.simantics.basicexpression.node.AStringValue;\r
21 import org.simantics.basicexpression.node.AVariablePrimary;\r
22 import org.simantics.basicexpression.node.PArgList;\r
23 import org.simantics.common.format.Formatter;\r
24 import org.simantics.db.ReadGraph;\r
25 import org.simantics.db.Resource;\r
26 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
27 import org.simantics.db.common.utils.Logger;\r
28 import org.simantics.db.exception.DatabaseException;\r
29 import org.simantics.db.layer0.request.ModelInstances;\r
30 import org.simantics.db.layer0.request.VariableIndexRoot;\r
31 import org.simantics.db.layer0.variable.Variable;\r
32 import org.simantics.layer0.Layer0;\r
33 import org.simantics.scl.runtime.function.Function;\r
34 \r
35 public class MonitorExpressionVisitor extends DepthFirstAdapter {\r
36 \r
37     public static final boolean DEBUG_APPLICATION = false;\r
38     public static final boolean DEBUG = false;\r
39     \r
40         public static class ApplicationException extends Exception {\r
41 \r
42                 private static final long serialVersionUID = 1L;\r
43 \r
44                 public ApplicationException(String message) {\r
45                         super(message);\r
46                 }\r
47 \r
48         }\r
49 \r
50         final ReadGraph graph;\r
51         final Variable variable;\r
52         final Formatter formatter;\r
53         \r
54         Stack<Object> stack = new Stack<Object>();\r
55 \r
56         HashMap<String, Function> builtins = new HashMap<String, Function>();\r
57 \r
58         public MonitorExpressionVisitor(ReadGraph graph, Formatter formatter, Variable variable) {\r
59 \r
60                 this.graph = graph;\r
61                 this.formatter = formatter;\r
62                 this.variable = variable;\r
63 \r
64         }\r
65 \r
66         public Object getResult() {\r
67                 if(exception != null) return exception;\r
68                 return stack.pop();\r
69         }\r
70 \r
71         public void outAConstantValue(AConstantValue node) {\r
72                 if(DEBUG) System.out.println("outAConstantValue " + node);\r
73                 stack.push(Double.valueOf(node.toString()));\r
74         }\r
75 \r
76         public void outAStringValue(AStringValue node) {\r
77                 if(DEBUG) System.out.println("outAStringValue " + node);\r
78                 String value = node.toString();\r
79                 stack.push(value.substring(1, value.length() - 2));\r
80         }\r
81 \r
82         public void outAAddressValue(AAddressValue node) {\r
83                 if(DEBUG) System.out.println("outAAddressValue " + node);\r
84                 stack.push('&' + node.getRange().toString());\r
85         }\r
86 \r
87         @Override\r
88         public void outASingleRange(ASingleRange node) {\r
89                 \r
90                 if(DEBUG) System.out.println("outASingleRange " + node);\r
91                 \r
92         }\r
93         \r
94         @Override\r
95         public void outARviValue(ARviValue node) {\r
96                 \r
97                 if(DEBUG) System.out.println("outARviValue " + node);\r
98                 \r
99                 String rvi = node.toString().trim();\r
100                 \r
101                 try {\r
102                         Variable var = variable.browse(graph, rvi);\r
103                         stack.push(format(var.getValue(graph)));\r
104                 } catch (DatabaseException e) {\r
105                         Logger.defaultLogError(e);\r
106                         stack.push("<No value for '" + rvi + "'>");\r
107                 }\r
108                 \r
109         }\r
110         \r
111         @Override\r
112         public void outAVariablePrimary(AVariablePrimary node) {\r
113                 \r
114                 if(DEBUG) System.out.println("outAVariablePrimary " + node);\r
115                 \r
116                 String identifier = node.toString().trim();\r
117                 if("value".equals(identifier)) {\r
118                         try {\r
119                                 stack.push(format(variable.getValue(graph)));\r
120                         } catch (DatabaseException e) {\r
121                                 stack.push(e);\r
122                         }\r
123                 } else {\r
124                         stack.push(identifier);\r
125                 }\r
126                 \r
127         }\r
128         \r
129         public void outARangeValue(ARangeValue node) {\r
130 \r
131                 if(DEBUG) System.out.println("outARangeValue " + node);\r
132 \r
133                 String identifier = node.getRange().toString().trim();\r
134                 stack.push(identifier);\r
135 \r
136         }\r
137         \r
138         private String format(Object o) {\r
139                 if(formatter != null)\r
140                         return formatter.format(o);\r
141                 else return o != null ? o.toString() : "";\r
142         }\r
143 \r
144         private double extractValue(Object o) {\r
145                 if (o instanceof Number) {\r
146                         return ((Number) o).doubleValue();\r
147                 } else if (o instanceof String) {\r
148                         String s = (String) o;\r
149                         if (s.isEmpty())\r
150                                 return 0;\r
151                         return Double.valueOf((String) o);\r
152                 } else {\r
153                         return Double.NaN;\r
154                 }\r
155         }\r
156         \r
157         private Object extractSum(Object o1, Object o2) {\r
158                 \r
159                 if(o1 instanceof String) {\r
160                         return o1.toString() + o2;\r
161                 } else if (o2 instanceof String) {\r
162                         return o1.toString() + o2.toString();                   \r
163                 } else if (o1 instanceof Number && o2 instanceof Number) {\r
164                         return ((Number) o1).doubleValue() + ((Number) o2).doubleValue();\r
165                 } else {\r
166                         return o1.toString() + o2.toString();\r
167                 }\r
168                 \r
169         }\r
170 \r
171         public void outAPlusExpression(APlusExpression node) {\r
172                 \r
173                 if(DEBUG) System.out.println("outAPlusExpression " + node);\r
174                 \r
175                 Object o2 = stack.pop();\r
176                 Object o1 = stack.pop();\r
177                 \r
178                 Object out = extractSum(o1, o2);\r
179                 stack.push(out);\r
180                 \r
181         }\r
182 \r
183         public void outAMultMultiplicative(AMultMultiplicative node) {\r
184                 \r
185                 if(DEBUG) System.out.println("outAMultiplicative " + node);\r
186                 \r
187                 Object o1 = stack.pop();\r
188                 Object o2 = stack.pop();\r
189                 double d1 = extractValue(o1);\r
190                 double d2 = extractValue(o2);\r
191                 stack.push(d1 * d2);\r
192                 \r
193         }\r
194 \r
195         int countArguments(PArgList args) {\r
196                 if (args == null)\r
197                         return 0;\r
198                 if (args instanceof ASingleArgList)\r
199                         return 1;\r
200                 ASequenceArgList seq = (ASequenceArgList) args;\r
201                 return 1 + countArguments(seq.getArgList());\r
202         }\r
203 \r
204         public void outAFunctionPrimary(AFunctionPrimary node) {\r
205 \r
206                 if(DEBUG) System.out.println("outAFunctionPrimary " + node);\r
207 \r
208                 try {\r
209 \r
210                         String functionName = node.getFunc().getText().replace("(", "");\r
211 \r
212                         if (DEBUG_APPLICATION)\r
213                             System.out.println("function apply " + functionName);\r
214 \r
215                         Function function = builtins.get(functionName);\r
216                         if (function != null) {\r
217 \r
218                                 LinkedList<Object> args = new LinkedList<Object>();\r
219                                 int argc = countArguments(node.getArgList());\r
220                                 for (int i = 0; i < argc; i++) {\r
221                                         args.addFirst(stack.pop());\r
222                                 }\r
223                                 args.addFirst(formatter);\r
224                                 args.addFirst(variable);\r
225                                 args.addFirst(graph);\r
226 \r
227                                 Object result = function.applyArray(args);\r
228                                 stack.push(format(result));\r
229 \r
230                         } else {\r
231 \r
232                             //    Instances instances = graph.adapt(L0.Function, Instances.class);\r
233                             //    Collection<Resource> functions = instances.find(graph, Variables.getModel(graph, variable),\r
234                             //      "Name:" + functionName);\r
235                             //             if (DEBUG_APPLICATION)\r
236                             //                 System.out.println("Found " + functions.size() + " matches.");\r
237                             //    if (functions != null && functions.size() == 1) {\r
238                                 Layer0 L0 = Layer0.getInstance(graph);\r
239                                 Resource functionResource = null;\r
240                                 Resource indexRoot = graph.sync(new VariableIndexRoot(variable));\r
241                                 if (indexRoot != null) {\r
242                                         Map<String, Resource> functions = graph.syncRequest(\r
243                                                         new ModelInstances(indexRoot, L0.Function),\r
244                                                         TransientCacheListener.<Map<String, Resource>> instance());\r
245                                         functionResource = functions.get(functionName);\r
246                                 }\r
247                                 if(functionResource != null) {\r
248 //                                      Resource functionResource = functions.iterator().next();\r
249                                         function = graph.adapt(functionResource, Function.class);\r
250                                         LinkedList<Object> args = new LinkedList<Object>();\r
251                                         int argc = countArguments(node.getArgList());\r
252                                         for (int i = 0; i < argc; i++) {\r
253                                                 args.addFirst(stack.pop());\r
254                                         }\r
255                                         args.addFirst(formatter);\r
256                                         args.addFirst(variable);\r
257                                         args.addFirst(graph);\r
258                                         Object result = function.applyArray(args.toArray());\r
259                                         stack.push(format(result));\r
260 \r
261                                 } else {\r
262 \r
263                                     //stack.push(null);\r
264                                     throw new EvaluationException("Function not found in dependencies: '" + functionName + "'");\r
265 \r
266                                 }\r
267 \r
268                         }\r
269 \r
270                 } catch (DatabaseException e) {\r
271 \r
272                         stack.push(null);\r
273 \r
274                 }\r
275 \r
276         }\r
277 \r
278 }\r