]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/SpreadsheetGraphUtils.java
Adopt spreadsheet changes made in Balas development
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / SpreadsheetGraphUtils.java
index 032acfcfce722809848b8fceeeac10bb9bd19800..35a05d7aa59c7d45980f0a781a8fdd726ea621e3 100644 (file)
@@ -23,28 +23,52 @@ import org.simantics.datatypes.utils.BTree;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.BinaryRead;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.LiteralFileUtil;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.db.common.utils.LiteralFileUtil;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.variable.StandardGraphChildVariable;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.layer0.variable.Variables;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.procedure.Listener;
 import org.simantics.db.service.ClusteringSupport;
 import org.simantics.layer0.Layer0;
 import org.simantics.db.service.ClusteringSupport;
 import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.scl.runtime.tuple.Tuple2;
 import org.simantics.simulator.toolkit.StandardRealm;
 import org.simantics.scl.runtime.tuple.Tuple2;
 import org.simantics.simulator.toolkit.StandardRealm;
+import org.simantics.spreadsheet.CellEditor;
+import org.simantics.spreadsheet.ExternalRef;
+import org.simantics.spreadsheet.OperationMode;
 import org.simantics.spreadsheet.Range;
 import org.simantics.spreadsheet.Range;
+import org.simantics.spreadsheet.Spreadsheets;
+import org.simantics.spreadsheet.Transaction;
 import org.simantics.spreadsheet.graph.synchronization.SpreadsheetSynchronizationEventHandler;
 import org.simantics.spreadsheet.resource.SpreadsheetResource;
 import org.simantics.spreadsheet.graph.synchronization.SpreadsheetSynchronizationEventHandler;
 import org.simantics.spreadsheet.resource.SpreadsheetResource;
