1 package org.simantics.modeling.ui.diagram.monitor;
\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
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
35 public class MonitorExpressionVisitor extends DepthFirstAdapter {
\r
37 public static final boolean DEBUG_APPLICATION = false;
\r
38 public static final boolean DEBUG = false;
\r
40 public static class ApplicationException extends Exception {
\r
42 private static final long serialVersionUID = 1L;
\r
44 public ApplicationException(String message) {
\r
50 final ReadGraph graph;
\r
51 final Variable variable;
\r
52 final Formatter formatter;
\r
54 Stack<Object> stack = new Stack<Object>();
\r
56 HashMap<String, Function> builtins = new HashMap<String, Function>();
\r
58 public MonitorExpressionVisitor(ReadGraph graph, Formatter formatter, Variable variable) {
\r
61 this.formatter = formatter;
\r
62 this.variable = variable;
\r
66 public Object getResult() {
\r
67 if(exception != null) return exception;
\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
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
82 public void outAAddressValue(AAddressValue node) {
\r
83 if(DEBUG) System.out.println("outAAddressValue " + node);
\r
84 stack.push('&' + node.getRange().toString());
\r
88 public void outASingleRange(ASingleRange node) {
\r
90 if(DEBUG) System.out.println("outASingleRange " + node);
\r
95 public void outARviValue(ARviValue node) {
\r
97 if(DEBUG) System.out.println("outARviValue " + node);
\r
99 String rvi = node.toString().trim();
\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
112 public void outAVariablePrimary(AVariablePrimary node) {
\r
114 if(DEBUG) System.out.println("outAVariablePrimary " + node);
\r
116 String identifier = node.toString().trim();
\r
117 if("value".equals(identifier)) {
\r
119 stack.push(format(variable.getValue(graph)));
\r
120 } catch (DatabaseException e) {
\r
124 stack.push(identifier);
\r
129 public void outARangeValue(ARangeValue node) {
\r
131 if(DEBUG) System.out.println("outARangeValue " + node);
\r
133 String identifier = node.getRange().toString().trim();
\r
134 stack.push(identifier);
\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
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
151 return Double.valueOf((String) o);
\r
157 private Object extractSum(Object o1, Object o2) {
\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
166 return o1.toString() + o2.toString();
\r
171 public void outAPlusExpression(APlusExpression node) {
\r
173 if(DEBUG) System.out.println("outAPlusExpression " + node);
\r
175 Object o2 = stack.pop();
\r
176 Object o1 = stack.pop();
\r
178 Object out = extractSum(o1, o2);
\r
183 public void outAMultMultiplicative(AMultMultiplicative node) {
\r
185 if(DEBUG) System.out.println("outAMultiplicative " + node);
\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
195 int countArguments(PArgList args) {
\r
198 if (args instanceof ASingleArgList)
\r
200 ASequenceArgList seq = (ASequenceArgList) args;
\r
201 return 1 + countArguments(seq.getArgList());
\r
204 public void outAFunctionPrimary(AFunctionPrimary node) {
\r
206 if(DEBUG) System.out.println("outAFunctionPrimary " + node);
\r
210 String functionName = node.getFunc().getText().replace("(", "");
\r
212 if (DEBUG_APPLICATION)
\r
213 System.out.println("function apply " + functionName);
\r
215 Function function = builtins.get(functionName);
\r
216 if (function != null) {
\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
223 args.addFirst(formatter);
\r
224 args.addFirst(variable);
\r
225 args.addFirst(graph);
\r
227 Object result = function.applyArray(args);
\r
228 stack.push(format(result));
\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
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
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
263 //stack.push(null);
\r
264 throw new EvaluationException("Function not found in dependencies: '" + functionName + "'");
\r
270 } catch (DatabaseException e) {
\r