From: Jason Height Date: Thu, 27 Jul 2006 14:15:11 +0000 (+0000) Subject: Made a bit of a meal out of the Shared formula patch, some of our test cases failed... X-Git-Tag: REL_3_0_ALPHA3~61 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=2ece1574eb34bcb764a4dba87c174b9891cd4f6f;p=poi.git Made a bit of a meal out of the Shared formula patch, some of our test cases failed. Guess that is a good thing. Now working. Committed patch provided in Bug 40024. Avik, sorry bet you to it. Committed a patch to Bug 13249. HSSF will now raise an exception if a name is provided that is case-insensitive match to an existing name. In addition the getNameIndex now performs a case-insensitive search. This now matches excel behaviour. git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@426082 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java index 2f66be6bab..b74284eb46 100755 --- a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java +++ b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java @@ -199,59 +199,60 @@ public class SharedFormulaRecord formula.setExpressionLength(getExpressionLength()); Stack newPtgStack = new Stack(); - for (int k = 0; k < field_7_parsed_expr.size(); k++) { - Ptg ptg = (Ptg) field_7_parsed_expr.get(k); - if (ptg instanceof RefNPtg) { - RefNPtg refNPtg = (RefNPtg)ptg; - ptg = new ReferencePtg( (short)(formulaRow + refNPtg.getRow()), - (byte)(formulaColumn + refNPtg.getColumn()), - refNPtg.isRowRelative(), - refNPtg.isColRelative()); - } else if (ptg instanceof RefNVPtg) { - RefNVPtg refNVPtg = (RefNVPtg)ptg; - ptg = new RefVPtg( (short)(formulaRow + refNVPtg.getRow()), - (byte)(formulaColumn + refNVPtg.getColumn()), - refNVPtg.isRowRelative(), - refNVPtg.isColRelative()); - } else if (ptg instanceof RefNAPtg) { - RefNAPtg refNAPtg = (RefNAPtg)ptg; - ptg = new RefAPtg( (short)(formulaRow + refNAPtg.getRow()), - (byte)(formulaColumn + refNAPtg.getColumn()), - refNAPtg.isRowRelative(), - refNAPtg.isColRelative()); - } else if (ptg instanceof AreaNPtg) { - AreaNPtg areaNPtg = (AreaNPtg)ptg; - ptg = new AreaPtg((short)(formulaRow + areaNPtg.getFirstRow()), - (short)(formulaRow + areaNPtg.getLastRow()), - (short)(formulaColumn + areaNPtg.getFirstColumn()), - (short)(formulaColumn + areaNPtg.getLastColumn()), - areaNPtg.isFirstRowRelative(), - areaNPtg.isLastRowRelative(), - areaNPtg.isFirstColRelative(), - areaNPtg.isLastColRelative()); - } else if (ptg instanceof AreaNVPtg) { - AreaNVPtg areaNVPtg = (AreaNVPtg)ptg; - ptg = new AreaVPtg((short)(formulaRow + areaNVPtg.getFirstRow()), - (short)(formulaRow + areaNVPtg.getLastRow()), - (short)(formulaColumn + areaNVPtg.getFirstColumn()), - (short)(formulaColumn + areaNVPtg.getLastColumn()), - areaNVPtg.isFirstRowRelative(), - areaNVPtg.isLastRowRelative(), - areaNVPtg.isFirstColRelative(), - areaNVPtg.isLastColRelative()); - } else if (ptg instanceof AreaNAPtg) { - AreaNAPtg areaNAPtg = (AreaNAPtg)ptg; - ptg = new AreaAPtg((short)(formulaRow + areaNAPtg.getFirstRow()), - (short)(formulaRow + areaNAPtg.getLastRow()), - (short)(formulaColumn + areaNAPtg.getFirstColumn()), - (short)(formulaColumn + areaNAPtg.getLastColumn()), - areaNAPtg.isFirstRowRelative(), - areaNAPtg.isLastRowRelative(), - areaNAPtg.isFirstColRelative(), - areaNAPtg.isLastColRelative()); + if (field_7_parsed_expr != null) + for (int k = 0; k < field_7_parsed_expr.size(); k++) { + Ptg ptg = (Ptg) field_7_parsed_expr.get(k); + if (ptg instanceof RefNPtg) { + RefNPtg refNPtg = (RefNPtg)ptg; + ptg = new ReferencePtg( (short)(formulaRow + refNPtg.getRow()), + (byte)(formulaColumn + refNPtg.getColumn()), + refNPtg.isRowRelative(), + refNPtg.isColRelative()); + } else if (ptg instanceof RefNVPtg) { + RefNVPtg refNVPtg = (RefNVPtg)ptg; + ptg = new RefVPtg( (short)(formulaRow + refNVPtg.getRow()), + (byte)(formulaColumn + refNVPtg.getColumn()), + refNVPtg.isRowRelative(), + refNVPtg.isColRelative()); + } else if (ptg instanceof RefNAPtg) { + RefNAPtg refNAPtg = (RefNAPtg)ptg; + ptg = new RefAPtg( (short)(formulaRow + refNAPtg.getRow()), + (byte)(formulaColumn + refNAPtg.getColumn()), + refNAPtg.isRowRelative(), + refNAPtg.isColRelative()); + } else if (ptg instanceof AreaNPtg) { + AreaNPtg areaNPtg = (AreaNPtg)ptg; + ptg = new AreaPtg((short)(formulaRow + areaNPtg.getFirstRow()), + (short)(formulaRow + areaNPtg.getLastRow()), + (short)(formulaColumn + areaNPtg.getFirstColumn()), + (short)(formulaColumn + areaNPtg.getLastColumn()), + areaNPtg.isFirstRowRelative(), + areaNPtg.isLastRowRelative(), + areaNPtg.isFirstColRelative(), + areaNPtg.isLastColRelative()); + } else if (ptg instanceof AreaNVPtg) { + AreaNVPtg areaNVPtg = (AreaNVPtg)ptg; + ptg = new AreaVPtg((short)(formulaRow + areaNVPtg.getFirstRow()), + (short)(formulaRow + areaNVPtg.getLastRow()), + (short)(formulaColumn + areaNVPtg.getFirstColumn()), + (short)(formulaColumn + areaNVPtg.getLastColumn()), + areaNVPtg.isFirstRowRelative(), + areaNVPtg.isLastRowRelative(), + areaNVPtg.isFirstColRelative(), + areaNVPtg.isLastColRelative()); + } else if (ptg instanceof AreaNAPtg) { + AreaNAPtg areaNAPtg = (AreaNAPtg)ptg; + ptg = new AreaAPtg((short)(formulaRow + areaNAPtg.getFirstRow()), + (short)(formulaRow + areaNAPtg.getLastRow()), + (short)(formulaColumn + areaNAPtg.getFirstColumn()), + (short)(formulaColumn + areaNAPtg.getLastColumn()), + areaNAPtg.isFirstRowRelative(), + areaNAPtg.isLastRowRelative(), + areaNAPtg.isFirstColRelative(), + areaNAPtg.isLastColRelative()); + } + newPtgStack.add(ptg); } - newPtgStack.add(ptg); - } formula.setParsedExpression(newPtgStack); } else { throw new RuntimeException("Shared Formula Conversion: Coding Error"); diff --git a/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java index 0502f71d99..4b7fa23e5a 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java @@ -34,32 +34,12 @@ public class FormulaRecordAggregate private FormulaRecord formulaRecord; private StringRecord stringRecord; - /** - * will only be set through the RecordFactory - */ - private SharedFormulaRecord sharedFormulaRecord; - public FormulaRecordAggregate( FormulaRecord formulaRecord, StringRecord stringRecord ) { this.formulaRecord = formulaRecord; this.stringRecord = stringRecord; } - /** - * Used only in the clone - * @param formulaRecord - * @param stringRecord - * @param sharedRecord - */ - public FormulaRecordAggregate( FormulaRecord formulaRecord, StringRecord stringRecord, SharedFormulaRecord sharedRecord) - { - this.formulaRecord = formulaRecord; - this.stringRecord = stringRecord; - this.sharedFormulaRecord = sharedRecord; - } - - - protected void validateSid( short id ) { } @@ -82,10 +62,7 @@ public class FormulaRecordAggregate { int pos = offset; pos += formulaRecord.serialize(pos, data); - if (this.getSharedFormulaRecord() != null) - { - pos += getSharedFormulaRecord().serialize(pos, data); - } + if (stringRecord != null) { pos += stringRecord.serialize(pos, data); @@ -100,7 +77,6 @@ public class FormulaRecordAggregate public int getRecordSize() { int size = formulaRecord.getRecordSize() + (stringRecord == null ? 0 : stringRecord.getRecordSize()); - size += (getSharedFormulaRecord() == null) ? 0 : getSharedFormulaRecord().getRecordSize(); return size; } @@ -198,28 +174,10 @@ public class FormulaRecordAggregate */ public Object clone() { StringRecord clonedString = (stringRecord == null) ? null : (StringRecord)stringRecord.clone(); - SharedFormulaRecord clonedShared = (sharedFormulaRecord == null) ? null : (SharedFormulaRecord)sharedFormulaRecord.clone(); - return new FormulaRecordAggregate((FormulaRecord) this.formulaRecord.clone(), clonedString, clonedShared); + return new FormulaRecordAggregate((FormulaRecord) this.formulaRecord.clone(), clonedString); } - - - /** - * @return SharedFormulaRecord - */ - public SharedFormulaRecord getSharedFormulaRecord() { - return sharedFormulaRecord; - } - - /** - * Sets the sharedFormulaRecord, only set from RecordFactory since they are not generated by POI and are an Excel optimization - * @param sharedFormulaRecord The sharedFormulaRecord to set - */ - public void setSharedFormulaRecord(SharedFormulaRecord sharedFormulaRecord) { - this.sharedFormulaRecord = sharedFormulaRecord; - } - /* * Setting to true so that this value does not abort the whole ValueAggregation * (non-Javadoc) diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java index d13db98b46..46d50ceab5 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java @@ -125,7 +125,8 @@ public class ValueRecordsAggregate int k = 0; FormulaRecordAggregate lastFormulaAggregate = null; - SharedFormulaRecord lastSharedFormula = null; + + List sharedFormulas = new java.util.ArrayList(); for (k = offset; k < records.size(); k++) { @@ -134,17 +135,37 @@ public class ValueRecordsAggregate if (rec instanceof StringRecord == false && !rec.isInValueSection() && !(rec instanceof UnknownRecord)) { break; - } - if (rec instanceof FormulaRecord) + } else if (rec instanceof SharedFormulaRecord) { + sharedFormulas.add(rec); + } else if (rec instanceof FormulaRecord) { FormulaRecord formula = (FormulaRecord)rec; if (formula.isSharedFormula()) { + Record nextRecord = (Record) records.get(k + 1); + if (nextRecord instanceof SharedFormulaRecord) { + sharedFormulas.add(nextRecord); + k++; + } + //traverse the list of shared formulas in reverse order, and try to find the correct one + //for us + boolean found = false; + for (int i=sharedFormulas.size()-1;i>=0;i--) { + SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i); + if (shrd.isFormulaInShared(formula)) { + shrd.convertSharedFormulaRecord(formula); + found = true; + } + } + if (!found) + throw new RecordFormatException("Could not find appropriate shared formula"); +/* + if ((lastSharedFormula != null) && (lastSharedFormula.isFormulaInShared(formula))) { //Convert this Formula Record from a shared formula to a real formula lastSharedFormula.convertSharedFormulaRecord(formula); - } else { - Record nextRecord = (Record) records.get(k + 1); + } else { if (nextRecord instanceof SharedFormulaRecord) { + //Handle the SharedFormulaRecord and move on. k++; lastSharedFormula = (SharedFormulaRecord) nextRecord; @@ -154,21 +175,16 @@ public class ValueRecordsAggregate else throw new RuntimeException( "Shared formula bit set but next record is not a Shared Formula??"); - } + }*/ } - lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null); - insertCell( lastFormulaAggregate ); + lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null); + insertCell( lastFormulaAggregate ); } else if (rec instanceof StringRecord) { lastFormulaAggregate.setStringRecord((StringRecord)rec); } - //else if (rec instanceof SharedFormulaRecord) - //{ - // //these follow the first formula in a group - // lastFormulaAggregate.setSharedFormulaRecord((SharedFormulaRecord)rec); - //} else if (rec.isValue()) { insertCell(( CellValueRecordInterface ) rec); diff --git a/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java b/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java index 4f121ab0c2..343292c51c 100644 --- a/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java @@ -359,7 +359,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg { dmap.put(new Integer(258),"GETTOOLBAR"); dmap.put(new Integer(259),"GETTOOL"); dmap.put(new Integer(260),"SPELLINGCHECK"); - dmap.put(new Integer(261),"ERRORTYPE"); + dmap.put(new Integer(261),"ERROR.TYPE"); dmap.put(new Integer(262),"APPTITLE"); dmap.put(new Integer(263),"WINDOWTITLE"); dmap.put(new Integer(264),"SAVETOOLBAR"); @@ -716,7 +716,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg { - + functionData[261][0]=new Byte(Ptg.CLASS_VALUE);functionData[261][1]=new byte[] {Ptg.CLASS_VALUE};functionData[261][2]=new Integer(1); diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java new file mode 100644 index 0000000000..8144354f68 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java @@ -0,0 +1,88 @@ +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.BitField; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * AreaErr - handles deleted cell area references. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class AreaErrPtg extends AreaPtg +{ + public final static byte sid = 0x2b; + + private AreaErrPtg() + { + //Required for clone methods + super(); + } + + public AreaErrPtg(RecordInputStream in) + { + super(in); + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + + buffer.append("AreaErrPtg\n"); + buffer.append("firstRow = " + getFirstRow()).append("\n"); + buffer.append("lastRow = " + getLastRow()).append("\n"); + buffer.append("firstCol = " + getFirstColumn()).append("\n"); + buffer.append("lastCol = " + getLastColumn()).append("\n"); + buffer.append("firstColRowRel= " + + isFirstRowRelative()).append("\n"); + buffer.append("lastColRowRel = " + + isLastRowRelative()).append("\n"); + buffer.append("firstColRel = " + isFirstColRelative()).append("\n"); + buffer.append("lastColRel = " + isLastColRelative()).append("\n"); + return buffer.toString(); + } + + public void writeBytes(byte [] array, int offset) { + super.writeBytes(array, offset); + array[offset] = (byte) (sid + ptgClass); + } + + public String toFormulaString(Workbook book) + { + return "#REF!"; + } + + public Object clone() + { + AreaErrPtg ptg = new AreaErrPtg(); + ptg.setFirstRow(getFirstRow()); + ptg.setFirstColumn(getFirstColumn()); + ptg.setLastRow(getLastRow()); + ptg.setLastColumn(getLastColumn()); + ptg.setFirstColRelative(isFirstColRelative()); + ptg.setLastColRelative(isLastColRelative()); + ptg.setFirstRowRelative(isFirstRowRelative()); + ptg.setLastRowRelative(isLastRowRelative()); + ptg.setClass(ptgClass); + return ptg; + } +} + diff --git a/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java new file mode 100644 index 0000000000..47ab6116de --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java @@ -0,0 +1,90 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.hssf.usermodel.HSSFErrorConstants; + +/** + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class ErrPtg extends Ptg +{ + public static final short sid = 0x1c; + private static final int SIZE = 7; + private byte field_1_error_code; + + /** Creates new ErrPtg */ + + public ErrPtg() + { + } + + public ErrPtg(RecordInputStream in) + { + field_1_error_code = in.readByte(); + } + + public void writeBytes(byte [] array, int offset) + { + array[offset] = (byte) (sid + ptgClass); + array[offset + 1] = field_1_error_code; + } + + public String toFormulaString(Workbook book) + { + switch(field_1_error_code) + { + case HSSFErrorConstants.ERROR_NULL: + return "#NULL!"; + case HSSFErrorConstants.ERROR_DIV_0: + return "#DIV/0!"; + case HSSFErrorConstants.ERROR_VALUE: + return "#VALUE!"; + case HSSFErrorConstants.ERROR_REF: + return "#REF!"; + case HSSFErrorConstants.ERROR_NAME: + return "#NAME?"; + case HSSFErrorConstants.ERROR_NUM: + return "#NUM!"; + case HSSFErrorConstants.ERROR_NA: + return "#N/A"; + } + + // Shouldn't happen anyway. Excel docs say that this is returned for all other codes. + return "#N/A"; + } + + public int getSize() + { + return SIZE; + } + + public byte getDefaultOperandClass() + { + return Ptg.CLASS_VALUE; + } + + public Object clone() { + ErrPtg ptg = new ErrPtg(); + ptg.field_1_error_code = field_1_error_code; + return ptg; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java b/src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java new file mode 100644 index 0000000000..220c19ca0f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java @@ -0,0 +1,83 @@ +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class IntersectionPtg extends OperationPtg +{ + public final static byte sid = 0x0f; + + + public IntersectionPtg() + { + } + + public IntersectionPtg(RecordInputStream in) + { + // doesn't need anything + } + + + public int getSize() + { + return 1; + } + + public void writeBytes( byte[] array, int offset ) + { + array[ offset + 0 ] = sid; + } + + public Object clone() + { + return new IntersectionPtg(); + } + + public int getType() + { + return TYPE_BINARY; + } + + /** Implementation of method from Ptg */ + public String toFormulaString(Workbook book) + { + return " "; + } + + + /** implementation of method from OperationsPtg*/ + public String toFormulaString(String[] operands) + { + StringBuffer buffer = new StringBuffer(); + + buffer.append(operands[ 0 ]); + buffer.append(" "); + buffer.append(operands[ 1 ]); + return buffer.toString(); + } + + public int getNumberOfOperands() + { + return 2; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java b/src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java new file mode 100644 index 0000000000..75c041eca0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java @@ -0,0 +1,98 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +/* + * MemAreaPtg.java + * + * Created on November 21, 2001, 8:46 AM + */ +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class MemAreaPtg + extends Ptg +{ + public final static short sid = 0x26; + private final static int SIZE = 7; + private int field_1_reserved; + private short field_2_subex_len; + + /** Creates new MemAreaPtg */ + + public MemAreaPtg() + { + } + + public MemAreaPtg(RecordInputStream in) + { + field_1_reserved = in.readInt(); + field_2_subex_len = in.readShort(); + } + + public void setReserved(int res) + { + field_1_reserved = res; + } + + public int getReserved() + { + return field_1_reserved; + } + + public void setSubexpressionLength(short subexlen) + { + field_2_subex_len = subexlen; + } + + public short getSubexpressionLength() + { + return field_2_subex_len; + } + + public void writeBytes(byte [] array, int offset) + { + array[offset] = (byte) (sid + ptgClass); + LittleEndian.putInt(array, offset + 1, field_1_reserved); + LittleEndian.putShort(array, offset + 5, field_2_subex_len); + } + + public int getSize() + { + return SIZE; + } + + public String toFormulaString(Workbook book) + { + return ""; // TODO: Not sure how to format this. -- DN + } + + public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;} + + public Object clone() { + MemAreaPtg ptg = new MemAreaPtg(); + ptg.field_1_reserved = field_1_reserved; + ptg.field_2_subex_len = field_2_subex_len; + return ptg; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java index b4c6a34b06..c96983de83 100644 --- a/src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java @@ -31,15 +31,13 @@ import org.apache.poi.hssf.record.RecordInputStream; * * @author andy * @author Jason Height (jheight at chariot dot net dot au) + * @author Daniel Noll (daniel at nuix dot com dot au) */ public class MemErrPtg - extends Ptg + extends MemAreaPtg { public final static short sid = 0x27; - private final static int SIZE = 7; - private int field_1_reserved; - private short field_2_subex_len; /** Creates new MemErrPtg */ @@ -49,49 +47,24 @@ public class MemErrPtg public MemErrPtg(RecordInputStream in) { - field_1_reserved = in.readInt(); - field_2_subex_len = in.readShort(); - } - - public void setReserved(int res) - { - field_1_reserved = res; - } - - public int getReserved() - { - return field_1_reserved; - } - - public void setSubexpressionLength(short subexlen) - { - field_2_subex_len = subexlen; - } - - public short getSubexpressionLength() - { - return field_2_subex_len; + super(in); } public void writeBytes(byte [] array, int offset) { - } - - public int getSize() - { - return SIZE; + super.writeBytes(array, offset); + array[offset] = (byte) (sid + ptgClass); } public String toFormulaString(Workbook book) { return "ERR#"; } - public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;} public Object clone() { MemErrPtg ptg = new MemErrPtg(); - ptg.field_1_reserved = field_1_reserved; - ptg.field_2_subex_len = field_2_subex_len; + ptg.setReserved(getReserved()); + ptg.setSubexpressionLength(getSubexpressionLength()); return ptg; } } diff --git a/src/java/org/apache/poi/hssf/record/formula/PercentPtg.java b/src/java/org/apache/poi/hssf/record/formula/PercentPtg.java new file mode 100644 index 0000000000..4639f25678 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/PercentPtg.java @@ -0,0 +1,96 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +/* + * PercentPtg.java + * + * Created on March 29, 2006, 9:23 PM + */ +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * Percent PTG. + * + * @author Daniel Noll (daniel at nuix.com.au) + */ + +public class PercentPtg + extends OperationPtg +{ + public final static int SIZE = 1; + public final static byte sid = 0x14; + + private final static String PERCENT = "%"; + + /** Creates new PercentPtg */ + + public PercentPtg() + { + } + + public PercentPtg(RecordInputStream in) + { + + // doesn't need anything + } + + + public void writeBytes(byte [] array, int offset) + { + array[ offset + 0 ] = sid; + } + + public int getSize() + { + return SIZE; + } + + public int getType() + { + return TYPE_UNARY; + } + + public int getNumberOfOperands() + { + return 1; + } + + /** Implementation of method from Ptg */ + public String toFormulaString(Workbook book) + { + return "%"; + } + + /** implementation of method from OperationsPtg*/ + public String toFormulaString(String[] operands) { + StringBuffer buffer = new StringBuffer(); + + buffer.append(operands[ 0 ]); + buffer.append(PERCENT); + return buffer.toString(); + } + + public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;} + + public Object clone() { + return new PercentPtg(); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java index 660952c189..e02dba49c4 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java @@ -117,227 +117,238 @@ public abstract class Ptg byte id = in.readByte(); Ptg retval = null; - final byte valueFunc = FuncPtg.sid + 0x20; - final byte arrayFunc = FuncPtg.sid + 0x40; - final byte valueFuncVar = FuncVarPtg.sid +0x20; - final byte arrayFuncVar = FuncVarPtg.sid+0x40; - switch (id) { - case AddPtg.sid : - retval = new AddPtg(in); - break; - - case SubtractPtg.sid : - retval = new SubtractPtg(in); - break; - - case BoolPtg.sid: - retval = new BoolPtg(in); - break; - - case IntPtg.sid : - retval = new IntPtg(in); - break; - - case DividePtg.sid : - retval = new DividePtg(in); - break; - - case MultiplyPtg.sid : - retval = new MultiplyPtg(in); - break; - - case PowerPtg.sid : - retval = new PowerPtg(in); - break; + case ExpPtg.sid : // 0x01 + retval = new ExpPtg(in); + break; - case EqualPtg.sid: - retval = new EqualPtg(in); - break; - - case GreaterThanPtg.sid: - retval = new GreaterThanPtg(in); - break; - - case LessThanPtg.sid: - retval = new LessThanPtg(in); - break; - - case LessEqualPtg.sid: - retval = new LessEqualPtg(in); - break; - - case GreaterEqualPtg.sid: - retval = new GreaterEqualPtg(in); - break; - - case NotEqualPtg.sid: - retval = new NotEqualPtg(in); - break; - - case ConcatPtg.sid : - retval = new ConcatPtg(in); - break; - - case ArrayPtg.sid: - retval = new ArrayPtg(in); - break; - case ArrayPtgV.sid: - retval = new ArrayPtgV(in); - break; - case ArrayPtgA.sid: - retval = new ArrayPtgA(in); - break; - - case AreaPtg.sid : - retval = new AreaPtg(in); - break; - case AreaAPtg.sid: - retval = new AreaAPtg(in); - break; - case AreaVPtg.sid: - retval = new AreaVPtg(in); - break; - case AreaNAPtg.sid : - retval = new AreaNAPtg(in); + case AddPtg.sid : // 0x03 + retval = new AddPtg(in); break; - case AreaNPtg.sid : - retval = new AreaNPtg(in); - break; - case AreaNVPtg.sid : - retval = new AreaNVPtg(in); - break; - - case MemErrPtg.sid : // 0x27 These 3 values - case MemErrPtg.sid+0x20 : // 0x47 documented in - case MemErrPtg.sid+0x40 : // 0x67 openOffice.org doc. - retval = new MemErrPtg(in); - break; - - case AttrPtg.sid : - retval = new AttrPtg(in); - break; - - case ReferencePtg.sid : - retval = new ReferencePtg(in); - break; - case RefAPtg.sid : - retval = new RefAPtg(in); - break; - case RefVPtg.sid : - retval = new RefVPtg(in); - break; - case RefNAPtg.sid : - retval = new RefNAPtg(in); - break; - case RefNPtg.sid : - retval = new RefNPtg(in); - break; - case RefNVPtg.sid : - retval = new RefNVPtg(in); - break; - case RefErrorPtg.sid: - retval = new RefErrorPtg(in); - break; - - case ParenthesisPtg.sid : - retval = new ParenthesisPtg(in); - break; - - case MemFuncPtg.sid : - retval = new MemFuncPtg(in); - break; - - case UnionPtg.sid : - retval = new UnionPtg(in); - break; - - case FuncPtg.sid : - retval = new FuncPtg(in); - break; - - case valueFunc : - retval = new FuncPtg(in); - break; - case arrayFunc : - retval = new FuncPtg(in); - break; - - case FuncVarPtg.sid : - retval = new FuncVarPtg(in); - break; - - case valueFuncVar : - retval = new FuncVarPtg(in); - break; - case arrayFuncVar : - retval = new FuncVarPtg(in); - break; - - case NumberPtg.sid : - retval = new NumberPtg(in); - break; - - case StringPtg.sid : - retval = new StringPtg(in); - break; - - case NamePtg.sid : // 0x23 These 3 values - case NamePtg.sid+0x20 : // 0x43 documented in - case NamePtg.sid+0x40 : // 0x63 openOffice.org doc. - - retval = new NamePtg(in); - break; - - case NameXPtg.sid : // 0x39 - case NameXPtg.sid+0x20 : // 0x45 - case NameXPtg.sid+0x40 : // 0x79 - - retval = new NameXPtg(in); - break; - - case ExpPtg.sid : - retval = new ExpPtg(in); - break; - - case Area3DPtg.sid : // 0x3b These 3 values - case Area3DPtg.sid+0x20 : // 0x5b documented in - case Area3DPtg.sid+0x40 : // 0x7b openOffice.org doc. - - retval = new Area3DPtg(in); - break; - - case Ref3DPtg.sid: // 0x3a These 3 values - case Ref3DPtg.sid+0x20: // 0x5a documented in - case Ref3DPtg.sid+0x40: // 0x7a openOffice.org doc. - - retval = new Ref3DPtg(in); - break; - - case DeletedArea3DPtg.sid : // 0x3d - case DeletedArea3DPtg.sid+0x20 : // 0x5d - case DeletedArea3DPtg.sid+0x40 : // 0x7d - - retval = new DeletedArea3DPtg(in); - break; - - case DeletedRef3DPtg.sid: // 0x3c - case DeletedRef3DPtg.sid+0x20: // 0x5c - case DeletedRef3DPtg.sid+0x40: // 0x7c - - retval = new DeletedRef3DPtg(in); - break; - - case MissingArgPtg.sid: - retval = new MissingArgPtg(in); - break; - case UnaryPlusPtg.sid: - retval=new UnaryPlusPtg(in); + + case SubtractPtg.sid : // 0x04 + retval = new SubtractPtg(in); + break; + + case MultiplyPtg.sid : // 0x05 + retval = new MultiplyPtg(in); + break; + + case DividePtg.sid : // 0x06 + retval = new DividePtg(in); + break; + + case PowerPtg.sid : // 0x07 + retval = new PowerPtg(in); + break; + + case ConcatPtg.sid : // 0x08 + retval = new ConcatPtg(in); + break; + + case LessThanPtg.sid: // 0x09 + retval = new LessThanPtg(in); + break; + + case LessEqualPtg.sid : // 0x0a + retval = new LessEqualPtg(in); + break; + + case EqualPtg.sid : // 0x0b + retval = new EqualPtg(in); + break; + + case GreaterEqualPtg.sid : // 0x0c + retval = new GreaterEqualPtg(in); + break; + + case GreaterThanPtg.sid : // 0x0d + retval = new GreaterThanPtg(in); + break; + + case NotEqualPtg.sid : // 0x0e + retval = new NotEqualPtg(in); + break; + + case IntersectionPtg.sid : // 0x0f + retval = new IntersectionPtg(in); + break; + case UnionPtg.sid : // 0x10 + retval = new UnionPtg(in); + break; + + case RangePtg.sid : // 0x11 + retval = new RangePtg(in); + break; + + case UnaryPlusPtg.sid : // 0x12 + retval = new UnaryPlusPtg(in); + break; + + case UnaryMinusPtg.sid : // 0x13 + retval = new UnaryMinusPtg(in); + break; + + case PercentPtg.sid : // 0x14 + retval = new PercentPtg(in); + break; + + case ParenthesisPtg.sid : // 0x15 + retval = new ParenthesisPtg(in); + break; + + case MissingArgPtg.sid : // 0x16 + retval = new MissingArgPtg(in); + break; + + case StringPtg.sid : // 0x17 + retval = new StringPtg(in); break; - case UnaryMinusPtg.sid: - retval=new UnaryMinusPtg(in); + + case AttrPtg.sid : // 0x19 + retval = new AttrPtg(in); + break; + + case ErrPtg.sid : // 0x1c + retval = new ErrPtg(in); + break; + + case BoolPtg.sid : // 0x1d + retval = new BoolPtg(in); break; + + case IntPtg.sid : // 0x1e + retval = new IntPtg(in); + break; + + case NumberPtg.sid : // 0x1f + retval = new NumberPtg(in); + break; + + case ArrayPtg.sid : // 0x20 + retval = new ArrayPtg(in); + break; + case ArrayPtgV.sid : // 0x40 + retval = new ArrayPtgV(in); + break; + case ArrayPtgA.sid : // 0x60 + retval = new ArrayPtgA(in); + break; + + case FuncPtg.sid : // 0x21 + case FuncPtg.sid + 0x20 : // 0x41 + case FuncPtg.sid + 0x40 : // 0x61 + retval = new FuncPtg(in); + break; + + case FuncVarPtg.sid : // 0x22 + case FuncVarPtg.sid + 0x20 : // 0x42 + case FuncVarPtg.sid + 0x40 : // 0x62 + retval = new FuncVarPtg(in); + break; + + case ReferencePtg.sid : // 0x24 + retval = new ReferencePtg(in); + break; + case RefAPtg.sid : // 0x64 + retval = new RefAPtg(in); + break; + case RefVPtg.sid : // 0x44 + retval = new RefVPtg(in); + break; + case RefNAPtg.sid : // 0x6C + retval = new RefNAPtg(in); + break; + case RefNPtg.sid : // 0x2C + retval = new RefNPtg(in); + break; + case RefNVPtg.sid : // 0x4C + retval = new RefNVPtg(in); + break; + + case AreaPtg.sid : // 0x25 + retval = new AreaPtg(in); + break; + case AreaVPtg.sid: // 0x45 + retval = new AreaVPtg(in); + break; + case AreaAPtg.sid: // 0x65 + retval = new AreaAPtg(in); + break; + case AreaNAPtg.sid : // 0x6D + retval = new AreaNAPtg(in); + break; + case AreaNPtg.sid : // 0x2D + retval = new AreaNPtg(in); + break; + case AreaNVPtg.sid : // 0x4D + retval = new AreaNVPtg(in); + break; + + case MemAreaPtg.sid : // 0x26 + case MemAreaPtg.sid + 0x40 : // 0x46 + case MemAreaPtg.sid + 0x20 : // 0x66 + retval = new MemAreaPtg(in); + break; + + case MemErrPtg.sid : // 0x27 + case MemErrPtg.sid + 0x20 : // 0x47 + case MemErrPtg.sid + 0x40 : // 0x67 + retval = new MemErrPtg(in); + break; + + case MemFuncPtg.sid : // 0x29 + retval = new MemFuncPtg(in); + break; + + case RefErrorPtg.sid : // 0x2a + case RefErrorPtg.sid + 0x20 : // 0x4a + case RefErrorPtg.sid + 0x40 : // 0x6a + retval = new RefErrorPtg(in); + break; + + case AreaErrPtg.sid : // 0x2b + case AreaErrPtg.sid + 0x20 : // 0x4b + case AreaErrPtg.sid + 0x40 : // 0x6b + retval = new AreaErrPtg(in); + break; + + case NamePtg.sid : // 0x23 + case NamePtg.sid + 0x20 : // 0x43 + case NamePtg.sid + 0x40 : // 0x63 + retval = new NamePtg(in); + break; + + case NameXPtg.sid : // 0x39 + case NameXPtg.sid + 0x20 : // 0x45 + case NameXPtg.sid + 0x40 : // 0x79 + retval = new NameXPtg(in); + break; + + case Area3DPtg.sid : // 0x3b + case Area3DPtg.sid + 0x20 : // 0x5b + case Area3DPtg.sid + 0x40 : // 0x7b + retval = new Area3DPtg(in); + break; + + case Ref3DPtg.sid : // 0x3a + case Ref3DPtg.sid + 0x20: // 0x5a + case Ref3DPtg.sid + 0x40: // 0x7a + retval = new Ref3DPtg(in); + break; + + case DeletedRef3DPtg.sid: // 0x3c + case DeletedRef3DPtg.sid + 0x20: // 0x5c + case DeletedRef3DPtg.sid + 0x40: // 0x7c + retval = new DeletedRef3DPtg(in); + break; + + case DeletedArea3DPtg.sid : // 0x3d + case DeletedArea3DPtg.sid + 0x20 : // 0x5d + case DeletedArea3DPtg.sid + 0x40 : // 0x7d + retval = new DeletedArea3DPtg(in); + break; default : @@ -350,8 +361,10 @@ public abstract class Ptg retval.setClass(CLASS_ARRAY); } else if (id > 0x40) { retval.setClass(CLASS_VALUE); - } else + } else { retval.setClass(CLASS_REF); + } + return retval; } diff --git a/src/java/org/apache/poi/hssf/record/formula/RangePtg.java b/src/java/org/apache/poi/hssf/record/formula/RangePtg.java new file mode 100644 index 0000000000..637317e178 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/RangePtg.java @@ -0,0 +1,83 @@ +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class RangePtg extends OperationPtg +{ + public final static byte sid = 0x11; + + + public RangePtg() + { + } + + public RangePtg(RecordInputStream in) + { + // doesn't need anything + } + + + public int getSize() + { + return 1; + } + + public void writeBytes( byte[] array, int offset ) + { + array[ offset + 0 ] = sid; + } + + public Object clone() + { + return new RangePtg(); + } + + public int getType() + { + return TYPE_BINARY; + } + + /** Implementation of method from Ptg */ + public String toFormulaString(Workbook book) + { + return ":"; + } + + + /** implementation of method from OperationsPtg*/ + public String toFormulaString(String[] operands) + { + StringBuffer buffer = new StringBuffer(); + + buffer.append(operands[ 0 ]); + buffer.append(":"); + buffer.append(operands[ 1 ]); + return buffer.toString(); + } + + public int getNumberOfOperands() + { + return 2; + } + +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java index 2b4edd8fff..3f47080f2a 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.BoundSheetRecord; import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.util.RangeAddress; @@ -75,6 +76,16 @@ public class HSSFName { public void setNameName(String nameName){ name.setNameText(nameName); name.setNameTextLength((byte)nameName.length()); + + //Check to ensure no other names have the same case-insensitive name + for ( int i = book.getNumNames()-1; i >=0; i-- ) + { + NameRecord rec = book.getNameRecord(i); + if (rec != name) { + if (rec.getNameText().equalsIgnoreCase(getNameName())) + throw new IllegalArgumentException("The workbook already contains this name (case-insensitive)"); + } + } } /** diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index a953315f96..13c4669e22 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -1076,6 +1076,9 @@ public class HSSFWorkbook } /** gets the named range index by his name + * Note:Excel named ranges are case-insensitive and + * this method performs a case-insensitive search. + * * @param name named range name * @return named range index */ @@ -1087,7 +1090,7 @@ public class HSSFWorkbook { String nameName = getNameName(k); - if (nameName.equals(name)) + if (nameName.equalsIgnoreCase(name)) { retval = k; break; diff --git a/src/testcases/org/apache/poi/hssf/HSSFTests.java b/src/testcases/org/apache/poi/hssf/HSSFTests.java index 8d1b1bfc83..5f68d8608f 100644 --- a/src/testcases/org/apache/poi/hssf/HSSFTests.java +++ b/src/testcases/org/apache/poi/hssf/HSSFTests.java @@ -74,7 +74,13 @@ import org.apache.poi.hssf.record.TestUnitsRecord; import org.apache.poi.hssf.record.TestValueRangeRecord; import org.apache.poi.hssf.record.aggregates.TestRowRecordsAggregate; import org.apache.poi.hssf.record.aggregates.TestValueRecordsAggregate; +import org.apache.poi.hssf.record.formula.TestAreaErrPtg; +import org.apache.poi.hssf.record.formula.TestErrPtg; import org.apache.poi.hssf.record.formula.TestFuncPtg; +import org.apache.poi.hssf.record.formula.TestIntersectionPtg; +import org.apache.poi.hssf.record.formula.TestPercentPtg; +import org.apache.poi.hssf.record.formula.TestRangePtg; +import org.apache.poi.hssf.record.formula.TestUnionPtg; import org.apache.poi.hssf.usermodel.TestBugs; import org.apache.poi.hssf.usermodel.TestCellStyle; import org.apache.poi.hssf.usermodel.TestCloneSheet; @@ -207,7 +213,13 @@ public class HSSFTests suite.addTest(new TestSuite(TestSheetReferences.class)); + suite.addTest(new TestSuite(TestAreaErrPtg.class)); + suite.addTest(new TestSuite(TestErrPtg.class)); suite.addTest(new TestSuite(TestFuncPtg.class)); + suite.addTest(new TestSuite(TestIntersectionPtg.class)); + suite.addTest(new TestSuite(TestPercentPtg.class)); + suite.addTest(new TestSuite(TestRangePtg.class)); + suite.addTest(new TestSuite(TestUnionPtg.class)); suite.addTest(new TestSuite(TestValueRecordsAggregate.class)); suite.addTest(new TestSuite(TestNameRecord.class)); suite.addTest(new TestSuite(TestEventRecordFactory.class)); diff --git a/src/testcases/org/apache/poi/hssf/data/AreaErrPtg.xls b/src/testcases/org/apache/poi/hssf/data/AreaErrPtg.xls new file mode 100644 index 0000000000..ce863b8f61 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/AreaErrPtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/ErrPtg.xls b/src/testcases/org/apache/poi/hssf/data/ErrPtg.xls new file mode 100644 index 0000000000..50035994a4 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/ErrPtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/IntersectionPtg.xls b/src/testcases/org/apache/poi/hssf/data/IntersectionPtg.xls new file mode 100644 index 0000000000..74b87db3cd Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/IntersectionPtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/PercentPtg.xls b/src/testcases/org/apache/poi/hssf/data/PercentPtg.xls new file mode 100644 index 0000000000..42414766c5 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/PercentPtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/RangePtg.xls b/src/testcases/org/apache/poi/hssf/data/RangePtg.xls new file mode 100644 index 0000000000..889dd00717 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/RangePtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/UnionPtg.xls b/src/testcases/org/apache/poi/hssf/data/UnionPtg.xls new file mode 100644 index 0000000000..189f8c6413 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/UnionPtg.xls differ diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java index 560db0a655..fd30da835c 100755 --- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java @@ -28,7 +28,7 @@ public class TestValueRecordsAggregate extends TestCase ValueRecordsAggregate valueRecord = new ValueRecordsAggregate(); /** - * Make sure the shared formula makes it to the FormulaRecordAggregate when being parsed + * Make sure the shared formula DOESNT makes it to the FormulaRecordAggregate when being parsed * as part of the value records */ public void testSharedFormula() @@ -42,8 +42,8 @@ public class TestValueRecordsAggregate extends TestCase Record record = (Record) iterator.next(); assertNotNull( "Row contains a value", record ); assertTrue( "First record is a FormulaRecordsAggregate", ( record instanceof FormulaRecordAggregate ) ); - FormulaRecordAggregate aggregate = (FormulaRecordAggregate) record; - assertNotNull( "SharedFormulaRecord is null", aggregate.getSharedFormulaRecord() ); + //Ensure that the SharedFormulaRecord has been converted + assertFalse( "SharedFormulaRecord is null", iterator.hasNext() ); } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java b/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java new file mode 100644 index 0000000000..71d85c8657 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java @@ -0,0 +1,61 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Convenient abstract class to reduce the amount of boilerplate code needed + * in ptg-related unit tests. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class AbstractPtgTestCase extends TestCase +{ + /** Directory containing the test data. */ + private static String dataDir = System.getProperty("HSSF.testdata.path"); + + /** + * Loads a workbook from the given filename in the test data dir. + * + * @param filename the filename. + * @return the loaded workbook. + * @throws IOException if an error occurs loading the workbook. + */ + protected static HSSFWorkbook loadWorkbook(String filename) + throws IOException { + File file = new File(dataDir, filename); + InputStream stream = new BufferedInputStream(new FileInputStream(file)); + try + { + return new HSSFWorkbook(stream); + } + finally + { + stream.close(); + } + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestAreaErrPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestAreaErrPtg.java new file mode 100644 index 0000000000..2c35a09c45 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestAreaErrPtg.java @@ -0,0 +1,40 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link AreaErrPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestAreaErrPtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("AreaErrPtg.xls"); + assertEquals("Wrong formula string for area error", "SUM(#REF!)", + workbook.getSheetAt(0).getRow(0).getCell((short) 2).getCellFormula()); + } +} + + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestErrPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestErrPtg.java new file mode 100644 index 0000000000..cb9522c3b3 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestErrPtg.java @@ -0,0 +1,42 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link ErrPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestErrPtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("ErrPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(3).getCell((short) 0); + assertEquals("Wrong cell value", 4.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "ERROR.TYPE(#REF!)", cell.getCellFormula()); + } +} + + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestIntersectionPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestIntersectionPtg.java new file mode 100644 index 0000000000..9aa651cd1f --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestIntersectionPtg.java @@ -0,0 +1,42 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link IntersectionPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestIntersectionPtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("IntersectionPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(4).getCell((short) 2); + assertEquals("Wrong cell value", 5.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(A1:B2 B2:C3)", cell.getCellFormula()); + } +} + + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestPercentPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestPercentPtg.java new file mode 100644 index 0000000000..d76071ce78 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestPercentPtg.java @@ -0,0 +1,47 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link PercentPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestPercentPtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("PercentPtg.xls"); + HSSFSheet sheet = workbook.getSheetAt(0); + + assertEquals("Wrong numeric value for original number", 53000.0, + sheet.getRow(0).getCell((short) 0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for percent formula result", 5300.0, + sheet.getRow(1).getCell((short) 0).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for percent formula", "A1*10%", + sheet.getRow(1).getCell((short) 0).getCellFormula()); + } +} + + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestRangePtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestRangePtg.java new file mode 100644 index 0000000000..4ab7b49a54 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestRangePtg.java @@ -0,0 +1,42 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link RangePtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestRangePtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("RangePtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(3).getCell((short) 1); + assertEquals("Wrong cell value", 10.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(pineapple:B2)", cell.getCellFormula()); + } +} + + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestUnionPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestUnionPtg.java new file mode 100644 index 0000000000..0db0fd5d45 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestUnionPtg.java @@ -0,0 +1,42 @@ + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link UnionPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class TestUnionPtg extends AbstractPtgTestCase +{ + /** + * Tests reading a file containing this ptg. + */ + public void testReading() throws Exception + { + HSSFWorkbook workbook = loadWorkbook("UnionPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(4).getCell((short) 2); + assertEquals("Wrong cell value", 24.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(A1:B2,B2:C3)", cell.getCellFormula()); + } +} + +