Lines 1-18
Link Here
|
|
|
1 |
/* ==================================================================== |
2 |
Licensed to the Apache Software Foundation (ASF) under one or more |
3 |
contributor license agreements. See the NOTICE file distributed with |
4 |
this work for additional information regarding copyright ownership. |
5 |
The ASF licenses this file to You under the Apache License, Version 2.0 |
6 |
(the "License"); you may not use this file except in compliance with |
7 |
the License. You may obtain a copy of the License at |
8 |
|
9 |
http://www.apache.org/licenses/LICENSE-2.0 |
10 |
|
11 |
Unless required by applicable law or agreed to in writing, software |
12 |
distributed under the License is distributed on an "AS IS" BASIS, |
13 |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 |
See the License for the specific language governing permissions and |
15 |
limitations under the License. |
16 |
==================================================================== */ |
1 |
package org.apache.poi.hssf.model; |
17 |
package org.apache.poi.hssf.model; |
2 |
|
18 |
|
3 |
import junit.framework.TestCase; |
19 |
import junit.framework.TestCase; |
|
|
20 |
import org.apache.poi.ddf.EscherClientDataRecord; |
21 |
import org.apache.poi.ddf.EscherContainerRecord; |
4 |
import org.apache.poi.ddf.EscherDggRecord; |
22 |
import org.apache.poi.ddf.EscherDggRecord; |
|
|
23 |
import org.apache.poi.ddf.EscherRecord; |
24 |
import org.apache.poi.ddf.EscherSpRecord; |
5 |
import org.apache.poi.hssf.HSSFTestDataSamples; |
25 |
import org.apache.poi.hssf.HSSFTestDataSamples; |
6 |
import org.apache.poi.hssf.record.ContinueRecord; |
26 |
import org.apache.poi.hssf.record.*; |
7 |
import org.apache.poi.hssf.record.DrawingRecord; |
|
|
8 |
import org.apache.poi.hssf.record.EOFRecord; |
9 |
import org.apache.poi.hssf.record.EscherAggregate; |
10 |
import org.apache.poi.hssf.record.ObjRecord; |
11 |
import org.apache.poi.hssf.record.Record; |
12 |
import org.apache.poi.hssf.record.RecordBase; |
13 |
import org.apache.poi.hssf.record.RecordFactory; |
14 |
import org.apache.poi.hssf.record.TextObjectRecord; |
15 |
import org.apache.poi.hssf.record.WindowTwoRecord; |
16 |
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; |
27 |
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; |
17 |
import org.apache.poi.hssf.usermodel.HSSFSheet; |
28 |
import org.apache.poi.hssf.usermodel.HSSFSheet; |
18 |
import org.apache.poi.hssf.usermodel.HSSFTestHelper; |
29 |
import org.apache.poi.hssf.usermodel.HSSFTestHelper; |
Lines 20-26
Link Here
|
20 |
import org.apache.poi.util.HexRead; |
31 |
import org.apache.poi.util.HexRead; |
21 |
|
32 |
|
22 |
import java.io.ByteArrayInputStream; |
33 |
import java.io.ByteArrayInputStream; |
|
|
34 |
import java.util.ArrayList; |
35 |
import java.util.LinkedHashMap; |
23 |
import java.util.List; |
36 |
import java.util.List; |
|
|
37 |
import java.util.Map; |
24 |
|
38 |
|
25 |
/** |
39 |
/** |
26 |
* @author Yegor Kozlov |
40 |
* @author Yegor Kozlov |
Lines 28-33
Link Here
|
28 |
*/ |
42 |
*/ |
29 |
public class TestDrawingAggregate extends TestCase { |
43 |
public class TestDrawingAggregate extends TestCase { |
30 |
/** |
44 |
/** |
|
|
45 |
* Serialize escher aggregate, read back and assert that the drawing data is preserved. |
46 |
* |
47 |
* @param agg the aggregate to test |
48 |
* @return verified aggregate (serialized and read back) |
49 |
*/ |
50 |
public static EscherAggregate assertWriteAndReadBack(EscherAggregate agg) { |
51 |
byte[] dgBytes = agg.serialize(); |
52 |
|
53 |
|
54 |
List<Record> dgRecords = RecordFactory.createRecords(new ByteArrayInputStream(dgBytes)); |
55 |
|
56 |
DrawingManager2 drawingManager = new DrawingManager2(new EscherDggRecord()); |
57 |
|
58 |
// create a dummy sheet consisting of our test data |
59 |
InternalSheet sheet = InternalSheet.createSheet(); |
60 |
List<RecordBase> records = sheet.getRecords(); |
61 |
records.clear(); |
62 |
records.addAll(dgRecords); |
63 |
records.add(EOFRecord.instance); |
64 |
|
65 |
|
66 |
sheet.aggregateDrawingRecords(drawingManager, false); |
67 |
assertEquals("drawing was not fully aggregated", 2, records.size()); |
68 |
assertTrue("expected EscherAggregate", records.get(0) instanceof EscherAggregate); |
69 |
assertTrue("expected EOFRecord", records.get(1) instanceof EOFRecord); |
70 |
EscherAggregate agg2 = (EscherAggregate) records.get(0); |
71 |
|
72 |
assertEquals(agg.getEscherRecords().size(), agg2.getEscherRecords().size()); |
73 |
|
74 |
// assert that both pre- and after- serialize aggregates have the same xml representation |
75 |
for (int i = 0; i < agg.getEscherRecords().size(); i++) { |
76 |
EscherRecord r1 = agg.getEscherRecords().get(i); |
77 |
EscherRecord r2 = agg2.getEscherRecords().get(i); |
78 |
|
79 |
assertEquals(r1.toXml(), r2.toXml()); |
80 |
} |
81 |
|
82 |
return agg2; |
83 |
} |
84 |
|
85 |
/** |
86 |
* assert that mapping of Obj records to escher shape containers is the same in both aggregates |
87 |
*/ |
88 |
public static void assertObjectMappingSame(EscherAggregate agg1, EscherAggregate agg2) { |
89 |
|
90 |
// map EscherClientDataRecord and EscherTextboxRecord to their parents |
91 |
Map<EscherRecord, EscherContainerRecord> map1 = new LinkedHashMap<EscherRecord, EscherContainerRecord>(); |
92 |
for (EscherRecord r : agg1.getEscherRecords()) mapShapeContainers(r, map1); |
93 |
|
94 |
Map<EscherRecord, EscherContainerRecord> map2 = new LinkedHashMap<EscherRecord, EscherContainerRecord>(); |
95 |
for (EscherRecord r : agg2.getEscherRecords()) mapShapeContainers(r, map2); |
96 |
|
97 |
assertEquals("aggregates have different number of shapes", map1.size(), map2.size()); |
98 |
|
99 |
// for each EscherClientDataRecord get parent SP_CONTAINER and corresponding ObjRecord |
100 |
// verify that ObjRecord to |
101 |
List<EscherRecord> l1 = new ArrayList<EscherRecord>(map1.keySet()); |
102 |
List<EscherRecord> l2 = new ArrayList<EscherRecord>(map2.keySet()); |
103 |
for (int i = 0; i < l1.size(); i++) { |
104 |
EscherRecord e1 = l1.get(i); |
105 |
EscherRecord e2 = l2.get(i); |
106 |
ObjRecord obj1 = (ObjRecord) HSSFRecordTestHelper.getShapeToObjForTest(agg1).get(e1); |
107 |
ObjRecord obj2 = (ObjRecord) HSSFRecordTestHelper.getShapeToObjForTest(agg2).get(e2); |
108 |
|
109 |
CommonObjectDataSubRecord cmo1 = (CommonObjectDataSubRecord) obj1.getSubRecords().get(0); |
110 |
CommonObjectDataSubRecord cmo2 = (CommonObjectDataSubRecord) obj2.getSubRecords().get(0); |
111 |
|
112 |
assertEquals(cmo1.getObjectId(), cmo2.getObjectId()); |
113 |
assertEquals(obj1.toString(), obj2.toString()); |
114 |
|
115 |
// test that obj parents have the same shapeId, that is, that shape is the same |
116 |
EscherContainerRecord p1 = map1.get(e1); |
117 |
EscherContainerRecord p2 = map2.get(e2); |
118 |
EscherSpRecord sp1 = (EscherSpRecord) p1.getChildById(EscherSpRecord.RECORD_ID); |
119 |
EscherSpRecord sp2 = (EscherSpRecord) p2.getChildById(EscherSpRecord.RECORD_ID); |
120 |
assertEquals(sp1.getShapeId(), sp2.getShapeId()); |
121 |
|
122 |
assertEquals("wrong shape2obj mapping", sp1.getShapeId() % 1024, cmo1.getObjectId()); |
123 |
assertEquals(p1.toXml(), p2.toXml()); |
124 |
} |
125 |
} |
126 |
|
127 |
/** |
128 |
* recursively map EscherClientDataRecords to their parent shape containers: |
129 |
* <p/> |
130 |
* EscherClientDataRecord1 --> EscherContainerRecord1 |
131 |
* EscherClientDataRecord2 --> EscherContainerRecord2 |
132 |
* ... |
133 |
* <p/> |
134 |
* TODO: YK: this method can be avoided if we have EscherRecord.getParent() |
135 |
*/ |
136 |
private static void mapShapeContainers(EscherRecord parent, Map<EscherRecord, EscherContainerRecord> map) { |
137 |
if (parent.isContainerRecord()) { |
138 |
if (parent.getRecordId() == EscherContainerRecord.SP_CONTAINER) { |
139 |
// iterate over shape's children and search for EscherClientDataRecord |
140 |
for (EscherRecord r : parent.getChildRecords()) { |
141 |
if (r.getRecordId() == EscherClientDataRecord.RECORD_ID) { |
142 |
map.put(r, (EscherContainerRecord) parent); |
143 |
} |
144 |
} |
145 |
} else { |
146 |
for (EscherRecord ch : parent.getChildRecords()) { |
147 |
mapShapeContainers(ch, map); |
148 |
} |
149 |
} |
150 |
} |
151 |
} |
152 |
|
153 |
/** |
31 |
* test reading drawing aggregate from a test file from Bugzilla 45129 |
154 |
* test reading drawing aggregate from a test file from Bugzilla 45129 |
32 |
*/ |
155 |
*/ |
33 |
public void test45129() { |
156 |
public void test45129() { |
Lines 69-75
Link Here
|
69 |
// The subrange [19, 388] is expected to be replaced with a EscherAggregate object |
192 |
// The subrange [19, 388] is expected to be replaced with a EscherAggregate object |
70 |
DrawingManager2 drawingManager = iworkbook.findDrawingGroup(); |
193 |
DrawingManager2 drawingManager = iworkbook.findDrawingGroup(); |
71 |
int loc = isheet.aggregateDrawingRecords(drawingManager, false); |
194 |
int loc = isheet.aggregateDrawingRecords(drawingManager, false); |
72 |
EscherAggregate ag = (EscherAggregate) records.get(loc); |
195 |
EscherAggregate agg = (EscherAggregate) records.get(loc); |
73 |
|
196 |
|
74 |
assertEquals("wrong size of the aggregated sheet records stream", 25, records.size()); |
197 |
assertEquals("wrong size of the aggregated sheet records stream", 25, records.size()); |
75 |
assertTrue( |
198 |
assertTrue( |
Lines 80-87
Link Here
|
80 |
assertTrue("records.get(20) is expected to be Window2 but was " + records.get(20).getClass().getSimpleName(), |
203 |
assertTrue("records.get(20) is expected to be Window2 but was " + records.get(20).getClass().getSimpleName(), |
81 |
records.get(20) instanceof WindowTwoRecord); |
204 |
records.get(20) instanceof WindowTwoRecord); |
82 |
|
205 |
|
83 |
// TODO figure out why serialization fails |
206 |
EscherAggregate agg2 = assertWriteAndReadBack(agg); |
84 |
// byte[] bytes = ag.serialize(); |
207 |
|
|
|
208 |
assertObjectMappingSame(agg, agg2); |
85 |
} |
209 |
} |
86 |
|
210 |
|
87 |
public void testFileWithPictures() { |
211 |
public void testFileWithPictures() { |
Lines 93-102
Link Here
|
93 |
|
217 |
|
94 |
List<RecordBase> records = isheet.getRecords(); |
218 |
List<RecordBase> records = isheet.getRecords(); |
95 |
|
219 |
|
96 |
for (RecordBase recordBase : records) { |
|
|
97 |
System.out.println(recordBase.toString()); |
98 |
} |
99 |
|
100 |
// the sheet's drawing is not aggregated |
220 |
// the sheet's drawing is not aggregated |
101 |
assertEquals("wrong size of sheet records stream", 315, records.size()); |
221 |
assertEquals("wrong size of sheet records stream", 315, records.size()); |
102 |
// the last record before the drawing block |
222 |
// the last record before the drawing block |
Lines 127-133
Link Here
|
127 |
// The subrange [19, 388] is expected to be replaced with a EscherAggregate object |
247 |
// The subrange [19, 388] is expected to be replaced with a EscherAggregate object |
128 |
DrawingManager2 drawingManager = iworkbook.findDrawingGroup(); |
248 |
DrawingManager2 drawingManager = iworkbook.findDrawingGroup(); |
129 |
int loc = isheet.aggregateDrawingRecords(drawingManager, false); |
249 |
int loc = isheet.aggregateDrawingRecords(drawingManager, false); |
130 |
EscherAggregate ag = (EscherAggregate) records.get(loc); |
250 |
EscherAggregate agg = (EscherAggregate) records.get(loc); |
131 |
|
251 |
|
132 |
assertEquals("wrong size of the aggregated sheet records stream", 38, records.size()); |
252 |
assertEquals("wrong size of the aggregated sheet records stream", 38, records.size()); |
133 |
assertTrue( |
253 |
assertTrue( |
Lines 137-142
Link Here
|
137 |
records.get(22) instanceof EscherAggregate); |
257 |
records.get(22) instanceof EscherAggregate); |
138 |
assertTrue("records.get(23) is expected to be Window2 but was " + records.get(23).getClass().getSimpleName(), |
258 |
assertTrue("records.get(23) is expected to be Window2 but was " + records.get(23).getClass().getSimpleName(), |
139 |
records.get(23) instanceof WindowTwoRecord); |
259 |
records.get(23) instanceof WindowTwoRecord); |
|
|
260 |
|
261 |
EscherAggregate agg2 = assertWriteAndReadBack(agg); |
262 |
|
263 |
assertObjectMappingSame(agg, agg2); |
140 |
} |
264 |
} |
141 |
|
265 |
|
142 |
public void testUnhandledContinue() { |
266 |
public void testUnhandledContinue() { |
Lines 848-855
Link Here
|
848 |
assertTrue("expected EOFRecord", records.get(1) instanceof EOFRecord); |
972 |
assertTrue("expected EOFRecord", records.get(1) instanceof EOFRecord); |
849 |
EscherAggregate agg = (EscherAggregate) records.get(0); |
973 |
EscherAggregate agg = (EscherAggregate) records.get(0); |
850 |
|
974 |
|
851 |
// TODO figure out why serialization fails |
975 |
// serialize, read back and assert that the drawing data is preserved |
852 |
// byte[] writtenBytes = agg.serialize(); |
976 |
EscherAggregate agg2 = assertWriteAndReadBack(agg); |
|
|
977 |
|
978 |
assertObjectMappingSame(agg, agg2); |
853 |
} |
979 |
} |
854 |
|
980 |
|
855 |
public void testUnhandledContinue2() { |
981 |
public void testUnhandledContinue2() { |
Lines 1793-1802
Link Here
|
1793 |
records.addAll(dgRecords); |
1919 |
records.addAll(dgRecords); |
1794 |
records.add(EOFRecord.instance); |
1920 |
records.add(EOFRecord.instance); |
1795 |
|
1921 |
|
1796 |
|
|
|
1797 |
sheet.aggregateDrawingRecords(drawingManager, false); |
1922 |
sheet.aggregateDrawingRecords(drawingManager, false); |
1798 |
assertEquals("drawing was not fully aggregated", 2, records.size()); |
1923 |
assertEquals("drawing was not fully aggregated", 2, records.size()); |
1799 |
assertTrue("expected EscherAggregate", records.get(0) instanceof EscherAggregate); |
1924 |
assertTrue("expected EscherAggregate", records.get(0) instanceof EscherAggregate); |
1800 |
assertTrue("expected EOFRecord", records.get(1) instanceof EOFRecord); |
1925 |
assertTrue("expected EOFRecord", records.get(1) instanceof EOFRecord); |
|
|
1926 |
|
1927 |
EscherAggregate agg = (EscherAggregate) records.get(0); |
1928 |
|
1929 |
EscherAggregate agg2 = assertWriteAndReadBack(agg); |
1930 |
|
1931 |
assertObjectMappingSame(agg, agg2); |
1801 |
} |
1932 |
} |
1802 |
} |
1933 |
} |