-package org.simantics.spreadsheet.graph;\r
-\r
-import java.io.Serializable;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Optional;\r
-\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.StandardEngine;\r
-import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment;\r
-import org.simantics.spreadsheet.graph.synchronization.LineNodeUpdater;\r
-import org.simantics.spreadsheet.graph.synchronization.LineUpdater;\r
-import org.simantics.spreadsheet.graph.synchronization.NullUpdater;\r
-import org.simantics.spreadsheet.graph.synchronization.SheetLineComponent;\r
-import org.simantics.spreadsheet.graph.synchronization.StyleUpdater;\r
-import org.simantics.structural.synchronization.base.ComponentFactory;\r
-import org.simantics.structural.synchronization.base.MappingBase;\r
-import org.simantics.structural.synchronization.base.ModuleUpdaterBase;\r
-import org.simantics.structural.synchronization.base.ModuleUpdaterFactoryBase;\r
-import org.simantics.structural.synchronization.base.Solver;\r
-import org.simantics.structural.synchronization.base.SolverNameUtil;\r
-\r
-import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;\r
-import it.unimi.dsi.fastutil.longs.AbstractLongList;\r
-import it.unimi.dsi.fastutil.longs.AbstractLongSet;\r
-import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;\r
-import it.unimi.dsi.fastutil.longs.LongArraySet;\r
-import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet;\r
-\r
-public class SpreadsheetBook implements SpreadsheetElement<SpreadsheetElement, SpreadsheetElement>, StandardEngine<SheetNode>, Serializable, SheetNode<SpreadsheetEngine, SheetNode>, Solver, SolverNameUtil, ComponentFactory<SheetLineComponent>, ModuleUpdaterFactoryBase<SheetLineComponent> {\r
-\r
- private static final long serialVersionUID = 7417208688311691396L;\r
- \r
- public Serializable NotAvailableError = new Serializable() {};\r
- \r
- public Long2ObjectOpenHashMap<AbstractLongSet> referenceMap = new Long2ObjectOpenHashMap<>();\r
- \r
- private Int2ObjectArrayMap<SpreadsheetStyle> styles = new Int2ObjectArrayMap<>();\r
-// public ObjectArrayList<SpreadsheetStyle> styles = new ObjectArrayList<SpreadsheetStyle>();\r
- public ArrayList<SpreadsheetEngine> sheets = new ArrayList<SpreadsheetEngine>();\r
- \r
- private SpreadsheetMapping mapping;\r
- \r
- \r
- private int idCounter = 1;\r
- \r
- public SpreadsheetBook() {\r
- getNewId(this);\r
- mapping = new SpreadsheetMapping(new SheetLineComponent(""));\r
- }\r
- \r
- public Map<Integer, SpreadsheetElement> children = new HashMap<>();\r
-\r
- public int getNewId(SpreadsheetElement element) {\r
- int result = idCounter++;\r
- children.put(result, element);\r
- return result; \r
- }\r
- \r
- public long getEngineIndex(SpreadsheetEngine engine) {\r
- for(int i=0;i<sheets.size();i++)\r
- if(sheets.get(i) == engine) return i;\r
- throw new IllegalStateException("Did not find sheet " + engine.getName());\r
- }\r
- \r
- public void registerReferences(long cell, AbstractLongList refs) {\r
- for(int i=0;i<refs.size();i++) {\r
- long key = refs.getLong(i);\r
- AbstractLongSet set = referenceMap.get(key);\r
- if(set == null) {\r
- set = new LongArraySet();\r
- referenceMap.put(key, set);\r
- }\r
- if(set.size() == 5) {\r
- AbstractLongSet newSet = new LongLinkedOpenHashSet();\r
- newSet.addAll(set);\r
- set = newSet;\r
- referenceMap.put(key, set);\r
- }\r
- set.add(cell);\r
- }\r
- }\r
- \r
- @Override\r
- public Object getValue(SheetNode node) {\r
- if(node instanceof SpreadsheetCellContent) {\r
- try {\r
- SpreadsheetCellContent scc = (SpreadsheetCellContent)node;\r
- Object content = scc.cell.evaluate(SpreadsheetEvaluationEnvironment.getInstance(this));\r
- if(content == null) return Variant.ofInstance("");\r
- if(content instanceof Variant) return content;\r
- else return Variant.ofInstance(content);\r
- } catch (Throwable t) {\r
- t.printStackTrace();\r
- return Variant.ofInstance(t.toString());\r
- }\r
- } else if (node instanceof SpreadsheetCellContentExpression) {\r
- SpreadsheetCellContentExpression scce = (SpreadsheetCellContentExpression)node;\r
- if (scce.cell.content instanceof SpreadsheetFormula) {\r
- SpreadsheetFormula formula = (SpreadsheetFormula)scce.cell.content; \r
- return formula.expression;\r
- } else if (scce.cell.content instanceof SpreadsheetSCLConstant) {\r
- SpreadsheetSCLConstant sclConstant = (SpreadsheetSCLConstant) scce.cell.content;\r
- return "=" + sclConstant.expression;\r
- } else {\r
- System.out.println("Broken SpreadsheetCellContentExpression possibly due to overwriting an existing expression with a constant or something else (current content is " + scce.cell.content + ")");\r
- if (scce.cell.content instanceof Variant) {\r
- return scce.cell.content;\r
- } else {\r
- return Variant.ofInstance(scce.cell.content);\r
- }\r
- }\r
- } else if (node instanceof SpreadsheetTypeNode) {\r
- SpreadsheetTypeNode stn = (SpreadsheetTypeNode)node;\r
- return stn.uri;\r
- } else if (node instanceof SpreadsheetCellStyle) {\r
- int styleId = ((SpreadsheetCellStyle) node).cell.style;\r
- SpreadsheetStyle style = getStyle(styleId);\r
- if (style == null) {\r
- style = SpreadsheetStyle.empty();\r
- if (styleId != style.getStyleId())\r
- new Exception("different style ids!" + styleId + " " + style.getStyleId()).printStackTrace();\r
- addStyle(style);\r
- }\r
- return style;\r
- } else if (node instanceof SpreadsheetCellEditable) {\r
- boolean editable = ((SpreadsheetCellEditable) node).editable();\r
- return editable;\r
- }\r
- return null;\r
- }\r
-\r
- @Override\r
- public void setValue(SheetNode node, Object value) {\r
- }\r
-\r
- @Override\r
- public String getName(SheetNode node) {\r
- return node.getName();\r
- }\r
-\r
- @Override\r
- public Map<String, SheetNode> getChildren(SheetNode node) {\r
- return node.getChildren();\r
- }\r
-\r
- @Override\r
- public Map<String, SheetNode> getProperties(SheetNode node) {\r
- return node.getProperties();\r
- }\r
-\r
- @Override\r
- public String getName() {\r
- return "";\r
- }\r
-\r
- @Override\r
- public Map<String, SpreadsheetEngine> getChildren() {\r
- Map<String,SpreadsheetEngine> result = new HashMap<String,SpreadsheetEngine>();\r
- for(SpreadsheetEngine engine : sheets)\r
- result.put(engine.getName(), engine);\r
- return result;\r
- }\r
-\r
- @Override\r
- public Map<String, SheetNode> getProperties() {\r
- return Collections.emptyMap();\r
- }\r
- \r
- public SpreadsheetCell get(String sheet, int row, int column) {\r
- SpreadsheetEngine engine = getEngine(sheet);\r
- if(engine == null) return null;\r
- SpreadsheetLine line = engine.getLine(row);\r
- if(line == null) return null;\r
- if(line.cells.size() <= column) return null;\r
- return line.cells.get(column);\r
- }\r
-\r
- public SpreadsheetCell get(SpreadsheetEngine engine, int row, int column) {\r
- SpreadsheetLine line = engine.getLine(row);\r
- if(line == null) return null;\r
- if(line.cells.size() <= column) return null;\r
- return line.cells.get(column);\r
- }\r
-\r
- public SpreadsheetEngine getEngine(String sheet) {\r
- for(SpreadsheetEngine engine : sheets)\r
- if(sheet.equals(engine.getName())) return engine;\r
- return null;\r
- }\r
-\r
- @Override\r
- public ModuleUpdaterBase<SheetLineComponent> createUpdater(String id) throws DatabaseException {\r
- if("http://www.simantics.org/Spreadsheet-1.2/Line".equals(id))\r
- return new LineUpdater(id);\r
- else if("http://www.simantics.org/Spreadsheet-1.2/LineNode".equals(id))\r
- return new LineNodeUpdater(id);\r
- else if ("http://www.simantics.org/Spreadsheet-1.2/Style".equals(id))\r
- return new StyleUpdater(id);\r
- else if("http://www.simantics.org/Spreadsheet-1.2/Lines".equals(id))\r
- return new NullUpdater(id);\r
- else if("http://www.simantics.org/Spreadsheet-1.2/Spreadsheet".equals(id))\r
- return new NullUpdater(id);\r
- else if("http://www.simantics.org/Spreadsheet-1.2/Book".equals(id))\r
- return new NullUpdater(id);\r
- else\r
- throw new IllegalStateException("createUpdater " + id);\r
- }\r
-\r
- @Override\r
- public SheetLineComponent create(String uid) {\r
- return new SheetLineComponent(uid);\r
- }\r
-\r
- @Override\r
- public String getFreshName(String parentName, String name) {\r
- return parentName + "/" + name;\r
- }\r
-\r
- @Override\r
- public String ensureNameIsVariationOf(String parentName, int id, String name) {\r
- if (parentName.isEmpty())\r
- return name;\r
- return parentName + "/" + name;\r
- }\r
-\r
- final static int COMP_ROOT_POS = "COMP_ROOT/".length();\r
- \r
- @Override\r
- public int getId(String name) {\r
- \r
- if("COMP_ROOT".equals(name)) return 1;\r
-\r
- String path = name.substring(COMP_ROOT_POS);\r
- String[] parts = path.split("/");\r
- Object o = resolve(parts, 0);\r
- if(o instanceof SpreadsheetLines) {\r
- return ((SpreadsheetLines)o).getId();\r
- } else if(o instanceof SpreadsheetLine) {\r
- return ((SpreadsheetLine)o).getId();\r
- } else if(o instanceof SpreadsheetEngine) {\r
- return ((SpreadsheetEngine)o).getId();\r
- } else if (o instanceof SpreadsheetStyle) {\r
- return ((SpreadsheetStyle) o).getId();\r
- }\r
- \r
- throw new IllegalStateException("Resolved object for parts " + Arrays.toString(parts) + " is not the right type! It is " + o);\r
- \r
- }\r
- \r
- Object resolve(String[] parts, int index) {\r
- String part = parts[index];\r
- if (part.startsWith("Style")) {\r
- for (SpreadsheetStyle style : styles.values()) {\r
- if (style.name.equals(part)) {\r
- return style;\r
- }\r
- }\r
- }\r
- SpreadsheetEngine engine = getEngine(part);\r
- if(engine == null) return 0;\r
- if(index == parts.length-1) return engine;\r
- else return engine.resolve(parts, index+1);\r
- }\r
-\r
- @Override\r
- public String getName(int id) {\r
- if(id == -2) return "http://www.simantics.org/Spreadsheet-1.2/Book";\r
- else if(id == -3) return "http://www.simantics.org/Spreadsheet-1.2/Spreadsheet";\r
- else if(id == -4) return "http://www.simantics.org/Spreadsheet-1.2/Lines";\r
- else if(id == -5)\r
- return "http://www.simantics.org/Spreadsheet-1.2/LineNode";\r
- else if (id == -6)\r
- return "http://www.simantics.org/Spreadsheet-1.2/Line";\r
- else if(id == -7)\r
- return "http://www.simantics.org/Spreadsheet-1.2/Style";\r
- else return "" + id;\r
- }\r
-\r
- @Override\r
- public int getModuleType(int id) {\r
- Serializable s = children.get(id);\r
- if(s instanceof SpreadsheetBook) return -2;\r
- else if(s instanceof SpreadsheetEngine) return -3;\r
- else if(s instanceof SpreadsheetLines) {\r
- if("Lines".equals(((SpreadsheetLines) s).getName()))\r
- return -4;\r
- else\r
- return -5;\r
- }\r
- else if(s instanceof SpreadsheetLine)\r
- return -6;\r
- else if (s instanceof SpreadsheetStyle)\r
- return -7;\r
- else throw new IllegalStateException();\r
- }\r
-\r
- @Override\r
- public void remove(int id) {\r
- \r
- SpreadsheetElement child = children.get(id);\r
- Optional<SpreadsheetElement> parent = child.getParent();\r
- \r
- if (parent.isPresent()) {\r
- parent.get().remove(child);\r
- children.remove(id);\r
- }\r
- }\r
-\r
- @Override\r
- public void addSubprocess(String name) {\r
- ensureSubprocess(name);\r
- }\r
- \r
- public <T> T ensureSubprocess(String name) {\r
- String[] parts = name.split("/");\r
- if(parts.length == 2) {\r
- SpreadsheetEngine engine = getEngine(parts[1]);\r
- if(engine == null) {\r
- engine = new SpreadsheetEngine(this, parts[1]);\r
- sheets.add(engine);\r
- }\r
- return (T)engine;\r
- } else if (parts.length > 2) {\r
- SpreadsheetEngine engine = getEngine(parts[1]);\r
- return (T)engine.ensureSubprocess(parts, 2);\r
- }\r
- throw new IllegalStateException();\r
- }\r
- \r
-\r
- @Override\r
- public void includeSubprocess(String parentName, String subprocessName) {\r
- // Nop\r
- }\r
-\r
- @Override\r
- public <T> T getConcreteSolver() {\r
- return (T)this;\r
- }\r
- \r
- @Override\r
- public void accept(SpreadsheetVisitor v) {\r
- v.visit(this);\r
- }\r
- \r
- public List<SpreadsheetCell> invalidate(SpreadsheetCell cell) {\r
- ArrayList<SpreadsheetCell> result = new ArrayList<>();\r
- result.add(cell);\r
- cell.invalidate();\r
- long refKey = cell.makeReferenceKey();\r
- AbstractLongSet refs = referenceMap.remove(refKey);\r
- if(refs == null) return result;\r
- for(long ref : refs) {\r
- long sheet = ref >> 40;\r
- long row = (ref >> 20) & 0xFFFFF;\r
- long col = (ref) & 0xFFFFF;\r
- SpreadsheetCell referer = get(sheets.get((int)sheet), (int)row, (int)col);\r
- invalidate(referer);\r
- result.add(referer);\r
- }\r
- return result;\r
- }\r
-\r
- public void addStyle(SpreadsheetStyle style) {\r
- if (style.name == null) {\r
- new Exception("Trying to add style to book without name!!").printStackTrace();\r
- return;\r
- }\r
- style.setSynchronizationId(getNewId(style));\r
- styles.put(style.getStyleId(), style);\r
- }\r
-\r
- public SpreadsheetStyle getStyle(int styleId) {\r
- return styles.get(styleId);\r
- }\r
-\r
- public MappingBase<SheetLineComponent> getMapping() {\r
- return mapping;\r
- }\r
-\r
- @Override\r
- public Optional<SpreadsheetElement> getParent() {\r
- return Optional.empty();\r
- }\r
-\r
- @Override\r
- public Collection<SpreadsheetElement> getSpreadsheetChildren() {\r
- return children.values();\r
- }\r
-\r
- @Override\r
- public void remove(SpreadsheetElement child) {\r
- // TODO Auto-generated method stub\r
- \r
- }\r
-\r
-}\r
+package org.simantics.spreadsheet.graph;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.simulator.toolkit.StandardNodeManagerSupport;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment;
+import org.simantics.spreadsheet.graph.synchronization.LineNodeUpdater;
+import org.simantics.spreadsheet.graph.synchronization.LineUpdater;
+import org.simantics.spreadsheet.graph.synchronization.NullUpdater;
+import org.simantics.spreadsheet.graph.synchronization.SheetLineComponent;
+import org.simantics.spreadsheet.graph.synchronization.StyleUpdater;
+import org.simantics.structural.synchronization.base.ModuleUpdaterBase;
+import org.simantics.structural.synchronization.base.ModuleUpdaterFactoryBase;
+import org.simantics.structural.synchronization.base.SolverNameUtil;
+import org.simantics.structural.synchronization.utils.ComponentFactory;
+import org.simantics.structural.synchronization.utils.MappingBase;
+import org.simantics.structural.synchronization.utils.Solver;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.longs.AbstractLongList;
+import it.unimi.dsi.fastutil.longs.AbstractLongSet;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.longs.LongArraySet;
+import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet;
+
+public class SpreadsheetBook implements StandardNodeManagerSupport<SheetNode>, SpreadsheetElement<SpreadsheetElement, SpreadsheetElement>, Serializable, SheetNode<SpreadsheetEngine, SheetNode>, Solver, SolverNameUtil, ComponentFactory<SheetLineComponent>, ModuleUpdaterFactoryBase<SheetLineComponent> {
+
+ private static final long serialVersionUID = 7417208688311691396L;
+
+ public Serializable NotAvailableError = new Serializable() {
+ private static final long serialVersionUID = 2535371785498129460L;
+ };
+
+ public Long2ObjectOpenHashMap<AbstractLongSet> referenceMap = new Long2ObjectOpenHashMap<>();
+
+ private Int2ObjectArrayMap<SpreadsheetStyle> styles = new Int2ObjectArrayMap<>();
+// public ObjectArrayList<SpreadsheetStyle> styles = new ObjectArrayList<SpreadsheetStyle>();
+ public ArrayList<SpreadsheetEngine> sheets = new ArrayList<SpreadsheetEngine>();
+
+ private SpreadsheetMapping mapping;
+
+
+ private int idCounter = 1;
+
+ public SpreadsheetBook() {
+ getNewId(this);
+ mapping = new SpreadsheetMapping(new SheetLineComponent(""));
+ }
+
+ public Map<Integer, SpreadsheetElement> children = new HashMap<>();
+
+ private boolean iterationEnabled;
+
+ public int getNewId(SpreadsheetElement element) {
+ int result = idCounter++;
+ children.put(result, element);
+ return result;
+ }
+
+ public long getEngineIndex(SpreadsheetEngine engine) {
+ for(int i=0;i<sheets.size();i++)
+ if(sheets.get(i) == engine) return i;
+ throw new IllegalStateException("Did not find sheet " + engine.getName());
+ }
+
+ public void registerReferences(long cell, AbstractLongList refs) {
+ for(int i=0;i<refs.size();i++) {
+ long key = refs.getLong(i);
+ AbstractLongSet set = referenceMap.get(key);
+ if(set == null) {
+ set = new LongArraySet();
+ referenceMap.put(key, set);
+ }
+ if(set.size() == 5) {
+ AbstractLongSet newSet = new LongLinkedOpenHashSet();
+ newSet.addAll(set);
+ set = newSet;
+ referenceMap.put(key, set);
+ }
+ set.add(cell);
+ }
+ }
+
+ @Override
+ public Binding getEngineBinding(SheetNode node) throws NodeManagerException {
+ Object value = getEngineValue(node);
+ if(value instanceof Variant) return Bindings.VARIANT;
+ if(value instanceof String) return Bindings.STRING;
+ if(value instanceof Boolean) return Bindings.BOOLEAN;
+ else return Bindings.VOID;
+
+ }
+
+ @Override
+ public Object getEngineValue(SheetNode node) {
+ if(node instanceof SpreadsheetCellContent) {
+ try {
+ SpreadsheetCellContent scc = (SpreadsheetCellContent)node;
+ Object content = scc.cell.evaluate(SpreadsheetEvaluationEnvironment.getInstance(this));
+ if(content == null) return Variant.ofInstance("");
+ if(content instanceof Variant) return content;
+ else return Variant.ofInstance(content);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return Variant.ofInstance(t.toString());
+ }
+ } else if (node instanceof SpreadsheetCellContentExpression) {
+ SpreadsheetCellContentExpression scce = (SpreadsheetCellContentExpression)node;
+ if (scce.cell.content instanceof SpreadsheetFormula) {
+ SpreadsheetFormula formula = (SpreadsheetFormula)scce.cell.content;
+ return formula.expression;
+ } else if (scce.cell.content instanceof SpreadsheetSCLConstant) {
+ SpreadsheetSCLConstant sclConstant = (SpreadsheetSCLConstant) scce.cell.content;
+ return "=" + sclConstant.expression;
+ } else {
+ System.out.println("Broken SpreadsheetCellContentExpression possibly due to overwriting an existing expression with a constant or something else (current content is " + scce.cell.content + ")");
+ if (scce.cell.content instanceof Variant) {
+ return scce.cell.content;
+ } else {
+ return Variant.ofInstance(scce.cell.content);
+ }
+ }
+ } else if (node instanceof SpreadsheetTypeNode) {
+ SpreadsheetTypeNode stn = (SpreadsheetTypeNode)node;
+ return stn.uri;
+ } else if (node instanceof SpreadsheetCellStyle) {
+ int styleId = ((SpreadsheetCellStyle) node).cell.style;
+ SpreadsheetStyle style = getStyle(styleId);
+ if (style == null) {
+ style = SpreadsheetStyle.empty();
+ if (styleId != style.getStyleId())
+ new Exception("different style ids!" + styleId + " " + style.getStyleId()).printStackTrace();
+ addStyle(style);
+ }
+ return style;
+ } else if (node instanceof SpreadsheetCellEditable) {
+ boolean editable = ((SpreadsheetCellEditable) node).editable();
+ return editable;
+ }
+ return null;
+ }
+
+ @Override
+ public void setEngineValue(SheetNode node, Object value) {
+ }
+
+ @Override
+ public String getName(SheetNode node) {
+ return node.getName();
+ }
+
+ @Override
+ public Map<String, SheetNode> getChildren(SheetNode node) {
+ return node.getChildren();
+ }
+
+ @Override
+ public Map<String, SheetNode> getProperties(SheetNode node) {
+ return node.getProperties();
+ }
+
+ @Override
+ public String getName() {
+ return "";
+ }
+
+ @Override
+ public Map<String, SpreadsheetEngine> getChildren() {
+ Map<String,SpreadsheetEngine> result = new HashMap<String,SpreadsheetEngine>();
+ for(SpreadsheetEngine engine : sheets)
+ result.put(engine.getName(), engine);
+ return result;
+ }
+
+ @Override
+ public Map<String, SheetNode> getProperties() {
+ return Collections.emptyMap();
+ }
+
+ public SpreadsheetCell get(String sheet, int row, int column) {
+ SpreadsheetEngine engine = getEngine(sheet);
+ if(engine == null) return null;
+ SpreadsheetLine line = engine.getLine(row);
+ if(line == null) return null;
+ if(line.cells.size() <= column) return null;
+ return line.cells.get(column);
+ }
+
+ public SpreadsheetCell get(SpreadsheetEngine engine, int row, int column) {
+ SpreadsheetLine line = engine.getLine(row);
+ if(line == null) return null;
+ if(line.cells.size() <= column) return null;
+ return line.cells.get(column);
+ }
+
+ public SpreadsheetEngine getEngine(String sheet) {
+ for(SpreadsheetEngine engine : sheets)
+ if(sheet.equals(engine.getName())) return engine;
+ return null;
+ }
+
+ @Override
+ public ModuleUpdaterBase<SheetLineComponent> createUpdater(String id) throws DatabaseException {
+ if("http://www.simantics.org/Spreadsheet-1.2/Line".equals(id))
+ return new LineUpdater(id);
+ else if("http://www.simantics.org/Spreadsheet-1.2/LineNode".equals(id))
+ return new LineNodeUpdater(id);
+ else if ("http://www.simantics.org/Spreadsheet-1.2/Style".equals(id))
+ return new StyleUpdater(id);
+ else if("http://www.simantics.org/Spreadsheet-1.2/Lines".equals(id))
+ return new NullUpdater(id);
+ else if("http://www.simantics.org/Spreadsheet-1.2/Spreadsheet".equals(id))
+ return new NullUpdater(id);
+ else if("http://www.simantics.org/Spreadsheet-1.2/Book".equals(id))
+ return new NullUpdater(id);
+ else
+ throw new IllegalStateException("createUpdater " + id);
+ }
+
+ @Override
+ public SheetLineComponent create(String uid) {
+ return new SheetLineComponent(uid);
+ }
+
+ @Override
+ public String getFreshName(String parentName, String name) {
+ return parentName + "/" + name;
+ }
+
+ @Override
+ public String ensureNameIsVariationOf(String parentName, int id, String name) {
+ if (parentName.isEmpty())
+ return name;
+ return parentName + "/" + name;
+ }
+
+ final static int COMP_ROOT_POS = "COMP_ROOT/".length();
+
+ @Override
+ public int getId(String name) {
+
+ if("COMP_ROOT".equals(name)) return 1;
+
+ String path = name.substring(COMP_ROOT_POS);
+ String[] parts = path.split("/");
+ Object o = resolve(parts, 0);
+ if(o instanceof SpreadsheetLines) {
+ return ((SpreadsheetLines)o).getId();
+ } else if(o instanceof SpreadsheetLine) {
+ return ((SpreadsheetLine)o).getId();
+ } else if(o instanceof SpreadsheetEngine) {
+ return ((SpreadsheetEngine)o).getId();
+ } else if (o instanceof SpreadsheetStyle) {
+ return ((SpreadsheetStyle) o).getId();
+ }
+
+ throw new IllegalStateException("Resolved object for parts " + Arrays.toString(parts) + " is not the right type! It is " + o);
+
+ }
+
+ Object resolve(String[] parts, int index) {
+ String part = parts[index];
+ if (part.startsWith("Style")) {
+ for (SpreadsheetStyle style : styles.values()) {
+ if (style.name.equals(part)) {
+ return style;
+ }
+ }
+ }
+ SpreadsheetEngine engine = getEngine(part);
+ if(engine == null) return 0;
+ if(index == parts.length-1) return engine;
+ else return engine.resolve(parts, index+1);
+ }
+
+ @Override
+ public String getName(int id) {
+ if(id == -2) return "http://www.simantics.org/Spreadsheet-1.2/Book";
+ else if(id == -3) return "http://www.simantics.org/Spreadsheet-1.2/Spreadsheet";
+ else if(id == -4) return "http://www.simantics.org/Spreadsheet-1.2/Lines";
+ else if(id == -5)
+ return "http://www.simantics.org/Spreadsheet-1.2/LineNode";
+ else if (id == -6)
+ return "http://www.simantics.org/Spreadsheet-1.2/Line";
+ else if(id == -7)
+ return "http://www.simantics.org/Spreadsheet-1.2/Style";
+ else return "" + id;
+ }
+
+ @Override
+ public int getModuleType(int id) {
+ Serializable s = children.get(id);
+ if(s instanceof SpreadsheetBook) return -2;
+ else if(s instanceof SpreadsheetEngine) return -3;
+ else if(s instanceof SpreadsheetLines) {
+ if("Lines".equals(((SpreadsheetLines) s).getName()))
+ return -4;
+ else
+ return -5;
+ }
+ else if(s instanceof SpreadsheetLine)
+ return -6;
+ else if (s instanceof SpreadsheetStyle)
+ return -7;
+ else throw new IllegalStateException();
+ }
+
+ @Override
+ public void remove(int id) {
+
+ SpreadsheetElement child = children.get(id);
+ Optional<SpreadsheetElement> parent = child.getParent();
+
+ if (parent.isPresent()) {
+ parent.get().remove(child);
+ children.remove(id);
+ }
+ }
+
+ @Override
+ public void addSubprocess(String name, String subprocessType) {
+ ensureSubprocess(name);
+ }
+
+ public <T> T ensureSubprocess(String name) {
+ String[] parts = name.split("/");
+ if(parts.length == 2) {
+ SpreadsheetEngine engine = getEngine(parts[1]);
+ if(engine == null) {
+ engine = new SpreadsheetEngine(this, parts[1]);
+ sheets.add(engine);
+ }
+ return (T)engine;
+ } else if (parts.length > 2) {
+ SpreadsheetEngine engine = getEngine(parts[1]);
+ return (T)engine.ensureSubprocess(parts, 2);
+ }
+ throw new IllegalStateException();
+ }
+
+
+ @Override
+ public void includeSubprocess(String parentName, String subprocessName) {
+ // Nop
+ }
+
+ @Override
+ public <T> T getConcreteSolver() {
+ return (T)this;
+ }
+
+ @Override
+ public void accept(SpreadsheetVisitor v) {
+ v.visit(this);
+ }
+
+ //Recursively find all SpreadsheetCells, invalidate them and return them all as a set
+ public Set<SpreadsheetCell> invalidate(SpreadsheetCell cell) {
+ Set<SpreadsheetCell> result = new HashSet<>();
+ result.add(cell);
+ cell.invalidate();
+ long refKey = cell.makeReferenceKey();
+ AbstractLongSet refs = referenceMap.remove(refKey);
+ if(refs == null) return result;
+ for(long ref : refs) {
+ long sheet = ref >> 40;
+ long row = (ref >> 20) & 0xFFFFF;
+ long col = (ref) & 0xFFFFF;
+ SpreadsheetCell referer = get(sheets.get((int)sheet), (int)row, (int)col);
+ result.addAll(invalidate(referer));
+ }
+ return result;
+ }
+
+ @Deprecated
+ public List<SpreadsheetCell> invalidateShallow(SpreadsheetCell cell) {
+ ArrayList<SpreadsheetCell> result = new ArrayList<>();
+ result.add(cell);
+ cell.invalidate();
+ long refKey = cell.makeReferenceKey();
+ AbstractLongSet refs = referenceMap.remove(refKey);
+ if(refs == null) return result;
+ for(long ref : refs) {
+ long sheet = ref >> 40;
+ long row = (ref >> 20) & 0xFFFFF;
+ long col = (ref) & 0xFFFFF;
+ SpreadsheetCell referer = get(sheets.get((int)sheet), (int)row, (int)col);
+ invalidate(referer);
+ result.add(referer);
+ }
+ return result;
+ }
+
+ public void addStyle(SpreadsheetStyle style) {
+ if (style.name == null) {
+ new Exception("Trying to add style to book without name!!").printStackTrace();
+ return;
+ }
+ style.setSynchronizationId(getNewId(style));
+ styles.put(style.getStyleId(), style);
+ }
+
+ public SpreadsheetStyle getStyle(int styleId) {
+ return styles.get(styleId);
+ }
+
+ public MappingBase<SheetLineComponent> getMapping() {
+ return mapping;
+ }
+
+ @Override
+ public Optional<SpreadsheetElement> getParent() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Collection<SpreadsheetElement> getSpreadsheetChildren() {
+ return children.values();
+ }
+
+ @Override
+ public void remove(SpreadsheetElement child) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setIterationEnabled(boolean value) {
+ this.iterationEnabled = value;
+ }
+
+ public boolean isIterationEnabled() {
+ return iterationEnabled;
+ }
+
+}