package jxl.write.biff; import common.Assert; import common.Logger; import jxl.Cell; import jxl.CellReferenceHelper; import jxl.CellType; import jxl.Sheet; import jxl.WorkbookSettings; import jxl.biff.FormattingRecords; import jxl.biff.FormulaData; import jxl.biff.IntegerHelper; import jxl.biff.Type; import jxl.biff.WorkbookMethods; import jxl.biff.formula.ExternalSheet; import jxl.biff.formula.FormulaException; import jxl.biff.formula.FormulaParser; import jxl.format.CellFormat; import jxl.write.WritableCell; public class FormulaRecord extends CellValue implements FormulaData { private static Logger logger = Logger.getLogger(FormulaRecord.class); private String formulaToParse; private FormulaParser parser; private String formulaString; private byte[] formulaBytes; private CellValue copiedFrom; public FormulaRecord(int c, int r, String f) { super(Type.FORMULA2, c, r); this.formulaToParse = f; this.copiedFrom = null; } public FormulaRecord(int c, int r, String f, CellFormat st) { super(Type.FORMULA, c, r, st); this.formulaToParse = f; this.copiedFrom = null; } protected FormulaRecord(int c, int r, FormulaRecord fr) { super(Type.FORMULA, c, r, fr); this.copiedFrom = fr; this.formulaBytes = new byte[fr.formulaBytes.length]; System.arraycopy(fr.formulaBytes, 0, this.formulaBytes, 0, this.formulaBytes.length); } protected FormulaRecord(int c, int r, ReadFormulaRecord rfr) { super(Type.FORMULA, c, r, rfr); try { this.copiedFrom = rfr; byte[] readFormulaData = rfr.getFormulaData(); this.formulaBytes = new byte[readFormulaData.length - 16]; System.arraycopy(readFormulaData, 16, this.formulaBytes, 0, this.formulaBytes.length); } catch (FormulaException e) { logger.error("", (Throwable)e); } } private void initialize(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) { if (this.copiedFrom != null) { initializeCopiedFormula(ws, es, nt); return; } this.parser = new FormulaParser(this.formulaToParse, es, nt, ws); try { this.parser.parse(); this.formulaString = this.parser.getFormula(); this.formulaBytes = this.parser.getBytes(); } catch (FormulaException e) { logger.warn(e.getMessage() + " when parsing formula " + this.formulaToParse + " in cell " + getSheet().getName() + "!" + CellReferenceHelper.getCellReference(getColumn(), getRow())); try { this.formulaToParse = "ERROR(1)"; this.parser = new FormulaParser(this.formulaToParse, es, nt, ws); this.parser.parse(); this.formulaString = this.parser.getFormula(); this.formulaBytes = this.parser.getBytes(); } catch (FormulaException e2) { logger.error("", (Throwable)e2); } } } private void initializeCopiedFormula(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) { try { this.parser = new FormulaParser(this.formulaBytes, (Cell)this, es, nt, ws); this.parser.parse(); this.parser.adjustRelativeCellReferences(getColumn() - this.copiedFrom.getColumn(), getRow() - this.copiedFrom.getRow()); this.formulaString = this.parser.getFormula(); this.formulaBytes = this.parser.getBytes(); } catch (FormulaException e) { try { this.formulaToParse = "ERROR(1)"; this.parser = new FormulaParser(this.formulaToParse, es, nt, ws); this.parser.parse(); this.formulaString = this.parser.getFormula(); this.formulaBytes = this.parser.getBytes(); } catch (FormulaException e2) { logger.error("", (Throwable)e2); } } } void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) { super.setCellDetails(fr, ss, s); initialize(s.getWorkbookSettings(), s.getWorkbook(), s.getWorkbook()); s.getWorkbook().addRCIRCell(this); } public byte[] getData() { byte[] celldata = super.getData(); byte[] formulaData = getFormulaData(); byte[] data = new byte[formulaData.length + celldata.length]; System.arraycopy(celldata, 0, data, 0, celldata.length); System.arraycopy(formulaData, 0, data, celldata.length, formulaData.length); return data; } public CellType getType() { return CellType.ERROR; } public String getContents() { return this.formulaString; } public byte[] getFormulaData() { byte[] data = new byte[this.formulaBytes.length + 16]; System.arraycopy(this.formulaBytes, 0, data, 16, this.formulaBytes.length); data[6] = 16; data[7] = 64; data[12] = -32; data[13] = -4; data[8] = (byte)(data[8] | 0x2); IntegerHelper.getTwoBytes(this.formulaBytes.length, data, 14); return data; } public WritableCell copyTo(int col, int row) { Assert.verify(false); return null; } void columnInserted(Sheet s, int sheetIndex, int col) { this.parser.columnInserted(sheetIndex, col, (s == getSheet())); this.formulaBytes = this.parser.getBytes(); } void columnRemoved(Sheet s, int sheetIndex, int col) { this.parser.columnRemoved(sheetIndex, col, (s == getSheet())); this.formulaBytes = this.parser.getBytes(); } void rowInserted(Sheet s, int sheetIndex, int row) { this.parser.rowInserted(sheetIndex, row, (s == getSheet())); this.formulaBytes = this.parser.getBytes(); } void rowRemoved(Sheet s, int sheetIndex, int row) { this.parser.rowRemoved(sheetIndex, row, (s == getSheet())); this.formulaBytes = this.parser.getBytes(); } }