git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1348168 13f79535-47bb-0310-9956-ffa450edef68tags/3.10-beta1
@@ -43,16 +43,7 @@ import org.apache.poi.hssf.model.CommentShape; | |||
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; | |||
@@ -322,7 +313,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
/** | |||
* 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; | |||
@@ -413,7 +404,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
} | |||
// 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); | |||
@@ -486,7 +477,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
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); | |||
} | |||
} | |||
@@ -501,12 +492,17 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
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]; | |||
@@ -790,7 +786,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
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()); | |||
@@ -804,7 +800,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
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() ); | |||
@@ -1081,4 +1077,24 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
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); | |||
} | |||
} |
@@ -18,7 +18,16 @@ | |||
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() | |||
{ | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hssf.usermodel; | |||
import org.apache.poi.ddf.EscherClientAnchorRecord; | |||
import org.apache.poi.ss.usermodel.ClientAnchor; | |||
@@ -33,6 +34,13 @@ public final class HSSFClientAnchor extends HSSFAnchor implements 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. | |||
*/ |
@@ -22,9 +22,11 @@ import java.util.Iterator; | |||
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; | |||
@@ -314,4 +316,23 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { | |||
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); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,15 @@ | |||
package org.apache.poi.hssf.usermodel; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.hssf.record.ObjRecord; | |||
/** | |||
* @author Evgeniy Berlog | |||
* @date 08.06.12 | |||
*/ | |||
public class HSSFRectangle extends HSSFShape{ | |||
public HSSFRectangle(EscherContainerRecord spContainer, ObjRecord objRecord) { | |||
super(spContainer, objRecord); | |||
} | |||
} |
@@ -17,6 +17,9 @@ | |||
package org.apache.poi.hssf.usermodel; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.hssf.record.ObjRecord; | |||
/** | |||
* An abstract shape. | |||
* | |||
@@ -40,7 +43,7 @@ public abstract class HSSFShape { | |||
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; | |||
@@ -49,15 +52,30 @@ public abstract class HSSFShape { | |||
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. | |||
*/ |
@@ -31,4 +31,15 @@ public interface HSSFShapeContainer | |||
*/ | |||
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 ); | |||
} |
@@ -0,0 +1,157 @@ | |||
/* | |||
* 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.usermodel; | |||
import org.apache.poi.ddf.EscherClientDataRecord; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.ddf.EscherSpRecord; | |||
import org.apache.poi.ddf.EscherSpgrRecord; | |||
import org.apache.poi.ddf.EscherTextboxRecord; | |||
import org.apache.poi.hssf.model.TextboxShape; | |||
import org.apache.poi.hssf.record.CommonObjectDataSubRecord; | |||
import org.apache.poi.hssf.record.EscherAggregate; | |||
import org.apache.poi.hssf.record.NoteRecord; | |||
import org.apache.poi.hssf.record.ObjRecord; | |||
import org.apache.poi.hssf.record.Record; | |||
import org.apache.poi.hssf.record.TextObjectRecord; | |||
import org.apache.poi.hssf.usermodel.drawing.HSSFShapeType; | |||
import java.lang.reflect.Constructor; | |||
import java.lang.reflect.InvocationTargetException; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* @author evgeniy | |||
* date: 05.06.12 | |||
*/ | |||
public class HSSFShapeFactory { | |||
private static final Map<Short, Class> shapeTypeToClass = new HashMap<Short, Class>(HSSFShapeType.values().length); | |||
private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass); | |||
static { | |||
for (HSSFShapeType type: HSSFShapeType.values()){ | |||
shapeTypeToClass.put(type.getType(), type.getShape()); | |||
} | |||
} | |||
private static class ReflectionConstructorShapeCreator { | |||
private final Map<Short, Class> shapeTypeToClass; | |||
private ReflectionConstructorShapeCreator(Map<Short, Class> shapeTypeToClass) { | |||
this.shapeTypeToClass = shapeTypeToClass; | |||
} | |||
public HSSFShape createNewShape(Short type, EscherContainerRecord spContainer, ObjRecord objRecord){ | |||
if (!shapeTypeToClass.containsKey(type)){ | |||
return new HSSFUnknownShape(spContainer, objRecord); | |||
} | |||
Class clazz = shapeTypeToClass.get(type); | |||
if (null == clazz){ | |||
System.out.println("No class attached to shape type: "+type); | |||
return new HSSFUnknownShape(spContainer, objRecord); | |||
} | |||
try{ | |||
Constructor constructor = clazz.getConstructor(new Class[]{EscherContainerRecord.class, ObjRecord.class}); | |||
return (HSSFShape) constructor.newInstance(spContainer, objRecord); | |||
} catch (NoSuchMethodException e) { | |||
throw new IllegalStateException(clazz.getName() +" doesn't have required for shapes constructor"); | |||
} catch (Exception e) { | |||
throw new IllegalStateException("Couldn't create new instance of " + clazz.getName()); | |||
} | |||
} | |||
} | |||
public static HSSFShape createShape(EscherRecord container, ObjRecord objRecord){ | |||
if (0 == container.getChildRecords().size()){ | |||
throw new IllegalArgumentException("Couldn't create shape from empty escher container"); | |||
} | |||
if (container.getChild(0) instanceof EscherSpgrRecord){ | |||
return new HSSFShapeGroup((EscherContainerRecord) container, objRecord); | |||
} | |||
//TODO implement cases for all shapes | |||
return new HSSFUnknownShape(container, objRecord); | |||
} | |||
public static HSSFShapeGroup createShapeGroup(){ | |||
return null; | |||
} | |||
public static HSSFShapeGroup createSimpleShape(EscherRecord container, ObjRecord objRecord){ | |||
return null; | |||
} | |||
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out){ | |||
if(container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ | |||
HSSFShapeGroup group = new HSSFShapeGroup(container, | |||
null /* shape containers don't have a associated Obj record*/); | |||
List<EscherContainerRecord> children = container.getChildContainers(); | |||
// skip the first child record, it is group descriptor | |||
for(int i = 0; i < children.size(); i++) { | |||
EscherContainerRecord spContainer = children.get(i); | |||
if(i == 0){ | |||
EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID); | |||
group.setCoordinates( | |||
spgr.getRectX1(), spgr.getRectY1(), | |||
spgr.getRectX2(), spgr.getRectY2() | |||
); | |||
} else { | |||
createShapeTree(spContainer, agg, group); | |||
} | |||
} | |||
out.addShape(group); | |||
} else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER){ | |||
Map<EscherRecord, Record> shapeToObj = agg.getShapeToObjMapping(); | |||
EscherSpRecord spRecord = null; | |||
ObjRecord objRecord = null; | |||
TextObjectRecord txtRecord = null; | |||
for(EscherRecord record : container.getChildRecords()) { | |||
switch(record.getRecordId()) { | |||
case EscherSpRecord.RECORD_ID: | |||
spRecord = (EscherSpRecord)record; | |||
break; | |||
case EscherClientDataRecord.RECORD_ID: | |||
objRecord = (ObjRecord)shapeToObj.get(record); | |||
break; | |||
case EscherTextboxRecord.RECORD_ID: | |||
txtRecord = (TextObjectRecord)shapeToObj.get(record); | |||
break; | |||
} | |||
} | |||
if (null != objRecord){ | |||
HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord); | |||
out.addShape(shape); | |||
} | |||
if (null != txtRecord){ | |||
//TODO resolve textbox | |||
// TextboxShape shape = new TextboxShape(container, txtRecord); | |||
// out.a | |||
} | |||
// | |||
// //TODO decide what shape to create based on ObjRecord / EscherSpRecord | |||
// HSSFShape shape = new HSSFUnknownShape(container, objRecord); | |||
// out.addShape(shape); | |||
} | |||
} | |||
} |
@@ -17,6 +17,15 @@ | |||
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; | |||
@@ -37,6 +46,32 @@ public class HSSFShapeGroup | |||
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 ) | |||
{ | |||
@@ -61,6 +96,11 @@ public class HSSFShapeGroup | |||
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. |
@@ -1738,12 +1738,16 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { | |||
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; |
@@ -0,0 +1,33 @@ | |||
/* | |||
* 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.usermodel; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.hssf.record.ObjRecord; | |||
/** | |||
* @author Evgeniy Berlog | |||
* date: 05.06.12 | |||
*/ | |||
public class HSSFUnknownShape extends HSSFShape { | |||
public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) { | |||
super((EscherContainerRecord) spContainer, objRecord); | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
package org.apache.poi.hssf.usermodel.drawing; | |||
import org.apache.poi.hssf.usermodel.HSSFRectangle; | |||
/** | |||
* @author Evgeniy Berlog | |||
* date: 08.06.12 | |||
*/ | |||
public enum HSSFShapeType { | |||
NOT_PRIMITIVE(0x0, null), | |||
RECTANGLE(0x1, HSSFRectangle.class), | |||
ROUND_RECTANGLE(0x2, null); | |||
private Short type; | |||
private Class shape; | |||
HSSFShapeType(Integer type, Class shape) { | |||
this.type = type.shortValue(); | |||
this.shape = shape; | |||
} | |||
public Short getType() { | |||
return type; | |||
} | |||
public Class getShape() { | |||
return shape; | |||
} | |||
} |
@@ -17,13 +17,13 @@ | |||
package org.apache.poi.hssf.model; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.ddf.EscherDggRecord; | |||
import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.hssf.HSSFTestDataSamples; | |||
import org.apache.poi.hssf.record.*; | |||
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; | |||
import org.apache.poi.hssf.usermodel.HSSFSheet; | |||
import org.apache.poi.hssf.usermodel.HSSFTestHelper; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.hssf.usermodel.*; | |||
import org.apache.poi.util.HexRead; | |||
import java.io.*; | |||
@@ -35,18 +35,84 @@ import java.util.List; | |||
* @author Evgeniy Berlog | |||
*/ | |||
public class TestDrawingAggregate extends TestCase { | |||
private static byte[] toByteArray(List<RecordBase> records){ | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
for(RecordBase rb : records) { | |||
Record r = (Record)rb; | |||
try { | |||
out.write(r.serialize()); | |||
} catch (IOException e){ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
return out.toByteArray(); | |||
private int spgrCount = 0; | |||
private int spCount = 0; | |||
private int shapeCount = 0; | |||
private int shGroupCount = 0; | |||
/* | |||
* EscherAggregate must have for each SpgrContainer HSSFShapeGroup and for each SpContainer HSSFShape | |||
*/ | |||
private void checkEscherAndShapesCount(EscherAggregate agg, HSSFSheet sheet) { | |||
/* | |||
HSSFPatriarch patriarch = HSSFTestHelper.createTestPatriarch(sheet, agg); | |||
agg.setPatriarch(patriarch); | |||
EscherAggregate.createShapeTree(EscherAggregate.getMainSpgrContainer(agg), agg.getPatriarch(), agg); | |||
EscherContainerRecord mainContainer = EscherAggregate.getMainSpgrContainer(agg); | |||
calculateShapesCount(agg.getPatriarch()); | |||
calculateEscherContainersCount(mainContainer); | |||
assertEquals(spgrCount, shGroupCount); | |||
assertEquals(spCount - spgrCount - 1, shapeCount); | |||
*/ | |||
} | |||
private void calculateEscherContainersCount(EscherContainerRecord spgr) { | |||
for (EscherRecord record : spgr.getChildRecords()) { | |||
if (EscherContainerRecord.SP_CONTAINER == record.getRecordId()) { | |||
spCount++; | |||
continue; | |||
} | |||
if (EscherContainerRecord.SPGR_CONTAINER == record.getRecordId()) { | |||
spgrCount++; | |||
calculateEscherContainersCount((EscherContainerRecord) record); | |||
} | |||
} | |||
} | |||
private void calculateShapesCount(HSSFShapeContainer group) { | |||
for (HSSFShape shape : (List<HSSFShape>) group.getChildren()) { | |||
if (shape instanceof HSSFShapeGroup) { | |||
shGroupCount++; | |||
calculateShapesCount((HSSFShapeGroup) shape); | |||
} else { | |||
shapeCount++; | |||
} | |||
} | |||
} | |||
private static byte[] toByteArray(List<RecordBase> records) { | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
for (RecordBase rb : records) { | |||
Record r = (Record) rb; | |||
try { | |||
out.write(r.serialize()); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
return out.toByteArray(); | |||
} | |||
public void testSolverContainerMustBeSavedDuringSerialization(){ | |||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SolverContainerAfterSPGR.xls"); | |||
HSSFSheet sh = wb.getSheetAt(0); | |||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh); | |||
sh.getDrawingPatriarch(); | |||
EscherAggregate agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid); | |||
assertEquals(agg.getEscherRecords().get(0).getChildRecords().size(), 3); | |||
assertEquals(agg.getEscherRecords().get(0).getChild(2).getRecordId(), EscherContainerRecord.SOLVER_CONTAINER); | |||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
sh = wb.getSheetAt(0); | |||
sh.getDrawingPatriarch(); | |||
ish = HSSFTestHelper.getSheetForTest(sh); | |||
agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid); | |||
assertEquals(agg.getEscherRecords().get(0).getChildRecords().size(), 3); | |||
assertEquals(agg.getEscherRecords().get(0).getChild(2).getRecordId(), EscherContainerRecord.SOLVER_CONTAINER); | |||
} | |||
/** | |||
* test reading drawing aggregate from a test file from Bugzilla 45129 | |||
@@ -107,6 +173,7 @@ public class TestDrawingAggregate extends TestCase { | |||
byte[] dgBytesAfterSave = agg.serialize(); | |||
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length); | |||
assertTrue("drawing data brefpore and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave)); | |||
checkEscherAndShapesCount(agg, sh); | |||
} | |||
/** | |||
@@ -174,7 +241,7 @@ public class TestDrawingAggregate extends TestCase { | |||
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length); | |||
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave)); | |||
checkEscherAndShapesCount(agg, sh); | |||
} | |||
@@ -185,21 +252,20 @@ public class TestDrawingAggregate extends TestCase { | |||
List<RecordBase> records = isheet.getRecords(); | |||
HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb); | |||
InternalSheet isheet2 = HSSFTestHelper.getSheetForTest( wb2.getSheetAt(0)); | |||
InternalSheet isheet2 = HSSFTestHelper.getSheetForTest(wb2.getSheetAt(0)); | |||
List<RecordBase> records2 = isheet2.getRecords(); | |||
assertEquals(records.size(), records2.size()); | |||
for(int i = 0; i < records.size(); i++) { | |||
for (int i = 0; i < records.size(); i++) { | |||
RecordBase r1 = records.get(i); | |||
RecordBase r2 = records2.get(i); | |||
assertTrue(r1.getClass() == r2.getClass()); | |||
assertEquals(r1.getRecordSize(), r2.getRecordSize()); | |||
if(r1 instanceof Record ){ | |||
assertEquals(((Record)r1).getSid(), ((Record)r2).getSid()); | |||
if (r1 instanceof Record) { | |||
assertEquals(((Record) r1).getSid(), ((Record) r2).getSid()); | |||
assertTrue(Arrays.equals(((Record) r1).serialize(), ((Record) r2).serialize())); | |||
} | |||
} | |||
} | |||
public void testSerializeDrawingWithComments() throws IOException { | |||
@@ -257,6 +323,7 @@ public class TestDrawingAggregate extends TestCase { | |||
byte[] dgBytesAfterSave = agg.serialize(); | |||
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length); | |||
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave)); | |||
checkEscherAndShapesCount(agg, sh); | |||
} | |||
@@ -314,7 +381,8 @@ public class TestDrawingAggregate extends TestCase { | |||
byte[] dgBytesAfterSave = agg.serialize(); | |||
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length); | |||
assertTrue("drawing data brefpore and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave)); | |||
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave)); | |||
checkEscherAndShapesCount(agg, sh); | |||
} | |||
public void testUnhandledContinue() { |
@@ -18,6 +18,7 @@ | |||
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 | |||
@@ -34,4 +35,8 @@ public class HSSFTestHelper { | |||
public static InternalSheet getSheetForTest(HSSFSheet sheet) { | |||
return sheet.getSheet(); | |||
} | |||
public static HSSFPatriarch createTestPatriarch(HSSFSheet sheet, EscherAggregate agg){ | |||
return new HSSFPatriarch(sheet, agg); | |||
} | |||
} |