Bug 45312: Add unit-test and javadoc, also convert file to proper line-ending and make poi.deserialize.escher=true behave for full reading of files outside of BiffViewer

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1621586 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2014-08-31 11:40:22 +00:00
parent 0cbbbfe5d5
commit 809ec00a7d
6 changed files with 836 additions and 673 deletions

View File

@ -145,7 +145,7 @@ public final class BiffViewer {
case DatRecord.sid: return new DatRecord(in); case DatRecord.sid: return new DatRecord(in);
case DataFormatRecord.sid: return new DataFormatRecord(in); case DataFormatRecord.sid: return new DataFormatRecord(in);
case DateWindow1904Record.sid: return new DateWindow1904Record(in); case DateWindow1904Record.sid: return new DateWindow1904Record(in);
case DConRefRecord.sid: return new DConRefRecord(in); case DConRefRecord.sid: return new DConRefRecord(in);
case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in); case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in); case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in); case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);

View File

@ -57,20 +57,19 @@ public abstract class AbstractEscherHolderRecord extends Record {
public AbstractEscherHolderRecord(RecordInputStream in) public AbstractEscherHolderRecord(RecordInputStream in)
{ {
escherRecords = new ArrayList<EscherRecord>(); escherRecords = new ArrayList<EscherRecord>();
if (! DESERIALISE ) if (! DESERIALISE ) {
{
rawDataContainer.concatenate(in.readRemainder()); rawDataContainer.concatenate(in.readRemainder());
} } else {
else
{
byte[] data = in.readAllContinuedRemainder(); byte[] data = in.readAllContinuedRemainder();
convertToEscherRecords( 0, data.length, data ); convertToEscherRecords( 0, data.length, data );
} }
} }
protected void convertRawBytesToEscherRecords() { protected void convertRawBytesToEscherRecords() {
byte[] rawData = getRawData(); if (! DESERIALISE ) {
convertToEscherRecords(0, rawData.length, rawData); byte[] rawData = getRawData();
convertToEscherRecords(0, rawData.length, rawData);
}
} }
private void convertToEscherRecords( int offset, int size, byte[] data ) private void convertToEscherRecords( int offset, int size, byte[] data )
{ {
@ -224,7 +223,7 @@ public abstract class AbstractEscherHolderRecord extends Record {
public EscherRecord getEscherRecord(int index) public EscherRecord getEscherRecord(int index)
{ {
return (EscherRecord) escherRecords.get(index); return escherRecords.get(index);
} }
/** /**

View File

@ -43,6 +43,10 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
* Creates a new client anchor and sets the top-left and bottom-right * Creates a new client anchor and sets the top-left and bottom-right
* coordinates of the anchor. * coordinates of the anchor.
* *
* Note: Microsoft Excel seems to sometimes disallow
* higher y1 than y2 or higher x1 than x2, you might need to
* reverse them and draw shapes vertically or horizontally flipped!
*
* @param dx1 the x coordinate within the first cell. * @param dx1 the x coordinate within the first cell.
* @param dy1 the y coordinate within the first cell. * @param dy1 the y coordinate within the first cell.
* @param dx2 the x coordinate within the second cell. * @param dx2 the x coordinate within the second cell.
@ -186,8 +190,12 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
} }
/** /**
* Dets the top-left and bottom-right * Sets the top-left and bottom-right coordinates of
* coordinates of the anchor. * the anchor.
*
* Note: Microsoft Excel seems to sometimes disallow
* higher y1 than y2 or higher x1 than x2, you might need to
* reverse them and draw shapes vertically or horizontally flipped!
* *
* @param x1 the x coordinate within the first cell. * @param x1 the x coordinate within the first cell.
* @param y1 the y coordinate within the first cell. * @param y1 the y coordinate within the first cell.

View File

@ -172,6 +172,10 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
* Creates a simple shape. This includes such shapes as lines, rectangles, * Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals. * and ovals.
* *
* Note: Microsoft Excel seems to sometimes disallow
* higher y1 than y2 or higher x1 than x2 in the anchor, you might need to
* reverse them and draw shapes vertically or horizontally flipped!
*
* @param anchor the client anchor describes how this group is attached * @param anchor the client anchor describes how this group is attached
* to the sheet. * to the sheet.
* @return the newly created shape. * @return the newly created shape.

View File

@ -27,6 +27,11 @@ import java.io.IOException;
/** /**
* An abstract shape. * An abstract shape.
*
* Note: Microsoft Excel seems to sometimes disallow
* higher y1 than y2 or higher x1 than x2 in the anchor, you might need to
* reverse them and draw shapes vertically or horizontally flipped via
* setFlipVertical() or setFlipHorizontally().
*/ */
public abstract class HSSFShape { public abstract class HSSFShape {
public static final int LINEWIDTH_ONE_PT = 12700; public static final int LINEWIDTH_ONE_PT = 12700;

View File

@ -17,8 +17,19 @@
package org.apache.poi.hssf.model; package org.apache.poi.hssf.model;
import java.io.IOException;
import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.ddf.*;
import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord; import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.EscherAggregate; import org.apache.poi.hssf.record.EscherAggregate;
@ -27,13 +38,15 @@ import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.HexDump; import org.apache.poi.util.HexDump;
import java.io.IOException;
/** /**
* @author Evgeniy Berlog * @author Evgeniy Berlog
* date: 12.06.12 * date: 12.06.12
*/ */
public class TestDrawingShapes extends TestCase { public class TestDrawingShapes extends TestCase {
static {
//System.setProperty("poi.deserialize.escher", "true");
}
/** /**
* HSSFShape tree bust be built correctly * HSSFShape tree bust be built correctly
@ -327,46 +340,59 @@ public class TestDrawingShapes extends TestCase {
public void testOpt() throws Exception { public void testOpt() throws Exception {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
// create a sheet with a text box try {
HSSFSheet sheet = wb.createSheet(); // create a sheet with a text box
HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor()); HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox); EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);
EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID); EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);
assertSame(opt1, opt2); assertSame(opt1, opt2);
} finally {
wb.close();
}
} }
public void testCorrectOrderInOptRecord(){ public void testCorrectOrderInOptRecord() throws IOException{
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor()); try {
EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox); HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
String opt1Str = opt.toXml(); HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);
textbox.setFillColor(textbox.getFillColor()); String opt1Str = opt.toXml();
EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID); textbox.setFillColor(textbox.getFillColor());
assertEquals(opt1Str, optRecord.toXml()); EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
textbox.setLineStyle(textbox.getLineStyle()); EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
assertEquals(opt1Str, optRecord.toXml()); assertEquals(opt1Str, optRecord.toXml());
textbox.setLineWidth(textbox.getLineWidth()); textbox.setLineStyle(textbox.getLineStyle());
assertEquals(opt1Str, optRecord.toXml()); assertEquals(opt1Str, optRecord.toXml());
textbox.setLineStyleColor(textbox.getLineStyleColor()); textbox.setLineWidth(textbox.getLineWidth());
assertEquals(opt1Str, optRecord.toXml()); assertEquals(opt1Str, optRecord.toXml());
textbox.setLineStyleColor(textbox.getLineStyleColor());
assertEquals(opt1Str, optRecord.toXml());
} finally {
wb.close();
}
} }
public void testDgRecordNumShapes(){ public void testDgRecordNumShapes() throws IOException{
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(); try {
HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch); EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch);
EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0); EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);
assertEquals(dgRecord.getNumShapes(), 1); assertEquals(dgRecord.getNumShapes(), 1);
} finally {
wb.close();
}
} }
public void testTextForSimpleShape(){ public void testTextForSimpleShape(){
@ -614,20 +640,25 @@ public class TestDrawingShapes extends TestCase {
rectangle.setString(new HSSFRichTextString("1234")); rectangle.setString(new HSSFRichTextString("1234"));
} }
public void testShapeContainerImplementsIterable(){ public void testShapeContainerImplementsIterable() throws IOException{
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
patriarch.createSimpleShape(new HSSFClientAnchor()); try {
patriarch.createSimpleShape(new HSSFClientAnchor()); HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
int i=2; patriarch.createSimpleShape(new HSSFClientAnchor());
patriarch.createSimpleShape(new HSSFClientAnchor());
for (HSSFShape shape: patriarch){ int i=2;
i--;
for (HSSFShape shape: patriarch){
i--;
}
assertEquals(i, 0);
} finally {
wb.close();
} }
assertEquals(i, 0);
} }
public void testClearShapesForPatriarch(){ public void testClearShapesForPatriarch(){
@ -659,4 +690,120 @@ public class TestDrawingShapes extends TestCase {
assertEquals(agg.getTailRecords().size(), 0); assertEquals(agg.getTailRecords().size(), 0);
assertEquals(patriarch.getChildren().size(), 0); assertEquals(patriarch.getChildren().size(), 0);
} }
public void testBug45312() throws Exception {
HSSFWorkbook wb = new HSSFWorkbook();
try {
HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
{
HSSFClientAnchor a1 = new HSSFClientAnchor();
a1.setAnchor( (short)1, 1, 0, 0, (short) 1, 1, 512, 100);
HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
}
{
HSSFClientAnchor a1 = new HSSFClientAnchor();
a1.setAnchor( (short)1, 1, 512, 0, (short) 1, 1, 1024, 100);
HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
shape1.setFlipVertical(true);
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
}
{
HSSFClientAnchor a1 = new HSSFClientAnchor();
a1.setAnchor( (short)2, 2, 0, 0, (short) 2, 2, 512, 100);
HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
}
{
HSSFClientAnchor a1 = new HSSFClientAnchor();
a1.setAnchor( (short)2, 2, 0, 100, (short) 2, 2, 512, 200);
HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
shape1.setFlipHorizontal(true);
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
}
/*OutputStream stream = new FileOutputStream("/tmp/45312.xls");
try {
wb.write(stream);
} finally {
stream.close();
}*/
checkWorkbookBack(wb);
} finally {
wb.close();
}
}
private void checkWorkbookBack(HSSFWorkbook wb) {
HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertNotNull(wbBack);
HSSFSheet sheetBack = wbBack.getSheetAt(0);
assertNotNull(sheetBack);
HSSFPatriarch patriarchBack = sheetBack.getDrawingPatriarch();
assertNotNull(patriarchBack);
List<HSSFShape> children = patriarchBack.getChildren();
assertEquals(4, children.size());
HSSFShape hssfShape = children.get(0);
assertTrue(hssfShape instanceof HSSFSimpleShape);
HSSFAnchor anchor = hssfShape.getAnchor();
assertTrue(anchor instanceof HSSFClientAnchor);
assertEquals(0, anchor.getDx1());
assertEquals(512, anchor.getDx2());
assertEquals(0, anchor.getDy1());
assertEquals(100, anchor.getDy2());
HSSFClientAnchor cAnchor = (HSSFClientAnchor) anchor;
assertEquals(1, cAnchor.getCol1());
assertEquals(1, cAnchor.getCol2());
assertEquals(1, cAnchor.getRow1());
assertEquals(1, cAnchor.getRow2());
hssfShape = children.get(1);
assertTrue(hssfShape instanceof HSSFSimpleShape);
anchor = hssfShape.getAnchor();
assertTrue(anchor instanceof HSSFClientAnchor);
assertEquals(512, anchor.getDx1());
assertEquals(1024, anchor.getDx2());
assertEquals(0, anchor.getDy1());
assertEquals(100, anchor.getDy2());
cAnchor = (HSSFClientAnchor) anchor;
assertEquals(1, cAnchor.getCol1());
assertEquals(1, cAnchor.getCol2());
assertEquals(1, cAnchor.getRow1());
assertEquals(1, cAnchor.getRow2());
hssfShape = children.get(2);
assertTrue(hssfShape instanceof HSSFSimpleShape);
anchor = hssfShape.getAnchor();
assertTrue(anchor instanceof HSSFClientAnchor);
assertEquals(0, anchor.getDx1());
assertEquals(512, anchor.getDx2());
assertEquals(0, anchor.getDy1());
assertEquals(100, anchor.getDy2());
cAnchor = (HSSFClientAnchor) anchor;
assertEquals(2, cAnchor.getCol1());
assertEquals(2, cAnchor.getCol2());
assertEquals(2, cAnchor.getRow1());
assertEquals(2, cAnchor.getRow2());
hssfShape = children.get(3);
assertTrue(hssfShape instanceof HSSFSimpleShape);
anchor = hssfShape.getAnchor();
assertTrue(anchor instanceof HSSFClientAnchor);
assertEquals(0, anchor.getDx1());
assertEquals(512, anchor.getDx2());
assertEquals(100, anchor.getDy1());
assertEquals(200, anchor.getDy2());
cAnchor = (HSSFClientAnchor) anchor;
assertEquals(2, cAnchor.getCol1());
assertEquals(2, cAnchor.getCol2());
assertEquals(2, cAnchor.getRow1());
assertEquals(2, cAnchor.getRow2());
}
} }