1 package org.simantics.spreadsheet.graph;
3 import java.util.Collections;
4 import java.util.HashMap;
7 import java.util.Optional;
9 import org.simantics.spreadsheet.graph.formula.FormulaError2;
10 import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment;
11 import org.simantics.spreadsheet.graph.parser.ast.AstValue;
12 import org.simantics.spreadsheet.resource.SpreadsheetResource;
13 import org.simantics.spreadsheet.util.SpreadsheetUtils;
15 public class SpreadsheetCell implements SpreadsheetElement, SheetNode {
17 private static final long serialVersionUID = 6616793596542239339L;
19 public static SpreadsheetCell EMPTY;
22 EMPTY = new SpreadsheetCell(null, -1);
24 EMPTY.setStyle(SpreadsheetStyle.empty().getStyleId());
27 private boolean inProgress = false;
28 private int iterations = 0;
30 final private SpreadsheetLine line;
31 final private int column;
35 public SpreadsheetCell(SpreadsheetLine line, int column) {
40 public boolean hasExpression() {
41 return content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant;
44 public void setContent(Object newContent) {
45 // if(newContent != null) {
46 // if (!(newContent instanceof Serializable)) {
47 // throw new AssertionError("content not instanceof Serializable but it is " + newContent.getClass().getSimpleName());
51 System.out.println("SpreadsheetCell.setContent "+ this + " " + newContent);
52 this.content = newContent;
56 public String getName() {
57 return SpreadsheetUtils.cellName(line.row, column);
61 public Map<?, ?> getChildren() {
62 return Collections.emptyMap();
65 private static String[] keys = { "typeURI", "content" };
68 public Map<String, SheetNode> getProperties() {
69 Map<String, SheetNode> properties = new HashMap<>();
72 System.out.println("SpreadsheetCell.getProperties: " + this + " " + content + " " + style);
74 properties.put("typeURI", new SpreadsheetTypeNode(SpreadsheetResource.URIs.Cell));
75 properties.put("content", new SpreadsheetCellContent(this));
76 properties.put("style", new SpreadsheetCellStyle(this));
77 properties.put("editable", new SpreadsheetCellEditable(this));
81 public SpreadsheetBook getBook() {
82 return line.getEngine().getBook();
85 public SpreadsheetEngine getEngine() {
86 return line.getEngine();
89 public <T> T evaluate(SpreadsheetEvaluationEnvironment env) {
90 return evaluate(env, null);
93 public <T> T evaluate(SpreadsheetEvaluationEnvironment env, CellValueVisitor caller) {
94 // System.err.println(getEngine().getName() + ":" + getName() + ": evaluate");
96 caller.addReference(makeReferenceKey());
97 if(content instanceof SpreadsheetFormula) {
98 SpreadsheetFormula f = (SpreadsheetFormula)content;
99 if(f.result == null) {
100 CellValueVisitor visitor = new CellValueVisitor(env, this);
101 AstValue value = ((SpreadsheetFormula)content).value;
102 if(this.inProgress == true) this.iterations++;
104 if(!env.getBook().isIterationEnabled()){
105 if(this.inProgress == false){
106 this.inProgress = true;
107 f.result = value.accept(visitor);
109 else f.result = FormulaError2.CIRCULAR_REF.getString();
111 else if(this.iterations<env.iterationLimit){
112 this.inProgress = true;
113 f.result = value.accept(visitor);
120 env.getBook().registerReferences(makeReferenceKey(), visitor.getReferences());
122 this.inProgress = false;
125 } else if (content instanceof SpreadsheetSCLConstant) {
126 SpreadsheetSCLConstant sclConstant = (SpreadsheetSCLConstant) content;
127 return (T) sclConstant.content;
129 this.inProgress = false;
134 public long makeReferenceKey() {
135 SpreadsheetBook book = getBook();
136 SpreadsheetEngine engine = getEngine();
137 long engineIndex = book.getEngineIndex(engine);
140 return (engineIndex << 40) + (row << 20) + col;
143 public void invalidate() {
144 getEngine().rangeCache = null;
145 if(content instanceof SpreadsheetFormula) {
146 SpreadsheetFormula f = (SpreadsheetFormula)content;
152 public void accept(SpreadsheetVisitor v) {
157 public Optional<SpreadsheetElement> getParent() {
158 return Optional.of(line);
162 public List<SpreadsheetElement> getSpreadsheetChildren() {
163 return Collections.emptyList();
167 public void remove(SpreadsheetElement child) {
168 // TODO Auto-generated method stub
173 public int hashCode() {
174 final int prime = 31;
176 result = prime * result + column;
177 result = prime * result + ((line == null) ? 0 : line.hashCode());
182 public boolean equals(Object obj) {
187 if (getClass() != obj.getClass())
189 SpreadsheetCell other = (SpreadsheetCell) obj;
190 if (column != other.column)
193 if (other.line != null)
195 } else if (!line.equals(other.line))
200 public void setStyle(int styleId) {
201 this.style = styleId;
204 public int getStyle() {
208 public Object getContent() {
212 public static SpreadsheetCell empty(SpreadsheetLine line, int column) {
213 SpreadsheetCell cell = new SpreadsheetCell(line, column);
215 cell.setStyle(SpreadsheetStyle.empty().getStyleId());