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