]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/request/SpreadsheetExpressionVisitor.java
Adopt spreadsheet changes made in Balas development
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / request / SpreadsheetExpressionVisitor.java
1 package org.simantics.spreadsheet.graph.request;
2
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;
8
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.Spreadsheets;
33
34 public class SpreadsheetExpressionVisitor extends DepthFirstAdapter {
35
36     public static final boolean DEBUG_APPLICATION = false;
37     public static final boolean DEBUG = false;
38     
39         public static class ApplicationException extends Exception {
40
41                 private static final long serialVersionUID = 1L;
42
43                 public ApplicationException(String message) {
44                         super(message);
45                 }
46
47         }
48
49         final ReadGraph graph;
50         final Variable cellVariable;
51         final Resource model;
52         final Resource sheet;
53         final int row;
54         final int column;
55         // final EvaluationEnvironmentImpl env;
56         Stack<Object> stack = new Stack<Object>();
57
58         HashMap<String, Function> builtins = new HashMap<String, Function>();
59
60         // class EvaluationEnvironmentImpl implements EvaluationEnvironment {
61         //        
62         // private boolean ready = false;
63         // private boolean valid = true;
64         // public HashSet<Range> deps = new HashSet<Range>();
65         //        
66         //
67         // @Override
68         // public int getColumn() {
69         // return column;
70         // }
71         //
72         // @Override
73         // public Model getModel() {
74         // return model;
75         // }
76         //
77         // @Override
78         // public int getRow() {
79         // return row;
80         // }
81         //        
82         // public void depend(Range range) {
83         // deps.add(range);
84         // }
85         //        
86         // public void listen() {
87         // ready = true;
88         // }
89         //        
90         // @Override
91         // public void invalidate() {
92         // // DependencyHandler handler = model.getAdapter(DependencyHandler.class);
93         // // handler.invalidate(row, column);
94         // if(!ready) return;
95         // valid = false;
96         // ThreadUtils.getNonBlockingWorkExecutor().execute(new Runnable() {
97         //
98         // @Override
99         // public void run() {
100         //
101         // Cell cell = model.get(row, column);
102         // UpdateHandler handler = cell.getAdapter(UpdateHandler.class);
103         // if(handler != null) handler.update();
104         //                    
105         // }
106         //                
107         // });
108         //            
109         // }
110         //        
111         // @Override
112         // public boolean isDisposed() {
113         // return !valid;
114         // }
115         //        
116         // }
117
118         public SpreadsheetExpressionVisitor(ReadGraph graph, Variable cellVariable, int row, int column) throws DatabaseException {
119
120                 // assert(model != null);
121                 // // assert(graph != null);
122                 // // assert(sheet != null);
123                 this.graph = graph;
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;
130                 this.row = row;
131                 this.column = column;
132                 //        
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());
138                 //        
139                 // env = new EvaluationEnvironmentImpl();
140                 //        
141
142                 // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
143                 //          
144                 // builtins.put("SUBSCRIPT", new Runnable() {
145                 //
146                 // @Override
147                 // public void run() {
148                 //                
149                 // try {
150                 //                
151                 // int column = ((Double)stack.pop()).intValue();
152                 // int row = ((Double)stack.pop()).intValue();
153                 // Object value = stack.pop();
154                 //                    
155                 // //System.out.println("subscript(value=" + value + " row=" + row +
156                 // " column=" + column + ")");
157                 //                    
158                 // if(value instanceof Collection) {
159                 // stack.push(((Collection)value).toArray()[row]);
160                 // }
161                 //                    
162                 // } catch (Throwable t) {
163                 // t.printStackTrace();
164                 // }
165                 //                
166                 // }
167                 //              
168                 // });
169
170         }
171
172         public Object getResult() {
173                 return stack.pop();
174         }
175
176         public void outAConstantValue(AConstantValue node) {
177                 if(DEBUG) System.out.println("outAConstantValue " + node);
178                 stack.push(Double.valueOf(node.toString()));
179         }
180
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());
185         }
186
187         public void outAAddressValue(AAddressValue node) {
188                 if(DEBUG) System.out.println("outAAddressValue " + node);
189                 stack.push('&' + node.getRange().toString());
190         }
191
192         @Override
193         public void outASingleRange(ASingleRange node) {
194                 
195                 if(DEBUG) System.out.println("outASingleRange " + node);
196                 
197         }
198         
199         @Override
200         public void outARviValue(ARviValue node) {
201                 
202                 if(DEBUG) System.out.println("outARviValue " + node);
203                 
204                 String rvi = node.toString().trim();
205                 
206                 try {
207                         System.out.println("browsing at " + cellVariable.getURI(graph));
208                         Variable var = cellVariable.browse(graph, rvi);
209                         stack.push(var);
210                 } catch (DatabaseException e) {
211                         e.printStackTrace();
212                 }
213                 
214         }
215         
216         @Override
217         public void outAVariablePrimary(AVariablePrimary node) {
218                 
219                 if(DEBUG) System.out.println("outAVariablePrimary " + node);
220                 
221                 String identifier = node.toString().trim();
222
223                 Range range = Spreadsheets.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++) {
228                                         try {
229                                                 String location = Spreadsheets.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);
234                                                 value.add(label);
235                                         } catch (DatabaseException e) {
236                                                 value.add(null);
237                                         }
238                                 }
239                         }
240                         stack.push(value);
241                         // System.out.println("pushing " + value);
242                         return;
243                 }
244
245 //              try {
246 //                      String location = SpreadsheetUtils.cellName(range.startRow,
247 //                                      range.startColumn);
248 //                      stack.push(graph.syncRequest(new CellResult(sheet, model, location)));
249 //              } catch (DatabaseException e) {
250 //                      stack.push(null);
251 //              }
252                 
253         }
254         
255         public void outARangeValue(ARangeValue node) {
256
257                 if(DEBUG) System.out.println("outARangeValue " + node);
258
259                 String identifier = node.getRange().toString().trim();
260                 // try {
261
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++) {
268 //                                      try {
269 //                                              String location = SpreadsheetUtils.cellName(r, c);
270 //                                              
271 //                                              value.add(graph
272 //                                                              .syncRequest(new CellResult(sheet, model, location)));
273 //                                      } catch (DatabaseException e) {
274 //                                              value.add(null);
275 //                                      }
276 //                              }
277 //                      }
278 //                      stack.push(value);
279 //                      // System.out.println("pushing " + value);
280 //                      return;
281 //              }
282 //
283 //              try {
284 //                      String location = SpreadsheetUtils.cellName(range.startRow,
285 //                                      range.startColumn);
286 //                      stack.push(graph.syncRequest(new CellResult(sheet, model, location)));
287 //              } catch (DatabaseException e) {
288 //                      stack.push(null);
289 //              }
290
291         }
292
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);
298                 } else {
299                         return Double.NaN;
300                 }
301         }
302
303         public void outAPlusExpression(APlusExpression node) {
304                 
305                 if(DEBUG) System.out.println("outAPlusExpression " + node);
306                 
307                 Object o1 = stack.pop();
308                 Object o2 = stack.pop();
309                 double d1 = extractValue(o1);
310                 double d2 = extractValue(o2);
311                 stack.push(d1 + d2);
312                 // System.out.println("plus " + d1 + " " + d2);
313         }
314
315         public void outAMultMultiplicative(AMultMultiplicative node) {
316                 
317                 if(DEBUG) System.out.println("outAMultiplicative " + node);
318                 
319                 Object o1 = stack.pop();
320                 Object o2 = stack.pop();
321                 double d1 = extractValue(o1);
322                 double d2 = extractValue(o2);
323                 stack.push(d1 * d2);
324                 // System.out.println("mult " + d1 + " " + d2);
325         }
326
327         int countArguments(PArgList args) {
328                 if (args == null)
329                         return 0;
330                 if (args instanceof ASingleArgList)
331                         return 1;
332                 ASequenceArgList seq = (ASequenceArgList) args;
333                 return 1 + countArguments(seq.getArgList());
334         }
335
336         public void outAFunctionPrimary(AFunctionPrimary node) {
337
338                 if(DEBUG) System.out.println("outAFunctionPrimary " + node);
339
340                 try {
341
342                         String functionName = node.getFunc().getText().replace("(", "");
343
344                         if (DEBUG_APPLICATION)
345                             System.out.println("function apply " + functionName);
346
347                         Function function = builtins.get(functionName);
348                         if (function != null) {
349
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());
354                                 }
355                                 args.addFirst(sheet);
356                                 args.addFirst(model);
357
358                                 Object result = function.apply(graph, args);
359                                 stack.push(result);
360
361                         } else {
362
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) {
370
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());
377                                         }
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());
383                                         stack.push(result);
384
385                                 } else {
386
387                                         stack.push(null);
388
389                                 }
390
391                         }
392
393                 } catch (DatabaseException e) {
394
395                         stack.push(null);
396
397                 }
398
399         }
400
401 }