package jxl.write.biff; import common.Assert; import common.Logger; import jxl.Cell; import jxl.CellReferenceHelper; import jxl.CellType; import jxl.FormulaCell; import jxl.Sheet; import jxl.biff.FormattingRecords; import jxl.biff.FormulaData; import jxl.biff.IntegerHelper; import jxl.biff.Type; import jxl.biff.formula.FormulaException; import jxl.biff.formula.FormulaParser; import jxl.write.WritableCell; class ReadFormulaRecord extends CellValue implements FormulaData { private static Logger logger = Logger.getLogger(ReadFormulaRecord.class); private FormulaData formula; private FormulaParser parser; protected ReadFormulaRecord(FormulaData f) { super(Type.FORMULA, (Cell)f); this.formula = f; } protected final byte[] getCellData() { return super.getData(); } protected byte[] handleFormulaException() { byte[] expressiondata = null; byte[] celldata = super.getData(); WritableWorkbookImpl w = getSheet().getWorkbook(); this.parser = new FormulaParser(getContents(), w, w, w.getSettings()); try { this.parser.parse(); } catch (FormulaException e2) { logger.warn(e2.getMessage()); this.parser = new FormulaParser("\"ERROR\"", w, w, w.getSettings()); try { this.parser.parse(); } catch (FormulaException e3) { Assert.verify(false); } } byte[] formulaBytes = this.parser.getBytes(); expressiondata = new byte[formulaBytes.length + 16]; IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14); System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length); expressiondata[8] = (byte)(expressiondata[8] | 0x2); byte[] data = new byte[celldata.length + expressiondata.length]; System.arraycopy(celldata, 0, data, 0, celldata.length); System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length); return data; } public byte[] getData() { byte[] celldata = super.getData(); byte[] expressiondata = null; try { if (this.parser == null) { expressiondata = this.formula.getFormulaData(); } else { byte[] formulaBytes = this.parser.getBytes(); expressiondata = new byte[formulaBytes.length + 16]; IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14); System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length); } expressiondata[8] = (byte)(expressiondata[8] | 0x2); byte[] data = new byte[celldata.length + expressiondata.length]; System.arraycopy(celldata, 0, data, 0, celldata.length); System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length); return data; } catch (FormulaException e) { logger.warn(CellReferenceHelper.getCellReference(getColumn(), getRow()) + " " + e.getMessage()); return handleFormulaException(); } } public CellType getType() { return this.formula.getType(); } public String getContents() { return this.formula.getContents(); } public byte[] getFormulaData() throws FormulaException { byte[] d = this.formula.getFormulaData(); byte[] data = new byte[d.length]; System.arraycopy(d, 0, data, 0, d.length); data[8] = (byte)(data[8] | 0x2); return data; } public WritableCell copyTo(int col, int row) { return new FormulaRecord(col, row, this); } void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) { super.setCellDetails(fr, ss, s); s.getWorkbook().addRCIRCell(this); } void columnInserted(Sheet s, int sheetIndex, int col) { try { if (this.parser == null) { byte[] formulaData = this.formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.length - 16]; System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length); this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings()); this.parser.parse(); } this.parser.columnInserted(sheetIndex, col, (s == getSheet())); } catch (FormulaException e) { logger.warn("cannot insert column within formula: " + e.getMessage()); } } void columnRemoved(Sheet s, int sheetIndex, int col) { try { if (this.parser == null) { byte[] formulaData = this.formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.length - 16]; System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length); this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings()); this.parser.parse(); } this.parser.columnRemoved(sheetIndex, col, (s == getSheet())); } catch (FormulaException e) { logger.warn("cannot remove column within formula: " + e.getMessage()); } } void rowInserted(Sheet s, int sheetIndex, int row) { try { if (this.parser == null) { byte[] formulaData = this.formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.length - 16]; System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length); this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings()); this.parser.parse(); } this.parser.rowInserted(sheetIndex, row, (s == getSheet())); } catch (FormulaException e) { logger.warn("cannot insert row within formula: " + e.getMessage()); } } void rowRemoved(Sheet s, int sheetIndex, int row) { try { if (this.parser == null) { byte[] formulaData = this.formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.length - 16]; System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length); this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings()); this.parser.parse(); } this.parser.rowRemoved(sheetIndex, row, (s == getSheet())); } catch (FormulaException e) { logger.warn("cannot remove row within formula: " + e.getMessage()); } } protected FormulaData getReadFormula() { return this.formula; } public String getFormula() throws FormulaException { return ((FormulaCell)this.formula).getFormula(); } }