moved HSSFObjectData into drawing layer
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1361278 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
73b0c8390c
commit
57f0fe06b9
@ -21,6 +21,7 @@ package org.apache.poi.hssf.usermodel;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
||||||
import org.apache.poi.hssf.record.ObjRecord;
|
import org.apache.poi.hssf.record.ObjRecord;
|
||||||
import org.apache.poi.hssf.record.SubRecord;
|
import org.apache.poi.hssf.record.SubRecord;
|
||||||
@ -31,29 +32,19 @@ import org.apache.poi.util.HexDump;
|
|||||||
/**
|
/**
|
||||||
* Represents binary object (i.e. OLE) data stored in the file. Eg. A GIF, JPEG etc...
|
* Represents binary object (i.e. OLE) data stored in the file. Eg. A GIF, JPEG etc...
|
||||||
*
|
*
|
||||||
|
* Right now, 13, july, 2012 can not be created from scratch
|
||||||
|
*
|
||||||
* @author Daniel Noll
|
* @author Daniel Noll
|
||||||
*/
|
*/
|
||||||
public final class HSSFObjectData {
|
public final class HSSFObjectData extends HSSFShape{
|
||||||
/**
|
|
||||||
* Underlying object record ultimately containing a reference to the object.
|
|
||||||
*/
|
|
||||||
private final ObjRecord _record;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the filesystem root, required for retrieving the object data.
|
* Reference to the filesystem root, required for retrieving the object data.
|
||||||
*/
|
*/
|
||||||
private final DirectoryEntry _root;
|
private final DirectoryEntry _root;
|
||||||
|
|
||||||
/**
|
public HSSFObjectData(EscherContainerRecord spContainer, ObjRecord objRecord, DirectoryEntry _root) {
|
||||||
* Constructs object data by wrapping a lower level object record.
|
super(spContainer, objRecord);
|
||||||
*
|
this._root = _root;
|
||||||
* @param record the low-level object record.
|
|
||||||
* @param root the root of the filesystem, required for retrieving the object data.
|
|
||||||
*/
|
|
||||||
public HSSFObjectData(ObjRecord record, DirectoryEntry root)
|
|
||||||
{
|
|
||||||
_record = record;
|
|
||||||
_root = root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,7 +101,7 @@ public final class HSSFObjectData {
|
|||||||
* Exception if there wasn't one
|
* Exception if there wasn't one
|
||||||
*/
|
*/
|
||||||
protected EmbeddedObjectRefSubRecord findObjectRecord() {
|
protected EmbeddedObjectRefSubRecord findObjectRecord() {
|
||||||
Iterator<SubRecord> subRecordIter = _record.getSubRecords().iterator();
|
Iterator<SubRecord> subRecordIter = getObjRecord().getSubRecords().iterator();
|
||||||
|
|
||||||
while (subRecordIter.hasNext()) {
|
while (subRecordIter.hasNext()) {
|
||||||
Object subRecord = subRecordIter.next();
|
Object subRecord = subRecordIter.next();
|
||||||
@ -121,4 +112,24 @@ public final class HSSFObjectData {
|
|||||||
|
|
||||||
throw new IllegalStateException("Object data does not contain a reference to an embedded object OLE2 directory");
|
throw new IllegalStateException("Object data does not contain a reference to an embedded object OLE2 directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EscherContainerRecord createSpContainer() {
|
||||||
|
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ObjRecord createObjRecord() {
|
||||||
|
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||||
|
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void afterInsert(HSSFPatriarch patriarch) {
|
||||||
|
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
|||||||
if (i == 0){
|
if (i == 0){
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this);
|
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getRootDirectory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,18 +18,14 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hssf.model.TextboxShape;
|
import org.apache.poi.hssf.record.*;
|
||||||
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 org.apache.poi.hssf.usermodel.drawing.HSSFShapeType;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -43,7 +39,7 @@ public class HSSFShapeFactory {
|
|||||||
private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass);
|
private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (HSSFShapeType type: HSSFShapeType.values()){
|
for (HSSFShapeType type : HSSFShapeType.values()) {
|
||||||
shapeTypeToClass.put(type.getType(), type);
|
shapeTypeToClass.put(type.getType(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,60 +52,65 @@ public class HSSFShapeFactory {
|
|||||||
this.shapeTypeToClass = shapeTypeToClass;
|
this.shapeTypeToClass = shapeTypeToClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSSFShape createNewShape(Short type, EscherContainerRecord spContainer, ObjRecord objRecord){
|
public HSSFShape createNewShape(Short type, EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||||
if (!shapeTypeToClass.containsKey(type)){
|
if (!shapeTypeToClass.containsKey(type)) {
|
||||||
return new HSSFUnknownShape(spContainer, objRecord);
|
return new HSSFUnknownShape(spContainer, objRecord);
|
||||||
}
|
}
|
||||||
Class clazz = shapeTypeToClass.get(type).getShape();
|
Class clazz = shapeTypeToClass.get(type).getShape();
|
||||||
if (null == clazz){
|
if (null == clazz) {
|
||||||
//System.out.println("No class attached to shape type: "+type);
|
//System.out.println("No class attached to shape type: "+type);
|
||||||
return new HSSFUnknownShape(spContainer, objRecord);
|
return new HSSFUnknownShape(spContainer, objRecord);
|
||||||
}
|
}
|
||||||
try{
|
try {
|
||||||
Constructor constructor = clazz.getConstructor(new Class[]{EscherContainerRecord.class, ObjRecord.class});
|
Constructor constructor = clazz.getConstructor(new Class[]{EscherContainerRecord.class, ObjRecord.class});
|
||||||
return (HSSFShape) constructor.newInstance(spContainer, objRecord);
|
return (HSSFShape) constructor.newInstance(spContainer, objRecord);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new IllegalStateException(clazz.getName() +" doesn't have required for shapes constructor");
|
throw new IllegalStateException(clazz.getName() + " doesn't have required for shapes constructor");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException("Couldn't create new instance of " + clazz.getName());
|
throw new IllegalStateException("Couldn't create new instance of " + clazz.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out){
|
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) {
|
||||||
if(container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
|
if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
|
||||||
HSSFShapeGroup group = new HSSFShapeGroup(container,
|
HSSFShapeGroup group = new HSSFShapeGroup(container,
|
||||||
null /* shape containers don't have a associated Obj record*/);
|
null /* shape containers don't have a associated Obj record*/);
|
||||||
List<EscherContainerRecord> children = container.getChildContainers();
|
List<EscherContainerRecord> children = container.getChildContainers();
|
||||||
// skip the first child record, it is group descriptor
|
// skip the first child record, it is group descriptor
|
||||||
for(int i = 0; i < children.size(); i++) {
|
for (int i = 0; i < children.size(); i++) {
|
||||||
EscherContainerRecord spContainer = children.get(i);
|
EscherContainerRecord spContainer = children.get(i);
|
||||||
if(i == 0){
|
if (i == 0) {
|
||||||
EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
EscherSpgrRecord spgr = (EscherSpgrRecord) spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
||||||
} else {
|
} else {
|
||||||
createShapeTree(spContainer, agg, group);
|
createShapeTree(spContainer, agg, group, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.addShape(group);
|
out.addShape(group);
|
||||||
} else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER){
|
} else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
|
||||||
Map<EscherRecord, Record> shapeToObj = agg.getShapeToObjMapping();
|
Map<EscherRecord, Record> shapeToObj = agg.getShapeToObjMapping();
|
||||||
EscherSpRecord spRecord = null;
|
EscherSpRecord spRecord = null;
|
||||||
ObjRecord objRecord = null;
|
ObjRecord objRecord = null;
|
||||||
TextObjectRecord txtRecord = null;
|
TextObjectRecord txtRecord = null;
|
||||||
|
|
||||||
for(EscherRecord record : container.getChildRecords()) {
|
for (EscherRecord record : container.getChildRecords()) {
|
||||||
switch(record.getRecordId()) {
|
switch (record.getRecordId()) {
|
||||||
case EscherSpRecord.RECORD_ID:
|
case EscherSpRecord.RECORD_ID:
|
||||||
spRecord = (EscherSpRecord)record;
|
spRecord = (EscherSpRecord) record;
|
||||||
break;
|
break;
|
||||||
case EscherClientDataRecord.RECORD_ID:
|
case EscherClientDataRecord.RECORD_ID:
|
||||||
objRecord = (ObjRecord)shapeToObj.get(record);
|
objRecord = (ObjRecord) shapeToObj.get(record);
|
||||||
break;
|
break;
|
||||||
case EscherTextboxRecord.RECORD_ID:
|
case EscherTextboxRecord.RECORD_ID:
|
||||||
txtRecord = (TextObjectRecord)shapeToObj.get(record);
|
txtRecord = (TextObjectRecord) shapeToObj.get(record);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isEmbeddedObject(objRecord)){
|
||||||
|
HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root);
|
||||||
|
out.addShape(objectData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
|
CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
|
||||||
HSSFShape shape = null;
|
HSSFShape shape = null;
|
||||||
switch (cmo.getObjectType()) {
|
switch (cmo.getObjectType()) {
|
||||||
@ -128,7 +129,7 @@ public class HSSFShapeFactory {
|
|||||||
case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING:
|
case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING:
|
||||||
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
|
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
|
||||||
EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
|
EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||||
if (null != property){
|
if (null != property) {
|
||||||
shape = new HSSFPolygon(container, objRecord);
|
shape = new HSSFPolygon(container, objRecord);
|
||||||
} else {
|
} else {
|
||||||
shape = new HSSFSimpleShape(container, objRecord);
|
shape = new HSSFSimpleShape(container, objRecord);
|
||||||
@ -143,9 +144,20 @@ public class HSSFShapeFactory {
|
|||||||
default:
|
default:
|
||||||
shape = new HSSFSimpleShape(container, objRecord);
|
shape = new HSSFSimpleShape(container, objRecord);
|
||||||
}
|
}
|
||||||
if (null != shape){
|
if (null != shape) {
|
||||||
out.addShape(shape);
|
out.addShape(shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isEmbeddedObject(ObjRecord obj) {
|
||||||
|
Iterator<SubRecord> subRecordIter = obj.getSubRecords().iterator();
|
||||||
|
while (subRecordIter.hasNext()) {
|
||||||
|
SubRecord sub = subRecordIter.next();
|
||||||
|
if (sub instanceof EmbeddedObjectRefSubRecord) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1706,7 +1706,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||||||
List<HSSFObjectData> objects = new ArrayList<HSSFObjectData>();
|
List<HSSFObjectData> objects = new ArrayList<HSSFObjectData>();
|
||||||
for (int i = 0; i < getNumberOfSheets(); i++)
|
for (int i = 0; i < getNumberOfSheets(); i++)
|
||||||
{
|
{
|
||||||
getAllEmbeddedObjects(getSheetAt(i).getSheet().getRecords(), objects);
|
getAllEmbeddedObjects(getSheetAt(i), objects);
|
||||||
}
|
}
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
@ -1714,25 +1714,18 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||||||
/**
|
/**
|
||||||
* Gets all embedded OLE2 objects from the Workbook.
|
* Gets all embedded OLE2 objects from the Workbook.
|
||||||
*
|
*
|
||||||
* @param records the list of records to search.
|
* @param sheet embedded object attached to
|
||||||
* @param objects the list of embedded objects to populate.
|
* @param objects the list of embedded objects to populate.
|
||||||
*/
|
*/
|
||||||
private void getAllEmbeddedObjects(List<RecordBase> records, List<HSSFObjectData> objects)
|
private void getAllEmbeddedObjects(HSSFSheet sheet, List<HSSFObjectData> objects)
|
||||||
{
|
{
|
||||||
for (RecordBase obj : records) {
|
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
|
||||||
if (obj instanceof ObjRecord)
|
if (null == patriarch){
|
||||||
{
|
return;
|
||||||
// TODO: More convenient way of determining if there is stored binary.
|
|
||||||
// TODO: Link to the data stored in the other stream.
|
|
||||||
Iterator<SubRecord> subRecordIter = ((ObjRecord) obj).getSubRecords().iterator();
|
|
||||||
while (subRecordIter.hasNext())
|
|
||||||
{
|
|
||||||
SubRecord sub = subRecordIter.next();
|
|
||||||
if (sub instanceof EmbeddedObjectRefSubRecord)
|
|
||||||
{
|
|
||||||
objects.add(new HSSFObjectData((ObjRecord) obj, directory));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (HSSFShape shape: patriarch.getChildren()){
|
||||||
|
if (shape instanceof HSSFObjectData){
|
||||||
|
objects.add((HSSFObjectData) shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1808,4 +1801,8 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||||||
public boolean changeExternalReference(String oldUrl, String newUrl) {
|
public boolean changeExternalReference(String oldUrl, String newUrl) {
|
||||||
return workbook.changeExternalReference(oldUrl, newUrl);
|
return workbook.changeExternalReference(oldUrl, newUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DirectoryNode getRootDirectory(){
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ public class TestDrawingShapes extends TestCase {
|
|||||||
assertEquals(1, drawing.getChildren().size());
|
assertEquals(1, drawing.getChildren().size());
|
||||||
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
|
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
|
||||||
|
|
||||||
assertEquals(picture.getPictureIndex(), 1);
|
assertEquals(picture.getPictureIndex(), 2);
|
||||||
assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
|
assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
|
||||||
assertEquals(picture.getFillColor(), 0x5DC943);
|
assertEquals(picture.getFillColor(), 0x5DC943);
|
||||||
assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
|
assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Evgeniy Berlog
|
||||||
|
* @date 13.07.12
|
||||||
|
*/
|
||||||
|
public class TestEmbeddedObjects extends TestCase{
|
||||||
|
|
||||||
|
public void testReadExistingObject() throws IOException {
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||||
|
List<HSSFObjectData> list = wb.getAllEmbeddedObjects();
|
||||||
|
assertEquals(list.size(), 1);
|
||||||
|
HSSFObjectData obj = list.get(0);
|
||||||
|
assertNotNull(obj.getObjectData());
|
||||||
|
assertNotNull(obj.getDirectory());
|
||||||
|
assertNotNull(obj.getOLE2ClassName());
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user