]> gerrit.simantics Code Review - simantics/platform.git/blob
52b7cab5cea0e542218d1a4ec666a0dbf7232f09
[simantics/platform.git] /
1 package org.simantics.spreadsheet.graph;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.ObjectOutputStream;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.simantics.Simantics;
16 import org.simantics.databoard.Bindings;
17 import org.simantics.databoard.binding.mutable.Variant;
18 import org.simantics.databoard.util.binary.RandomAccessBinary;
19 import org.simantics.datatypes.DatatypeResource;
20 import org.simantics.datatypes.literal.Font;
21 import org.simantics.datatypes.literal.RGB;
22 import org.simantics.datatypes.utils.BTree;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.WriteGraph;
26 import org.simantics.db.common.request.BinaryRead;
27 import org.simantics.db.common.request.ObjectsWithType;
28 import org.simantics.db.common.request.UnaryRead;
29 import org.simantics.db.common.utils.LiteralFileUtil;
30 import org.simantics.db.exception.DatabaseException;
31 import org.simantics.db.exception.ServiceException;
32 import org.simantics.db.layer0.util.Layer0Utils;
33 import org.simantics.db.layer0.variable.Variable;
34 import org.simantics.db.layer0.variable.Variables;
35 import org.simantics.db.procedure.Listener;
36 import org.simantics.db.service.ClusteringSupport;
37 import org.simantics.layer0.Layer0;
38 import org.simantics.scl.runtime.tuple.Tuple2;
39 import org.simantics.simulator.toolkit.StandardRealm;
40 import org.simantics.spreadsheet.ExternalRef;
41 import org.simantics.spreadsheet.Range;
42 import org.simantics.spreadsheet.Spreadsheets;
43 import org.simantics.spreadsheet.graph.synchronization.SpreadsheetSynchronizationEventHandler;
44 import org.simantics.spreadsheet.resource.SpreadsheetResource;
45 import org.simantics.spreadsheet.solver.SheetNode;
46 import org.simantics.spreadsheet.solver.SpreadsheetBook;
47 import org.simantics.spreadsheet.solver.SpreadsheetEngine;
48 import org.simantics.spreadsheet.solver.SpreadsheetLine;
49 import org.simantics.spreadsheet.solver.SpreadsheetStyle;
50 import org.simantics.spreadsheet.util.SpreadsheetUtils;
51 import org.simantics.structural.synchronization.client.Synchronizer;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import gnu.trove.iterator.TObjectIntIterator;
56 import gnu.trove.map.hash.TObjectIntHashMap;
57
58 public class SpreadsheetGraphUtils {
59
60     private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetGraphUtils.class);
61
62     public static File extractInitialCondition(ReadGraph graph, Resource ic) throws DatabaseException, IOException {
63
64         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
65
66         File temp = Simantics.getTempfile("excel","ic");
67
68         LiteralFileUtil.copyRandomAccessBinaryToFile(graph, ic, SR.InitialCondition_bytes, temp);
69         if (temp.length() == 0)
70             throw new FileNotFoundException("Snapshot file does not exist.\nThis seems to be a database bug that manifests as total loss of state file data.\nThis error prevents the program from crashing.");
71
72         return temp;
73         
74     }
75         
76     public static RandomAccessBinary getOrCreateRandomAccessBinary(WriteGraph graph, Resource initialCondition) throws DatabaseException, IOException {
77
78         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
79         
80         // We put snapshot literals in their own clusters for now just to be safe
81         Resource literal = graph.getPossibleObject(initialCondition, SR.InitialCondition_bytes);
82         if (literal != null) {
83             RandomAccessBinary rab = graph.getRandomAccessBinary(literal);
84             rab.position(0);
85             rab.removeBytes(rab.length(), RandomAccessBinary.ByteSide.Right);
86             return rab;
87         } else {
88             Layer0 L0 = Layer0.getInstance(graph);
89             ClusteringSupport cs = graph.getService(ClusteringSupport.class);
90             literal = graph.newResource(cs.createCluster());
91             graph.claim(literal, L0.InstanceOf, null, L0.ByteArray);
92             graph.claim(initialCondition, SR.InitialCondition_bytes, SR.InitialCondition_bytes_Inverse, literal);
93             return graph.createRandomAccessBinary(literal, Bindings.BYTE_ARRAY.type(), null);
94         }
95     }
96
97     public static Resource saveInitialCondition(WriteGraph graph, Variable run, Resource container, String name) throws DatabaseException {
98
99                 String sessionName = run.getParent(graph).getURI(graph);
100
101                 Resource bookResource = run.getRepresents(graph);
102                 
103         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
104         SpreadsheetBook book = realm.getEngine();
105
106         try {
107         
108                 File temp = Simantics.getTempfile("excel", "ic");
109                 System.err.println("Saving initial condition to " + temp.getAbsolutePath());
110                 
111                         FileOutputStream fileOut = new FileOutputStream(temp);
112                         ObjectOutputStream out = new ObjectOutputStream(fileOut);
113                         out.writeObject(book);
114                         out.close();
115                         fileOut.close();
116                         
117                         Layer0 L0 = Layer0.getInstance(graph);
118                 SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
119                         Resource ic = graph.newResource();
120                         graph.claim(ic, L0.InstanceOf, SR.InitialCondition);
121                         graph.addLiteral(ic, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);
122                 
123                 RandomAccessBinary rab = getOrCreateRandomAccessBinary(graph, ic);
124                 LiteralFileUtil.copyRandomAccessBinaryFromFile(temp, rab);
125                 
126                         graph.claim(container, L0.ConsistsOf, L0.PartOf, ic);
127                         
128                         graph.deny(bookResource, SR.HasInitialCondition);
129                         graph.claim(bookResource, SR.HasInitialCondition, ic);
130                         graph.claim(ic, SR.InitialCondition_ConditionOf, bookResource);
131                         
132                         setDefaultInitialConditionForBook(graph, bookResource, ic);
133
134                 return ic;
135                 
136         } catch (IOException e) {
137                 
138                 throw new DatabaseException(e);
139                 
140         }
141     }
142     
143     public static void setDefaultInitialConditionForBook(WriteGraph graph, Resource book, Resource ic) throws ServiceException {
144         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
145         graph.deny(book, SR.Book_HasDefaultInitialCondition);
146         graph.claim(ic, SR.InitialCondition_DefaultConditionOf, book);
147     }
148
149     public static void evaluateAll(ReadGraph graph, Variable run) throws DatabaseException {
150
151                 String sessionName = run.getParent(graph).getURI(graph);
152         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
153         SpreadsheetBook book = realm.getEngine();
154         book.accept(new EvaluateAll(book));
155         
156     }
157
158     public static void invalidateAll(ReadGraph graph, Variable run) throws DatabaseException {
159
160                 String sessionName = run.getParent(graph).getURI(graph);
161         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
162         SpreadsheetBook book = realm.getEngine();
163         book.accept(new InvalidateAll());
164         realm.getNodeManager().refreshVariables();
165         
166     }
167     
168     public static boolean fullSynchronization(ReadGraph graph, Variable run) throws DatabaseException {
169         return partialSynchronization(graph, run, null);
170     }
171
172     public static boolean partialSynchronization(ReadGraph graph, Variable run, TObjectIntHashMap<Variable> changeFlags) throws DatabaseException {
173
174         Synchronizer synchronizer = new Synchronizer(graph);
175                 String sessionName = run.getParent(graph).getURI(graph);
176                 
177         Resource bookResource = run.getRepresents(graph);
178         Variable configuration = Variables.getVariable(graph, bookResource);
179         
180         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
181         SpreadsheetBook book = realm.getEngine();
182                         
183         SpreadsheetSynchronizationEventHandler handler = new SpreadsheetSynchronizationEventHandler(graph, book);
184         
185         if (changeFlags == null) {
186             synchronizer.fullSynchronization(configuration, handler);
187         } else {
188             
189             TObjectIntIterator<Variable> iter = changeFlags.iterator();
190             iter.advance();
191             Variable row = iter.key();
192             
193             Variable rowParent = row.getParent(graph);
194             while (!rowParent.equals(configuration)) {
195                 changeFlags.put(rowParent, 1);
196                 rowParent = rowParent.getParent(graph);
197             }
198             
199             changeFlags.put(configuration, 1);
200             
201             synchronizer.partialSynchronization(configuration, handler, changeFlags);
202         }
203         
204         realm.getNodeManager().fireNodeListeners();
205         return handler.getDidChanges();
206         
207     }
208
209     public static Variable findCell(ReadGraph graph, Variable run, String reference) throws DatabaseException {
210
211         int pos = reference.indexOf("!");
212         String sheetName = reference.substring(0, pos);
213         String cellName = reference.substring(pos+1);
214
215                 String sessionName = run.getParent(graph).getURI(graph);
216         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
217         SpreadsheetBook book = realm.getEngine();
218         SpreadsheetEngine engine = book.getEngine(sheetName);
219         if(engine == null) return null;
220         
221         Range r = Spreadsheets.decodeCellAbsolute(cellName);
222         SpreadsheetLine line = engine.getLine(r.startRow);
223         if(line == null) return null;
224         
225         String path = line.getPath();
226         if(path == null) return null;
227         
228         Variable lineVariable = run.browse(graph, path);
229         if(lineVariable==null) return null;
230         
231         return lineVariable.getChild(graph, cellName);
232         
233     }
234
235     
236
237     public static List<Variable> possibleConfigurationCellVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {
238         List<Variable> rowVariables = possibleConfigurationLineVariables(graph, sheet, range);
239         List<Variable> result = new ArrayList<>();
240         for (Variable variable : rowVariables) {
241             Collection<Variable> children = variable.getChildren(graph);
242             for (Variable child : children) {
243                 if (variableInRange(graph, child, range)) {
244                     result.add(child);
245                 }
246             }
247         }
248         return result;
249     }
250     
251     public static Map<Integer, Resource> possibleConfigurationLineResources(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {
252         Variable lines = sheet.getPossibleChild(graph, "Lines");
253         if (lines == null)
254             throw new DatabaseException("Invalid input variable " + sheet.getURI(graph));
255         Resource linesR = lines.getRepresents(graph);
256         BTree bt = new BTree(graph, linesR);
257         List<Tuple2> tuples = bt.searchRangeBTree(graph, Variant.ofInstance(range.startRow), Variant.ofInstance(range.endRow));
258         Map<Integer, Resource> result = new HashMap<>(tuples.size());
259         for (Tuple2 tuple : tuples) {
260             Integer lineNumber = (Integer)((Variant)tuple.c0).getValue();
261             Resource resource = (Resource)tuple.c1;
262             result.put(lineNumber, resource);
263         }
264         return result; 
265     }
266     
267     public static List<Variable> possibleConfigurationLineVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {
268         Map<Integer, Resource> rows = possibleConfigurationLineResources(graph, sheet, range);
269         List<Variable> result = new ArrayList<>(rows.size());
270         for (Resource row: rows.values()) {
271             Variable lineVar = Variables.getPossibleVariable(graph, row);
272             if (lineVar != null)
273                 result.add(lineVar);
274         }
275         return result;
276     }
277     
278     public static List<Variable> possibleRunLineVariables(ReadGraph graph, Variable sheetRun, Range range) throws DatabaseException {
279         
280         Variable run = sheetRun.getParent(graph);
281         
282         String sheetName = sheetRun.getName(graph);
283         String sessionName = run.getParent(graph).getURI(graph);
284         
285         StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
286         SpreadsheetBook book = realm.getEngine();
287         
288         SpreadsheetEngine engine = book.getEngine(sheetName);
289         if(engine == null) return null;
290         
291         List<Variable> result = new ArrayList<>();
292         
293         int end = range.endRow < engine.lines.getMaxRow() ? range.endRow : engine.lines.getMaxRow();
294         for (int i = range.startRow; i <= end; i++) {
295                 SpreadsheetLine line = engine.getLine(i);
296                 if(line == null)
297                         continue;
298                 
299                 String path = line.getPath();
300                 path = line.getPath();
301                 if(path == null)
302                         continue;
303                 
304                 Variable lineVariable = run.browse(graph, path);
305                 if(lineVariable==null)
306                         continue;
307                 result.add(lineVariable);
308         }
309     
310         return result;
311     }
312     
313     public static List<Variable> possibleRunCellVariables(ReadGraph graph, Variable sheetRun, Range range) throws DatabaseException {
314         List<Variable> runLineVariable = possibleRunLineVariables(graph, sheetRun, range);
315         List<Variable> result = new ArrayList<>();
316         for (Variable variable : runLineVariable) {
317 //              System.out.println("line: " + variable.getURI(graph));
318             for (Variable child : variable.getChildren(graph)) {
319 //              System.out.print("cell : " + child.getURI(graph));
320                 if (variableInRange(graph, child, range)) {
321                     result.add(child);
322                 }
323             }
324         }
325         return result;
326     }
327     
328     private static boolean variableInRange(ReadGraph graph, Variable child, Range range) throws DatabaseException {
329         String name = child.getName(graph);
330         Range childRange = Spreadsheets.decodeCellAbsolute(name);
331 //        System.out.print(" and range " + childRange);
332         if (childRange != null && range.contains(childRange)) {
333 //              System.out.println(" => range.contains(childRange) = true");
334             return true;
335         }
336 //        System.out.println();
337         return false;
338     }
339     
340     public static Map<Integer, Resource> createConfigurationLineResources(WriteGraph graph, Variable sheet, Range range) throws DatabaseException {
341         Layer0 L0 = Layer0.getInstance(graph);
342         SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
343         
344         Variable lines = sheet.getPossibleChild(graph, "Lines");
345         if (lines == null)
346             throw new DatabaseException("Invalid input variable " + sheet.getURI(graph));
347         Resource linesR = lines.getRepresents(graph);
348         BTree bt = new BTree(graph, linesR);
349         
350         Map<Integer, Resource> result = new HashMap<>();
351         for (int lineNumber = range.startRow; lineNumber <= range.endRow; lineNumber++) {
352             Resource line = graph.newResource();
353             graph.claim(line, L0.InstanceOf, null, SHEET.Line);
354             graph.claimLiteral(line, L0.HasName, L0.NameOf, L0.String, "Row" + lineNumber, Bindings.STRING);
355             bt.insertBTree(graph, Variant.ofInstance(lineNumber), line);
356             result.put(lineNumber, line);
357         }
358         return result;
359     }
360
361     public static List<Variable> getOrCreateConfigurationCellVariables(WriteGraph graph, Variable sheet, Range range) throws DatabaseException {
362         
363         List<Variable> rows = possibleConfigurationLineVariables(graph, sheet, range);
364         if (rows.isEmpty()) {
365             createConfigurationLineResources(graph, sheet, range);
366             rows = possibleConfigurationLineVariables(graph, sheet, range);
367         }
368         
369         List<Variable> cells = possibleConfigurationCellVariables(graph, sheet, range);
370         if (cells.isEmpty()) {
371             Iterator<Variable> rowIterator = rows.iterator();
372             for (int rowNumber = range.startRow; rowNumber <= range.endRow; rowNumber++) {
373                 Variable row = rowIterator.next();
374                 for (int colNumber = range.startColumn; colNumber <= range.endColumn; colNumber++) {
375                     String location = Spreadsheets.cellName(rowNumber, colNumber);
376                     defaultCreateCell(graph, row, location, new Variant(Bindings.STRING, ""));
377                 }
378             }
379         }
380         
381         cells = possibleConfigurationCellVariables(graph, sheet, range);
382         if(cells.isEmpty())
383             throw new DatabaseException("Unexpected problem while creating spreadsheet cell at '" + range + "'");
384         
385         return cells;
386     }
387     
388     private static void defaultCreateCell(WriteGraph graph, Variable parent, String location, Variant value) throws DatabaseException {
389
390         Layer0 L0 = Layer0.getInstance(graph);
391         SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
392         Resource container = parent.getRepresents(graph);
393         
394         Resource cell = graph.newResource();
395         graph.claim(cell, L0.InstanceOf, null, SHEET.TextCell);
396         graph.addLiteral(cell, L0.HasName, L0.NameOf, L0.String, location, Bindings.STRING);
397         graph.addLiteral(cell, SHEET.Cell_content, SHEET.Cell_content_Inverse, L0.Variant, value, Bindings.VARIANT);
398         graph.claim(cell, L0.PartOf, container);
399         
400         Resource book = Variables.getContext(graph, parent).getRepresents(graph);
401         
402         
403         Collection<Resource> objects = graph.sync(new ObjectsWithType(book, L0.ConsistsOf, SHEET.Style));
404         
405         int styleId = SpreadsheetStyle.empty().getStyleId();
406         Resource style = null;
407         for (Resource possibleStyle : objects) {
408             int possibleStyleId = graph.getRelatedValue2(possibleStyle, SHEET.Style_id, Bindings.INTEGER);
409             if (possibleStyleId == styleId) {
410                 style = possibleStyle;
411                 break;
412             }
413         }
414         
415         if (style == null) {
416             style = graph.newResource();
417             graph.claim(style, L0.InstanceOf, null, SHEET.Style);
418             graph.claim(style, L0.PartOf, book);
419             
420             int id = objects.size();
421             graph.claimLiteral(style, L0.HasName, "Style_" + id);
422             graph.claimLiteral(style, SHEET.Style_id, styleId, Bindings.INTEGER);
423         }
424         graph.claim(cell, SHEET.Cell_HasStyle, style);
425         Layer0Utils.addCommentMetadata(graph, "Created cell on location " + location + " with value " + value.toString());
426     }
427
428     public static Resource createStyle(WriteGraph graph, Resource book, SpreadsheetStyle sstyle) throws DatabaseException {
429         Layer0 L0 = Layer0.getInstance(graph);
430         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
431         Resource style = graph.newResource();
432         graph.claim(style, L0.InstanceOf, null, SR.Style);
433         graph.claim(style, L0.PartOf, book);
434         
435         int styleId = sstyle.getStyleId();
436         String styleName = sstyle.name;
437         
438         graph.claimLiteral(style, L0.HasName, styleName);
439         //System.err.println("CREATING STYLE " + styleName + " WITH ID: " + styleId);
440         graph.claimLiteral(style, SR.Style_id, styleId, Bindings.INTEGER);
441         
442         DatatypeResource DATATYPES = DatatypeResource.getInstance(graph);
443         if (sstyle.foreground != null)
444             graph.claimLiteral(style, SR.Cell_foreground, DATATYPES.RGB_Integer, sstyle.foreground, RGB.Integer.BINDING);
445         if (sstyle.background != null)
446             graph.claimLiteral(style, SR.Cell_background, DATATYPES.RGB_Integer, sstyle.background, RGB.Integer.BINDING);
447         if (sstyle.align != -1)
448             graph.claimLiteral(style, SR.Cell_align, sstyle.align, Bindings.INTEGER);
449         if (sstyle.font != null)
450             graph.claimLiteral(style, SR.Cell_font, DATATYPES.Font, sstyle.font, Font.BINDING);
451         if (sstyle.border != -1)
452             graph.claimLiteral(style, SR.Cell_border, sstyle.border);
453         if (sstyle.formatString != null && !sstyle.formatString.isEmpty())
454             graph.claimLiteral(style, SR.Cell_formatString, sstyle.formatString, Bindings.STRING);
455         if (sstyle.formatIndex != -1)
456             graph.claimLiteral(style, SR.Cell_formatIndex, sstyle.formatIndex, Bindings.INTEGER);
457         
458         return style;
459     }
460     
461     public static Resource createBook(WriteGraph graph, Resource parent, String name) throws DatabaseException {
462         Layer0 L0 = Layer0.getInstance(graph);
463         SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
464         Resource book = graph.newResource();
465         graph.claim(book, L0.InstanceOf, SR.Book);
466         graph.claimLiteral(book, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);
467         graph.claim(parent, L0.ConsistsOf, book);
468         
469         return book;
470     }
471     
472     public static Variable constructAndInitializeRunVariable(WriteGraph graph, Resource root) throws DatabaseException {
473         Variable run = SpreadsheetUtils.getBookVariable(graph, root);
474         SpreadsheetGraphUtils.fullSynchronization(graph, run);
475         SpreadsheetGraphUtils.evaluateAll(graph, run);
476         SpreadsheetGraphUtils.saveInitialCondition(graph, run, root, "Initial");
477         return run;
478     }
479     
480     public static Variant extRefVariable(ReadGraph graph, Variable var) throws DatabaseException {
481         return new Variant(Bindings.VOID, new ExternalRefVariable(graph, var));
482     }
483     
484     static class ExternalRefVariable implements ExternalRef {
485
486         final private String uri;
487         
488         public ExternalRefVariable(ReadGraph graph, Variable variable) throws DatabaseException {
489             this.uri = variable.getURI(graph);
490         }
491         
492         @Override
493         public void listen(Object context, ExternalRefListener listener) {
494             Simantics.getSession().asyncRequest(new UnaryRead<String, Variant>(uri) {
495
496                 @Override
497                 public Variant perform(ReadGraph graph) throws DatabaseException {
498                     Variable variable = Variables.getVariable(graph, parameter);
499                     return variable.getVariantValue(graph);
500                 }
501                 
502             }, new Listener<Variant>() {
503
504                 @Override
505                 public void execute(Variant result) {
506                     listener.newValue(result);
507                 }
508
509                 @Override
510                 public void exception(Throwable t) {
511                     LOGGER.error("Error while evaluating variable value", t);
512                 }
513
514                 @Override
515                 public boolean isDisposed() {
516                     return listener.isDisposed();
517                 }
518                 
519             });
520         }
521         
522     }
523
524     public static Variant extRefActiveVariable(ReadGraph graph, Variable var) throws DatabaseException {
525         return new Variant(Bindings.VOID, new ExternalRefActiveVariable(graph, var));
526     }
527     
528     static class ExternalRefActiveVariable implements ExternalRef {
529
530         final private String uri;
531         
532         public ExternalRefActiveVariable(ReadGraph graph, Variable variable) throws DatabaseException {
533             this.uri = variable.getURI(graph);
534         }
535         
536         @Override
537         public void listen(Object context, ExternalRefListener listener) {
538             Simantics.getSession().asyncRequest(new BinaryRead<String, String, Variant>((String)context, uri) {
539
540                 @Override
541                 public Variant perform(ReadGraph graph) throws DatabaseException {
542                     Variable contextVariable = Variables.getVariable(graph, parameter);
543                     Variable configVariable = Variables.getVariable(graph, parameter2);
544                     Variable activeVariable = Variables.switchPossibleContext(graph, configVariable, contextVariable.getRepresents(graph));
545                     return activeVariable.getVariantValue(graph);
546                 }
547             }, new Listener<Variant>() {
548
549                 @Override
550                 public void execute(Variant result) {
551                     listener.newValue(result);
552                 }
553
554                 @Override
555                 public void exception(Throwable t) {
556                     LOGGER.error("Error while evaluating variable value", t);
557                 }
558
559                 @Override
560                 public boolean isDisposed() {
561                     return listener.isDisposed();
562                 }
563                 
564             });
565         }
566         
567     }
568     
569 }