package org.simantics.spreadsheet.graph; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import org.simantics.spreadsheet.graph.formula.FormulaError2; import org.simantics.spreadsheet.graph.formula.SpreadsheetEvaluationEnvironment; import org.simantics.spreadsheet.graph.parser.ast.AstValue; import org.simantics.spreadsheet.resource.SpreadsheetResource; import org.simantics.spreadsheet.util.SpreadsheetUtils; public class SpreadsheetCell implements SpreadsheetElement, SheetNode { private static final long serialVersionUID = 6616793596542239339L; public static SpreadsheetCell EMPTY; static { EMPTY = new SpreadsheetCell(null, -1); EMPTY.setContent(""); EMPTY.setStyle(SpreadsheetStyle.empty().getStyleId()); } private boolean inProgress = false; private int iterations = 0; final private SpreadsheetLine line; final private int column; int style; Object content; final private Map properties; public SpreadsheetCell(SpreadsheetLine line, int column) { this.properties = createProperties(); this.line = line; this.column = column; } //All SpreadsheetCells have these properties - create them when object is created private Map createProperties() { Map p = new HashMap<>(); p.put("typeURI", new SpreadsheetTypeNode(SpreadsheetResource.URIs.Cell)); p.put("content", new SpreadsheetCellContent(this)); p.put("style", new SpreadsheetCellStyle(this)); p.put("editable", new SpreadsheetCellEditable(this)); return p; } public boolean hasExpression() { return content instanceof SpreadsheetFormula || content instanceof SpreadsheetSCLConstant; } public void setContent(Object newContent) { // if(newContent != null) { // if (!(newContent instanceof Serializable)) { // throw new AssertionError("content not instanceof Serializable but it is " + newContent.getClass().getSimpleName()); // } // } if (GraphUI.DEBUG) System.out.println("SpreadsheetCell.setContent "+ this + " " + newContent); this.content = newContent; } @Override public String getName() { return SpreadsheetUtils.cellName(line.row, column); } @Override public Map getChildren() { return Collections.emptyMap(); } private static String[] keys = { "typeURI", "content" }; @Override public Map getProperties() { if (GraphUI.DEBUG) System.out.println("SpreadsheetCell.getProperties: " + this + " " + content + " " + style); return properties; //Return this SpreadsheetCells's properties, rather than a new HashMap } public SpreadsheetBook getBook() { return line.getEngine().getBook(); } public SpreadsheetEngine getEngine() { return line.getEngine(); } public T evaluate(SpreadsheetEvaluationEnvironment env) { return evaluate(env, null); } public T evaluate(SpreadsheetEvaluationEnvironment env, CellValueVisitor caller) { // System.err.println(getEngine().getName() + ":" + getName() + ": evaluate"); if(caller != null) caller.addReference(makeReferenceKey()); if(content instanceof SpreadsheetFormula) { SpreadsheetFormula f = (SpreadsheetFormula)content; if(f.result == null) { CellValueVisitor visitor = new CellValueVisitor(env, this); AstValue value = ((SpreadsheetFormula)content).value; if(this.inProgress == true) this.iterations++; if(!env.getBook().isIterationEnabled()){ if(this.inProgress == false){ this.inProgress = true; f.result = value.accept(visitor); } else f.result = FormulaError2.CIRCULAR_REF.getString(); } else if(this.iterations getParent() { return Optional.of(line); } @Override public List getSpreadsheetChildren() { return Collections.emptyList(); } @Override public void remove(SpreadsheetElement child) { // TODO Auto-generated method stub } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + column; result = prime * result + ((line == null) ? 0 : line.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SpreadsheetCell other = (SpreadsheetCell) obj; if (column != other.column) return false; if (line == null) { if (other.line != null) return false; } else if (!line.equals(other.line)) return false; return true; } public void setStyle(int styleId) { this.style = styleId; } public int getStyle() { return style; } public Object getContent() { return content; } public static SpreadsheetCell empty(SpreadsheetLine line, int column) { SpreadsheetCell cell = new SpreadsheetCell(line, column); cell.setContent(""); cell.setStyle(SpreadsheetStyle.empty().getStyleId()); return cell; } }