You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/09/13 15:48:31 UTC
svn commit: r694947 [2/6] - in /poi/branches/ooxml: ./
src/documentation/content/xdocs/ src/java/org/apache/poi/hssf/extractor/
src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/
src/java/org/apache/poi/hssf/record/aggregates/ src...
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java Sat Sep 13 06:48:27 2008
@@ -18,18 +18,35 @@
package org.apache.poi.hssf.record.aggregates;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.ColumnInfoRecord;
-import org.apache.poi.hssf.record.Record;
/**
* @author Glen Stampoultzis
- * @version $Id$
*/
public final class ColumnInfoRecordsAggregate extends RecordAggregate {
+ /**
+ * List of {@link ColumnInfoRecord}s assumed to be in order
+ */
private final List records;
+
+
+ private static final class CIRComparator implements Comparator {
+ public static final Comparator instance = new CIRComparator();
+ private CIRComparator() {
+ // enforce singleton
+ }
+ public int compare(Object a, Object b) {
+ return compareColInfos((ColumnInfoRecord)a, (ColumnInfoRecord)b);
+ }
+ public static int compareColInfos(ColumnInfoRecord a, ColumnInfoRecord b) {
+ return a.getFirstColumn()-b.getFirstColumn();
+ }
+ }
/**
* Creates an empty aggregate
@@ -37,486 +54,470 @@
public ColumnInfoRecordsAggregate() {
records = new ArrayList();
}
- public ColumnInfoRecordsAggregate(RecordStream rs) {
- this();
-
- while(rs.peekNextClass() == ColumnInfoRecord.class) {
- records.add(rs.getNext());
- }
- if (records.size() < 1) {
- throw new RuntimeException("No column info records found");
- }
- }
-
- /**
- * Performs a deep clone of the record
- */
- public Object clone()
- {
- ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate();
- for (int k = 0; k < records.size(); k++)
- {
- ColumnInfoRecord ci = ( ColumnInfoRecord ) records.get(k);
- ci=(ColumnInfoRecord) ci.clone();
- rec.insertColumn( ci );
- }
- return rec;
- }
-
- /**
- * Inserts a column into the aggregate (at the end of the list).
- */
- public void insertColumn( ColumnInfoRecord col )
- {
- records.add( col );
- }
-
- /**
- * Inserts a column into the aggregate (at the position specified
- * by <code>idx</code>.
- */
- public void insertColumn( int idx, ColumnInfoRecord col )
- {
- records.add( idx, col );
- }
-
- public int getNumColumns( )
- {
- return records.size();
- }
-
- public void visitContainedRecords(RecordVisitor rv) {
- int nItems = records.size();
- if (nItems < 1) {
- return;
- }
- for(int i=0; i<nItems; i++) {
- rv.visitRecord((Record)records.get(i));
- }
- }
-
- public int findStartOfColumnOutlineGroup(int idx)
- {
- // Find the start of the group.
- ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx );
- int level = columnInfo.getOutlineLevel();
- while (idx != 0)
- {
- ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) records.get( idx - 1 );
- if (columnInfo.getFirstColumn() - 1 == prevColumnInfo.getLastColumn())
- {
- if (prevColumnInfo.getOutlineLevel() < level)
- {
- break;
- }
- idx--;
- columnInfo = prevColumnInfo;
- }
- else
- {
- break;
- }
- }
-
- return idx;
- }
-
- public int findEndOfColumnOutlineGroup(int idx)
- {
- // Find the end of the group.
- ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx );
- int level = columnInfo.getOutlineLevel();
- while (idx < records.size() - 1)
- {
- ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get( idx + 1 );
- if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn())
- {
- if (nextColumnInfo.getOutlineLevel() < level)
- {
- break;
- }
- idx++;
- columnInfo = nextColumnInfo;
- }
- else
- {
- break;
- }
- }
-
- return idx;
- }
-
- private ColumnInfoRecord getColInfo(int idx) {
- return (ColumnInfoRecord) records.get( idx );
- }
-
- public ColumnInfoRecord writeHidden( ColumnInfoRecord columnInfo, int idx, boolean hidden )
- {
- int level = columnInfo.getOutlineLevel();
- while (idx < records.size())
- {
- columnInfo.setHidden( hidden );
- if (idx + 1 < records.size())
- {
- ColumnInfoRecord nextColumnInfo = getColInfo(idx + 1);
- if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn())
- {
- if (nextColumnInfo.getOutlineLevel() < level)
- break;
- columnInfo = nextColumnInfo;
- }
- else
- {
- break;
- }
- }
- idx++;
- }
- return columnInfo;
- }
-
- public boolean isColumnGroupCollapsed( int idx )
- {
- int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
- if (endOfOutlineGroupIdx >= records.size())
- return false;
- if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn())
- return false;
- else
- return getColInfo(endOfOutlineGroupIdx+1).getCollapsed();
- }
-
-
- public boolean isColumnGroupHiddenByParent( int idx )
- {
- // Look out outline details of end
- int endLevel;
- boolean endHidden;
- int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
- if (endOfOutlineGroupIdx >= records.size())
- {
- endLevel = 0;
- endHidden = false;
- }
- else if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn())
- {
- endLevel = 0;
- endHidden = false;
- }
- else
- {
- endLevel = getColInfo( endOfOutlineGroupIdx + 1).getOutlineLevel();
- endHidden = getColInfo( endOfOutlineGroupIdx + 1).getHidden();
- }
-
- // Look out outline details of start
- int startLevel;
- boolean startHidden;
- int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx );
- if (startOfOutlineGroupIdx <= 0)
- {
- startLevel = 0;
- startHidden = false;
- }
- else if (getColInfo(startOfOutlineGroupIdx).getFirstColumn() - 1 != getColInfo(startOfOutlineGroupIdx - 1).getLastColumn())
- {
- startLevel = 0;
- startHidden = false;
- }
- else
- {
- startLevel = getColInfo( startOfOutlineGroupIdx - 1).getOutlineLevel();
- startHidden = getColInfo( startOfOutlineGroupIdx - 1 ).getHidden();
- }
-
- if (endLevel > startLevel)
- {
- return endHidden;
- }
- else
- {
- return startHidden;
- }
- }
-
- public void collapseColumn( short columnNumber )
- {
- int idx = findColumnIdx( columnNumber, 0 );
- if (idx == -1)
- return;
-
- // Find the start of the group.
- ColumnInfoRecord columnInfo = getColInfo( findStartOfColumnOutlineGroup( idx ) );
-
- // Hide all the columns until the end of the group
- columnInfo = writeHidden( columnInfo, idx, true );
-
- // Write collapse field
- setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, null, Boolean.TRUE);
- }
-
- public void expandColumn( short columnNumber )
- {
- int idx = findColumnIdx( columnNumber, 0 );
- if (idx == -1)
- return;
-
- // If it is already exapanded do nothing.
- if (!isColumnGroupCollapsed(idx))
- return;
-
- // Find the start of the group.
- int startIdx = findStartOfColumnOutlineGroup( idx );
- ColumnInfoRecord columnInfo = getColInfo( startIdx );
-
- // Find the end of the group.
- int endIdx = findEndOfColumnOutlineGroup( idx );
- ColumnInfoRecord endColumnInfo = getColInfo( endIdx );
-
- // expand:
- // colapsed bit must be unset
- // hidden bit gets unset _if_ surrounding groups are expanded you can determine
- // this by looking at the hidden bit of the enclosing group. You will have
- // to look at the start and the end of the current group to determine which
- // is the enclosing group
- // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
- if (!isColumnGroupHiddenByParent( idx ))
- {
- for (int i = startIdx; i <= endIdx; i++)
- {
- if (columnInfo.getOutlineLevel() == getColInfo(i).getOutlineLevel())
- getColInfo(i).setHidden( false );
- }
- }
-
- // Write collapse field
- setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, null, Boolean.FALSE);
- }
-
- /**
- * creates the ColumnInfo Record and sets it to a default column/width
- * @see org.apache.poi.hssf.record.ColumnInfoRecord
- * @return record containing a ColumnInfoRecord
- */
- public static ColumnInfoRecord createColInfo()
- {
- ColumnInfoRecord retval = new ColumnInfoRecord();
-
- retval.setColumnWidth(( short ) 2275);
- // was: retval.setOptions(( short ) 6);
- retval.setOptions(( short ) 2);
- retval.setXFIndex(( short ) 0x0f);
- return retval;
- }
-
-
- public void setColumn(short column, Short xfIndex, Short width, Integer level, Boolean hidden, Boolean collapsed)
- {
- ColumnInfoRecord ci = null;
- int k = 0;
-
- for (k = 0; k < records.size(); k++)
- {
- ci = ( ColumnInfoRecord ) records.get(k);
- if ((ci.getFirstColumn() <= column)
- && (column <= ci.getLastColumn()))
- {
- break;
- }
- ci = null;
- }
-
- if (ci != null)
- {
- boolean styleChanged = xfIndex != null && ci.getXFIndex() != xfIndex.shortValue();
- boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue();
- boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue();
- boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue();
- boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue();
- boolean columnChanged = styleChanged || widthChanged || levelChanged || hiddenChanged || collapsedChanged;
- if (!columnChanged)
- {
- // do nothing...nothing changed.
- }
- else if ((ci.getFirstColumn() == column)
- && (ci.getLastColumn() == column))
- { // if its only for this cell then
- setColumnInfoFields( ci, xfIndex, width, level, hidden, collapsed );
- }
- else if ((ci.getFirstColumn() == column)
- || (ci.getLastColumn() == column))
- {
- // okay so the width is different but the first or last column == the column we'return setting
- // we'll just divide the info and create a new one
- if (ci.getFirstColumn() == column)
- {
- ci.setFirstColumn(( short ) (column + 1));
- }
- else
- {
- ci.setLastColumn(( short ) (column - 1));
- }
- ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
-
- nci.setFirstColumn(column);
- nci.setLastColumn(column);
- nci.setOptions(ci.getOptions());
- nci.setXFIndex(ci.getXFIndex());
- setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
-
- insertColumn(k, nci);
- }
- else
- {
- //split to 3 records
- short lastcolumn = ci.getLastColumn();
- ci.setLastColumn(( short ) (column - 1));
-
- ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
- nci.setFirstColumn(column);
- nci.setLastColumn(column);
- nci.setOptions(ci.getOptions());
- nci.setXFIndex(ci.getXFIndex());
- setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
- insertColumn(++k, nci);
-
- nci = ( ColumnInfoRecord ) createColInfo();
- nci.setFirstColumn((short)(column+1));
- nci.setLastColumn(lastcolumn);
- nci.setOptions(ci.getOptions());
- nci.setXFIndex(ci.getXFIndex());
- nci.setColumnWidth(ci.getColumnWidth());
- insertColumn(++k, nci);
- }
- }
- else
- {
-
- // okay so there ISN'T a column info record that cover's this column so lets create one!
- ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
-
- nci.setFirstColumn(column);
- nci.setLastColumn(column);
- setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
- insertColumn(k, nci);
- }
- }
-
- /**
- * Sets all non null fields into the <code>ci</code> parameter.
- */
- private void setColumnInfoFields( ColumnInfoRecord ci, Short xfStyle, Short width, Integer level, Boolean hidden, Boolean collapsed )
- {
- if (xfStyle != null)
- ci.setXFIndex(xfStyle.shortValue());
- if (width != null)
- ci.setColumnWidth(width.shortValue());
- if (level != null)
- ci.setOutlineLevel( level.shortValue() );
- if (hidden != null)
- ci.setHidden( hidden.booleanValue() );
- if (collapsed != null)
- ci.setCollapsed( collapsed.booleanValue() );
- }
-
- private int findColumnIdx(int column, int fromIdx)
- {
- if (column < 0)
- throw new IllegalArgumentException( "column parameter out of range: " + column );
- if (fromIdx < 0)
- throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromIdx );
-
- ColumnInfoRecord ci;
- for (int k = fromIdx; k < records.size(); k++)
- {
- ci = getColInfo(k);
- if ((ci.getFirstColumn() <= column)
- && (column <= ci.getLastColumn()))
- {
- return k;
- }
- ci = null;
- }
- return -1;
- }
-
- public void collapseColInfoRecords( int columnIdx )
- {
- if (columnIdx == 0)
- return;
- ColumnInfoRecord previousCol = getColInfo( columnIdx - 1);
- ColumnInfoRecord currentCol = getColInfo( columnIdx );
- boolean adjacentColumns = previousCol.getLastColumn() == currentCol.getFirstColumn() - 1;
- if (!adjacentColumns)
- return;
-
- boolean columnsMatch =
- previousCol.getXFIndex() == currentCol.getXFIndex() &&
- previousCol.getOptions() == currentCol.getOptions() &&
- previousCol.getColumnWidth() == currentCol.getColumnWidth();
-
- if (columnsMatch)
- {
- previousCol.setLastColumn( currentCol.getLastColumn() );
- records.remove( columnIdx );
- }
- }
-
- /**
- * Creates an outline group for the specified columns.
- * @param fromColumn group from this column (inclusive)
- * @param toColumn group to this column (inclusive)
- * @param indent if true the group will be indented by one level,
- * if false indenting will be removed by one level.
- */
- public void groupColumnRange(short fromColumn, short toColumn, boolean indent)
- {
-
- // Set the level for each column
- int fromIdx = 0;
- for (int i = fromColumn; i <= toColumn; i++)
- {
- int level = 1;
- int columnIdx = findColumnIdx( i, Math.max(0,fromIdx) );
- if (columnIdx != -1)
- {
- level = getColInfo(columnIdx).getOutlineLevel();
- if (indent) level++; else level--;
- level = Math.max(0, level);
- level = Math.min(7, level);
- fromIdx = columnIdx - 1; // subtract 1 just in case this column is collapsed later.
- }
- setColumn((short)i, null, null, new Integer(level), null, null);
- columnIdx = findColumnIdx( i, Math.max(0, fromIdx ) );
- collapseColInfoRecords( columnIdx );
- }
-
- }
- /**
- * Finds the <tt>ColumnInfoRecord</tt> which contains the specified columnIndex
- * @param columnIndex index of the column (not the index of the ColumnInfoRecord)
- * @return <code>null</code> if no column info found for the specified column
- */
+ public ColumnInfoRecordsAggregate(RecordStream rs) {
+ this();
+
+ boolean isInOrder = true;
+ ColumnInfoRecord cirPrev = null;
+ while(rs.peekNextClass() == ColumnInfoRecord.class) {
+ ColumnInfoRecord cir = (ColumnInfoRecord) rs.getNext();
+ records.add(cir);
+ if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) {
+ isInOrder = false;
+ }
+ cirPrev = cir;
+ }
+ if (records.size() < 1) {
+ throw new RuntimeException("No column info records found");
+ }
+ if (!isInOrder) {
+ Collections.sort(records, CIRComparator.instance);
+ }
+ }
+
+ /**
+ * Performs a deep clone of the record
+ */
+ public Object clone() {
+ ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate();
+ for (int k = 0; k < records.size(); k++) {
+ ColumnInfoRecord ci = ( ColumnInfoRecord ) records.get(k);
+ rec.records.add(ci.clone());
+ }
+ return rec;
+ }
+
+ /**
+ * Inserts a column into the aggregate (at the end of the list).
+ */
+ public void insertColumn(ColumnInfoRecord col) {
+ records.add(col);
+ Collections.sort(records, CIRComparator.instance);
+ }
+
+ /**
+ * Inserts a column into the aggregate (at the position specified by
+ * <code>idx</code>.
+ */
+ private void insertColumn(int idx, ColumnInfoRecord col) {
+ records.add(idx, col);
+ }
+
+ /* package */ int getNumColumns() {
+ return records.size();
+ }
+
+ public void visitContainedRecords(RecordVisitor rv) {
+ int nItems = records.size();
+ if (nItems < 1) {
+ return;
+ }
+ ColumnInfoRecord cirPrev = null;
+ for(int i=0; i<nItems; i++) {
+ ColumnInfoRecord cir = (ColumnInfoRecord)records.get(i);
+ rv.visitRecord(cir);
+ if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) {
+ // Excel probably wouldn't mind, but there is much logic in this class
+ // that assumes the column info records are kept in order
+ throw new RuntimeException("Column info records are out of order");
+ }
+ cirPrev = cir;
+ }
+ }
+
+ private int findStartOfColumnOutlineGroup(int pIdx) {
+ // Find the start of the group.
+ ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get(pIdx);
+ int level = columnInfo.getOutlineLevel();
+ int idx = pIdx;
+ while (idx != 0) {
+ ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) records.get(idx - 1);
+ if (!prevColumnInfo.isAdjacentBefore(columnInfo)) {
+ break;
+ }
+ if (prevColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ idx--;
+ columnInfo = prevColumnInfo;
+ }
+
+ return idx;
+ }
+
+ private int findEndOfColumnOutlineGroup(int colInfoIndex) {
+ // Find the end of the group.
+ ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get(colInfoIndex);
+ int level = columnInfo.getOutlineLevel();
+ int idx = colInfoIndex;
+ while (idx < records.size() - 1) {
+ ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get(idx + 1);
+ if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
+ break;
+ }
+ if (nextColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ idx++;
+ columnInfo = nextColumnInfo;
+ }
+ return idx;
+ }
+
+ private ColumnInfoRecord getColInfo(int idx) {
+ return (ColumnInfoRecord) records.get( idx );
+ }
+
+ /**
+ * 'Collapsed' state is stored in a single column col info record immediately after the outline group
+ * @param idx
+ * @return
+ */
+ private boolean isColumnGroupCollapsed(int idx) {
+ int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
+ int nextColInfoIx = endOfOutlineGroupIdx+1;
+ if (nextColInfoIx >= records.size()) {
+ return false;
+ }
+ ColumnInfoRecord nextColInfo = getColInfo(nextColInfoIx);
+ if (!getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextColInfo)) {
+ return false;
+ }
+ return nextColInfo.getCollapsed();
+ }
+
+
+ private boolean isColumnGroupHiddenByParent(int idx) {
+ // Look out outline details of end
+ int endLevel = 0;
+ boolean endHidden = false;
+ int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
+ if (endOfOutlineGroupIdx < records.size()) {
+ ColumnInfoRecord nextInfo = getColInfo(endOfOutlineGroupIdx + 1);
+ if (getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextInfo)) {
+ endLevel = nextInfo.getOutlineLevel();
+ endHidden = nextInfo.getHidden();
+ }
+ }
+ // Look out outline details of start
+ int startLevel = 0;
+ boolean startHidden = false;
+ int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx );
+ if (startOfOutlineGroupIdx > 0) {
+ ColumnInfoRecord prevInfo = getColInfo(startOfOutlineGroupIdx - 1);
+ if (prevInfo.isAdjacentBefore(getColInfo(startOfOutlineGroupIdx))) {
+ startLevel = prevInfo.getOutlineLevel();
+ startHidden = prevInfo.getHidden();
+ }
+ }
+ if (endLevel > startLevel) {
+ return endHidden;
+ }
+ return startHidden;
+ }
+
+ public void collapseColumn(int columnIndex) {
+ int colInfoIx = findColInfoIdx(columnIndex, 0);
+ if (colInfoIx == -1) {
+ return;
+ }
+
+ // Find the start of the group.
+ int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx);
+ ColumnInfoRecord columnInfo = getColInfo(groupStartColInfoIx);
+
+ // Hide all the columns until the end of the group
+ int lastColIx = setGroupHidden(groupStartColInfoIx, columnInfo.getOutlineLevel(), true);
+
+ // Write collapse field
+ setColumn(lastColIx + 1, null, null, null, null, Boolean.TRUE);
+ }
+ /**
+ * Sets all adjacent columns of the same outline level to the specified hidden status.
+ * @param pIdx the col info index of the start of the outline group
+ * @return the column index of the last column in the outline group
+ */
+ private int setGroupHidden(int pIdx, int level, boolean hidden) {
+ int idx = pIdx;
+ ColumnInfoRecord columnInfo = getColInfo(idx);
+ while (idx < records.size()) {
+ columnInfo.setHidden(hidden);
+ if (idx + 1 < records.size()) {
+ ColumnInfoRecord nextColumnInfo = getColInfo(idx + 1);
+ if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
+ break;
+ }
+ if (nextColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ columnInfo = nextColumnInfo;
+ }
+ idx++;
+ }
+ return columnInfo.getLastColumn();
+ }
+
+
+ public void expandColumn(int columnIndex) {
+ int idx = findColInfoIdx(columnIndex, 0);
+ if (idx == -1) {
+ return;
+ }
+
+ // If it is already expanded do nothing.
+ if (!isColumnGroupCollapsed(idx)) {
+ return;
+ }
+
+ // Find the start/end of the group.
+ int startIdx = findStartOfColumnOutlineGroup(idx);
+ int endIdx = findEndOfColumnOutlineGroup(idx);
+
+ // expand:
+ // colapsed bit must be unset
+ // hidden bit gets unset _if_ surrounding groups are expanded you can determine
+ // this by looking at the hidden bit of the enclosing group. You will have
+ // to look at the start and the end of the current group to determine which
+ // is the enclosing group
+ // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
+ ColumnInfoRecord columnInfo = getColInfo(endIdx);
+ if (!isColumnGroupHiddenByParent(idx)) {
+ int outlineLevel = columnInfo.getOutlineLevel();
+ for (int i = startIdx; i <= endIdx; i++) {
+ ColumnInfoRecord ci = getColInfo(i);
+ if (outlineLevel == ci.getOutlineLevel())
+ ci.setHidden(false);
+ }
+ }
+
+ // Write collapse flag (stored in a single col info record after this outline group)
+ setColumn(columnInfo.getLastColumn() + 1, null, null, null, null, Boolean.FALSE);
+ }
+
+ private static ColumnInfoRecord copyColInfo(ColumnInfoRecord ci) {
+ return (ColumnInfoRecord) ci.clone();
+ }
+
+
+ public void setColumn(int targetColumnIx, Short xfIndex, Short width,
+ Integer level, Boolean hidden, Boolean collapsed) {
+ ColumnInfoRecord ci = null;
+ int k = 0;
+
+ for (k = 0; k < records.size(); k++) {
+ ColumnInfoRecord tci = (ColumnInfoRecord) records.get(k);
+ if (tci.containsColumn(targetColumnIx)) {
+ ci = tci;
+ break;
+ }
+ if (tci.getFirstColumn() > targetColumnIx) {
+ // call column infos after k are for later columns
+ break; // exit now so k will be the correct insert pos
+ }
+ }
+
+ if (ci == null) {
+ // okay so there ISN'T a column info record that covers this column so lets create one!
+ ColumnInfoRecord nci = new ColumnInfoRecord();
+
+ nci.setFirstColumn(targetColumnIx);
+ nci.setLastColumn(targetColumnIx);
+ setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
+ insertColumn(k, nci);
+ attemptMergeColInfoRecords(k);
+ return;
+ }
+
+ boolean styleChanged = xfIndex != null && ci.getXFIndex() != xfIndex.shortValue();
+ boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue();
+ boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue();
+ boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue();
+ boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue();
+
+ boolean columnChanged = styleChanged || widthChanged || levelChanged || hiddenChanged || collapsedChanged;
+ if (!columnChanged) {
+ // do nothing...nothing changed.
+ return;
+ }
+
+ if (ci.getFirstColumn() == targetColumnIx && ci.getLastColumn() == targetColumnIx) {
+ // ColumnInfo ci for a single column, the target column
+ setColumnInfoFields(ci, xfIndex, width, level, hidden, collapsed);
+ attemptMergeColInfoRecords(k);
+ return;
+ }
+
+ if (ci.getFirstColumn() == targetColumnIx || ci.getLastColumn() == targetColumnIx) {
+ // The target column is at either end of the multi-column ColumnInfo ci
+ // we'll just divide the info and create a new one
+ if (ci.getFirstColumn() == targetColumnIx) {
+ ci.setFirstColumn(targetColumnIx + 1);
+ } else {
+ ci.setLastColumn(targetColumnIx - 1);
+ k++; // adjust insert pos to insert after
+ }
+ ColumnInfoRecord nci = copyColInfo(ci);
+
+ nci.setFirstColumn(targetColumnIx);
+ nci.setLastColumn(targetColumnIx);
+ setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
+
+ insertColumn(k, nci);
+ attemptMergeColInfoRecords(k);
+ } else {
+ //split to 3 records
+ ColumnInfoRecord ciStart = ci;
+ ColumnInfoRecord ciMid = copyColInfo(ci);
+ ColumnInfoRecord ciEnd = copyColInfo(ci);
+ int lastcolumn = ci.getLastColumn();
+
+ ciStart.setLastColumn(targetColumnIx - 1);
+
+ ciMid.setFirstColumn(targetColumnIx);
+ ciMid.setLastColumn(targetColumnIx);
+ setColumnInfoFields(ciMid, xfIndex, width, level, hidden, collapsed);
+ insertColumn(++k, ciMid);
+
+ ciEnd.setFirstColumn(targetColumnIx+1);
+ ciEnd.setLastColumn(lastcolumn);
+ insertColumn(++k, ciEnd);
+ // no need to attemptMergeColInfoRecords because we
+ // know both on each side are different
+ }
+ }
+
+ /**
+ * Sets all non null fields into the <code>ci</code> parameter.
+ */
+ private static void setColumnInfoFields( ColumnInfoRecord ci, Short xfStyle, Short width,
+ Integer level, Boolean hidden, Boolean collapsed ) {
+ if (xfStyle != null) {
+ ci.setXFIndex(xfStyle.shortValue());
+ }
+ if (width != null) {
+ ci.setColumnWidth(width.shortValue());
+ }
+ if (level != null) {
+ ci.setOutlineLevel( level.shortValue() );
+ }
+ if (hidden != null) {
+ ci.setHidden( hidden.booleanValue() );
+ }
+ if (collapsed != null) {
+ ci.setCollapsed( collapsed.booleanValue() );
+ }
+ }
+
+ private int findColInfoIdx(int columnIx, int fromColInfoIdx) {
+ if (columnIx < 0) {
+ throw new IllegalArgumentException( "column parameter out of range: " + columnIx );
+ }
+ if (fromColInfoIdx < 0) {
+ throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromColInfoIdx );
+ }
+
+ for (int k = fromColInfoIdx; k < records.size(); k++) {
+ ColumnInfoRecord ci = getColInfo(k);
+ if (ci.containsColumn(columnIx)) {
+ return k;
+ }
+ if (ci.getFirstColumn() > columnIx) {
+ break;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Attempts to merge the col info record at the specified index
+ * with either or both of its neighbours
+ */
+ private void attemptMergeColInfoRecords(int colInfoIx) {
+ int nRecords = records.size();
+ if (colInfoIx < 0 || colInfoIx >= nRecords) {
+ throw new IllegalArgumentException("colInfoIx " + colInfoIx
+ + " is out of range (0.." + (nRecords-1) + ")");
+ }
+ ColumnInfoRecord currentCol = getColInfo(colInfoIx);
+ int nextIx = colInfoIx+1;
+ if (nextIx < nRecords) {
+ if (mergeColInfoRecords(currentCol, getColInfo(nextIx))) {
+ records.remove(nextIx);
+ }
+ }
+ if (colInfoIx > 0) {
+ if (mergeColInfoRecords(getColInfo(colInfoIx - 1), currentCol)) {
+ records.remove(colInfoIx);
+ }
+ }
+ }
+ /**
+ * merges two column info records (if they are adjacent and have the same formatting, etc)
+ * @return <code>false</code> if the two column records could not be merged
+ */
+ private static boolean mergeColInfoRecords(ColumnInfoRecord ciA, ColumnInfoRecord ciB) {
+ if (ciA.isAdjacentBefore(ciB) && ciA.formatMatches(ciB)) {
+ ciA.setLastColumn(ciB.getLastColumn());
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Creates an outline group for the specified columns, by setting the level
+ * field for each col info record in the range. {@link ColumnInfoRecord}s
+ * may be created, split or merged as a result of this operation.
+ *
+ * @param fromColumnIx
+ * group from this column (inclusive)
+ * @param toColumnIx
+ * group to this column (inclusive)
+ * @param indent
+ * if <code>true</code> the group will be indented by one
+ * level, if <code>false</code> indenting will be decreased by
+ * one level.
+ */
+ public void groupColumnRange(int fromColumnIx, int toColumnIx, boolean indent) {
+
+ int colInfoSearchStartIdx = 0; // optimization to speed up the search for col infos
+ for (int i = fromColumnIx; i <= toColumnIx; i++) {
+ int level = 1;
+ int colInfoIdx = findColInfoIdx(i, colInfoSearchStartIdx);
+ if (colInfoIdx != -1) {
+ level = getColInfo(colInfoIdx).getOutlineLevel();
+ if (indent) {
+ level++;
+ } else {
+ level--;
+ }
+ level = Math.max(0, level);
+ level = Math.min(7, level);
+ colInfoSearchStartIdx = Math.max(0, colInfoIdx - 1); // -1 just in case this column is collapsed later.
+ }
+ setColumn(i, null, null, new Integer(level), null, null);
+ }
+ }
+ /**
+ * Finds the <tt>ColumnInfoRecord</tt> which contains the specified columnIndex
+ * @param columnIndex index of the column (not the index of the ColumnInfoRecord)
+ * @return <code>null</code> if no column info found for the specified column
+ */
public ColumnInfoRecord findColumnInfo(int columnIndex) {
int nInfos = records.size();
for(int i=0; i< nInfos; i++) {
ColumnInfoRecord ci = getColInfo(i);
- if (ci.getFirstColumn() <= columnIndex && columnIndex <= ci.getLastColumn()) {
+ if (ci.containsColumn(columnIndex)) {
return ci;
}
}
return null;
}
public int getMaxOutlineLevel() {
- int result = 0;
- int count=records.size();
- for (int i=0; i<count; i++) {
- ColumnInfoRecord columnInfoRecord = getColInfo(i);
- result = Math.max(columnInfoRecord.getOutlineLevel(), result);
- }
- return result;
+ int result = 0;
+ int count=records.size();
+ for (int i=0; i<count; i++) {
+ ColumnInfoRecord columnInfoRecord = getColInfo(i);
+ result = Math.max(columnInfoRecord.getOutlineLevel(), result);
+ }
+ return result;
}
-
-
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java Sat Sep 13 06:48:27 2008
@@ -20,6 +20,7 @@
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordFormatException;
import org.apache.poi.hssf.record.StringRecord;
/**
@@ -34,9 +35,9 @@
private SharedValueManager _sharedValueManager;
/** caches the calculated result of the formula */
private StringRecord _stringRecord;
-
+
/**
- * @param stringRec may be <code>null</code> if this formula does not have a cached text
+ * @param stringRec may be <code>null</code> if this formula does not have a cached text
* value.
* @param svm the {@link SharedValueManager} for the current sheet
*/
@@ -44,6 +45,14 @@
if (svm == null) {
throw new IllegalArgumentException("sfm must not be null");
}
+ boolean hasStringRec = stringRec != null;
+ boolean hasCachedStringFlag = formulaRec.hasCachedResultString();
+ if (hasStringRec != hasCachedStringFlag) {
+ throw new RecordFormatException("String record was "
+ + (hasStringRec ? "": "not ") + " supplied but formula record flag is "
+ + (hasCachedStringFlag ? "" : "not ") + " set");
+ }
+
if (formulaRec.isSharedFormula()) {
svm.convertSharedFormulaRecord(formulaRec);
}
@@ -52,18 +61,18 @@
_stringRecord = stringRec;
}
- public void setStringRecord(StringRecord stringRecord) {
- _stringRecord = stringRecord;
- }
-
public FormulaRecord getFormulaRecord() {
return _formulaRecord;
}
+ /**
+ * debug only
+ * TODO - encapsulate
+ */
public StringRecord getStringRecord() {
return _stringRecord;
}
-
+
public short getXFIndex() {
return _formulaRecord.getXFIndex();
}
@@ -91,7 +100,7 @@
public String toString() {
return _formulaRecord.toString();
}
-
+
public void visitContainedRecords(RecordVisitor rv) {
rv.visitRecord(_formulaRecord);
Record sharedFormulaRecord = _sharedValueManager.getRecordForFirstCell(_formulaRecord);
@@ -102,11 +111,33 @@
rv.visitRecord(_stringRecord);
}
}
-
+
public String getStringValue() {
if(_stringRecord==null) {
return null;
}
return _stringRecord.getString();
}
+
+ public void setCachedStringResult(String value) {
+
+ // Save the string into a String Record, creating one if required
+ if(_stringRecord == null) {
+ _stringRecord = new StringRecord();
+ }
+ _stringRecord.setString(value);
+ if (value.length() < 1) {
+ _formulaRecord.setCachedResultTypeEmptyString();
+ } else {
+ _formulaRecord.setCachedResultTypeString();
+ }
+ }
+ public void setCachedBooleanResult(boolean value) {
+ _stringRecord = null;
+ _formulaRecord.setCachedResultBoolean(value);
+ }
+ public void setCachedErrorResult(int errorCode) {
+ _stringRecord = null;
+ _formulaRecord.setCachedResultErrorCode(errorCode);
+ }
}
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
('svn:mergeinfo' removed)
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
('svn:mergeinfo' removed)
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
('svn:mergeinfo' removed)
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java Sat Sep 13 06:48:27 2008
@@ -18,7 +18,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.LittleEndian;
/**
@@ -45,7 +45,7 @@
public final int getSize() {
return SIZE;
}
- public final String toFormulaString(HSSFWorkbook book) {
+ public final String toFormulaString(Workbook book) {
return formatReferenceAsString();
}
public final String toString() {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java Sat Sep 13 06:48:27 2008
@@ -44,8 +44,11 @@
* (not including the data which comes after all formula tokens)
*/
public static final int PLAIN_TOKEN_SIZE = 1+RESERVED_FIELD_LEN;
+
+ private static final byte[] DEFAULT_RESERVED_DATA = new byte[RESERVED_FIELD_LEN];
+
// TODO - fix up field visibility and subclasses
- private byte[] field_1_reserved;
+ private final byte[] field_1_reserved;
// data from these fields comes after the Ptg data of all tokens in current formula
private short token_1_columns;
@@ -59,8 +62,42 @@
field_1_reserved[i] = in.readByte();
}
}
- public Object[] getTokenArrayValues() {
- return (Object[]) token_3_arrayValues.clone();
+ /**
+ * @param values2d array values arranged in rows
+ */
+ public ArrayPtg(Object[][] values2d) {
+ int nColumns = values2d[0].length;
+ int nRows = values2d.length;
+ // convert 2-d to 1-d array (row by row according to getValueIndex())
+ token_1_columns = (short) nColumns;
+ token_2_rows = (short) nRows;
+
+ Object[] vv = new Object[token_1_columns * token_2_rows];
+ for (int r=0; r<nRows; r++) {
+ Object[] rowData = values2d[r];
+ for (int c=0; c<nColumns; c++) {
+ vv[getValueIndex(c, r)] = rowData[c];
+ }
+ }
+
+ token_3_arrayValues = vv;
+ field_1_reserved = DEFAULT_RESERVED_DATA;
+ }
+ /**
+ * @return 2-d array (inner index is rowIx, outer index is colIx)
+ */
+ public Object[][] getTokenArrayValues() {
+ if (token_3_arrayValues == null) {
+ throw new IllegalStateException("array values not read yet");
+ }
+ Object[][] result = new Object[token_2_rows][token_1_columns];
+ for (int r = 0; r < token_2_rows; r++) {
+ Object[] rowData = result[r];
+ for (int c = 0; c < token_1_columns; c++) {
+ rowData[c] = token_3_arrayValues[getValueIndex(c, r)];
+ }
+ }
+ return result;
}
public boolean isBaseToken() {
@@ -88,27 +125,21 @@
token_3_arrayValues = ConstantValueParser.parse(in, totalCount);
}
- public String toString()
- {
- StringBuffer buffer = new StringBuffer("[ArrayPtg]\n");
+ public String toString() {
+ StringBuffer sb = new StringBuffer("[ArrayPtg]\n");
- buffer.append("columns = ").append(getColumnCount()).append("\n");
- buffer.append("rows = ").append(getRowCount()).append("\n");
+ sb.append("nRows = ").append(getRowCount()).append("\n");
+ sb.append("nCols = ").append(getColumnCount()).append("\n");
if (token_3_arrayValues == null) {
- buffer.append(" #values#uninitialised#\n");
+ sb.append(" #values#uninitialised#\n");
} else {
- for (int x=0;x<getColumnCount();x++) {
- for (int y=0;y<getRowCount();y++) {
- Object o = token_3_arrayValues[getValueIndex(x, y)];
- buffer.append("[").append(x).append("][").append(y).append("] = ").append(o).append("\n");
- }
- }
+ sb.append(" ").append(formatAsString());
}
- return buffer.toString();
+ return sb.toString();
}
/**
- * Note - (2D) array elements are stored column by column
+ * Note - (2D) array elements are stored row by row
* @return the index into the internal 1D array for the specified column and row
*/
/* package */ int getValueIndex(int colIx, int rowIx) {
@@ -120,7 +151,7 @@
throw new IllegalArgumentException("Specified rowIx (" + rowIx
+ ") is outside the allowed range (0.." + (token_2_rows-1) + ")");
}
- return rowIx + token_2_rows * colIx;
+ return rowIx * token_1_columns + colIx;
}
public void writeBytes(byte[] data, int offset) {
@@ -153,16 +184,15 @@
+ ConstantValueParser.getEncodedSize(token_3_arrayValues);
}
- public String toFormulaString(Workbook book)
- {
+ public String formatAsString() {
StringBuffer b = new StringBuffer();
b.append("{");
- for (int x=0;x<getColumnCount();x++) {
- if (x > 0) {
+ for (int y=0;y<getRowCount();y++) {
+ if (y > 0) {
b.append(";");
}
- for (int y=0;y<getRowCount();y++) {
- if (y > 0) {
+ for (int x=0;x<getColumnCount();x++) {
+ if (x > 0) {
b.append(",");
}
Object o = token_3_arrayValues[getValueIndex(x, y)];
@@ -172,11 +202,14 @@
b.append("}");
return b.toString();
}
+ public String toFormulaString(Workbook book) {
+ return formatAsString();
+ }
private static String getConstantText(Object o) {
if (o == null) {
- return ""; // TODO - how is 'empty value' represented in formulas?
+ throw new RuntimeException("Array item cannot be null");
}
if (o instanceof UnicodeString) {
return "\"" + ((UnicodeString)o).getString() + "\"";
@@ -196,11 +229,4 @@
public byte getDefaultOperandClass() {
return Ptg.CLASS_ARRAY;
}
-
- public Object clone() {
- ArrayPtg ptg = (ArrayPtg) super.clone();
- ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
- ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
- return ptg;
- }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java Sat Sep 13 06:48:27 2008
@@ -24,12 +24,12 @@
* @author Daniel Noll (daniel at nuix dot com dot au)
*/
public final class ErrPtg extends ScalarConstantPtg {
-
+
// convenient access to namespace
private static final HSSFErrorConstants EC = null;
-
+
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */
- public static final ErrPtg NULL_INTERSECTION = new ErrPtg(EC.ERROR_NULL);
+ public static final ErrPtg NULL_INTERSECTION = new ErrPtg(EC.ERROR_NULL);
/** <b>#DIV/0!</b> - Division by zero */
public static final ErrPtg DIV_ZERO = new ErrPtg(EC.ERROR_DIV_0);
/** <b>#VALUE!</b> - Wrong type of operand */
@@ -37,28 +37,28 @@
/** <b>#REF!</b> - Illegal or deleted cell reference */
public static final ErrPtg REF_INVALID = new ErrPtg(EC.ERROR_REF);
/** <b>#NAME?</b> - Wrong function or range name */
- public static final ErrPtg NAME_INVALID = new ErrPtg(EC.ERROR_NAME);
+ public static final ErrPtg NAME_INVALID = new ErrPtg(EC.ERROR_NAME);
/** <b>#NUM!</b> - Value range overflow */
public static final ErrPtg NUM_ERROR = new ErrPtg(EC.ERROR_NUM);
/** <b>#N/A</b> - Argument or function not available */
public static final ErrPtg N_A = new ErrPtg(EC.ERROR_NA);
-
-
+
+
public static final short sid = 0x1c;
private static final int SIZE = 2;
private final int field_1_error_code;
/** Creates new ErrPtg */
- public ErrPtg(int errorCode) {
+ private ErrPtg(int errorCode) {
if(!HSSFErrorConstants.isValidCode(errorCode)) {
throw new IllegalArgumentException("Invalid error code (" + errorCode + ")");
}
field_1_error_code = errorCode;
}
-
- public ErrPtg(RecordInputStream in) {
- this(in.readByte());
+
+ public static ErrPtg read(RecordInputStream in) {
+ return valueOf(in.readByte());
}
public void writeBytes(byte [] array, int offset)
@@ -78,4 +78,17 @@
public int getErrorCode() {
return field_1_error_code;
}
+
+ public static ErrPtg valueOf(int code) {
+ switch(code) {
+ case HSSFErrorConstants.ERROR_DIV_0: return DIV_ZERO;
+ case HSSFErrorConstants.ERROR_NA: return N_A;
+ case HSSFErrorConstants.ERROR_NAME: return NAME_INVALID;
+ case HSSFErrorConstants.ERROR_NULL: return NULL_INTERSECTION;
+ case HSSFErrorConstants.ERROR_NUM: return NUM_ERROR;
+ case HSSFErrorConstants.ERROR_REF: return REF_INVALID;
+ case HSSFErrorConstants.ERROR_VALUE: return VALUE_INVALID;
+ }
+ throw new RuntimeException("Unexpected error code (" + code + ")");
+ }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ptg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ptg.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ptg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ptg.java Sat Sep 13 06:48:27 2008
@@ -56,20 +56,21 @@
/**
* @deprecated - use readTokens()
*/
- public static Stack createParsedExpressionTokens(short size, RecordInputStream in)
- {
+ public static Stack createParsedExpressionTokens(short size, RecordInputStream in) {
Stack stack = new Stack();
int pos = 0;
List arrayPtgs = null;
- while ( pos < size )
- {
+ while (pos < size) {
Ptg ptg = Ptg.createPtg( in );
if (ptg instanceof ArrayPtg) {
- if (arrayPtgs == null)
+ if (arrayPtgs == null) {
arrayPtgs = new ArrayList(5);
+ }
arrayPtgs.add(ptg);
- pos += 8;
- } else pos += ptg.getSize();
+ pos += ArrayPtg.PLAIN_TOKEN_SIZE;
+ } else {
+ pos += ptg.getSize();
+ }
stack.push( ptg );
}
if(pos != size) {
@@ -109,25 +110,25 @@
int baseId = id & 0x1F | 0x20;
switch (baseId) {
- case ArrayPtg.sid: return new ArrayPtg(in); // 0x20, 0x40, 0x60
- case FuncPtg.sid: return new FuncPtg(in); // 0x21, 0x41, 0x61
- case FuncVarPtg.sid: return new FuncVarPtg(in); // 0x22, 0x42, 0x62
- case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63
- case RefPtg.sid: return new RefPtg(in); // 0x24, 0x44, 0x64
- case AreaPtg.sid: return new AreaPtg(in); // 0x25, 0x45, 0x65
- case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66
- case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67
- case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69
- case RefErrorPtg.sid: return new RefErrorPtg(in);// 0x2a, 0x4a, 0x6a
- case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b
- case RefNPtg.sid: return new RefNPtg(in); // 0x2c, 0x4c, 0x6c
- case AreaNPtg.sid: return new AreaNPtg(in); // 0x2d, 0x4d, 0x6d
-
- case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79
- case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a
- case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b
- case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c
- case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
+ case ArrayPtg.sid: return new ArrayPtg(in); // 0x20, 0x40, 0x60
+ case FuncPtg.sid: return new FuncPtg(in); // 0x21, 0x41, 0x61
+ case FuncVarPtg.sid: return new FuncVarPtg(in); // 0x22, 0x42, 0x62
+ case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63
+ case RefPtg.sid: return new RefPtg(in); // 0x24, 0x44, 0x64
+ case AreaPtg.sid: return new AreaPtg(in); // 0x25, 0x45, 0x65
+ case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66
+ case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67
+ case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69
+ case RefErrorPtg.sid: return new RefErrorPtg(in); // 0x2a, 0x4a, 0x6a
+ case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b
+ case RefNPtg.sid: return new RefNPtg(in); // 0x2c, 0x4c, 0x6c
+ case AreaNPtg.sid: return new AreaNPtg(in); // 0x2d, 0x4d, 0x6d
+
+ case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79
+ case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a
+ case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b
+ case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c
+ case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
}
throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
Integer.toHexString(id) + " (" + ( int ) id + ")");
@@ -162,7 +163,7 @@
case StringPtg.sid: return new StringPtg(in); // 0x17
case AttrPtg.sid:
case 0x1a: return new AttrPtg(in); // 0x19
- case ErrPtg.sid: return new ErrPtg(in); // 0x1c
+ case ErrPtg.sid: return ErrPtg.read(in); // 0x1c
case BoolPtg.sid: return new BoolPtg(in); // 0x1d
case IntPtg.sid: return new IntPtg(in); // 0x1e
case NumberPtg.sid: return new NumberPtg(in); // 0x1f
@@ -262,11 +263,14 @@
ptg.writeBytes(array, pos + offset);
if (ptg instanceof ArrayPtg) {
- if (arrayPtgs == null)
- arrayPtgs = new ArrayList(5);
- arrayPtgs.add(ptg);
- pos += 8;
- } else pos += ptg.getSize();
+ if (arrayPtgs == null) {
+ arrayPtgs = new ArrayList(5);
+ }
+ arrayPtgs.add(ptg);
+ pos += ArrayPtg.PLAIN_TOKEN_SIZE;
+ } else {
+ pos += ptg.getSize();
+ }
}
if (arrayPtgs != null) {
for (int i=0;i<arrayPtgs.size();i++) {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java Sat Sep 13 06:48:27 2008
@@ -24,15 +24,14 @@
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public final class AnalysisToolPak {
private static final FreeRefFunction NotImplemented = new FreeRefFunction() {
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol,
- Workbook workbook, Sheet sheet) {
+ public ValueEval evaluate(Eval[] args, Workbook workbook, int srcCellSheet,
+ int srcCellRow, int srcCellCol) {
return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
}
};
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java Sat Sep 13 06:48:27 2008
@@ -42,8 +42,8 @@
_desiredParity = desiredParity;
}
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, Workbook workbook,
- Sheet sheet) {
+ public ValueEval evaluate(Eval[] args, Workbook workbook, int srcCellSheet, int srcCellRow,
+ int srcCellCol) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
@@ -58,8 +58,8 @@
return BoolEval.valueOf(val == _desiredParity);
}
- private static int evaluateArgParity(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static int evaluateArgParity(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short)srcCellCol);
double d = OperandResolver.coerceValueToDouble(ve);
if (d < 0) {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java Sat Sep 13 06:48:27 2008
@@ -61,8 +61,8 @@
// enforce singleton
}
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, Workbook workbook,
- Sheet sheet) {
+ public ValueEval evaluate(Eval[] args, Workbook workbook, int srcCellSheet, int srcCellRow,
+ int srcCellCol) {
double result;
try {
@@ -85,8 +85,8 @@
return new NumberEval(result);
}
- private static double evaluateDateArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static double evaluateDateArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
if (ve instanceof StringEval) {
String strVal = ((StringEval) ve).getStringValue();
@@ -155,8 +155,8 @@
return cal;
}
- private static int evaluateIntArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static int evaluateIntArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
return OperandResolver.coerceValueToInt(ve);
}
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java Sat Sep 13 06:48:27 2008
@@ -1,19 +1,19 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.eval;
@@ -24,7 +24,7 @@
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public final class ConcatEval extends StringOperationEval {
+public final class ConcatEval implements OperationEval {
private ConcatPtg delegate;
@@ -37,20 +37,23 @@
return ErrorEval.VALUE_INVALID;
}
StringBuffer sb = new StringBuffer();
- for (int i = 0; i < 2; i++) {
-
- ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol);
- if (ve instanceof StringValueEval) {
- StringValueEval sve = (StringValueEval) ve;
- sb.append(sve.getStringValue());
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else { // must be an error eval
- return ve;
- }
- }
+ try {
+ for (int i = 0; i < 2; i++) {
+
+ ValueEval ve = OperandResolver.getSingleValue(args[i], srcRow, srcCol);
+ if (ve instanceof StringValueEval) {
+ StringValueEval sve = (StringValueEval) ve;
+ sb.append(sve.getStringValue());
+ } else if (ve == BlankEval.INSTANCE) {
+ // do nothing
+ } else { // must be an error eval
+ throw new RuntimeException("Unexpected value type ("
+ + ve.getClass().getName() + ")");
+ }
+ }
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
return new StringEval(sb.toString());
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java Sat Sep 13 06:48:27 2008
@@ -19,7 +19,6 @@
import org.apache.poi.hssf.record.formula.atp.AnalysisToolPak;
import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
/**
*
@@ -31,7 +30,8 @@
*/
final class ExternalFunction implements FreeRefFunction {
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, Workbook workbook, Sheet sheet) {
+ public ValueEval evaluate(Eval[] args, Workbook workbook,
+ int srcCellSheet, int srcCellRow,int srcCellCol) {
int nIncomingArgs = args.length;
if(nIncomingArgs < 1) {
@@ -55,7 +55,7 @@
int nOutGoingArgs = nIncomingArgs -1;
Eval[] outGoingArgs = new Eval[nOutGoingArgs];
System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs);
- return targetFunc.evaluate(outGoingArgs, srcCellRow, srcCellCol, workbook, sheet);
+ return targetFunc.evaluate(outGoingArgs, workbook, srcCellSheet, srcCellRow, srcCellCol);
}
private FreeRefFunction findExternalUserDefinedFunction(Workbook workbook,
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java Sat Sep 13 06:48:27 2008
@@ -1,23 +1,20 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 8, 2005
- *
- */
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.eval;
import java.util.HashMap;
@@ -81,42 +78,42 @@
retval[1] = new If(); // IF
retval[2] = new IsNa(); // ISNA
retval[3] = new IsError(); // ISERROR
- retval[4] = new Sum(); // SUM
- retval[5] = new Average(); // AVERAGE
- retval[6] = new Min(); // MIN
- retval[7] = new Max(); // MAX
+ retval[4] = AggregateFunction.SUM;
+ retval[5] = AggregateFunction.AVERAGE;
+ retval[6] = AggregateFunction.MIN;
+ retval[7] = AggregateFunction.MAX;
retval[8] = new Row(); // ROW
retval[9] = new Column(); // COLUMN
retval[10] = new Na(); // NA
retval[11] = new Npv(); // NPV
- retval[12] = new Stdev(); // STDEV
- retval[13] = NumericFunctionOneArg.DOLLAR;
+ retval[12] = AggregateFunction.STDEV;
+ retval[13] = NumericFunction.DOLLAR;
retval[14] = new Fixed(); // FIXED
- retval[15] = NumericFunctionOneArg.SIN;
- retval[16] = NumericFunctionOneArg.COS;
- retval[17] = NumericFunctionOneArg.TAN;
- retval[18] = NumericFunctionOneArg.ATAN;
+ retval[15] = NumericFunction.SIN;
+ retval[16] = NumericFunction.COS;
+ retval[17] = NumericFunction.TAN;
+ retval[18] = NumericFunction.ATAN;
retval[19] = new Pi(); // PI
- retval[20] = NumericFunctionOneArg.SQRT;
- retval[21] = NumericFunctionOneArg.EXP;
- retval[22] = NumericFunctionOneArg.LN;
- retval[23] = NumericFunctionOneArg.LOG10;
- retval[24] = NumericFunctionOneArg.ABS;
- retval[25] = NumericFunctionOneArg.INT;
- retval[26] = NumericFunctionOneArg.SIGN;
- retval[27] = new Round(); // ROUND
+ retval[20] = NumericFunction.SQRT;
+ retval[21] = NumericFunction.EXP;
+ retval[22] = NumericFunction.LN;
+ retval[23] = NumericFunction.LOG10;
+ retval[24] = NumericFunction.ABS;
+ retval[25] = NumericFunction.INT;
+ retval[26] = NumericFunction.SIGN;
+ retval[27] = NumericFunction.ROUND;
retval[28] = new Lookup(); // LOOKUP
retval[29] = new Index(); // INDEX
retval[30] = new Rept(); // REPT
- retval[31] = new Mid(); // MID
- retval[32] = new Len(); // LEN
+ retval[31] = TextFunction.MID;
+ retval[32] = TextFunction.LEN;
retval[33] = new Value(); // VALUE
retval[34] = new True(); // TRUE
retval[35] = new False(); // FALSE
retval[36] = new And(); // AND
retval[37] = new Or(); // OR
retval[38] = new Not(); // NOT
- retval[39] = new Mod(); // MOD
+ retval[39] = NumericFunction.MOD;
retval[40] = new Dcount(); // DCOUNT
retval[41] = new Dsum(); // DSUM
retval[42] = new Daverage(); // DAVERAGE
@@ -132,16 +129,16 @@
retval[52] = new Growth(); // GROWTH
retval[53] = new Goto(); // GOTO
retval[54] = new Halt(); // HALT
- retval[56] = new Pv(); // PV
- retval[57] = new Fv(); // FV
- retval[58] = new Nper(); // NPER
- retval[59] = new Pmt(); // PMT
+ retval[56] = FinanceFunction.PV;
+ retval[57] = FinanceFunction.FV;
+ retval[58] = FinanceFunction.NPER;
+ retval[59] = FinanceFunction.PMT;
retval[60] = new Rate(); // RATE
retval[61] = new Mirr(); // MIRR
retval[62] = new Irr(); // IRR
retval[63] = new Rand(); // RAND
retval[64] = new Match(); // MATCH
- retval[65] = new Date(); // DATE
+ retval[65] = DateFunc.instance; // DATE
retval[66] = new Time(); // TIME
retval[67] = CalendarFieldFunction.DAY; // DAY
retval[68] = CalendarFieldFunction.MONTH; // MONTH
@@ -173,9 +170,9 @@
retval[94] = new Activecell(); // ACTIVECELL
retval[95] = new NotImplementedFunction(); // SELECTION
retval[96] = new Result(); // RESULT
- retval[97] = new Atan2(); // ATAN2
- retval[98] = NumericFunctionOneArg.ASIN;
- retval[99] = NumericFunctionOneArg.ACOS;
+ retval[97] = NumericFunction.ATAN2;
+ retval[98] = NumericFunction.ASIN;
+ retval[99] = NumericFunction.ACOS;
retval[100] = new Choose(); // CHOOSE
retval[101] = new Hlookup(); // HLOOKUP
retval[102] = new Vlookup(); // VLOOKUP
@@ -185,16 +182,16 @@
retval[106] = new NotImplementedFunction(); // GETFORMULA
retval[107] = new NotImplementedFunction(); // GETNAME
retval[108] = new Setvalue(); // SETVALUE
- retval[109] = new Log(); // LOG
+ retval[109] = NumericFunction.LOG;
retval[110] = new Exec(); // EXEC
retval[111] = new Char(); // CHAR
- retval[112] = new Lower(); // LOWER
- retval[113] = new Upper(); // UPPER
+ retval[112] = TextFunction.LOWER;
+ retval[113] = TextFunction.UPPER;
retval[114] = new Proper(); // PROPER
- retval[115] = new Left(); // LEFT
- retval[116] = new Right(); // RIGHT
- retval[117] = new Exact(); // EXACT
- retval[118] = new Trim(); // TRIM
+ retval[115] = TextFunction.LEFT;
+ retval[116] = TextFunction.RIGHT;
+ retval[117] = TextFunction.EXACT;
+ retval[118] = TextFunction.TRIM;
retval[119] = new Replace(); // REPLACE
retval[120] = new Substitute(); // SUBSTITUTE
retval[121] = new Code(); // CODE
@@ -255,8 +252,8 @@
retval[180] = new NotImplementedFunction(); // RESTART
retval[181] = new Help(); // HELP
retval[182] = new NotImplementedFunction(); // GETBAR
- retval[183] = new Product(); // PRODUCT
- retval[184] = NumericFunctionOneArg.FACT;
+ retval[183] = AggregateFunction.PRODUCT;
+ retval[184] = NumericFunction.FACT;
retval[185] = new NotImplementedFunction(); // GETCELL
retval[186] = new NotImplementedFunction(); // GETWORKSPACE
retval[187] = new NotImplementedFunction(); // GETWINDOW
@@ -282,8 +279,8 @@
retval[209] = new Rightb(); // RIGHTB
retval[210] = new Midb(); // MIDB
retval[211] = new Lenb(); // LENB
- retval[212] = new Roundup(); // ROUNDUP
- retval[213] = new Rounddown(); // ROUNDDOWN
+ retval[212] = NumericFunction.ROUNDUP;
+ retval[213] = NumericFunction.ROUNDDOWN;
retval[214] = new Asc(); // ASC
retval[215] = new Dbcs(); // DBCS
retval[216] = new Rank(); // RANK
@@ -291,14 +288,14 @@
retval[220] = new Days360(); // DAYS360
retval[221] = new Today(); // TODAY
retval[222] = new Vdb(); // VDB
- retval[227] = new Median(); // MEDIAN
+ retval[227] = AggregateFunction.MEDIAN;
retval[228] = new Sumproduct(); // SUMPRODUCT
- retval[229] = NumericFunctionOneArg.SINH;
- retval[230] = NumericFunctionOneArg.COSH;
- retval[231] = NumericFunctionOneArg.TANH;
- retval[232] = NumericFunctionOneArg.ASINH;
- retval[233] = NumericFunctionOneArg.ACOSH;
- retval[234] = NumericFunctionOneArg.ATANH;
+ retval[229] = NumericFunction.SINH;
+ retval[230] = NumericFunction.COSH;
+ retval[231] = NumericFunction.TANH;
+ retval[232] = NumericFunction.ASINH;
+ retval[233] = NumericFunction.ACOSH;
+ retval[234] = NumericFunction.ATANH;
retval[235] = new Dget(); // DGET
retval[236] = new NotImplementedFunction(); // CREATEOBJECT
retval[237] = new Volatile(); // VOLATILE
@@ -331,14 +328,14 @@
retval[266] = new NotImplementedFunction(); // PRESSTOOL
retval[267] = new NotImplementedFunction(); // REGISTERID
retval[268] = new NotImplementedFunction(); // GETWORKBOOK
- retval[269] = new Avedev(); // AVEDEV
+ retval[269] = AggregateFunction.AVEDEV;
retval[270] = new Betadist(); // BETADIST
retval[271] = new Gammaln(); // GAMMALN
retval[272] = new Betainv(); // BETAINV
retval[273] = new Binomdist(); // BINOMDIST
retval[274] = new Chidist(); // CHIDIST
retval[275] = new Chiinv(); // CHIINV
- retval[276] = new Combin(); // COMBIN
+ retval[276] = NumericFunction.COMBIN;
retval[277] = new Confidence(); // CONFIDENCE
retval[278] = new Critbinom(); // CRITBINOM
retval[279] = new Even(); // EVEN
@@ -347,10 +344,10 @@
retval[282] = new Finv(); // FINV
retval[283] = new Fisher(); // FISHER
retval[284] = new Fisherinv(); // FISHERINV
- retval[285] = new Floor(); // FLOOR
+ retval[285] = NumericFunction.FLOOR;
retval[286] = new Gammadist(); // GAMMADIST
retval[287] = new Gammainv(); // GAMMAINV
- retval[288] = new Ceiling(); // CEILING
+ retval[288] = NumericFunction.CEILING;
retval[289] = new Hypgeomdist(); // HYPGEOMDIST
retval[290] = new Lognormdist(); // LOGNORMDIST
retval[291] = new Loginv(); // LOGINV
@@ -380,15 +377,15 @@
retval[315] = new Slope(); // SLOPE
retval[316] = new Ttest(); // TTEST
retval[317] = new Prob(); // PROB
- retval[318] = new Devsq(); // DEVSQ
+ retval[318] = AggregateFunction.DEVSQ;
retval[319] = new Geomean(); // GEOMEAN
retval[320] = new Harmean(); // HARMEAN
- retval[321] = new Sumsq(); // SUMSQ
+ retval[321] = AggregateFunction.SUMSQ;
retval[322] = new Kurt(); // KURT
retval[323] = new Skew(); // SKEW
retval[324] = new Ztest(); // ZTEST
- retval[325] = new Large(); // LARGE
- retval[326] = new Small(); // SMALL
+ retval[325] = AggregateFunction.LARGE;
+ retval[326] = AggregateFunction.SMALL;
retval[327] = new Quartile(); // QUARTILE
retval[328] = new Percentile(); // PERCENTILE
retval[329] = new Percentrank(); // PERCENTRANK
@@ -397,14 +394,14 @@
retval[332] = new Tinv(); // TINV
retval[334] = new NotImplementedFunction(); // MOVIECOMMAND
retval[335] = new NotImplementedFunction(); // GETMOVIE
- retval[336] = new Concatenate(); // CONCATENATE
- retval[337] = new Power(); // POWER
+ retval[336] = TextFunction.CONCATENATE;
+ retval[337] = NumericFunction.POWER;
retval[338] = new NotImplementedFunction(); // PIVOTADDDATA
retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE
retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD
retval[341] = new NotImplementedFunction(); // GETPIVOTITEM
- retval[342] = NumericFunctionOneArg.RADIANS;
- retval[343] = NumericFunctionOneArg.DEGREES;
+ retval[342] = NumericFunction.RADIANS;
+ retval[343] = NumericFunction.DEGREES;
retval[344] = new Subtotal(); // SUBTOTAL
retval[345] = new Sumif(); // SUMIF
retval[346] = new Countif(); // COUNTIF
@@ -423,8 +420,8 @@
retval[359] = new Hyperlink(); // HYPERLINK
retval[360] = new NotImplementedFunction(); // PHONETIC
retval[361] = new Averagea(); // AVERAGEA
- retval[362] = new Maxa(); // MAXA
- retval[363] = new Mina(); // MINA
+ retval[362] = MinaMaxa.MAXA;
+ retval[363] = MinaMaxa.MINA;
retval[364] = new Stdevpa(); // STDEVPA
retval[365] = new Varpa(); // VARPA
retval[366] = new Stdeva(); // STDEVA
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java Sat Sep 13 06:48:27 2008
@@ -272,12 +272,7 @@
StringValueEval sve = (StringValueEval) ve;
return sve.getStringValue();
}
- if (ve instanceof NumberEval) {
- NumberEval neval = (NumberEval) ve;
- return neval.getStringValue();
- }
-
- if (ve instanceof BlankEval) {
+ if (ve == BlankEval.INSTANCE) {
return "";
}
throw new IllegalArgumentException("Unexpected eval class (" + ve.getClass().getName() + ")");
@@ -289,7 +284,7 @@
*/
public static Boolean coerceValueToBoolean(ValueEval ve, boolean stringsAreBlanks) throws EvaluationException {
- if (ve == null || ve instanceof BlankEval) {
+ if (ve == null || ve == BlankEval.INSTANCE) {
// TODO - remove 've == null' condition once AreaEval is fixed
return null;
}
@@ -297,7 +292,7 @@
return Boolean.valueOf(((BoolEval) ve).getBooleanValue());
}
- if (ve instanceof BlankEval) {
+ if (ve == BlankEval.INSTANCE) {
return null;
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Even.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Even.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Even.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Even.java Sat Sep 13 06:48:27 2008
@@ -22,7 +22,7 @@
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public final class Even extends NumericFunctionOneArg {
+public final class Even extends NumericFunction.OneArg {
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java Sat Sep 13 06:48:27 2008
@@ -1,71 +1,77 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
-package org.apache.poi.hssf.record.formula.functions;
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+package org.apache.poi.hssf.record.formula.functions;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
* Super class for all Evals for financial function evaluation.
- *
+ *
*/
-public abstract class FinanceFunction extends NumericFunction {
- private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
- new ValueEvalToNumericXlator((short) (0
- | ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- | ValueEvalToNumericXlator.BLANK_IS_PARSED
- | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
- //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
- //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
- //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
- ));
-
- /**
- * this is the default impl of the factory(ish) method getXlator.
- * Subclasses can override this method
- * if they desire to return a different ValueEvalToNumericXlator instance
- * than the default.
- */
- protected final ValueEvalToNumericXlator getXlator() {
- return DEFAULT_NUM_XLATOR;
- }
-
- protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) {
- ValueEval retval = null;
- retval = singleOperandEvaluate(eval, srcRow, srcCol);
- if (retval instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) retval;
- retval = (nve.getNumberValue() == 0)
- ? BoolEval.FALSE
- : BoolEval.TRUE;
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- return retval;
- }
+public abstract class FinanceFunction extends NumericFunction.MultiArg {
+
+ protected FinanceFunction() {
+ super (3, 5);
+ }
+
+ protected double evaluate(double[] ds) throws EvaluationException {
+ // All finance functions have 3 to 5 args, first 4 are numbers, last is boolean
+ // default for last 2 args are 0.0 and false
+ // Text boolean literals are not valid for the last arg
+
+ double arg3 = 0.0;
+ double arg4 = 0.0;
+
+ switch(ds.length) {
+ case 5:
+ arg4 = ds[4];
+ case 4:
+ arg3 = ds[3];
+ case 3:
+ break;
+ default:
+ throw new IllegalStateException("Wrong number of arguments");
+ }
+ return evaluate(ds[0], ds[1], ds[2], arg3, arg4!=0.0);
+ }
+
+ protected abstract double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) throws EvaluationException ;
+
+
+ public static final Function FV = new FinanceFunction() {
+ protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+ return FinanceLib.fv(rate, arg1, arg2, arg3, type);
+ }
+ };
+ public static final Function NPER = new FinanceFunction() {
+ protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+ return FinanceLib.nper(rate, arg1, arg2, arg3, type);
+ }
+ };
+ public static final Function PMT = new FinanceFunction() {
+ protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+ return FinanceLib.pmt(rate, arg1, arg2, arg3, type);
+ }
+ };
+ public static final Function PV = new FinanceFunction() {
+ protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+ return FinanceLib.pv(rate, arg1, arg2, arg3, type);
+ }
+ };
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/FreeRefFunction.java Sat Sep 13 06:48:27 2008
@@ -45,13 +45,13 @@
*
* @param args the pre-evaluated arguments for this function. args is never <code>null</code>,
* nor are any of its elements.
+ * @param srcCellSheet zero based sheet index of the cell containing the currently evaluating formula
* @param srcCellRow zero based row index of the cell containing the currently evaluating formula
* @param srcCellCol zero based column index of the cell containing the currently evaluating formula
* @param workbook is the workbook containing the formula/cell being evaluated
- * @param sheet is the sheet containing the formula/cell being evaluated
* @return never <code>null</code>. Possibly an instance of <tt>ErrorEval</tt> in the case of
* a specified Excel error (Exceptions are never thrown to represent Excel errors).
*
*/
- ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, Workbook workbook, Sheet sheet);
+ ValueEval evaluate(Eval[] args, Workbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org