1 /*******************************************************************************
2 * Copyright (c) 2007, 2018 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.spreadsheet.graph;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
19 import java.util.function.Consumer;
21 import org.eclipse.e4.core.contexts.IEclipseContext;
22 import org.eclipse.e4.ui.di.UISynchronize;
23 import org.eclipse.jface.dialogs.Dialog;
24 import org.eclipse.ui.PlatformUI;
25 import org.simantics.Simantics;
26 import org.simantics.databoard.Bindings;
27 import org.simantics.databoard.binding.Binding;
28 import org.simantics.databoard.binding.mutable.MutableVariant;
29 import org.simantics.databoard.binding.mutable.Variant;
30 import org.simantics.db.AsyncReadGraph;
31 import org.simantics.db.ReadGraph;
32 import org.simantics.db.RequestProcessor;
33 import org.simantics.db.Resource;
34 import org.simantics.db.WriteGraph;
35 import org.simantics.db.common.procedure.adapter.AsyncListenerSupport;
36 import org.simantics.db.common.procedure.adapter.ListenerSupport;
37 import org.simantics.db.common.procedure.adapter.SyncListenerSupport;
38 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
39 import org.simantics.db.common.procedure.single.SingleSetSyncListenerDelegate;
40 import org.simantics.db.common.request.ReadRequest;
41 import org.simantics.db.common.request.ResourceRead;
42 import org.simantics.db.common.request.UnaryRead;
43 import org.simantics.db.common.request.UniqueRead;
44 import org.simantics.db.common.request.WriteRequest;
45 import org.simantics.db.common.request.WriteResultRequest;
46 import org.simantics.db.common.session.SessionEventListenerAdapter;
47 import org.simantics.db.exception.DatabaseException;
48 import org.simantics.db.layer0.request.PossibleURIVariable;
49 import org.simantics.db.layer0.request.VariableName;
50 import org.simantics.db.layer0.request.VariableRead;
51 import org.simantics.db.layer0.variable.ProxyVariables;
52 import org.simantics.db.layer0.variable.Variable;
53 import org.simantics.db.layer0.variable.Variables;
54 import org.simantics.db.procedure.SyncListener;
55 import org.simantics.db.request.Write;
56 import org.simantics.db.service.SessionEventSupport;
57 import org.simantics.layer0.Layer0;
58 import org.simantics.simulator.toolkit.StandardRealm;
59 import org.simantics.spreadsheet.Adaptable;
60 import org.simantics.spreadsheet.CellEditor;
61 import org.simantics.spreadsheet.ClientModel;
62 import org.simantics.spreadsheet.OperationMode;
63 import org.simantics.spreadsheet.SheetCommands;
64 import org.simantics.spreadsheet.Transaction;
65 import org.simantics.spreadsheet.event.model.RemoveCellHandler;
66 import org.simantics.spreadsheet.resource.SpreadsheetResource;
67 import org.simantics.spreadsheet.solver.SheetNode;
68 import org.simantics.spreadsheet.solver.SpreadsheetBook;
69 import org.simantics.ui.selection.WorkbenchSelectionUtils;
70 import org.simantics.utils.datastructures.Pair;
71 import org.simantics.utils.strings.AlphanumComparator;
72 import org.simantics.utils.threads.logger.ITask;
73 import org.simantics.utils.threads.logger.ThreadLogger;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
77 import gnu.trove.map.hash.THashMap;
78 import gnu.trove.map.hash.TObjectIntHashMap;
80 class FilteredVariableProperties extends UnaryRead<Variable, Collection<Pair<String,Variable>>> {
82 final static String CLASSIFICATION = SpreadsheetResource.URIs.Attribute;
84 public FilteredVariableProperties(Variable variable) {
89 public Collection<Pair<String,Variable>> perform(ReadGraph graph) throws DatabaseException {
90 ArrayList<Pair<String,Variable>> result = new ArrayList<Pair<String,Variable>>();
91 for(Variable var : parameter.getProperties(graph, CLASSIFICATION)) {
92 String name = var.getName(graph);
93 String uri = var.getURI(graph);
94 result.add(Pair.make(name, var));
95 Variable expression = var.getPossibleProperty(graph, "expression");
96 if(expression != null)
97 result.add(Pair.make(name + "#expression", expression));
98 Variable editable = var.getPossibleProperty(graph, "editable");
100 result.add(Pair.make(name + "#editable", editable));
107 public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport, SyncListenerSupport {
109 private static final Logger LOGGER = LoggerFactory.getLogger(GraphUI.class);
111 final public static boolean DEBUG = false;
113 final private RequestProcessor processor;
115 private CellEditor<Write> cellEditor;
117 private Variable run;
118 private ClientModel client;
120 private Map<String, PropertyListener> listenerCache = new THashMap<>();
122 public GraphUI(RequestProcessor processor) {
123 this.processor = processor;
126 public void addCell(ReadGraph graph, Pair<String, Variable> child, final ClientModel client) throws DatabaseException {
128 if(DEBUG) System.out.println("GraphUI adds cell " + child.second.getURI(graph));
130 final String childName = child.second.getName(graph);
131 Boolean immutable = child.second.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
132 if(immutable != null && immutable) {
133 Collection<Variable> properties = child.second.getProperties(graph, FilteredVariableProperties.CLASSIFICATION);
134 addProperties(graph, properties, client, childName);
136 PropertyListener listener = listenerCache.get(child.first);
137 if (listener == null) {
138 listener = propertyListener(client, childName);
139 listenerCache.put(child.first, listener);
141 graph.syncRequest(new FilteredVariableProperties(child.second), listener);
146 public void removeCell(ReadGraph graph, Pair<String, Variable> child, final ClientModel client) throws DatabaseException {
148 if(DEBUG) System.out.println("GraphUI removed cell " + child.first);
150 client.clear(child.first);
151 PropertyListener listener = listenerCache.remove(child.first);
152 if (listener != null)
157 public void loadCells(ReadGraph graph, Variable container, boolean immutable, final ClientModel client) throws DatabaseException {
159 if(DEBUG) System.out.println("GraphUI loads cells from " + container.getURI(graph));
162 for(Pair<String, Variable> cell : graph.syncRequest(new Cells(container), TransientCacheAsyncListener.<Collection<Pair<String, Variable>>>instance())) {
163 addCell(graph, cell, client);
166 graph.syncRequest(new Cells(container), new SingleSetSyncListenerDelegate<Pair<String, Variable>>(GraphUI.this) {
169 public void add(ReadGraph graph, final Pair<String, Variable> child) throws DatabaseException {
170 addCell(graph, child, client);
174 public void remove(ReadGraph graph, final Pair<String, Variable> child) throws DatabaseException {
175 removeCell(graph, child, client);
182 private SessionEventListenerAdapter listener;
184 private String currentSource;
186 private boolean disposed;
188 public Resource load(final Variable variable, final ClientModel client) throws DatabaseException {
190 // for (PropertyListener listener : listenerCache.values())
191 // listener.dispose();
193 // listenerCache.clear();
197 assert(variable != null);
200 this.client = client;
202 SessionEventSupport support = processor.getService(SessionEventSupport.class);
204 for (PropertyListener listener : listenerCache.values()) {
207 listenerCache.clear();
210 support.removeListener(listener);
212 listener = new SessionEventListenerAdapter() {
215 public void writeTransactionFinished() {
221 support.addListener(listener);
223 this.cellEditor = processor.sync(new VariableRead<CellEditor<Write>>(variable) {
226 public CellEditor<Write> perform(ReadGraph graph) throws DatabaseException {
227 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
228 return variable.getPropertyValue(graph, SHEET.cellEditor);
233 final ITask task = ThreadLogger.getInstance().begin("GraphUI.init");
237 Map<String,Variable> sources = processor.syncRequest(new Sources(variable));
239 List<String> sheetList = processor.syncRequest(new Sheets(variable));
240 String currentSheet = processor.syncRequest(new VariableName(variable));
242 Map<String, Resource> stateList = processor.syncRequest(new SpreadsheetStates(variable));
244 if(currentSource == null) currentSource = "Sheet";
246 ArrayList<String> sourceList = new ArrayList<String>(sources.keySet());
248 Collections.sort(sourceList, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);
249 if(!sourceList.contains(currentSource)) sourceList.add(currentSource);
251 client.setProperty(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE, sourceList.toArray(new String[sourceList.size()]));
252 client.setProperty(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, currentSource);
254 client.setProperty(ClientModel.SHEETS, ClientModel.SHEETS_AVAILABLE, sheetList.toArray(new String[sheetList.size()]));
255 client.setProperty(ClientModel.SHEETS, ClientModel.SHEETS_CURRENT, currentSheet);
257 client.setProperty(ClientModel.STATES, ClientModel.STATES_AVAILABLE, stateList.keySet().toArray(new String[stateList.size()]));
259 client.setProperty(ClientModel.CONTEXT, ClientModel.CONTEXT_CURRENT, variable);
261 client.setProperty(ClientModel.MODE, ClientModel.MODE_CURRENT, OperationMode.OPERATION);
263 String currentState = processor.syncRequest(new UniqueRead<String>() {
266 public String perform(ReadGraph graph) throws DatabaseException {
267 Resource book = variable.getParent(graph).getRepresents(graph);
268 Resource ic = graph.getPossibleObject(book, SpreadsheetResource.getInstance(graph).Book_HasDefaultInitialCondition);
271 return graph.getRelatedValue2(ic, Layer0.getInstance(graph).HasName, Bindings.STRING);
275 client.setProperty(ClientModel.STATES, ClientModel.STATES_CURRENT, currentState);
277 processor.syncRequest(new ReadRequest() {
280 public void run(ReadGraph graph) throws DatabaseException {
282 loadCells(graph, variable, false, client);
284 graph.syncRequest(new Ranges(variable), new SingleSetSyncListenerDelegate<Variable>(GraphUI.this) {
287 public void add(ReadGraph graph, final Variable range) throws DatabaseException {
289 if(DEBUG) System.out.println("GraphUI adds range " + range.getURI(graph));
291 Boolean immutable = range.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
292 loadCells(graph, range, immutable != null && immutable, client);
297 public void remove(ReadGraph graph, final Variable range) throws DatabaseException {
304 graph.syncRequest(new SheetLines(variable), new SingleSetSyncListenerDelegate<Variable>(GraphUI.this) {
307 public void add(ReadGraph graph, final Variable range) throws DatabaseException {
309 if(DEBUG) System.out.println("GraphUI adds line " + range.getURI(graph));
311 Boolean immutable = range.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
312 loadCells(graph, range, immutable != null && immutable, client);
317 public void remove(ReadGraph graph, final Variable range) throws DatabaseException {
325 // public void remove(ReadGraph graph, Variable child) throws DatabaseException {
327 // String location = locations.get(cellResource);
328 // assert(location != null);
330 // client.setProperty(location, "Label", null);
331 // client.setProperty(location, "Expression", null);
345 private static class PropertyListener extends SingleSetSyncListenerDelegate<Pair<String,Variable>> {
347 private static final Logger LOGGER = LoggerFactory.getLogger(PropertyListener.class);
349 private ClientModel client;
350 private String childName;
351 private boolean listenerDisposed;
353 public PropertyListener(SyncListenerSupport support, ClientModel client, String childName) {
355 this.client = client;
356 this.childName = childName;
360 public void add(ReadGraph graph, final Pair<String,Variable> property) throws DatabaseException {
363 System.out.println("GraphUI adds property " + property.second.getURI(graph));
365 graph.syncRequest(new CellValue(property.second), new SyncListener<Object>() {
368 public void execute(ReadGraph graph, final Object value) throws DatabaseException {
370 String propertyName = property.first;
373 System.out.println("GraphUI detected content change(1) at " + childName + " - " + propertyName + " -> " + value);
374 client.setProperty(childName, propertyName, value);
379 public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
381 LOGGER.error("PropertyListener.exception", throwable);
383 String propertyName = property.first;
384 if("content".equals(propertyName)) {
385 if(throwable == null) throwable = new Exception();
386 String message = throwable.getMessage();
387 if(message == null) message = throwable.toString();
388 client.setProperty(childName, propertyName, Variant.ofInstance(message));
390 client.setProperty(childName, propertyName, null);
396 public boolean isDisposed() {
397 return listenerDisposed;
403 public void dispose() {
404 listenerDisposed = true;
408 public String toString() {
409 return super.toString() + ":" + childName;
414 private PropertyListener propertyListener(final ClientModel client, final String childName) {
415 return new PropertyListener(this, client, childName);
418 private void addProperties(ReadGraph graph, final Collection<Variable> properties, final ClientModel client, final String childName) throws DatabaseException {
420 for(Variable property : properties) {
422 if(DEBUG) System.out.println("GraphUI adds immutable property " + property.getURI(graph));
424 final String propertyName = property.getName(graph);
426 Object value = property.getValue(graph);
428 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + propertyName + " -> " + value);
429 client.setProperty(childName, propertyName, value);
431 String expression = property.getPossiblePropertyValue(graph, "expression", Bindings.STRING);
432 if(expression != null) {
433 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + (propertyName + "#expression") + " -> " + value);
434 client.setProperty(childName, propertyName + "#expression", expression);
437 Boolean editable = property.getPossiblePropertyValue(graph, "editable", Bindings.STRING);
438 if(editable != null) {
439 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + (propertyName + "#editable") + " -> " + value);
440 client.setProperty(childName, propertyName + "#editable", editable);
447 @SuppressWarnings("unchecked")
449 public <T> T getAdapter(Class<T> clazz) {
451 if(Variable.class == clazz) {
455 } else if(RemoveCellHandler.class == clazz) {
457 return (T) new RemoveCellHandler() {
460 public void handle(final String location) {
463 processor.syncRequest(new ReadRequest() {
466 public void run(ReadGraph graph) throws DatabaseException {
468 Variable cellVariable = run.getPossibleChild(graph, location);
469 if(cellVariable != null) {
470 final Resource config = cellVariable.getPossiblePropertyValue(graph, "Represents");
473 graph.asyncRequest(new WriteRequest() {
476 public void perform(WriteGraph graph) throws DatabaseException {
478 Layer0 l0 = Layer0.getInstance(graph);
479 // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
480 graph.deny(config, l0.PartOf);
481 // graph.deny(config, sr.RowOf);
482 // graph.deny(config, sr.ColumnOf);
494 } catch (DatabaseException e) {
495 LOGGER.error("Unexpected exception while removing cell", e);
502 } else if(CellEditor.class == clazz) {
504 return (T)new CellEditor<Write>() {
507 public <E> void edit(Transaction<Write> transaction, String location, String property, E value, Binding binding, Consumer<?> callback) {
509 if (ClientModel.ITERATION_ENABLED.equals(location)) {
510 Simantics.getSession().asyncRequest(new ReadRequest() {
512 public void run(ReadGraph graph) throws DatabaseException {
513 getBook(graph).setIterationEnabled((boolean)value);
519 if (ClientModel.MODE.equals(location)) {
520 if (ClientModel.MODE_CURRENT.equals(property)) {
521 client.setProperty(location, property, value);
527 if (ClientModel.CONTEXT.equals(location)) {
528 if(ClientModel.CONTEXT_CURRENT.equals(property)) {
529 if(value instanceof String) {
531 Variable newContext = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
534 public Variable perform(ReadGraph graph) throws DatabaseException {
536 String sheetName = run.getName(graph);
538 Variable book = Variables.getContext(graph, run);
539 Resource bookResource = book.getRepresents(graph);
541 Variable input = Variables.getVariable(graph, parameter);
542 Variable proxy = ProxyVariables.makeProxyVariable(graph, Variables.getVariable(graph, bookResource), input);
544 return proxy.getChild(graph, sheetName);
546 // return variable.getParent(graph).getChild(graph, parameter);
551 load(newContext, client);
553 } catch (DatabaseException e) {
554 LOGGER.error("edit failed for model key '" + ClientModel.CONTEXT_CURRENT + "'", e);
560 if(ClientModel.SHEETS.equals(location)) {
561 if(ClientModel.SHEETS_CURRENT.equals(property)) {
563 if(value instanceof String) {
567 Variable newInput = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
570 public Variable perform(ReadGraph graph) throws DatabaseException {
571 return run.getParent(graph).getChild(graph, parameter);
576 load(newInput, client);
578 } catch (DatabaseException e) {
579 LOGGER.error("edit failed for model key '" + ClientModel.SHEETS_CURRENT + "'", e);
585 if(ClientModel.STATES.equals(location)) {
586 if(ClientModel.STATES_CURRENT.equals(property)) {
587 if(value instanceof String) {
588 final String parameter = (String) value;
591 String uri = processor.syncRequest(new WriteResultRequest<String>() {
594 public String perform(WriteGraph graph) throws DatabaseException {
596 Map<String, Resource> states = graph.syncRequest(new SpreadsheetStates(run));
598 Resource state = null;
599 for (Map.Entry<String, Resource> entry : states.entrySet()) {
600 if (entry.getKey().equals(parameter)) {
601 state = entry.getValue();
606 Variable context = Variables.getContext(graph, run);
607 Resource bookResource = context.getRepresents(graph);
608 SpreadsheetGraphUtils.setDefaultInitialConditionForBook(graph, bookResource, state);
610 String contextURI = context.getURI(graph);
612 String sessionName = context.getParent(graph).getURI(graph);
613 SpreadsheetSessionManager.getInstance().removeRealm(graph, sessionName);
614 SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
617 return run.getURI(graph);
620 Variable newInput = processor.syncRequest(new PossibleURIVariable(uri));
621 load(newInput, client);
622 // fullSynchronize();
624 } catch (DatabaseException e) {
625 LOGGER.error("edit failed for model key '" + ClientModel.STATES_CURRENT + "'", e);
631 if(ClientModel.SOURCES.equals(location)) {
632 if(ClientModel.SOURCES_CURRENT.equals(property)) {
634 Resource res = WorkbenchSelectionUtils.getPossibleResource(value);
637 Variable newInput = processor.syncRequest(new ResourceRead<Variable>(res) {
640 public Variable perform(ReadGraph graph) throws DatabaseException {
641 Variable base = ProxyVariables.proxyVariableBase(graph, run);
642 Variable in = Variables.getVariable(graph, resource);
643 currentSource = in.getURI(graph);
644 return ProxyVariables.makeProxyVariable(graph, base, in);
649 load(newInput, client);
653 } else if(value instanceof String) {
655 Variable newInput = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
658 public Variable perform(ReadGraph graph) throws DatabaseException {
660 Variable base = ProxyVariables.proxyVariableBase(graph, run);
661 Map<String,Variable> sources = graph.syncRequest(new Sources(base));
663 Variable found = sources.get(parameter);
664 if(found == null) return null;
666 currentSource = parameter;
668 return ProxyVariables.makeProxyVariable(graph, base, found);
674 load(newInput, client);
678 } catch (DatabaseException e) {
679 LOGGER.error("edit failed for model key '" + ClientModel.SOURCES_CURRENT + "'", e);
684 boolean needsCommit = false;
685 if (transaction == null) {
686 OperationMode mode = client.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
687 transaction = startTransaction(mode);
688 // if (mode.equals(OperationMode.OPERATION))
689 transaction.setContext(run);
692 final Transaction<Write> finalTransaction = transaction;
693 cellEditor.edit(transaction, location, property, value, binding, new Consumer<Object>() {
696 public void accept(Object param) {
697 if (finalTransaction.needSynchronization() != null)
698 synchronize(finalTransaction.needSynchronization());
702 transaction.commit();
706 public void edit(Transaction<Write> transaction, String location, Variant variant, Consumer<?> callback) {
707 boolean needsCommit = false;
708 if (transaction == null) {
709 OperationMode mode = client.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
710 transaction = startTransaction(mode);
711 // if (mode.equals(OperationMode.OPERATION))
712 transaction.setContext(run);
715 final Transaction<Write> finalTransaction = transaction;
716 cellEditor.edit(transaction, location, variant, new Consumer<Object>() {
719 public void accept(Object param) {
720 if (finalTransaction.needSynchronization() != null)
721 synchronize(finalTransaction.needSynchronization());
725 transaction.commit();
729 public void copy(final Transaction<Write> transaction, String location, MutableVariant variant, Consumer<?> callback) {
730 cellEditor.edit(transaction, location, variant, new Consumer<Object>() {
733 public void accept(Object param) {
734 if (transaction.needSynchronization() != null)
735 synchronize(transaction.needSynchronization());
741 public Transaction<Write> startTransaction(OperationMode mode) {
742 return cellEditor.startTransaction(mode);
747 } else if (SheetCommands.class == clazz ) {
749 return (T) new SheetCommands() {
752 public void saveState() {
754 Simantics.getSession().asyncRequest(new ReadRequest() {
757 public void run(ReadGraph graph) throws DatabaseException {
758 IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
760 Resource uiContextResource = run.getRepresents(graph);
761 Resource bookResource = Variables.getContext(graph, run).getRepresents(graph);
762 Layer0 L0 = Layer0.getInstance(graph);
763 String uiContextName = graph.getRelatedValue2(uiContextResource, L0.HasName, Bindings.STRING);
764 String bookName = graph.getRelatedValue2(bookResource, L0.HasName, Bindings.STRING);
766 UISynchronize synchronizer = context.get(UISynchronize.class);
767 synchronizer.asyncExec(() -> {
768 Pair<String, Resource>[] pairs = new Pair[] {Pair.make(uiContextName, uiContextResource), Pair.make(bookName, bookResource) };
769 SaveSpreadsheetStateDialog dialog = new SaveSpreadsheetStateDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite(), "Save Spreadsheet state", pairs);
770 if (dialog.open() == Dialog.OK) {
771 Object[] result = dialog.getSelection();
772 if (result != null) {
773 Pair<Resource, String> p = (Pair<Resource, String>) result[0];
774 Simantics.getSession().asyncRequest(new WriteRequest() {
777 public void perform(WriteGraph graph) throws DatabaseException {
779 Variable parent = run.getParent(graph);
780 Variable base = ProxyVariables.proxyVariableBase(graph, parent);
781 SpreadsheetGraphUtils.saveInitialCondition(graph, parent, p.first, p.second);
800 public void exception(Throwable t) {
801 LOGGER.error("Failed to read properties.", t);
805 public boolean isDisposed() {
810 public void exception(AsyncReadGraph graph, Throwable t) {
811 LOGGER.error("Failed to read properties.", t);
815 public void exception(ReadGraph graph, Throwable t) {
816 LOGGER.error("Failed to read properties.", t);
819 public void dispose() {
820 for (PropertyListener listener : listenerCache.values())
823 listenerCache.clear();
824 SessionEventSupport support = processor.getService(SessionEventSupport.class);
825 support.removeListener(listener);
829 private void synchronize(List<Object> list) {
830 Simantics.getSession().asyncRequest(new FullSynchronizeBook(run, list));
833 public static class FullSynchronizeBook extends ReadRequest {
835 private final Variable run;
836 private final List<Object> location;
838 public FullSynchronizeBook(Variable run, List<Object> cellLocation) {
840 this.location = cellLocation;
844 public void run(ReadGraph graph) throws DatabaseException {
845 String uri = run.getURI(graph);
846 String parentUri = run.getParent(graph).getURI(graph);
847 System.err.println("Full sync for book " + parentUri);
849 Resource sheetResource = run.getRepresents(graph);
850 Variable sheetVariable = Variables.getVariable(graph, sheetResource);
852 TObjectIntHashMap<Variable> changes = null;
853 if (location != null) {
854 changes = new TObjectIntHashMap<>(location.size());
855 for (Object loc : location) {
856 Variable var = (Variable) loc;
860 SpreadsheetGraphUtils.partialSynchronization(graph, run.getParent(graph), changes);
865 private SpreadsheetBook getBook(ReadGraph graph) throws DatabaseException {
866 String sessionName = run.getParent(graph).getParent(graph).getURI(graph);
867 StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
868 SpreadsheetBook book = realm.getEngine();