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