import org.apache.poi.hssf.model.ConvertAnchor;
import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.model.TextboxShape;
-import org.apache.poi.hssf.usermodel.HSSFAnchor;
-import org.apache.poi.hssf.usermodel.HSSFChildAnchor;
-import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
-import org.apache.poi.hssf.usermodel.HSSFPatriarch;
-import org.apache.poi.hssf.usermodel.HSSFPicture;
-import org.apache.poi.hssf.usermodel.HSSFShape;
-import org.apache.poi.hssf.usermodel.HSSFShapeContainer;
-import org.apache.poi.hssf.usermodel.HSSFShapeGroup;
-import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
-import org.apache.poi.hssf.usermodel.HSSFTextbox;
+import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/**
* list of "tail" records that need to be serialized after all drawing group records
*/
- private List tailRec = new ArrayList();
+ private List<Record> tailRec = new ArrayList<Record>();
public EscherAggregate(DrawingManager2 drawingManager) {
this.drawingManager = drawingManager;
}
// Decode the shapes
- // agg.escherRecords = new ArrayList();
+ // agg.escherRecords = new ArrayList();
int pos = 0;
while (pos < buffer.size()) {
EscherRecord r = recordFactory.createRecord(buffer.toByteArray(), pos);
public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) {
if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) {
- spEndingOffsets.add(Integer.valueOf(offset));
+ spEndingOffsets.add(offset);
shapes.add(record);
}
}
pos = offset;
int writtenEscherBytes = 0;
for (int i = 1; i < shapes.size(); i++) {
- int endOffset = ((Integer) spEndingOffsets.get(i)).intValue() - 1;
+ int endOffset;
+ if (i == shapes.size()-1){
+ endOffset = buffer.length - 1;
+ } else {
+ endOffset = (Integer) spEndingOffsets.get(i) - 1;
+ }
int startOffset;
if (i == 1)
startOffset = 0;
else
- startOffset = ((Integer) spEndingOffsets.get(i - 1)).intValue();
+ startOffset = (Integer) spEndingOffsets.get(i - 1);
byte[] drawingData = new byte[endOffset - startOffset + 1];
container.getChildren().add(shape);
}
- private static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord) {
+ public static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord) {
HSSFClientAnchor anchor = new HSSFClientAnchor();
anchor.setAnchorType(anchorRecord.getFlag());
anchor.setCol1(anchorRecord.getCol1());
return anchor;
}
- private static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord) {
+ public static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord) {
HSSFChildAnchor anchor = new HSSFChildAnchor();
// anchor.setAnchorType(anchorRecord.getFlag());
// anchor.setCol1( anchorRecord.getCol1() );
return null;
}
+ /**
+ * Returns the mapping of {@link EscherClientDataRecord} and {@link EscherTextboxRecord}
+ * to their {@link TextObjectRecord} or {@link ObjRecord} .
+ *
+ * We need to access it outside of EscherAggregate when building shapes
+ *
+ * @return
+ */
+ public Map<EscherRecord, Record> getShapeToObjMapping(){
+ return Collections.unmodifiableMap(shapeToObj);
+ }
+
+ /**
+ *
+ * @return tails records. We need to access them when building shapes.
+ * Every HSSFComment shape has a link to a NoteRecord from the tailRec collection.
+ */
+ public List<Record> getTailRecords(){
+ return Collections.unmodifiableList(tailRec);
+ }
}
package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherChildAnchorRecord;
+
public final class HSSFChildAnchor extends HSSFAnchor {
+
+ private EscherChildAnchorRecord escherChildAnchorRecord;
+
+ public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) {
+ this.escherChildAnchorRecord = escherChildAnchorRecord;
+ }
+
public HSSFChildAnchor()
{
}
package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ss.usermodel.ClientAnchor;
int row2;
int anchorType;
+ private EscherClientAnchorRecord escherClientAnchorRecord;
+
+ public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) {
+ this.escherClientAnchorRecord = escherClientAnchorRecord;
+ //TODO set properties or read properties from EscherRecord ?
+ }
+
/**
* Creates a new client anchor and defaults all the anchor positions to 0.
*/
import java.util.List;
import org.apache.poi.ddf.EscherComplexProperty;
+import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherSpgrRecord;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.ss.usermodel.Chart;
import org.apache.poi.util.StringUtil;
throw new RuntimeException("NotImplemented");
}
+
+ void buildShapeTree(){
+ EscherContainerRecord dgContainer = _boundAggregate.getEscherContainer();
+ EscherContainerRecord spgrConrainer = dgContainer.getChildContainers().get(0);
+ List<EscherContainerRecord> spgrChildren = spgrConrainer.getChildContainers();
+
+ for(int i = 0; i < spgrChildren.size(); i++){
+ EscherContainerRecord spContainer = spgrChildren.get(i);
+ if (i == 0){
+ EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
+ setCoordinates(
+ spgr.getRectX1(), spgr.getRectY1(),
+ spgr.getRectX2(), spgr.getRectY2()
+ );
+ } else {
+ HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this);
+ }
+ }
+ }
}
--- /dev/null
+package org.apache.poi.hssf.usermodel;\r
+\r
+import org.apache.poi.ddf.EscherContainerRecord;\r
+import org.apache.poi.hssf.record.ObjRecord;\r
+\r
+/**\r
+ * @author Evgeniy Berlog\r
+ * @date 08.06.12\r
+ */\r
+public class HSSFRectangle extends HSSFShape{\r
+\r
+ public HSSFRectangle(EscherContainerRecord spContainer, ObjRecord objRecord) {\r
+ super(spContainer, objRecord);\r
+ }\r
+}\r
package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+
/**
* An abstract shape.
*
public static final int LINESTYLE_NONE = -1;
// TODO - make all these fields private
- final HSSFShape parent;
+ HSSFShape parent;
HSSFAnchor anchor;
HSSFPatriarch _patriarch;
private int _lineStyleColor = 0x08000040;
private int _lineStyle = LINESTYLE_SOLID;
private boolean _noFill = false;
+ private EscherContainerRecord spContainer;
+ private ObjRecord objRecord;
+
+ public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord){
+ this.spContainer = spContainer;
+ this.objRecord = objRecord;
+ }
/**
* Create a new shape with the specified parent and anchor.
*/
- HSSFShape( HSSFShape parent, HSSFAnchor anchor )
+ public HSSFShape( HSSFShape parent, HSSFAnchor anchor )
{
this.parent = parent;
this.anchor = anchor;
}
+ public EscherContainerRecord getSpContainer() {
+ return spContainer;
+ }
+
+ public ObjRecord getObjRecord() {
+ return objRecord;
+ }
+
/**
* Gets the parent shape.
*/
*/
List getChildren();
+ /**
+ * add shape to the list of child records
+ * @param shape
+ */
+ public void addShape(HSSFShape shape);
+
+ /**
+ * set coordinates of this group relative to the parent
+ */
+ void setCoordinates( int x1, int y1, int x2, int y2 );
+
}
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.apache.poi.hssf.usermodel;\r
+\r
+import org.apache.poi.ddf.EscherClientDataRecord;\r
+import org.apache.poi.ddf.EscherContainerRecord;\r
+import org.apache.poi.ddf.EscherRecord;\r
+import org.apache.poi.ddf.EscherSpRecord;\r
+import org.apache.poi.ddf.EscherSpgrRecord;\r
+import org.apache.poi.ddf.EscherTextboxRecord;\r
+import org.apache.poi.hssf.model.TextboxShape;\r
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;\r
+import org.apache.poi.hssf.record.EscherAggregate;\r
+import org.apache.poi.hssf.record.NoteRecord;\r
+import org.apache.poi.hssf.record.ObjRecord;\r
+import org.apache.poi.hssf.record.Record;\r
+import org.apache.poi.hssf.record.TextObjectRecord;\r
+import org.apache.poi.hssf.usermodel.drawing.HSSFShapeType;\r
+\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * @author evgeniy\r
+ * date: 05.06.12\r
+ */\r
+public class HSSFShapeFactory {\r
+\r
+ private static final Map<Short, Class> shapeTypeToClass = new HashMap<Short, Class>(HSSFShapeType.values().length);\r
+ private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass);\r
+\r
+ static {\r
+ for (HSSFShapeType type: HSSFShapeType.values()){\r
+ shapeTypeToClass.put(type.getType(), type.getShape());\r
+ }\r
+ }\r
+\r
+ private static class ReflectionConstructorShapeCreator {\r
+\r
+ private final Map<Short, Class> shapeTypeToClass;\r
+\r
+ private ReflectionConstructorShapeCreator(Map<Short, Class> shapeTypeToClass) {\r
+ this.shapeTypeToClass = shapeTypeToClass;\r
+ }\r
+\r
+ public HSSFShape createNewShape(Short type, EscherContainerRecord spContainer, ObjRecord objRecord){\r
+ if (!shapeTypeToClass.containsKey(type)){\r
+ return new HSSFUnknownShape(spContainer, objRecord);\r
+ }\r
+ Class clazz = shapeTypeToClass.get(type);\r
+ if (null == clazz){\r
+ System.out.println("No class attached to shape type: "+type);\r
+ return new HSSFUnknownShape(spContainer, objRecord);\r
+ }\r
+ try{\r
+ Constructor constructor = clazz.getConstructor(new Class[]{EscherContainerRecord.class, ObjRecord.class});\r
+ return (HSSFShape) constructor.newInstance(spContainer, objRecord);\r
+ } catch (NoSuchMethodException e) {\r
+ throw new IllegalStateException(clazz.getName() +" doesn't have required for shapes constructor");\r
+ } catch (Exception e) {\r
+ throw new IllegalStateException("Couldn't create new instance of " + clazz.getName());\r
+ }\r
+ }\r
+ }\r
+\r
+ public static HSSFShape createShape(EscherRecord container, ObjRecord objRecord){\r
+ if (0 == container.getChildRecords().size()){\r
+ throw new IllegalArgumentException("Couldn't create shape from empty escher container");\r
+ }\r
+ if (container.getChild(0) instanceof EscherSpgrRecord){\r
+ return new HSSFShapeGroup((EscherContainerRecord) container, objRecord);\r
+ }\r
+\r
+ //TODO implement cases for all shapes\r
+ return new HSSFUnknownShape(container, objRecord);\r
+ }\r
+\r
+ public static HSSFShapeGroup createShapeGroup(){\r
+ return null;\r
+ }\r
+\r
+ public static HSSFShapeGroup createSimpleShape(EscherRecord container, ObjRecord objRecord){\r
+ return null;\r
+ }\r
+\r
+ public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out){\r
+ if(container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){\r
+ HSSFShapeGroup group = new HSSFShapeGroup(container,\r
+ null /* shape containers don't have a associated Obj record*/);\r
+ List<EscherContainerRecord> children = container.getChildContainers();\r
+ // skip the first child record, it is group descriptor\r
+ for(int i = 0; i < children.size(); i++) {\r
+ EscherContainerRecord spContainer = children.get(i);\r
+ if(i == 0){\r
+ EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID);\r
+ group.setCoordinates(\r
+ spgr.getRectX1(), spgr.getRectY1(),\r
+ spgr.getRectX2(), spgr.getRectY2()\r
+ );\r
+ } else {\r
+ createShapeTree(spContainer, agg, group);\r
+ }\r
+ }\r
+ out.addShape(group);\r
+ } else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER){\r
+ Map<EscherRecord, Record> shapeToObj = agg.getShapeToObjMapping();\r
+ EscherSpRecord spRecord = null;\r
+ ObjRecord objRecord = null;\r
+ TextObjectRecord txtRecord = null;\r
+\r
+ for(EscherRecord record : container.getChildRecords()) {\r
+ switch(record.getRecordId()) {\r
+ case EscherSpRecord.RECORD_ID:\r
+ spRecord = (EscherSpRecord)record;\r
+ break;\r
+ case EscherClientDataRecord.RECORD_ID:\r
+ objRecord = (ObjRecord)shapeToObj.get(record);\r
+ break;\r
+ case EscherTextboxRecord.RECORD_ID:\r
+ txtRecord = (TextObjectRecord)shapeToObj.get(record);\r
+ break;\r
+ }\r
+ }\r
+ if (null != objRecord){\r
+ HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);\r
+ out.addShape(shape);\r
+ }\r
+ if (null != txtRecord){\r
+ //TODO resolve textbox\r
+// TextboxShape shape = new TextboxShape(container, txtRecord);\r
+// out.a\r
+ }\r
+//\r
+// //TODO decide what shape to create based on ObjRecord / EscherSpRecord\r
+// HSSFShape shape = new HSSFUnknownShape(container, objRecord);\r
+// out.addShape(shape);\r
+ }\r
+ }\r
+}\r
package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherChildAnchorRecord;
+import org.apache.poi.ddf.EscherClientAnchorRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSpgrRecord;
+import org.apache.poi.hssf.model.TextboxShape;
+import org.apache.poi.hssf.record.EscherAggregate;
+import org.apache.poi.hssf.record.ObjRecord;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
int x2 = 1023;
int y2 = 255;
+ public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) {
+ super(spgrContainer, objRecord);
+
+ // read internal and external coordinates from spgrContainer
+ EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0);
+ for(EscherRecord ch : spContainer.getChildRecords()){
+ switch(ch.getRecordId()) {
+ case EscherSpgrRecord.RECORD_ID:
+ EscherSpgrRecord spgr = (EscherSpgrRecord)ch;
+ setCoordinates(
+ spgr.getRectX1(), spgr.getRectY1(),
+ spgr.getRectX2(), spgr.getRectY2()
+ );
+ break;
+ case EscherClientAnchorRecord.RECORD_ID:
+ this.anchor = EscherAggregate.toClientAnchor((EscherClientAnchorRecord)ch);
+ // TODO anchor = new HSSFClientAnchor((EscherChildAnchorRecord)ch);
+ break;
+ case EscherChildAnchorRecord.RECORD_ID:
+ this.anchor = EscherAggregate.toChildAnchor((EscherChildAnchorRecord)ch);
+ // TODO anchor = new HSSFChildAnchor((EscherClientAnchorRecord)ch);
+ break;
+ }
+ }
+
+ }
public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
{
shapes.add(shape);
}
+ public void addTextBox(TextboxShape textboxShape){
+// HSSFTextbox shape = new HSSFTextbox(this, textboxShape.geanchor);
+// shapes.add(textboxShape);
+ }
+
/**
* Create a new simple shape under this group.
* @param anchor the position of the shape.
if(agg == null) return null;
_patriarch = new HSSFPatriarch(this, agg);
- agg.setPatriarch(_patriarch);
+ _patriarch.buildShapeTree();
+
+ //HSSFShapeFactory.createShapeTree();
+ //agg.setPatriarch(_patriarch);
+ //EscherAggregate.createShapeTree(EscherAggregate.getMainSpgrContainer(agg), agg.getPatriarch(), agg);
// Have it process the records into high level objects
// as best it can do (this step may eat anything
// that isn't supported, you were warned...)
- agg.convertRecordsToUserModel();
+// agg.convertRecordsToUserModel();
// Return what we could cope with
return _patriarch;
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.apache.poi.hssf.usermodel;\r
+\r
+import org.apache.poi.ddf.EscherContainerRecord;\r
+import org.apache.poi.ddf.EscherRecord;\r
+import org.apache.poi.hssf.record.ObjRecord;\r
+\r
+/**\r
+ * @author Evgeniy Berlog\r
+ * date: 05.06.12\r
+ */\r
+public class HSSFUnknownShape extends HSSFShape {\r
+\r
+ public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) {\r
+ super((EscherContainerRecord) spContainer, objRecord);\r
+ }\r
+}\r
--- /dev/null
+package org.apache.poi.hssf.usermodel.drawing;\r
+\r
+import org.apache.poi.hssf.usermodel.HSSFRectangle;\r
+\r
+/**\r
+ * @author Evgeniy Berlog\r
+ * date: 08.06.12\r
+ */\r
+public enum HSSFShapeType {\r
+ NOT_PRIMITIVE(0x0, null),\r
+ RECTANGLE(0x1, HSSFRectangle.class),\r
+ ROUND_RECTANGLE(0x2, null);\r
+\r
+ private Short type;\r
+ private Class shape;\r
+\r
+ HSSFShapeType(Integer type, Class shape) {\r
+ this.type = type.shortValue();\r
+ this.shape = shape;\r
+ }\r
+\r
+ public Short getType() {\r
+ return type;\r
+ }\r
+\r
+ public Class getShape() {\r
+ return shape;\r
+ }\r
+}\r
package org.apache.poi.hssf.model;\r
\r
import junit.framework.TestCase;\r
+import org.apache.poi.ddf.EscherContainerRecord;\r
import org.apache.poi.ddf.EscherDggRecord;\r
+import org.apache.poi.ddf.EscherRecord;\r
import org.apache.poi.hssf.HSSFTestDataSamples;\r
import org.apache.poi.hssf.record.*;\r
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;\r
-import org.apache.poi.hssf.usermodel.HSSFSheet;\r
-import org.apache.poi.hssf.usermodel.HSSFTestHelper;\r
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
+import org.apache.poi.hssf.usermodel.*;\r
import org.apache.poi.util.HexRead;\r
\r
import java.io.*;\r
* @author Evgeniy Berlog\r
*/\r
public class TestDrawingAggregate extends TestCase {\r
- private static byte[] toByteArray(List<RecordBase> records){\r
- ByteArrayOutputStream out = new ByteArrayOutputStream();\r
- for(RecordBase rb : records) {\r
- Record r = (Record)rb;\r
- try {\r
- out.write(r.serialize());\r
- } catch (IOException e){\r
- throw new RuntimeException(e);\r
- }\r
- }\r
- return out.toByteArray();\r
+\r
+ private int spgrCount = 0;\r
+ private int spCount = 0;\r
+ private int shapeCount = 0;\r
+ private int shGroupCount = 0;\r
+\r
+ /*\r
+ * EscherAggregate must have for each SpgrContainer HSSFShapeGroup and for each SpContainer HSSFShape\r
+ */\r
+ private void checkEscherAndShapesCount(EscherAggregate agg, HSSFSheet sheet) {\r
+ /*\r
+ HSSFPatriarch patriarch = HSSFTestHelper.createTestPatriarch(sheet, agg);\r
+ agg.setPatriarch(patriarch);\r
+ EscherAggregate.createShapeTree(EscherAggregate.getMainSpgrContainer(agg), agg.getPatriarch(), agg);\r
+ EscherContainerRecord mainContainer = EscherAggregate.getMainSpgrContainer(agg);\r
+ calculateShapesCount(agg.getPatriarch());\r
+ calculateEscherContainersCount(mainContainer);\r
+\r
+ assertEquals(spgrCount, shGroupCount);\r
+ assertEquals(spCount - spgrCount - 1, shapeCount);\r
+ */\r
+ }\r
+\r
+ private void calculateEscherContainersCount(EscherContainerRecord spgr) {\r
+ for (EscherRecord record : spgr.getChildRecords()) {\r
+ if (EscherContainerRecord.SP_CONTAINER == record.getRecordId()) {\r
+ spCount++;\r
+ continue;\r
+ }\r
+ if (EscherContainerRecord.SPGR_CONTAINER == record.getRecordId()) {\r
+ spgrCount++;\r
+ calculateEscherContainersCount((EscherContainerRecord) record);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void calculateShapesCount(HSSFShapeContainer group) {\r
+ for (HSSFShape shape : (List<HSSFShape>) group.getChildren()) {\r
+ if (shape instanceof HSSFShapeGroup) {\r
+ shGroupCount++;\r
+ calculateShapesCount((HSSFShapeGroup) shape);\r
+ } else {\r
+ shapeCount++;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ private static byte[] toByteArray(List<RecordBase> records) {\r
+ ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+ for (RecordBase rb : records) {\r
+ Record r = (Record) rb;\r
+ try {\r
+ out.write(r.serialize());\r
+ } catch (IOException e) {\r
+ throw new RuntimeException(e);\r
+ }\r
}\r
+ return out.toByteArray();\r
+ }\r
+\r
+ public void testSolverContainerMustBeSavedDuringSerialization(){\r
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SolverContainerAfterSPGR.xls");\r
+ HSSFSheet sh = wb.getSheetAt(0);\r
+ InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);\r
+ sh.getDrawingPatriarch();\r
+ EscherAggregate agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid);\r
+ assertEquals(agg.getEscherRecords().get(0).getChildRecords().size(), 3);\r
+ assertEquals(agg.getEscherRecords().get(0).getChild(2).getRecordId(), EscherContainerRecord.SOLVER_CONTAINER);\r
+ wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+ sh = wb.getSheetAt(0);\r
+ sh.getDrawingPatriarch();\r
+ ish = HSSFTestHelper.getSheetForTest(sh);\r
+ agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid);\r
+ assertEquals(agg.getEscherRecords().get(0).getChildRecords().size(), 3);\r
+ assertEquals(agg.getEscherRecords().get(0).getChild(2).getRecordId(), EscherContainerRecord.SOLVER_CONTAINER);\r
+\r
+ }\r
\r
/**\r
* test reading drawing aggregate from a test file from Bugzilla 45129\r
byte[] dgBytesAfterSave = agg.serialize();\r
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length);\r
assertTrue("drawing data brefpore and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));\r
+ checkEscherAndShapesCount(agg, sh);\r
}\r
\r
/**\r
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length);\r
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));\r
\r
-\r
+ checkEscherAndShapesCount(agg, sh);\r
}\r
\r
\r
List<RecordBase> records = isheet.getRecords();\r
\r
HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
- InternalSheet isheet2 = HSSFTestHelper.getSheetForTest( wb2.getSheetAt(0));\r
+ InternalSheet isheet2 = HSSFTestHelper.getSheetForTest(wb2.getSheetAt(0));\r
List<RecordBase> records2 = isheet2.getRecords();\r
\r
assertEquals(records.size(), records2.size());\r
- for(int i = 0; i < records.size(); i++) {\r
+ for (int i = 0; i < records.size(); i++) {\r
RecordBase r1 = records.get(i);\r
RecordBase r2 = records2.get(i);\r
assertTrue(r1.getClass() == r2.getClass());\r
assertEquals(r1.getRecordSize(), r2.getRecordSize());\r
- if(r1 instanceof Record ){\r
- assertEquals(((Record)r1).getSid(), ((Record)r2).getSid());\r
+ if (r1 instanceof Record) {\r
+ assertEquals(((Record) r1).getSid(), ((Record) r2).getSid());\r
assertTrue(Arrays.equals(((Record) r1).serialize(), ((Record) r2).serialize()));\r
}\r
}\r
-\r
}\r
\r
public void testSerializeDrawingWithComments() throws IOException {\r
byte[] dgBytesAfterSave = agg.serialize();\r
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length);\r
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));\r
+ checkEscherAndShapesCount(agg, sh);\r
}\r
\r
\r
\r
byte[] dgBytesAfterSave = agg.serialize();\r
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length);\r
- assertTrue("drawing data brefpore and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));\r
+ assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));\r
+ checkEscherAndShapesCount(agg, sh);\r
}\r
\r
public void testUnhandledContinue() {\r
package org.apache.poi.hssf.usermodel;
import org.apache.poi.hssf.model.InternalSheet;
import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.EscherAggregate;
/**
* Helper class for HSSF tests that aren't within the
public static InternalSheet getSheetForTest(HSSFSheet sheet) {
return sheet.getSheet();
}
+
+ public static HSSFPatriarch createTestPatriarch(HSSFSheet sheet, EscherAggregate agg){
+ return new HSSFPatriarch(sheet, agg);
+ }
}