1 2 17 18 package org.apache.poi.hdf.event; 19 20 21 import org.apache.poi.hdf.model.util.BTreeSet; 22 import org.apache.poi.hdf.model.util.NumberFormatter; 23 import org.apache.poi.hdf.model.hdftypes.*; 24 25 import org.apache.poi.util.LittleEndian; 26 27 import java.util.ArrayList ; 28 29 public class EventBridge implements HDFLowLevelParsingListener 30 { 31 32 private static int HEADER_EVEN_INDEX = 0; 33 private static int HEADER_ODD_INDEX = 1; 34 private static int FOOTER_EVEN_INDEX = 2; 35 private static int FOOTER_ODD_INDEX = 3; 36 private static int HEADER_FIRST_INDEX = 4; 37 private static int FOOTER_FIRST_INDEX = 5; 38 39 41 HDFParsingListener _listener; 42 43 StyleSheet _stsh; 44 45 DocumentProperties _dop; 46 47 StyleDescription _currentStd; 48 49 ListTables _listTables; 50 51 52 53 byte[] _mainDocument; 54 55 byte[] _tableStream; 56 57 58 int _fcMin; 59 int _ccpText; 60 int _ccpFtn; 61 int _hdrSize; 62 int _hdrOffset; 63 64 65 BTreeSet _text = new BTreeSet(); 66 67 private boolean _beginHeaders; 68 BTreeSet _hdrSections = new BTreeSet(); 69 BTreeSet _hdrParagraphs = new BTreeSet(); 70 BTreeSet _hdrCharacterRuns = new BTreeSet(); 71 72 int _sectionCounter = 1; 73 ArrayList _hdrs = new ArrayList (); 74 75 private boolean _holdParagraph = false; 76 private int _endHoldIndex = -1; 77 private ArrayList _onHold; 78 79 public EventBridge(HDFParsingListener listener) 80 { 81 _listener = listener; 82 } 83 public void mainDocument(byte[] mainDocument) 84 { 85 _mainDocument = mainDocument; 86 } 87 public void tableStream(byte[] tableStream) 88 { 89 _tableStream = tableStream; 90 } 91 public void miscellaneous(int fcMin, int ccpText, int ccpFtn, int fcPlcfhdd, int lcbPlcfhdd) 92 { 93 _fcMin = fcMin; 94 _ccpText = ccpText; 95 _ccpFtn = ccpFtn; 96 _hdrOffset = fcPlcfhdd; 97 _hdrSize = lcbPlcfhdd; 98 } 99 public void document(DocumentProperties dop) 100 { 101 _dop = dop; 102 } 103 public void bodySection(SepxNode sepx) 104 { 105 SectionProperties sep = (SectionProperties)StyleSheet.uncompressProperty(sepx.getSepx(), new SectionProperties(), _stsh); 106 HeaderFooter[] hdrArray = findSectionHdrFtrs(_sectionCounter); 107 _hdrs.add(hdrArray); 108 _listener.section(sep, sepx.getStart() - _fcMin, sepx.getEnd() - _fcMin); 109 _sectionCounter++; 110 } 111 112 public void hdrSection(SepxNode sepx) 113 { 114 _beginHeaders = true; 115 _hdrSections.add(sepx); 116 } 117 public void endSections() 118 { 119 for (int x = 1; x < _sectionCounter; x++) 120 { 121 HeaderFooter[] hdrArray = (HeaderFooter[])_hdrs.get(x-1); 122 HeaderFooter hf = null; 123 124 if (!hdrArray[HeaderFooter.HEADER_EVEN - 1].isEmpty()) 125 { 126 hf = hdrArray[HeaderFooter.HEADER_EVEN - 1]; 127 _listener.header(x - 1, HeaderFooter.HEADER_EVEN); 128 flushHeaderProps(hf.getStart(), hf.getEnd()); 129 } 130 if (!hdrArray[HeaderFooter.HEADER_ODD - 1].isEmpty()) 131 { 132 hf = hdrArray[HeaderFooter.HEADER_ODD - 1]; 133 _listener.header(x - 1, HeaderFooter.HEADER_ODD); 134 flushHeaderProps(hf.getStart(), hf.getEnd()); 135 } 136 if (!hdrArray[HeaderFooter.FOOTER_EVEN - 1].isEmpty()) 137 { 138 hf = hdrArray[HeaderFooter.FOOTER_EVEN - 1]; 139 _listener.footer(x - 1, HeaderFooter.FOOTER_EVEN); 140 flushHeaderProps(hf.getStart(), hf.getEnd()); 141 } 142 if (!hdrArray[HeaderFooter.FOOTER_ODD - 1].isEmpty()) 143 { 144 hf = hdrArray[HeaderFooter.FOOTER_EVEN - 1]; 145 _listener.footer(x - 1, HeaderFooter.FOOTER_EVEN); 146 flushHeaderProps(hf.getStart(), hf.getEnd()); 147 } 148 if (!hdrArray[HeaderFooter.HEADER_FIRST - 1].isEmpty()) 149 { 150 hf = hdrArray[HeaderFooter.HEADER_FIRST - 1]; 151 _listener.header(x - 1, HeaderFooter.HEADER_FIRST); 152 flushHeaderProps(hf.getStart(), hf.getEnd()); 153 } 154 if (!hdrArray[HeaderFooter.FOOTER_FIRST - 1].isEmpty()) 155 { 156 hf = hdrArray[HeaderFooter.FOOTER_FIRST - 1]; 157 _listener.footer(x - 1, HeaderFooter.FOOTER_FIRST); 158 flushHeaderProps(hf.getStart(), hf.getEnd()); 159 } 160 } 161 } 162 163 164 165 public void paragraph(PapxNode papx) 166 { 167 if (_beginHeaders) 168 { 169 _hdrParagraphs.add(papx); 170 } 171 byte[] bytePapx = papx.getPapx(); 172 int istd = LittleEndian.getShort(bytePapx, 0); 173 _currentStd = _stsh.getStyleDescription(istd); 174 175 ParagraphProperties pap = (ParagraphProperties)StyleSheet.uncompressProperty(bytePapx, _currentStd.getPAP(), _stsh); 176 177 if (pap.getFTtp() > 0) 178 { 179 TableProperties tap = (TableProperties)StyleSheet.uncompressProperty(bytePapx, new TableProperties(), _stsh); 180 _listener.tableRowEnd(tap, papx.getStart() - _fcMin, papx.getEnd() - _fcMin); 181 } 182 else if (pap.getIlfo() > 0) 183 { 184 _holdParagraph = true; 185 _endHoldIndex = papx.getEnd(); 186 _onHold.add(papx); 187 } 188 else 189 { 190 _listener.paragraph(pap, papx.getStart() - _fcMin, papx.getEnd() - _fcMin); 191 } 192 } 193 194 public void characterRun(ChpxNode chpx) 195 { 196 if (_beginHeaders) 197 { 198 _hdrCharacterRuns.add(chpx); 199 } 200 201 int start = chpx.getStart(); 202 int end = chpx.getEnd(); 203 if (_holdParagraph) 205 { 206 _onHold.add(chpx); 207 if (end >= _endHoldIndex) 208 { 209 _holdParagraph = false; 210 _endHoldIndex = -1; 211 flushHeldParagraph(); 212 _onHold = new ArrayList (); 213 } 214 } 215 216 byte[] byteChpx = chpx.getChpx(); 217 218 219 CharacterProperties chp = (CharacterProperties)StyleSheet.uncompressProperty(byteChpx, _currentStd.getCHP(), _stsh); 220 221 ArrayList textList = BTreeSet.findProperties(start, end, _text.root); 222 String text = getTextFromNodes(textList, start, end); 223 224 _listener.characterRun(chp, text, start - _fcMin, end - _fcMin); 225 } 226 public void text(TextPiece t) 227 { 228 _text.add(t); 229 } 230 public void fonts(FontTable fontTbl) 231 { 232 } 233 public void lists(ListTables listTbl) 234 { 235 _listTables = listTbl; 236 } 237 public void styleSheet(StyleSheet stsh) 238 { 239 _stsh = stsh; 240 } 241 private void flushHeaderProps(int start, int end) 242 { 243 ArrayList list = BTreeSet.findProperties(start, end, _hdrSections.root); 244 int size = list.size(); 245 246 for (int x = 0; x < size; x++) 247 { 248 SepxNode oldNode = (SepxNode)list.get(x); 249 int secStart = Math.max(oldNode.getStart(), start); 250 int secEnd = Math.min(oldNode.getEnd(), end); 251 252 255 ArrayList parList = BTreeSet.findProperties(secStart, secEnd, _hdrParagraphs.root); 256 int parSize = parList.size(); 257 258 for (int y = 0; y < parSize; y++) 259 { 260 PapxNode oldParNode = (PapxNode)parList.get(y); 261 int parStart = Math.max(oldParNode.getStart(), secStart); 262 int parEnd = Math.min(oldParNode.getEnd(), secEnd); 263 264 PapxNode parNode = new PapxNode(parStart, parEnd, oldParNode.getPapx()); 265 paragraph(parNode); 266 267 ArrayList charList = BTreeSet.findProperties(parStart, parEnd, _hdrCharacterRuns.root); 268 int charSize = charList.size(); 269 270 for (int z = 0; z < charSize; z++) 271 { 272 ChpxNode oldCharNode = (ChpxNode)charList.get(z); 273 int charStart = Math.max(oldCharNode.getStart(), parStart); 274 int charEnd = Math.min(oldCharNode.getEnd(), parEnd); 275 276 ChpxNode charNode = new ChpxNode(charStart, charEnd, oldCharNode.getChpx()); 277 characterRun(charNode); 278 } 279 } 280 281 } 282 283 } 284 private String getTextFromNodes(ArrayList list, int start, int end) 285 { 286 int size = list.size(); 287 288 StringBuffer sb = new StringBuffer (); 289 290 for (int x = 0; x < size; x++) 291 { 292 TextPiece piece = (TextPiece)list.get(x); 293 int charStart = Math.max(start, piece.getStart()); 294 int charEnd = Math.min(end, piece.getEnd()); 295 296 if(piece.usesUnicode()) 297 { 298 for (int y = charStart; y < charEnd; y += 2) 299 { 300 sb.append((char)LittleEndian.getShort(_mainDocument, y)); 301 } 302 } 303 else 304 { 305 for (int y = charStart; y < charEnd; y++) 306 { 307 sb.append(_mainDocument[y]); 308 } 309 } 310 } 311 return sb.toString(); 312 } 313 314 private void flushHeldParagraph() 315 { 316 PapxNode papx = (PapxNode)_onHold.get(0); 317 byte[] bytePapx = papx.getPapx(); 318 int istd = LittleEndian.getShort(bytePapx, 0); 319 StyleDescription std = _stsh.getStyleDescription(istd); 320 321 ParagraphProperties pap = (ParagraphProperties)StyleSheet.uncompressProperty(bytePapx, _currentStd.getPAP(), _stsh); 322 LVL lvl = _listTables.getLevel(pap.getIlfo(), pap.getIlvl()); 323 pap = (ParagraphProperties)StyleSheet.uncompressProperty(lvl._papx, pap, _stsh, false); 324 325 int size = _onHold.size() - 1; 326 327 CharacterProperties numChp = (CharacterProperties)StyleSheet.uncompressProperty(((ChpxNode)_onHold.get(size)).getChpx(), std.getCHP(), _stsh); 328 329 numChp = (CharacterProperties)StyleSheet.uncompressProperty(lvl._chpx, numChp, _stsh); 330 String bulletText = getBulletText(lvl, pap); 331 332 _listener.listEntry(bulletText, numChp, pap, papx.getStart() - _fcMin, papx.getEnd() - _fcMin); 333 for (int x = 1; x <= size; x++) 334 { 335 characterRun((ChpxNode)_onHold.get(x)); 336 } 337 338 } 339 340 private String getBulletText(LVL lvl, ParagraphProperties pap) 341 { 342 StringBuffer bulletBuffer = new StringBuffer (); 343 for(int x = 0; x < lvl._xst.length; x++) 344 { 345 if(lvl._xst[x] < 9) 346 { 347 LVL numLevel = _listTables.getLevel(pap.getIlfo(), lvl._xst[x]); 348 int num = numLevel._iStartAt; 349 if(lvl == numLevel) 350 { 351 numLevel._iStartAt++; 352 } 353 else if(num > 1) 354 { 355 num--; 356 } 357 bulletBuffer.append(NumberFormatter.getNumber(num, lvl._nfc)); 358 359 } 360 else 361 { 362 bulletBuffer.append(lvl._xst[x]); 363 } 364 365 } 366 367 switch (lvl._ixchFollow) 368 { 369 case 0: 370 bulletBuffer.append('\u0009'); 371 break; 372 case 1: 373 bulletBuffer.append(' '); 374 break; 375 } 376 return bulletBuffer.toString(); 377 } 378 379 private HeaderFooter[] findSectionHdrFtrs(int index) 380 { 381 HeaderFooter[] hdrArray = new HeaderFooter[6]; 382 383 for (int x = 1; x < 7; x++) 384 { 385 hdrArray[x-1] = createSectionHdrFtr(index, x); 386 } 387 388 return hdrArray; 389 } 390 391 private HeaderFooter createSectionHdrFtr(int index, int type) 392 { 393 if(_hdrSize < 50) 394 { 395 return new HeaderFooter(0,0,0); 396 } 397 398 int start = _fcMin + _ccpText + _ccpFtn; 399 int end = start; 400 int arrayIndex = 0; 401 402 switch(type) 403 { 404 case HeaderFooter.HEADER_EVEN: 405 arrayIndex = (HEADER_EVEN_INDEX + (index * 6)); 406 break; 407 case HeaderFooter.FOOTER_EVEN: 408 arrayIndex = (FOOTER_EVEN_INDEX + (index * 6)); 409 break; 410 case HeaderFooter.HEADER_ODD: 411 arrayIndex = (HEADER_ODD_INDEX + (index * 6)); 412 break; 413 case HeaderFooter.FOOTER_ODD: 414 arrayIndex = (FOOTER_ODD_INDEX + (index * 6)); 415 break; 416 case HeaderFooter.HEADER_FIRST: 417 arrayIndex = (HEADER_FIRST_INDEX + (index * 6)); 418 break; 419 case HeaderFooter.FOOTER_FIRST: 420 arrayIndex = (FOOTER_FIRST_INDEX + (index * 6)); 421 break; 422 } 423 start += LittleEndian.getInt(_tableStream, _hdrOffset + (arrayIndex * 4)); 424 end += LittleEndian.getInt(_tableStream, _hdrOffset + (arrayIndex + 1) * 4); 425 426 HeaderFooter retValue = new HeaderFooter(type, start, end); 427 428 if((end - start) == 0 && index > 1) 429 { 430 retValue = createSectionHdrFtr(type, index - 1); 431 } 432 return retValue; 433 } 434 } 435 | Popular Tags |