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