Improving AreaI interface and AreaPtg hierarchy

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690825 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-31 23:59:26 +00:00
parent a78cd8eb0a
commit 020bde0d66
11 changed files with 141 additions and 367 deletions

View File

@ -626,7 +626,7 @@ public final class NameRecord extends Record {
}
private Ptg createNewPtg(){
Ptg ptg = new Area3DPtg();
Ptg ptg = new Area3DPtg("A1", 0); // TODO - change to not be partially initialised
field_13_name_definition.push(ptg);
return ptg;
@ -673,9 +673,7 @@ public final class NameRecord extends Record {
// Add the area reference(s)
for(int i=0; i<refs.length; i++) {
ptg = new Area3DPtg();
((Area3DPtg) ptg).setExternSheetIndex(externSheetIndex);
((Area3DPtg) ptg).setArea(refs[i].formatAsString());
ptg = new Area3DPtg(refs[i].formatAsString(), externSheetIndex);
field_13_name_definition.push(ptg);
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
}

View File

@ -0,0 +1,59 @@
/* ====================================================================
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;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.LittleEndian;
/**
* Common superclass of 2-D area refs
*/
public abstract class Area2DPtgBase extends AreaPtgBase {
private final static int SIZE = 9;
protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
protected Area2DPtgBase(RecordInputStream in) {
readCoordinates(in);
}
protected abstract byte getSid();
public final void writeBytes(byte [] array, int offset) {
LittleEndian.putByte(array, offset+0, getSid() + getPtgClass());
writeCoordinates(array, offset+1);
}
public Area2DPtgBase(String arearef) {
super(arearef);
}
public final int getSize() {
return SIZE;
}
public final String toFormulaString(HSSFWorkbook book) {
return formatReferenceAsString();
}
public final String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append(formatReferenceAsString());
sb.append("]");
return sb.toString();
}
}

View File

@ -17,12 +17,8 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.util.AreaReference;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.LittleEndian;
/**
@ -34,229 +30,63 @@ import org.apache.poi.util.LittleEndian;
* @author Jason Height (jheight at chariot dot net dot au)
* @version 1.0-pre
*/
public final class Area3DPtg extends OperandPtg implements AreaI {
public final class Area3DPtg extends AreaPtgBase {
public final static byte sid = 0x3b;
private final static int SIZE = 11; // 10 + 1 for Ptg
private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
private short field_1_index_extern_sheet;
private int field_2_first_row;
private int field_3_last_row;
private int field_4_first_column;
private int field_5_last_column;
private int field_1_index_extern_sheet;
/** Creates new AreaPtg */
public Area3DPtg()
{
}
public Area3DPtg( String arearef, short externIdx )
{
setArea(arearef);
public Area3DPtg( String arearef, int externIdx ) {
super(arearef);
setExternSheetIndex( externIdx );
}
public Area3DPtg(RecordInputStream in)
{
public Area3DPtg(RecordInputStream in) {
field_1_index_extern_sheet = in.readShort();
field_2_first_row = in.readUShort();
field_3_last_row = in.readUShort();
field_4_first_column = in.readUShort();
field_5_last_column = in.readUShort();
readCoordinates(in);
}
public Area3DPtg(short firstRow, short lastRow, short firstColumn, short lastColumn,
public Area3DPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative,
short externalSheetIndex) {
setFirstRow(firstRow);
setLastRow(lastRow);
setFirstColumn(firstColumn);
setLastColumn(lastColumn);
setFirstRowRelative(firstRowRelative);
setLastRowRelative(lastRowRelative);
setFirstColRelative(firstColRelative);
setLastColRelative(lastColRelative);
int externalSheetIndex) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
setExternSheetIndex(externalSheetIndex);
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append("sheetIx=").append(getExternSheetIndex());
sb.append(" ! ");
sb.append(AreaReference.formatAsString(this));
sb.append(formatReferenceAsString());
sb.append("]");
return sb.toString();
}
public void writeBytes( byte[] array, int offset )
{
array[0 + offset] = (byte) ( sid + getPtgClass() );
LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
LittleEndian.putShort( array, 7 + offset, (short)getFirstColumnRaw() );
LittleEndian.putShort( array, 9 + offset, (short)getLastColumnRaw() );
public void writeBytes(byte[] array, int offset) {
LittleEndian.putByte(array, offset + 0, sid + getPtgClass());
LittleEndian.putUShort(array, 1 + offset, field_1_index_extern_sheet);
writeCoordinates(array, offset+3);
}
public int getSize()
{
public int getSize() {
return SIZE;
}
public short getExternSheetIndex()
{
return field_1_index_extern_sheet;
public short getExternSheetIndex() {
return (short)field_1_index_extern_sheet;
}
public void setExternSheetIndex( short index )
{
public void setExternSheetIndex(int index) {
field_1_index_extern_sheet = index;
}
public int getFirstRow()
{
return field_2_first_row;
}
public void setFirstRow( int row )
{
field_2_first_row = row;
}
public int getLastRow()
{
return field_3_last_row;
}
public void setLastRow( int row )
{
field_3_last_row = row;
}
public int getFirstColumn()
{
return field_4_first_column & 0xFF;
}
public int getFirstColumnRaw()
{
return field_4_first_column;
}
public boolean isFirstRowRelative()
{
return rowRelative.isSet( field_4_first_column );
}
public boolean isFirstColRelative()
{
return colRelative.isSet( field_4_first_column );
}
public void setFirstColumn( short column )
{
field_4_first_column &= 0xFF00;
field_4_first_column |= column & 0xFF;
}
public void setFirstColumnRaw( short column )
{
field_4_first_column = column;
}
public int getLastColumn()
{
return field_5_last_column & 0xFF;
}
public int getLastColumnRaw()
{
return field_5_last_column;
}
public boolean isLastRowRelative()
{
return rowRelative.isSet( field_5_last_column );
}
public boolean isLastColRelative()
{
return colRelative.isSet( field_5_last_column );
}
public void setLastColumn( short column )
{
field_5_last_column &= 0xFF00;
field_5_last_column |= column & 0xFF;
}
public void setLastColumnRaw( short column )
{
field_5_last_column = column;
}
/**
* sets the first row to relative or not
* @param rel FIXME: Document this!
*/
public void setFirstRowRelative( boolean rel )
{
field_4_first_column = rowRelative.setBoolean( field_4_first_column, rel );
}
/**
* set whether the first column is relative
*/
public void setFirstColRelative( boolean rel )
{
field_4_first_column = colRelative.setBoolean( field_4_first_column, rel );
}
/**
* set whether the last row is relative or not
* @param rel FIXME: Document this!
*/
public void setLastRowRelative( boolean rel )
{
field_5_last_column = rowRelative.setBoolean( field_5_last_column, rel );
}
/**
* set whether the last column should be relative or not
*/
public void setLastColRelative( boolean rel )
{
field_5_last_column = colRelative.setBoolean( field_5_last_column, rel );
}
public void setArea( String ref ) {
AreaReference ar = new AreaReference( ref );
CellReference frstCell = ar.getFirstCell();
CellReference lastCell = ar.getLastCell();
setFirstRow(frstCell.getRow());
setFirstColumn(frstCell.getCol());
setLastRow(lastCell.getRow());
setLastColumn(lastCell.getCol());
setFirstColRelative(!frstCell.isColAbsolute());
setLastColRelative(!lastCell.isColAbsolute());
setFirstRowRelative(!frstCell.isRowAbsolute());
setLastRowRelative(!lastCell.isRowAbsolute());
}
/**
* @return text representation of this area reference that can be used in text
* formulas. The sheet name will get properly delimited if required.
*/
public String toFormulaString(HSSFWorkbook book)
{
public String toFormulaString(HSSFWorkbook book) {
// First do the sheet name
StringBuffer retval = new StringBuffer();
String sheetName = Ref3DPtg.getSheetName(book, field_1_index_extern_sheet);
@ -273,29 +103,8 @@ public final class Area3DPtg extends OperandPtg implements AreaI {
}
// Now the normal area bit
retval.append(AreaReference.formatAsString(this));
retval.append(formatReferenceAsString());
// All done
return retval.toString();
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
}
// TODO - one junit relies on this. remove
public boolean equals( Object o )
{
if ( this == o ) return true;
if ( !( o instanceof Area3DPtg ) ) return false;
final Area3DPtg area3DPtg = (Area3DPtg) o;
if ( field_1_index_extern_sheet != area3DPtg.field_1_index_extern_sheet ) return false;
if ( field_2_first_row != area3DPtg.field_2_first_row ) return false;
if ( field_3_last_row != area3DPtg.field_3_last_row ) return false;
if ( field_4_first_column != area3DPtg.field_4_first_column ) return false;
if ( field_5_last_column != area3DPtg.field_5_last_column ) return false;
return true;
}
}

View File

@ -40,21 +40,4 @@ public interface AreaI {
* @return lastcolumn in the area
*/
public int getLastColumn();
/**
* @return isrelative first column to relative or not
*/
public boolean isFirstColRelative();
/**
* @return lastcol relative or not
*/
public boolean isLastColRelative();
/**
* @return whether or not the first row is a relative reference or not.
*/
public boolean isFirstRowRelative();
/**
* @return last row relative or not
*/
public boolean isLastRowRelative();
}

View File

@ -23,7 +23,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
* Specifies a rectangular area of cells A1:A4 for instance.
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class AreaNPtg extends AreaPtgBase {
public final class AreaNPtg extends Area2DPtgBase {
public final static short sid = 0x2D;
public AreaNPtg(RecordInputStream in) {

View File

@ -23,7 +23,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
* Specifies a rectangular area of cells A1:A4 for instance.
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class AreaPtg extends AreaPtgBase {
public final class AreaPtg extends Area2DPtgBase {
public final static short sid = 0x25;
public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {

View File

@ -40,8 +40,6 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
}
public final static short sid = 0x25;
private final static int SIZE = 9;
/** zero based, unsigned 16 bit */
private int field_1_first_row;
/** zero based, unsigned 16 bit */
@ -55,6 +53,10 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
private final static BitField columnMask = BitFieldFactory.getInstance(0x3FFF);
protected AreaPtgBase() {
// do nothing
}
protected AreaPtgBase(String arearef) {
AreaReference ar = new AreaReference(arearef);
CellReference firstCell = ar.getFirstCell();
@ -97,35 +99,17 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
}
}
protected AreaPtgBase(RecordInputStream in)
{
protected final void readCoordinates(RecordInputStream in) {
field_1_first_row = in.readUShort();
field_2_last_row = in.readUShort();
field_3_first_column = in.readUShort();
field_4_last_column = in.readUShort();
}
public final String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append(AreaReference.formatAsString(this));
sb.append("]");
return sb.toString();
}
protected abstract byte getSid();
public final void writeBytes(byte [] array, int offset) {
array[offset] = (byte) (getSid() + getPtgClass());
LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
LittleEndian.putShort(array,offset+7,(short)field_4_last_column);
}
public final int getSize() {
return SIZE;
protected final void writeCoordinates(byte[] array, int offset) {
LittleEndian.putUShort(array, offset + 0, field_1_first_row);
LittleEndian.putUShort(array, offset + 2, field_2_last_row);
LittleEndian.putUShort(array, offset + 4, field_3_first_column);
LittleEndian.putUShort(array, offset + 6, field_4_last_column);
}
/**
@ -275,9 +259,18 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
public final void setLastColumnRaw(short column) {
field_4_last_column = column;
}
protected final String formatReferenceAsString() {
CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative());
CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative());
if(AreaReference.isWholeColumnReference(topLeft, botRight)) {
return (new AreaReference(topLeft, botRight)).formatAsString();
}
return topLeft.formatAsString() + ":" + botRight.formatAsString();
}
public String toFormulaString(HSSFWorkbook book) {
return AreaReference.formatAsString(this);
return formatReferenceAsString();
}
public byte getDefaultOperandClass() {

View File

@ -925,35 +925,17 @@ public class HSSFWorkbook extends POIDocument
Stack ptgs = new Stack();
if (settingRowAndColumn) {
final int exprsSize = 2 * 11 + 1; // Area3DPtg.SIZE + UnionPtg.SIZE
final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE
ptgs.add(new MemFuncPtg(exprsSize));
}
if (startColumn >= 0)
{
Area3DPtg colArea = new Area3DPtg();
colArea.setExternSheetIndex(externSheetIndex);
colArea.setFirstColumn((short)startColumn);
colArea.setLastColumn((short)endColumn);
colArea.setFirstRow(0);
colArea.setLastRow(MAX_ROW);
colArea.setFirstColRelative(false);
colArea.setLastColRelative(false);
colArea.setFirstRowRelative(false);
colArea.setLastRowRelative(false);
if (startColumn >= 0) {
Area3DPtg colArea = new Area3DPtg(0, MAX_ROW, startColumn, endColumn,
false, false, false, false, externSheetIndex);
ptgs.add(colArea);
}
if (startRow >= 0)
{
Area3DPtg rowArea = new Area3DPtg();
rowArea.setExternSheetIndex(externSheetIndex);
rowArea.setFirstColumn((short)0);
rowArea.setLastColumn(MAX_COLUMN);
rowArea.setFirstRow(startRow);
rowArea.setLastRow(endRow);
rowArea.setFirstColRelative(false);
rowArea.setLastColRelative(false);
rowArea.setFirstRowRelative(false);
rowArea.setLastRowRelative(false);
if (startRow >= 0) {
Area3DPtg rowArea = new Area3DPtg(startRow, endRow, 0, MAX_COLUMN,
false, false, false, false, externSheetIndex);
ptgs.add(rowArea);
}
if (settingRowAndColumn)

View File

@ -20,8 +20,6 @@ package org.apache.poi.hssf.util;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.poi.hssf.record.formula.AreaI;
public final class AreaReference {
/** The character (!) that separates sheet names from cell references */
@ -211,18 +209,7 @@ public final class AreaReference {
}
return sb.toString();
}
/**
* Formats a 2-D area as it would appear in a formula. See formatAsString() (no-arg)
*/
public static String formatAsString(AreaI area) {
CellReference topLeft = new CellReference(area.getFirstRow(),area.getFirstColumn(),!area.isFirstRowRelative(),!area.isFirstColRelative());
CellReference botRight = new CellReference(area.getLastRow(),area.getLastColumn(),!area.isLastRowRelative(),!area.isLastColRelative());
if(isWholeColumnReference(topLeft, botRight)) {
return (new AreaReference(topLeft, botRight)).formatAsString();
}
return topLeft.formatAsString() + ":" + botRight.formatAsString();
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");

View File

@ -760,12 +760,8 @@ public final class HSSFChart {
r.setIndexNumberFmtRecord( (short) 0 );
LinkedDataFormulaField formula = new LinkedDataFormulaField();
Stack tokens = new Stack();
Area3DPtg p = new Area3DPtg();
p.setExternSheetIndex( (short) 0 );
p.setFirstColumn( (short) 1 );
p.setLastColumn( (short) 1 );
p.setFirstRow( (short) 0 );
p.setLastRow( (short) 31 );
Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
false, false, false, false, 0);
tokens.add( p );
formula.setFormulaTokens( tokens );
r.setFormulaOfLink( formula );
@ -781,12 +777,8 @@ public final class HSSFChart {
r.setIndexNumberFmtRecord( (short) 0 );
LinkedDataFormulaField formula = new LinkedDataFormulaField();
Stack tokens = new Stack();
Area3DPtg p = new Area3DPtg();
p.setExternSheetIndex( (short) 0 );
p.setFirstColumn( (short) 0 );
p.setLastColumn( (short) 0 );
p.setFirstRow( (short) 0 );
p.setLastRow( (short) 31 );
Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
false, false, false, false, 0);
tokens.add( p );
formula.setFormulaTokens( tokens );
r.setFormulaOfLink( formula );

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -16,8 +15,6 @@
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record;
@ -33,9 +30,7 @@ import java.util.Stack;
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class TestLinkedDataRecord
extends TestCase
{
public final class TestLinkedDataRecord extends TestCase {
/*
The records below are records that would appear in a simple bar chart
@ -160,14 +155,7 @@ recordid = 0x1051, size =8
(byte)0x00,(byte)0x00, // index to last column and relative flags
};
public TestLinkedDataRecord(String name)
{
super(name);
}
public void testLoad()
throws Exception
{
public void testLoad() {
LinkedDataRecord record = new LinkedDataRecord(new TestcaseRecordInputStream((short)0x1051, (short)data.length, data));
assertEquals( LinkedDataRecord.LINK_TYPE_VALUES, record.getLinkType());
@ -176,19 +164,11 @@ recordid = 0x1051, size =8
assertEquals( false, record.isCustomNumberFormat() );
assertEquals( 0, record.getIndexNumberFmtRecord());
Area3DPtg ptg = new Area3DPtg();
ptg.setExternSheetIndex((short)0);
ptg.setFirstColumn((short)0);
ptg.setLastColumn((short)0);
ptg.setFirstRow((short)0);
ptg.setLastRow((short)7936);
ptg.setFirstColRelative(false);
ptg.setLastColRelative(false);
ptg.setFirstRowRelative(false);
ptg.setLastRowRelative(false);
Stack s = new Stack();
s.push(ptg);
assertEquals( s, record.getFormulaOfLink().getFormulaTokens() );
Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
false, false, false, false, 0);
Object ptgActual = record.getFormulaOfLink().getFormulaTokens().get(0);
assertEquals(ptgExpected.toString(), ptgActual.toString());
assertEquals( data.length + 4, record.getRecordSize() );
@ -196,24 +176,15 @@ recordid = 0x1051, size =8
}
public void testStore()
{
public void testStore() {
LinkedDataRecord record = new LinkedDataRecord();
record.setLinkType( LinkedDataRecord.LINK_TYPE_VALUES );
record.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
record.setOptions( (short)0 );
record.setCustomNumberFormat( false );
record.setIndexNumberFmtRecord( (short)0 );
Area3DPtg ptg = new Area3DPtg();
ptg.setExternSheetIndex((short)0);
ptg.setFirstColumn((short)0);
ptg.setLastColumn((short)0);
ptg.setFirstRow((short)0);
ptg.setLastRow((short)7936);
ptg.setFirstColRelative(false);
ptg.setLastColRelative(false);
ptg.setFirstRowRelative(false);
ptg.setLastRowRelative(false);
Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
false, false, false, false, 0);
Stack s = new Stack();
s.push(ptg);
LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();