1 package org.simantics.spreadsheet.graph.request;
\r
3 import java.util.ArrayList;
\r
4 import java.util.Collection;
\r
5 import java.util.HashMap;
\r
6 import java.util.LinkedList;
\r
7 import java.util.Stack;
\r
9 import org.simantics.basicexpression.analysis.DepthFirstAdapter;
\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.db.ReadGraph;
\r
24 import org.simantics.db.Resource;
\r
25 import org.simantics.db.exception.DatabaseException;
\r
26 import org.simantics.db.layer0.adapter.Function;
\r
27 import org.simantics.db.layer0.adapter.Instances;
\r
28 import org.simantics.db.layer0.variable.Variable;
\r
29 import org.simantics.db.layer0.variable.Variables;
\r
30 import org.simantics.layer0.Layer0;
\r
31 import org.simantics.spreadsheet.Range;
\r
32 import org.simantics.spreadsheet.util.SpreadsheetUtils;
\r
34 public class SpreadsheetExpressionVisitor extends DepthFirstAdapter {
\r
36 public static final boolean DEBUG_APPLICATION = false;
\r
37 public static final boolean DEBUG = false;
\r
39 public static class ApplicationException extends Exception {
\r
41 private static final long serialVersionUID = 1L;
\r
43 public ApplicationException(String message) {
\r
49 final ReadGraph graph;
\r
50 final Variable cellVariable;
\r
51 final Resource model;
\r
52 final Resource sheet;
\r
55 // final EvaluationEnvironmentImpl env;
\r
56 Stack<Object> stack = new Stack<Object>();
\r
58 HashMap<String, Function> builtins = new HashMap<String, Function>();
\r
60 // class EvaluationEnvironmentImpl implements EvaluationEnvironment {
\r
62 // private boolean ready = false;
\r
63 // private boolean valid = true;
\r
64 // public HashSet<Range> deps = new HashSet<Range>();
\r
68 // public int getColumn() {
\r
73 // public Model getModel() {
\r
78 // public int getRow() {
\r
82 // public void depend(Range range) {
\r
86 // public void listen() {
\r
91 // public void invalidate() {
\r
92 // // DependencyHandler handler = model.getAdapter(DependencyHandler.class);
\r
93 // // handler.invalidate(row, column);
\r
94 // if(!ready) return;
\r
96 // ThreadUtils.getNonBlockingWorkExecutor().execute(new Runnable() {
\r
99 // public void run() {
\r
101 // Cell cell = model.get(row, column);
\r
102 // UpdateHandler handler = cell.getAdapter(UpdateHandler.class);
\r
103 // if(handler != null) handler.update();
\r
112 // public boolean isDisposed() {
\r
118 public SpreadsheetExpressionVisitor(ReadGraph graph, Variable cellVariable, int row, int column) throws DatabaseException {
\r
120 // assert(model != null);
\r
121 // // assert(graph != null);
\r
122 // // assert(sheet != null);
\r
123 this.graph = graph;
\r
124 this.cellVariable = cellVariable;
\r
125 this.model = Variables.getModel(graph, cellVariable);
\r
126 Resource cell = cellVariable.getPossiblePropertyValue(graph, Variables.RESOURCE);
\r
127 this.sheet = graph.getPossibleObject(cell, Layer0.getInstance(graph).PartOf);
\r
128 // this.sheet = sheet;
\r
129 // this.model = model;
\r
131 this.column = column;
\r
133 // builtins.put("Sequence", new Sequence());
\r
134 // builtins.put("Set", new Set());
\r
135 // builtins.put("SetBlock", new SetBlock());
\r
136 // builtins.put("Sum", new Sum());
\r
137 // builtins.put("Naturals", new Naturals());
\r
139 // env = new EvaluationEnvironmentImpl();
\r
142 // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
\r
144 // builtins.put("SUBSCRIPT", new Runnable() {
\r
147 // public void run() {
\r
151 // int column = ((Double)stack.pop()).intValue();
\r
152 // int row = ((Double)stack.pop()).intValue();
\r
153 // Object value = stack.pop();
\r
155 // //System.out.println("subscript(value=" + value + " row=" + row +
\r
156 // " column=" + column + ")");
\r
158 // if(value instanceof Collection) {
\r
159 // stack.push(((Collection)value).toArray()[row]);
\r
162 // } catch (Throwable t) {
\r
163 // t.printStackTrace();
\r
172 public Object getResult() {
\r
173 return stack.pop();
\r
176 public void outAConstantValue(AConstantValue node) {
\r
177 if(DEBUG) System.out.println("outAConstantValue " + node);
\r
178 stack.push(Double.valueOf(node.toString()));
\r
181 public void outAStringValue(AStringValue node) {
\r
182 if(DEBUG) System.out.println("outAStringValue " + node);
\r
183 String value = node.toString();
\r
184 stack.push(value.substring(1, value.length() - 2).trim());
\r
187 public void outAAddressValue(AAddressValue node) {
\r
188 if(DEBUG) System.out.println("outAAddressValue " + node);
\r
189 stack.push('&' + node.getRange().toString());
\r
193 public void outASingleRange(ASingleRange node) {
\r
195 if(DEBUG) System.out.println("outASingleRange " + node);
\r
200 public void outARviValue(ARviValue node) {
\r
202 if(DEBUG) System.out.println("outARviValue " + node);
\r
204 String rvi = node.toString().trim();
\r
207 System.out.println("browsing at " + cellVariable.getURI(graph));
\r
208 Variable var = cellVariable.browse(graph, rvi);
\r
210 } catch (DatabaseException e) {
\r
211 e.printStackTrace();
\r
217 public void outAVariablePrimary(AVariablePrimary node) {
\r
219 if(DEBUG) System.out.println("outAVariablePrimary " + node);
\r
221 String identifier = node.toString().trim();
\r
223 Range range = SpreadsheetUtils.decodeRange(identifier, row, column);
\r
224 if (range.size() != 1) {
\r
225 ArrayList<Object> value = new ArrayList<Object>();
\r
226 for (int c = range.startColumn; c <= range.endColumn; c++) {
\r
227 for (int r = range.startRow; r <= range.endRow; r++) {
\r
229 String location = SpreadsheetUtils.cellName(r, c);
\r
230 Variable cell = cellVariable.getChild(graph, location);
\r
231 System.out.println("cell=" + cell.getURI(graph));
\r
232 String label = cell.getPossiblePropertyValue(graph, "Label");
\r
233 System.out.println("lavel=" + label);
\r
235 } catch (DatabaseException e) {
\r
241 // System.out.println("pushing " + value);
\r
246 // String location = SpreadsheetUtils.cellName(range.startRow,
\r
247 // range.startColumn);
\r
248 // stack.push(graph.syncRequest(new CellResult(sheet, model, location)));
\r
249 // } catch (DatabaseException e) {
\r
250 // stack.push(null);
\r
255 public void outARangeValue(ARangeValue node) {
\r
257 if(DEBUG) System.out.println("outARangeValue " + node);
\r
259 String identifier = node.getRange().toString().trim();
\r
262 // Range range = SpreadsheetUtils.decodeRange(identifier, row, column);
\r
263 // // env.depend(range);
\r
264 // if (range.size() != 1) {
\r
265 // ArrayList<Object> value = new ArrayList<Object>();
\r
266 // for (int c = range.startColumn; c <= range.endColumn; c++) {
\r
267 // for (int r = range.startRow; r <= range.endRow; r++) {
\r
269 // String location = SpreadsheetUtils.cellName(r, c);
\r
272 // .syncRequest(new CellResult(sheet, model, location)));
\r
273 // } catch (DatabaseException e) {
\r
274 // value.add(null);
\r
278 // stack.push(value);
\r
279 // // System.out.println("pushing " + value);
\r
284 // String location = SpreadsheetUtils.cellName(range.startRow,
\r
285 // range.startColumn);
\r
286 // stack.push(graph.syncRequest(new CellResult(sheet, model, location)));
\r
287 // } catch (DatabaseException e) {
\r
288 // stack.push(null);
\r
293 private double extractValue(Object o) {
\r
294 if (o instanceof Number) {
\r
295 return ((Number) o).doubleValue();
\r
296 } else if (o instanceof String) {
\r
297 return Double.valueOf((String) o);
\r
303 public void outAPlusExpression(APlusExpression node) {
\r
305 if(DEBUG) System.out.println("outAPlusExpression " + node);
\r
307 Object o1 = stack.pop();
\r
308 Object o2 = stack.pop();
\r
309 double d1 = extractValue(o1);
\r
310 double d2 = extractValue(o2);
\r
311 stack.push(d1 + d2);
\r
312 // System.out.println("plus " + d1 + " " + d2);
\r
315 public void outAMultMultiplicative(AMultMultiplicative node) {
\r
317 if(DEBUG) System.out.println("outAMultiplicative " + node);
\r
319 Object o1 = stack.pop();
\r
320 Object o2 = stack.pop();
\r
321 double d1 = extractValue(o1);
\r
322 double d2 = extractValue(o2);
\r
323 stack.push(d1 * d2);
\r
324 // System.out.println("mult " + d1 + " " + d2);
\r
327 int countArguments(PArgList args) {
\r
330 if (args instanceof ASingleArgList)
\r
332 ASequenceArgList seq = (ASequenceArgList) args;
\r
333 return 1 + countArguments(seq.getArgList());
\r
336 public void outAFunctionPrimary(AFunctionPrimary node) {
\r
338 if(DEBUG) System.out.println("outAFunctionPrimary " + node);
\r
342 String functionName = node.getFunc().getText().replace("(", "");
\r
344 if (DEBUG_APPLICATION)
\r
345 System.out.println("function apply " + functionName);
\r
347 Function function = builtins.get(functionName);
\r
348 if (function != null) {
\r
350 LinkedList<Object> args = new LinkedList<Object>();
\r
351 int argc = countArguments(node.getArgList());
\r
352 for (int i = 0; i < argc; i++) {
\r
353 args.addFirst(stack.pop());
\r
355 args.addFirst(sheet);
\r
356 args.addFirst(model);
\r
358 Object result = function.apply(graph, args);
\r
359 stack.push(result);
\r
363 Layer0 L0 = Layer0.getInstance(graph);
\r
364 Instances instances = graph.adapt(L0.Function, Instances.class);
\r
365 Collection<Resource> functions = instances.find(graph, model,
\r
366 "Name:" + functionName);
\r
367 if (DEBUG_APPLICATION)
\r
368 System.out.println("Found " + functions.size() + " matches.");
\r
369 if (functions != null && functions.size() == 1) {
\r
371 Resource functionResource = functions.iterator().next();
\r
372 function = graph.adapt(functionResource, Function.class);
\r
373 LinkedList<Object> args = new LinkedList<Object>();
\r
374 int argc = countArguments(node.getArgList());
\r
375 for (int i = 0; i < argc; i++) {
\r
376 args.addFirst(stack.pop());
\r
378 args.addFirst(cellVariable);
\r
379 //args.addFirst(model);
\r
380 // System.out.println("args=" +
\r
381 // Arrays.toString(args.toArray()));
\r
382 Object result = function.apply(graph, args.toArray());
\r
383 stack.push(result);
\r
393 } catch (DatabaseException e) {
\r