+import org.simantics.spreadsheet.solver.SheetNode;
+import org.simantics.spreadsheet.solver.SpreadsheetBook;
+import org.simantics.spreadsheet.solver.SpreadsheetCell;
+import org.simantics.spreadsheet.solver.SpreadsheetEngine;
+import org.simantics.spreadsheet.solver.SpreadsheetLine;
+import org.simantics.spreadsheet.solver.SpreadsheetStyle;
 import org.simantics.spreadsheet.util.SpreadsheetUtils;
 import org.simantics.structural.synchronization.client.Synchronizer;
 import org.simantics.spreadsheet.util.SpreadsheetUtils;
 import org.simantics.structural.synchronization.client.Synchronizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.iterator.TObjectIntIterator;
 import gnu.trove.map.hash.TObjectIntHashMap;
 
 public class SpreadsheetGraphUtils {
 
 
 import gnu.trove.iterator.TObjectIntIterator;
 import gnu.trove.map.hash.TObjectIntHashMap;
 
 public class SpreadsheetGraphUtils {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetGraphUtils.class);
+
     public static File extractInitialCondition(ReadGraph graph, Resource ic) throws DatabaseException, IOException {
 
        SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
     public static File extractInitialCondition(ReadGraph graph, Resource ic) throws DatabaseException, IOException {
 
        SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
@@ -168,12 +192,6 @@ public class SpreadsheetGraphUtils {
                        
         SpreadsheetSynchronizationEventHandler handler = new SpreadsheetSynchronizationEventHandler(graph, book);
         
                        
         SpreadsheetSynchronizationEventHandler handler = new SpreadsheetSynchronizationEventHandler(graph, book);
         
-//        System.err.println("sessionName : " + sessionName);
-//        System.err.println("bookResource : " + graph.getURI(bookResource));
-//        System.err.println("configuration : " + configuration.getURI(graph));
-//        System.err.println("realm : " + realm);
-//        System.err.println("book : " + book);
-        
         if (changeFlags == null) {
             synchronizer.fullSynchronization(configuration, handler);
         } else {
         if (changeFlags == null) {
             synchronizer.fullSynchronization(configuration, handler);
         } else {
@@ -193,14 +211,6 @@ public class SpreadsheetGraphUtils {
             synchronizer.partialSynchronization(configuration, handler, changeFlags);
         }
         
             synchronizer.partialSynchronization(configuration, handler, changeFlags);
         }
         
-//        book.accept(new InvalidateAll());
-//        realm.getNodeManager().refreshVariables();
-//        mapping.currentRevision = synchronizer.getHeadRevisionId();
-//        mapping.setTrustUids(true);
-        // Clean up queries
-//        QueryControl qc = g.getService(QueryControl.class);
-//        qc.flush(g);
-//        TimeLogger.log("Finished full synchronization");
         realm.getNodeManager().fireNodeListeners();
         return handler.getDidChanges();
         
         realm.getNodeManager().fireNodeListeners();
         return handler.getDidChanges();
         
@@ -218,7 +228,7 @@ public class SpreadsheetGraphUtils {
        SpreadsheetEngine engine = book.getEngine(sheetName);
        if(engine == null) return null;
        
        SpreadsheetEngine engine = book.getEngine(sheetName);
        if(engine == null) return null;
        
-       Range r = SpreadsheetUtils.decodeCellAbsolute(cellName);
+       Range r = Spreadsheets.decodeCellAbsolute(cellName);
        SpreadsheetLine line = engine.getLine(r.startRow);
        if(line == null) return null;
        
        SpreadsheetLine line = engine.getLine(r.startRow);
        if(line == null) return null;
        
@@ -233,200 +243,6 @@ public class SpreadsheetGraphUtils {
     }
 
     
     }
 
     
-    public static boolean asBoolean(Object object) {
-       if(object instanceof Boolean) return (Boolean)object;
-       else if(object instanceof Number) return ((Number)object).doubleValue() != 0;
-       else if(object instanceof Variant) return asBoolean(((Variant)object).getValue());
-       else if(object instanceof String) {
-               Double d = asDoubleWhereEmptyStringIsZero((String)object);
-               if(d==null) return false;
-               else return d != 0;
-       }
-       return false;
-    }
-    
-    public static String asString(Object object) {
-       if(object == null) return "";
-       if(object instanceof String) return (String)object;
-       if(object instanceof Number) {
-               double dVal = ((Number)object).doubleValue();
-               if(dVal == Math.floor(dVal)){
-                       return ""+((Number)object).intValue();
-               } else {
-                       return object.toString();
-               }
-       }
-       else if(object instanceof Variant) {
-               Object o = ((Variant) object).getValue();
-               if(o instanceof String) return (String)o;
-               else if(o instanceof Number) asString((Number)o);
-               else return o.toString();
-       }
-       return object.toString();
-    }
-    
-    public static Double asDoubleWhereEmptyStringIsZero(Object object){
-       if(object instanceof Number)
-               return ((Number)object).doubleValue();
-       else if(object instanceof String) {
-               try {
-                       if(((String)object).isEmpty())
-                               return 0.0;
-                       return Double.parseDouble((String)object);
-                       } catch (NumberFormatException e) {
-                               return null;
-                       }
-       } else if(object instanceof Variant) {
-               Object o = ((Variant) object).getValue();
-               return asDoubleWhereEmptyStringIsZero(o);
-       } else if (SpreadsheetCell.EMPTY == object) {
-               return null;
-       }
-       return null;
-    }
-    
-    public static double asNumber(Object object) {
-       if(object instanceof Number) {
-               return ((Number)object).doubleValue();
-       } else if(object instanceof String) {
-               try {
-                       String str = (String)object;
-                       if(str.isEmpty()) return 0;
-                       return Double.parseDouble((String)object);
-                       } catch (NumberFormatException e) {
-                       return 0;
-                       }
-       } else if(object instanceof Variant) {
-               Object o = ((Variant) object).getValue();
-               return asNumber(o);
-       } else if (SpreadsheetCell.EMPTY == object) {
-               return 0.0;
-       }
-               
-       return 0.0;
-       
-    }
-    
-    public static Number asValidNumber(Object object) {
-       if(object instanceof Number) {
-               return (Number)object;
-       } else if(object instanceof String) {
-               try {
-                       return Double.parseDouble((String)object);
-                       } catch (NumberFormatException e) {
-                       return null;
-                       }
-       } else if(object instanceof Variant) {
-               Object o = ((Variant) object).getValue();
-               return asNumber(o);
-       } else if (SpreadsheetCell.EMPTY == object) {
-               return null;
-       }
-               
-       return null;
-       
-    }
-    
-    public static boolean matchCriteria(Object value, Object criteria) {
-       if(value==null || criteria==null) return false;
-       
-       if(value instanceof Variant){
-               Double dVal = asDoubleWhereEmptyStringIsZero(value);
-               if(dVal==null) value = ((Variant)value).getValue();
-               else value = dVal;
-       }
-       if(criteria instanceof Variant){
-               Double dVal = asDoubleWhereEmptyStringIsZero(criteria);
-               if(dVal==null) criteria = ((Variant)criteria).getValue();
-               else criteria = dVal;
-       }
-       
-       if(criteria instanceof Number && value instanceof Number) {
-               Number nc = (asNumber(criteria));
-               Number nv = (asNumber(value));
-               return nc.equals(nv);
-       }
-       if(criteria instanceof String){
-               boolean nums = false;
-               Object valueObj = null;
-                       if(value instanceof Number){
-                               valueObj = ((Number)value).doubleValue();
-                               nums = true;
-                       }
-                       else valueObj = value.toString();
-                       
-               String sc = criteria.toString();
-                       if(sc.length() >= 3){
-                               String oper = sc.substring(0, 2);
-                               String criteriaStr = sc.substring(2);
-                               Double criteriaNum = null;
-                               try {
-                                       criteriaNum = Double.parseDouble(criteriaStr);
-                                       if(oper.equals("<>")){
-                                               if(!nums) return true;
-                                       }
-                                       else if(!nums) return false;
-                                       nums = true;
-                               } catch (NumberFormatException e){
-                                       if(oper.equals("<>")){
-                                               if(nums) return true;
-                                       }
-                                       else if(nums) return false;
-                                       nums = false;
-                               }
-                               
-                               if(oper.equals(">=")){
-                                       if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) >= 0 ;
-                                       else return ((Number)valueObj).doubleValue() >= criteriaNum;
-                               } else if(oper.equals("<=")){
-                                       if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) <= 0 ;
-                                       else return ((Number)valueObj).doubleValue() <= criteriaNum;
-                               } else if(oper.equals("<>")){
-                                       if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) != 0 ;
-                                       else return ((Number)valueObj).doubleValue() != criteriaNum;
-                               }
-                       }
-               if(sc.length() >= 2){
-                       String oper = sc.substring(0, 1);
-                       String criteriaStr = sc.substring(1);
-                       Double criteriaNum = null;
-                       
-                       try {
-                                       criteriaNum = Double.parseDouble(criteriaStr);
-                                       if(!nums) return false;
-                                       nums = true;
-                               } catch (NumberFormatException e){
-                                       if(nums) return false;
-                                       nums = false;
-                               }
-                       if(oper.equals("<")){
-                               if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) < 0;
-                               else return ((Number)valueObj).doubleValue() < criteriaNum;
-                       } else if(oper.equals(">")){
-                               if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) > 0;
-                               else return ((Number)valueObj).doubleValue() > criteriaNum;
-                       } else if(oper.equals("=")){
-                               if(!nums) return (valueObj.toString().toLowerCase()).compareTo(criteriaStr.toLowerCase()) == 0;
-                               else return ((Number)valueObj).doubleValue() == criteriaNum;
-                       }
-               }
-               return sc.equals(valueObj);
-       }
-       else if (criteria instanceof Number){
-               return false;
-       }
-       throw new IllegalStateException();
-    }
-
-    public static boolean excelEquals(Object left, Object right) {
-       if(left instanceof String) {
-               if(right instanceof String) {
-                       return ((String) left).toLowerCase().equals(((String) right).toLowerCase());
-               }
-       }
-       return left.equals(right);
-    }
-    
 
     public static List<Variable> possibleConfigurationCellVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {
         List<Variable> rowVariables = possibleConfigurationLineVariables(graph, sheet, range);
 
     public static List<Variable> possibleConfigurationCellVariables(ReadGraph graph, Variable sheet, Range range) throws DatabaseException {
         List<Variable> rowVariables = possibleConfigurationLineVariables(graph, sheet, range);
@@ -521,7 +337,7 @@ public class SpreadsheetGraphUtils {
     
     private static boolean variableInRange(ReadGraph graph, Variable child, Range range) throws DatabaseException {
         String name = child.getName(graph);
     
     private static boolean variableInRange(ReadGraph graph, Variable child, Range range) throws DatabaseException {
         String name = child.getName(graph);
-        Range childRange = SpreadsheetUtils.decodeCellAbsolute(name);
+        Range childRange = Spreadsheets.decodeCellAbsolute(name);
 //        System.out.print(" and range " + childRange);
         if (childRange != null && range.contains(childRange)) {
 //             System.out.println(" => range.contains(childRange) = true");
 //        System.out.print(" and range " + childRange);
         if (childRange != null && range.contains(childRange)) {
 //             System.out.println(" => range.contains(childRange) = true");
@@ -566,7 +382,7 @@ public class SpreadsheetGraphUtils {
             for (int rowNumber = range.startRow; rowNumber <= range.endRow; rowNumber++) {
                 Variable row = rowIterator.next();
                 for (int colNumber = range.startColumn; colNumber <= range.endColumn; colNumber++) {
             for (int rowNumber = range.startRow; rowNumber <= range.endRow; rowNumber++) {
                 Variable row = rowIterator.next();
                 for (int colNumber = range.startColumn; colNumber <= range.endColumn; colNumber++) {
-                    String location = SpreadsheetUtils.cellName(rowNumber, colNumber);
+                    String location = Spreadsheets.cellName(rowNumber, colNumber);
                     defaultCreateCell(graph, row, location, new Variant(Bindings.STRING, ""));
                 }
             }
                     defaultCreateCell(graph, row, location, new Variant(Bindings.STRING, ""));
                 }
             }
@@ -670,5 +486,169 @@ public class SpreadsheetGraphUtils {
         SpreadsheetGraphUtils.saveInitialCondition(graph, run, root, "Initial");
         return run;
     }
         SpreadsheetGraphUtils.saveInitialCondition(graph, run, root, "Initial");
         return run;
     }
+    
+    public static Variant extRefVariable(ReadGraph graph, Variable var) throws DatabaseException {
+        return new Variant(Bindings.VOID, new ExternalRefVariable(graph, var));
+    }
+    
+    static class ExternalRefVariable implements ExternalRef {
+
+        final private String uri;
+        
+        public ExternalRefVariable(ReadGraph graph, Variable variable) throws DatabaseException {
+            this.uri = variable.getURI(graph);
+        }
+        
+        @Override
+        public void listen(Object context, ExternalRefListener listener) {
+            Simantics.getSession().asyncRequest(new UnaryRead<String, Variant>(uri) {
+
+                @Override
+                public Variant perform(ReadGraph graph) throws DatabaseException {
+                    Variable variable = Variables.getVariable(graph, parameter);
+                    return variable.getVariantValue(graph);
+                }
+                
+            }, new Listener<Variant>() {
+
+                @Override
+                public void execute(Variant result) {
+                    listener.newValue(result);
+                }
+
+                @Override
+                public void exception(Throwable t) {
+                    LOGGER.error("Error while evaluating variable value", t);
+                }
+
+                @Override
+                public boolean isDisposed() {
+                    return listener.isDisposed();
+                }
+                
+            });
+        }
+        
+        @Override
+        public void modify(Object context, Variant newValue) {
+            
+            Simantics.getSession().asyncRequest(new WriteRequest() {
 
 
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    Variable variable = Variables.getVariable(graph, uri);
+                    variable.setValue(graph, newValue);
+                }
+            });
+            
+        }
+        
+    }
+
+    public static Variant extRefActiveVariable(ReadGraph graph, Variable var) throws DatabaseException {
+        return new Variant(Bindings.VOID, new ExternalRefActiveVariable(graph, var));
+    }
+    
+    static class ExternalRefActiveVariable implements ExternalRef {
+
+        final private String uri;
+        
+        public ExternalRefActiveVariable(ReadGraph graph, Variable variable) throws DatabaseException {
+            this.uri = variable.getURI(graph);
+        }
+        
+        @Override
+        public void listen(Object context, ExternalRefListener listener) {
+            Simantics.getSession().asyncRequest(new BinaryRead<String, String, Variant>((String)context, uri) {
+
+                @Override
+                public Variant perform(ReadGraph graph) throws DatabaseException {
+                    Variable contextVariable = Variables.getVariable(graph, parameter);
+                    Variable configVariable = Variables.getVariable(graph, parameter2);
+                    Variable activeVariable = Variables.switchPossibleContext(graph, configVariable, contextVariable.getRepresents(graph));
+                    if(activeVariable == null) return Variant.ofInstance("Could not resolve " + configVariable.getURI(graph) + " for " + contextVariable.getURI(graph));
+                    return activeVariable.getVariantValue(graph);
+                }
+            }, new Listener<Variant>() {
+
+                @Override
+                public void execute(Variant result) {
+                    listener.newValue(result);
+                }
+
+                @Override
+                public void exception(Throwable t) {
+                    LOGGER.error("Error while evaluating variable value, context = " + context + " uri=" + uri, t);
+                }
+
+                @Override
+                public boolean isDisposed() {
+                    return listener.isDisposed();
+                }
+                
+            });
+        }
+        
+        @Override
+        public void modify(Object context, Variant newValue) {
+            
+            Simantics.getSession().asyncRequest(new WriteRequest() {
+
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    Variable contextVariable = Variables.getVariable(graph, (String)context);
+                    Variable configVariable = Variables.getVariable(graph,uri);
+                    Variable activeVariable = Variables.switchPossibleContext(graph, configVariable, contextVariable.getRepresents(graph));
+                    if(activeVariable == null) return;
+                    activeVariable.setValue(graph, newValue.getValue(), newValue.getBinding());
+                }
+            });
+            
+        }
+        
+    }
+    
+    public static CellEditor cellEditor(ReadGraph graph, Resource sheet) throws DatabaseException {
+        SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+        Variable sheetVariable = Variables.getVariable(graph, sheet);
+        return sheetVariable.getPropertyValue(graph, SHEET.cellEditor);
+    }
+    
+    public static final String SPREADSHEET_TRANSACTION = "spreadsheetTransaction";
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static Object syncExec(CellEditor editor, OperationMode mode, Function fun) throws InterruptedException {
+        
+        Transaction tr = editor.startTransaction(mode);
+        
+        SCLContext context = SCLContext.getCurrent();
+        Transaction oldTransaction = (Transaction)context.put(SPREADSHEET_TRANSACTION, tr);
+        
+        Object result = null;
+        
+        try {
+
+            result = fun.apply(Tuple0.INSTANCE);
+            
+        } finally {
+            
+            tr.commit();
+            
+            context.put(SPREADSHEET_TRANSACTION, oldTransaction);
+            
+        }
+        
+        return result;
+        
+    }
+    
+    public static int cellColumn(ReadGraph graph, Variable cell) {
+        if(cell instanceof StandardGraphChildVariable) {
+            StandardGraphChildVariable sgcv = (StandardGraphChildVariable)cell;
+            SpreadsheetCell sc = (SpreadsheetCell)sgcv.node.node;
+            return sc.getColumn();
+        }
+        throw new IllegalStateException("Expected StandardGraphChildVariable, got " + cell.getClass().getName());
+    }
+    
 }
 }