Author: berlog
Date: Sun Aug 12 10:18:43 2012
New Revision: 1372065
URL: http://svn.apache.org/viewvc?rev=1372065&view=rev
Log:
complete refactoring in EscherAggregate
Modified:
poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java?rev=1372065&r1=1372064&r2=1372065&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java Sun Aug 12
10:18:43 2012
@@ -1496,7 +1496,7 @@ public final class InternalSheet {
return -1;
}
- EscherAggregate aggregate = new EscherAggregate();
+ EscherAggregate aggregate = new EscherAggregate(true);
loc = findFirstRecordLocBySid(EscherAggregate.sid);
if (loc == -1) {
loc = findFirstRecordLocBySid( WindowTwoRecord.sid );
@@ -1508,7 +1508,7 @@ public final class InternalSheet {
}
List<RecordBase> records = getRecords();
- EscherAggregate.createAggregate( records, loc, drawingManager );
+ EscherAggregate.createAggregate(records, loc);
return loc;
}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java?rev=1372065&r1=1372064&r2=1372065&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java Sun Aug
12 10:18:43 2012
@@ -31,8 +31,6 @@ import org.apache.poi.ddf.EscherSerializ
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherSpgrRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
-import org.apache.poi.hssf.model.DrawingManager2;
-import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@@ -291,12 +289,6 @@ public final class EscherAggregate exten
public static final short ST_NIL = (short) 0x0FFF;
/**
- * if we want to get the same byte array if we open existing file and
serialize it we should save
- * note records in right order. This list contains ids of NoteRecords in
such order as we read from existing file
- */
- private List<Integer> _tailIds = new ArrayList<Integer>();
-
- /**
* Maps shape container objects to their {@link TextObjectRecord} or
{@link ObjRecord}
*/
private final Map<EscherRecord, Record> shapeToObj = new
HashMap<EscherRecord, Record>();
@@ -304,13 +296,17 @@ public final class EscherAggregate exten
/**
* list of "tail" records that need to be serialized after all drawing
group records
*/
- private Map<Integer, NoteRecord> tailRec = new HashMap<Integer,
NoteRecord>();
+ private Map<Integer, NoteRecord> tailRec = new LinkedHashMap<Integer,
NoteRecord>();
- public EscherAggregate() {
- buildBaseTree();
- }
-
- public EscherAggregate(DrawingManager2 drawingManager) {
+ /**
+ * create new EscherAggregate
+ * @param createDefaultTree if true creates base tree of the escher
records, see EscherAggregate.buildBaseTree()
+ * else return empty escher aggregate
+ */
+ public EscherAggregate(boolean createDefaultTree) {
+ if (createDefaultTree){
+ buildBaseTree();
+ }
}
/**
@@ -327,13 +323,12 @@ public final class EscherAggregate exten
public String toString() {
String nl = System.getProperty("line.separtor");
- StringBuffer result = new StringBuffer();
- result.append('[').append(getRecordName()).append(']' + nl);
- for (Iterator iterator = getEscherRecords().iterator();
iterator.hasNext(); ) {
- EscherRecord escherRecord = (EscherRecord) iterator.next();
+ StringBuilder result = new StringBuilder();
+ result.append('[').append(getRecordName()).append(']').append(nl);
+ for (EscherRecord escherRecord : getEscherRecords()) {
result.append(escherRecord.toString());
}
- result.append("[/").append(getRecordName()).append(']' + nl);
+ result.append("[/").append(getRecordName()).append(']').append(nl);
return result.toString();
}
@@ -341,18 +336,23 @@ public final class EscherAggregate exten
/**
* Calculates the xml representation of this record. This is
* simply a dump of all the records.
+ * @param tab - string which must be added before each line (used by
default '\t')
+ * @return xml representation of the all aggregated records
*/
public String toXml(String tab) {
StringBuilder builder = new StringBuilder();
builder.append(tab).append("<").append(getRecordName()).append(">\n");
- for (Iterator iterator = getEscherRecords().iterator();
iterator.hasNext(); ) {
- EscherRecord escherRecord = (EscherRecord) iterator.next();
+ for (EscherRecord escherRecord : getEscherRecords()) {
builder.append(escherRecord.toXml(tab + "\t"));
}
builder.append(tab).append("</").append(getRecordName()).append(">\n");
return builder.toString();
}
+ /**
+ * @param sid - record sid we want to check if it belongs to drawing layer
+ * @return true if record is instance of DrawingRecord or ContinueRecord
or ObjRecord or TextObjRecord
+ */
private static boolean isDrawingLayerRecord(final short sid) {
return sid == DrawingRecord.sid ||
sid == ContinueRecord.sid ||
@@ -365,8 +365,11 @@ public final class EscherAggregate exten
* read Drawing, Obj, TxtObj, Note and Continue records into single byte
array,
* create Escher tree from byte array, create map <EscherRecord, Record>
*
+ * @param records - list of all records inside sheet
+ * @param locFirstDrawingRecord - location of the first DrawingRecord
inside sheet
+ * @return new EscherAggregate create from all aggregated records which
belong to drawing layer
*/
- public static EscherAggregate createAggregate(List records, int
locFirstDrawingRecord, DrawingManager2 drawingManager) {
+ public static EscherAggregate createAggregate(List<RecordBase> records,
int locFirstDrawingRecord) {
// Keep track of any shape records created so we can match them back
to the object id's.
// Textbox objects are also treated as shape objects.
final List<EscherRecord> shapeRecords = new ArrayList<EscherRecord>();
@@ -382,8 +385,7 @@ public final class EscherAggregate exten
// Create one big buffer
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
- EscherAggregate agg = new EscherAggregate(drawingManager);
+ EscherAggregate agg = new EscherAggregate(false);
int loc = locFirstDrawingRecord;
while (loc + 1 < records.size()
&& (isDrawingLayerRecord(sid(records, loc)))) {
@@ -428,12 +430,10 @@ public final class EscherAggregate exten
}
// any NoteRecords that follow the drawing block must be aggregated
and and saved in the tailRec collection
- // TODO remove this logic. 'tail' records should be inserted in the
main record stream
while (loc < records.size()) {
if (sid(records, loc) == NoteRecord.sid) {
NoteRecord r = (NoteRecord) records.get(loc);
agg.tailRec.put(r.getShapeId(), r);
- agg._tailIds.add(agg._tailIds.size(), r.getShapeId());
} else {
break;
}
@@ -457,16 +457,16 @@ public final class EscherAggregate exten
*/
public int serialize(int offset, byte[] data) {
// Determine buffer size
- List records = getEscherRecords();
+ List <EscherRecord>records = getEscherRecords();
int size = getEscherRecordSize(records);
byte[] buffer = new byte[size];
// Serialize escher records into one big data structure and keep note
of ending offsets.
- final List spEndingOffsets = new ArrayList();
- final List shapes = new ArrayList();
+ final List <Integer>spEndingOffsets = new ArrayList<Integer>();
+ final List <EscherRecord> shapes = new ArrayList<EscherRecord>();
int pos = 0;
- for (Iterator iterator = records.iterator(); iterator.hasNext(); ) {
- EscherRecord e = (EscherRecord) iterator.next();
+ for (Object record : records) {
+ EscherRecord e = (EscherRecord) record;
pos += e.serialize(pos, buffer, new EscherSerializationListener() {
public void beforeRecordSerialize(int offset, short recordId,
EscherRecord record) {
}
@@ -479,9 +479,8 @@ public final class EscherAggregate exten
}
});
}
- // todo: fix this
shapes.add(0, null);
- spEndingOffsets.add(0, null);
+ spEndingOffsets.add(0, 0);
// Split escher records into separate MSODRAWING and OBJ, TXO records.
(We don't break on
// the first one because it's the patriach).
@@ -489,12 +488,12 @@ public final class EscherAggregate exten
int writtenEscherBytes = 0;
int i;
for (i = 1; i < shapes.size(); i++) {
- int endOffset = (Integer) spEndingOffsets.get(i) - 1;
+ int endOffset = spEndingOffsets.get(i) - 1;
int startOffset;
if (i == 1)
startOffset = 0;
else
- startOffset = (Integer) spEndingOffsets.get(i - 1);
+ startOffset = spEndingOffsets.get(i - 1);
byte[] drawingData = new byte[endOffset - startOffset + 1];
System.arraycopy(buffer, startOffset, drawingData, 0,
drawingData.length);
@@ -518,19 +517,8 @@ public final class EscherAggregate exten
pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes,
pos, data, i);
}
- // write records that need to be serialized after all drawing group
records
- Map<Integer, NoteRecord> tailCopy = new HashMap<Integer,
NoteRecord>(tailRec);
- // at first we should save records in correct order which were already
in the file during EscherAggregate.createAggregate()
- for (Integer id : _tailIds) {
- NoteRecord note = tailCopy.get(id);
- if (null != note) {
- pos += note.serialize(pos, data);
- tailCopy.remove(id);
- }
- }
- // Add all other notes which were created after createAggregate()
- for (i = 0; i < tailCopy.size(); i++) {
- Record rec = (Record) tailCopy.values().toArray()[i];
+ for (i = 0; i < tailRec.size(); i++) {
+ Record rec = (Record) tailRec.values().toArray()[i];
pos += rec.serialize(pos, data);
}
int bytesWritten = pos - offset;
@@ -583,10 +571,11 @@ public final class EscherAggregate exten
* @param records List of escher records
* @return the number of bytes
*/
- private int getEscherRecordSize(List records) {
+ private int getEscherRecordSize(List<EscherRecord> records) {
int size = 0;
- for (Iterator iterator = records.iterator(); iterator.hasNext(); )
- size += ((EscherRecord) iterator.next()).getRecordSize();
+ for (EscherRecord record : records){
+ size += record.getRecordSize();
+ }
return size;
}
@@ -632,49 +621,64 @@ public final class EscherAggregate exten
continueRecordsHeadersSize += 4;
}
int objRecordSize = 0;
- for (Iterator iterator = shapeToObj.values().iterator();
iterator.hasNext(); ) {
- Record r = (Record) iterator.next();
+ for (Record r : shapeToObj.values()) {
objRecordSize += r.getRecordSize();
}
int tailRecordSize = 0;
- for (Iterator iterator = tailRec.values().iterator();
iterator.hasNext(); ) {
- Record r = (Record) iterator.next();
- tailRecordSize += r.getRecordSize();
+ for (NoteRecord noteRecord : tailRec.values()) {
+ tailRecordSize += noteRecord.getRecordSize();
}
return drawingRecordSize + objRecordSize + tailRecordSize +
continueRecordsHeadersSize;
}
/**
* Associates an escher record to an OBJ record or a TXO record.
+ * @param r - ClientData or Textbox record
+ * @param objRecord - Obj or TextObj record
*/
- public Object associateShapeToObjRecord(EscherRecord r, Record objRecord) {
- return shapeToObj.put(r, objRecord);
+ public void associateShapeToObjRecord(EscherRecord r, Record objRecord) {
+ shapeToObj.put(r, objRecord);
}
+ /**
+ * Remove echerRecord and associated to it Obj or TextObj record
+ * @param rec - clientData or textbox record to be removed
+ */
public void removeShapeToObjRecord(EscherRecord rec) {
shapeToObj.remove(rec);
}
+ /**
+ * @return "ESCHERAGGREGATE"
+ */
protected String getRecordName() {
return "ESCHERAGGREGATE";
}
// =============== Private methods ========================
- private static boolean isObjectRecord(List records, int loc) {
+ /**
+ *
+ * @param records list of the record to look inside
+ * @param loc location of the checked record
+ * @return true if record is instance of ObjRecord or TextObjectRecord
+ */
+ private static boolean isObjectRecord(List <RecordBase>records, int loc) {
return sid(records, loc) == ObjRecord.sid || sid(records, loc) ==
TextObjectRecord.sid;
}
- private EscherRecord findClientData(EscherContainerRecord spContainer) {
- for (Iterator<EscherRecord> iterator = spContainer.getChildIterator();
iterator.hasNext(); ) {
- EscherRecord r = iterator.next();
- if (r.getRecordId() == EscherClientDataRecord.RECORD_ID) {
- return r;
- }
- }
- throw new IllegalArgumentException("Can not find client data record");
- }
-
+ /**
+ * create base tree with such structure:
+ * EscherDgContainer
+ * -EscherSpgrContainer
+ * --EscherSpContainer
+ * ---EscherSpRecord
+ * ---EscherSpgrRecord
+ * ---EscherSpRecord
+ * -EscherDgRecord
+ *
+ * id of DgRecord and SpRecord are empty and must be set later by
HSSFPatriarch
+ */
private void buildBaseTree() {
EscherContainerRecord dgContainer = new EscherContainerRecord();
EscherContainerRecord spgrContainer = new EscherContainerRecord();
@@ -713,12 +717,30 @@ public final class EscherAggregate exten
addEscherRecord(dgContainer);
}
+ /**
+ * EscherDgContainer
+ * -EscherSpgrContainer
+ * -EscherDgRecord - set id for this record
+ * set id for DgRecord of DgContainer
+ * @param dgId - id which must be set
+ */
public void setDgId(short dgId) {
EscherContainerRecord dgContainer = getEscherContainer();
EscherDgRecord dg = dgContainer.getChildById(EscherDgRecord.RECORD_ID);
dg.setOptions((short) (dgId << 4));
}
+ /**
+ * EscherDgContainer
+ * -EscherSpgrContainer
+ * --EscherSpContainer
+ * ---EscherSpRecord -set id for this record
+ * ---***
+ * --***
+ * -EscherDgRecord
+ * set id for the sp record of the first spContainer in main spgrConatiner
+ * @param shapeId - id which must be set
+ */
public void setMainSpRecordId(int shapeId) {
EscherContainerRecord dgContainer = getEscherContainer();
EscherContainerRecord spgrConatiner = (EscherContainerRecord)
dgContainer.getChildById(EscherContainerRecord.SPGR_CONTAINER);
@@ -727,27 +749,13 @@ public final class EscherAggregate exten
sp.setShapeId(shapeId);
}
- private static short sid(List records, int loc) {
- return ((Record) records.get(loc)).getSid();
- }
-
-
- // Duplicated from org.apache.poi.hslf.model.Shape
-
/**
- * Helper method to return escher child by record ID
- *
- * @return escher record or <code>null</code> if not found.
+ * @param records list of records to look into
+ * @param loc - location of the record which sid must be returned
+ * @return sid of the record with selected location
*/
- private static EscherRecord getEscherChild(EscherContainerRecord owner,
- int recordId) {
- for (Iterator iterator = owner.getChildRecords().iterator(); iterator
- .hasNext(); ) {
- EscherRecord escherRecord = (EscherRecord) iterator.next();
- if (escherRecord.getRecordId() == recordId)
- return escherRecord;
- }
- return null;
+ private static short sid(List <RecordBase>records, int loc) {
+ return ((Record) records.get(loc)).getSid();
}
/**
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java?rev=1372065&r1=1372064&r2=1372065&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java Sun Aug
12 10:18:43 2012
@@ -75,7 +75,7 @@ public final class HSSFPatriarch impleme
* @return new patriarch with copies of all shapes from the existing
patriarch
*/
static HSSFPatriarch createPatriarch(HSSFPatriarch patriarch, HSSFSheet
sheet){
- HSSFPatriarch newPatriarch = new HSSFPatriarch(sheet, new
EscherAggregate());
+ HSSFPatriarch newPatriarch = new HSSFPatriarch(sheet, new
EscherAggregate(true));
newPatriarch.afterCreate();
for (HSSFShape shape: patriarch.getChildren()){
HSSFShape newShape;
Modified:
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java?rev=1372065&r1=1372064&r2=1372065&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
Sun Aug 12 10:18:43 2012
@@ -72,14 +72,13 @@ public final class TestEscherAggregate e
ObjRecord r2 = new ObjRecord();
- List<Record> records = new ArrayList<Record>();
+ List<RecordBase> records = new ArrayList<RecordBase>();
records.add( d1 );
records.add( r1 );
records.add( d2 );
records.add( r2 );
- DrawingManager2 drawingManager = new DrawingManager2(new
EscherDggRecord() );
- EscherAggregate aggregate = EscherAggregate.createAggregate( records,
0, drawingManager );
+ EscherAggregate aggregate = EscherAggregate.createAggregate(records,
0);
assertEquals( 1, aggregate.getEscherRecords().size() );
assertEquals( (short) 0xF002, aggregate.getEscherRecord( 0
).getRecordId() );
@@ -120,7 +119,7 @@ public final class TestEscherAggregate e
spContainer2.addChildRecord( d2 );
spContainer3.addChildRecord( d3 );
- EscherAggregate aggregate = new EscherAggregate(null);
+ EscherAggregate aggregate = new EscherAggregate(false);
aggregate.addEscherRecord( container1 );
aggregate.associateShapeToObjRecord( d2, new ObjRecord() );
aggregate.associateShapeToObjRecord( d3, new ObjRecord() );
Modified:
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java?rev=1372065&r1=1372064&r2=1372065&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
Sun Aug 12 10:18:43 2012
@@ -88,21 +88,6 @@ public class HSSFTestHelper {
return shape.getOptRecord();
}
- public static void convertHSSFGroup(HSSFShapeGroup shape,
EscherContainerRecord escherParent, Map shapeToObj){
- Class clazz = EscherAggregate.class;
- try {
- Method method = clazz.getDeclaredMethod("convertGroup",
HSSFShapeGroup.class, EscherContainerRecord.class, Map.class);
- method.setAccessible(true);
- method.invoke(new EscherAggregate(new MockDrawingManager()),
shape, escherParent, shapeToObj);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
-
public static void setShapeId(HSSFShape shape, int id){
shape.setShapeId(id);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]