1 50 51 package com.lowagie.text.xml; 52 53 import java.lang.reflect.Field ; 54 import java.util.ArrayList ; 55 import java.util.Collections ; 56 import java.util.EmptyStackException ; 57 import java.util.HashMap ; 58 import java.util.Iterator ; 59 import java.util.Properties ; 60 import java.util.Stack ; 61 62 import org.xml.sax.Attributes ; 63 import org.xml.sax.helpers.DefaultHandler ; 64 65 import com.lowagie.text.Anchor; 66 import com.lowagie.text.Annotation; 67 import com.lowagie.text.BadElementException; 68 import com.lowagie.text.Cell; 69 import com.lowagie.text.Chapter; 70 import com.lowagie.text.Chunk; 71 import com.lowagie.text.DocListener; 72 import com.lowagie.text.DocumentException; 73 import com.lowagie.text.Element; 74 import com.lowagie.text.ElementTags; 75 import com.lowagie.text.ExceptionConverter; 76 import com.lowagie.text.Font; 77 import com.lowagie.text.Image; 78 import com.lowagie.text.List; 79 import com.lowagie.text.ListItem; 80 import com.lowagie.text.Meta; 81 import com.lowagie.text.PageSize; 82 import com.lowagie.text.Paragraph; 83 import com.lowagie.text.Rectangle; 84 import com.lowagie.text.Section; 85 import com.lowagie.text.Table; 86 import com.lowagie.text.TextElementArray; 87 import com.lowagie.text.factories.ElementFactory; 88 import com.lowagie.text.html.HtmlTagMap; 89 import com.lowagie.text.pdf.BaseFont; 90 import com.lowagie.text.xml.simpleparser.EntitiesToSymbol; 91 92 96 97 public class SAXiTextHandler extends DefaultHandler { 98 99 100 protected DocListener document; 101 102 106 protected Stack stack; 107 108 109 protected int chapters = 0; 110 111 112 protected Chunk currentChunk = null; 113 114 115 protected boolean ignore = false; 116 117 121 protected boolean controlOpenClose = true; 122 123 124 float topMargin = 36; 125 126 127 float rightMargin = 36; 128 129 130 float leftMargin = 36; 131 132 133 float bottomMargin = 36; 134 135 138 public SAXiTextHandler(DocListener document) { 139 super(); 140 this.document = document; 141 stack = new Stack (); 142 } 143 144 protected HashMap myTags; 145 146 150 public SAXiTextHandler(DocListener document, HtmlTagMap myTags) { 151 this(document); 152 this.myTags = myTags; 153 } 154 155 160 public SAXiTextHandler(DocListener document, HtmlTagMap myTags, 161 BaseFont bf){ 162 this(document, myTags); 163 this.bf = bf; 164 } 165 166 170 public SAXiTextHandler(DocListener document, HashMap myTags) { 171 this(document); 172 this.myTags = myTags; 173 } 174 175 188 189 public void setControlOpenClose(boolean controlOpenClose) { 190 this.controlOpenClose = controlOpenClose; 191 } 192 193 206 207 public void startElement(String uri, String lname, String name, 208 Attributes attrs) { 209 210 Properties attributes = new Properties (); 211 if (attrs != null) { 212 for (int i = 0; i < attrs.getLength(); i++) { 213 String attribute = attrs.getQName(i); 214 attributes.setProperty(attribute, attrs.getValue(i)); 215 } 216 } 217 handleStartingTags(name, attributes); 218 } 219 220 228 229 public void handleStartingTags(String name, Properties attributes) { 230 if (ignore || ElementTags.IGNORE.equals(name)) { 232 ignore = true; 233 return; 234 } 235 236 if (currentChunk != null) { 238 TextElementArray current; 239 try { 240 current = (TextElementArray) stack.pop(); 241 } catch (EmptyStackException ese) { 242 if (bf == null) { 243 current = new Paragraph("", new Font()); 244 } 245 else { 246 current = new Paragraph("", new Font(this.bf)); 247 } 248 } 249 current.add(currentChunk); 250 stack.push(current); 251 currentChunk = null; 252 } 253 254 if (ElementTags.CHUNK.equals(name)) { 256 currentChunk = ElementFactory.getChunk(attributes); 257 if (bf != null) { 258 currentChunk.setFont(new Font(this.bf)); 259 } 260 return; 261 } 262 263 if (ElementTags.ENTITY.equals(name)) { 265 Font f = new Font(); 266 if (currentChunk != null) { 267 handleEndingTags(ElementTags.CHUNK); 268 f = currentChunk.getFont(); 269 } 270 currentChunk = EntitiesToSymbol.get(attributes.getProperty(ElementTags.ID), 271 f); 272 return; 273 } 274 275 if (ElementTags.PHRASE.equals(name)) { 277 stack.push(ElementFactory.getPhrase(attributes)); 278 return; 279 } 280 281 if (ElementTags.ANCHOR.equals(name)) { 283 stack.push(ElementFactory.getAnchor(attributes)); 284 return; 285 } 286 287 if (ElementTags.PARAGRAPH.equals(name) || ElementTags.TITLE.equals(name)) { 289 stack.push(ElementFactory.getParagraph(attributes)); 290 return; 291 } 292 293 if (ElementTags.LIST.equals(name)) { 295 stack.push(ElementFactory.getList(attributes)); 296 return; 297 } 298 299 if (ElementTags.LISTITEM.equals(name)) { 301 stack.push(ElementFactory.getListItem(attributes)); 302 return; 303 } 304 305 if (ElementTags.CELL.equals(name)) { 307 stack.push(ElementFactory.getCell(attributes)); 308 return; 309 } 310 311 if (ElementTags.TABLE.equals(name)) { 313 Table table = ElementFactory.getTable(attributes); 314 float widths[] = table.getProportionalWidths(); 315 for (int i = 0; i < widths.length; i++) { 316 if (widths[i] == 0) { 317 widths[i] = 100.0f / (float) widths.length; 318 } 319 } 320 try { 321 table.setWidths(widths); 322 } catch (BadElementException bee) { 323 throw new ExceptionConverter(bee); 325 } 326 stack.push(table); 327 return; 328 } 329 330 if (ElementTags.SECTION.equals(name)) { 332 Element previous = (Element) stack.pop(); 333 Section section; 334 try { 335 section = ElementFactory.getSection((Section) previous, attributes); 336 } catch (ClassCastException cce) { 337 throw new ExceptionConverter(cce); 338 } 339 stack.push(previous); 340 stack.push(section); 341 return; 342 } 343 344 if (ElementTags.CHAPTER.equals(name)) { 346 stack.push(ElementFactory.getChapter(attributes)); 347 return; 348 } 349 350 if (ElementTags.IMAGE.equals(name)) { 352 try { 353 Image img = ElementFactory.getImage(attributes); 354 try { 355 addImage(img); 356 return; 357 } catch (EmptyStackException ese) { 358 try { 361 document.add(img); 362 } catch (DocumentException de) { 363 throw new ExceptionConverter(de); 364 } 365 return; 366 } 367 } catch (Exception e) { 368 throw new ExceptionConverter(e); 369 } 370 } 371 372 if (ElementTags.ANNOTATION.equals(name)) { 374 Annotation annotation = ElementFactory.getAnnotation(attributes); 375 TextElementArray current; 376 try { 377 try { 378 current = (TextElementArray) stack.pop(); 379 try { 380 current.add(annotation); 381 } catch (Exception e) { 382 document.add(annotation); 383 } 384 stack.push(current); 385 } catch (EmptyStackException ese) { 386 document.add(annotation); 387 } 388 return; 389 } catch (DocumentException de) { 390 throw new ExceptionConverter(de); 391 } 392 } 393 394 if (isNewline(name)) { 396 TextElementArray current; 397 try { 398 current = (TextElementArray) stack.pop(); 399 current.add(Chunk.NEWLINE); 400 stack.push(current); 401 } catch (EmptyStackException ese) { 402 if (currentChunk == null) { 403 try { 404 document.add(Chunk.NEWLINE); 405 } catch (DocumentException de) { 406 throw new ExceptionConverter(de); 407 } 408 } else { 409 currentChunk.append("\n"); 410 } 411 } 412 return; 413 } 414 415 if (isNewpage(name)) { 417 TextElementArray current; 418 try { 419 current = (TextElementArray) stack.pop(); 420 Chunk newPage = new Chunk(""); 421 newPage.setNewPage(); 422 if (bf != null) { 423 newPage.setFont(new Font(this.bf)); 424 } 425 current.add(newPage); 426 stack.push(current); 427 } catch (EmptyStackException ese) { 428 document.newPage(); 429 } 430 return; 431 } 432 433 if (isDocumentRoot(name)) { 435 String key; 436 String value; 437 Rectangle pageSize = null; 440 String orientation = null; 441 for (Iterator i = attributes.keySet().iterator(); i.hasNext();) { 442 key = (String ) i.next(); 443 value = attributes.getProperty(key); 444 try { 445 if (ElementTags.LEFT.equalsIgnoreCase(key)) 447 leftMargin = Float.parseFloat(value + "f"); 448 if (ElementTags.RIGHT.equalsIgnoreCase(key)) 449 rightMargin = Float.parseFloat(value + "f"); 450 if (ElementTags.TOP.equalsIgnoreCase(key)) 451 topMargin = Float.parseFloat(value + "f"); 452 if (ElementTags.BOTTOM.equalsIgnoreCase(key)) 453 bottomMargin = Float.parseFloat(value + "f"); 454 } catch (Exception ex) { 455 throw new ExceptionConverter(ex); 456 } 457 if (ElementTags.PAGE_SIZE.equals(key)) { 458 try { 459 String pageSizeName = value; 460 Field pageSizeField = PageSize.class 461 .getField(pageSizeName); 462 pageSize = (Rectangle) pageSizeField.get(null); 463 } catch (Exception ex) { 464 throw new ExceptionConverter(ex); 465 } 466 } else if (ElementTags.ORIENTATION.equals(key)) { 467 try { 468 if ("landscape".equals(value)) { 469 orientation = "landscape"; 470 } 471 } catch (Exception ex) { 472 throw new ExceptionConverter(ex); 473 } 474 } else { 475 try { 476 document.add(new Meta(key, value)); 477 } catch (DocumentException de) { 478 throw new ExceptionConverter(de); 479 } 480 } 481 } 482 if(pageSize != null) { 483 if ("landscape".equals(orientation)) { 484 pageSize = pageSize.rotate(); 485 } 486 document.setPageSize(pageSize); 487 } 488 document.setMargins(leftMargin, rightMargin, topMargin, 489 bottomMargin); 490 491 if (controlOpenClose) 492 document.open(); 493 } 494 495 } 496 497 protected void addImage(Image img) throws EmptyStackException { 498 Object current = stack.pop(); 500 if (current instanceof Chapter 503 || current instanceof Section 504 || current instanceof Cell) { 505 ((TextElementArray) current).add(img); 506 stack.push(current); 507 return; 508 } 509 else { 511 Stack newStack = new Stack (); 512 while (!(current instanceof Chapter 513 || current instanceof Section || current instanceof Cell)) { 514 newStack.push(current); 515 if (current instanceof Anchor) { 516 img.setAnnotation(new Annotation(0, 0, 0, 517 0, ((Anchor) current).getReference())); 518 } 519 current = stack.pop(); 520 } 521 ((TextElementArray) current).add(img); 522 stack.push(current); 523 while (!newStack.empty()) { 524 stack.push(newStack.pop()); 525 } 526 return; 527 } 528 } 529 530 540 541 public void ignorableWhitespace(char[] ch, int start, int length) { 542 } 544 545 555 556 public void characters(char[] ch, int start, int length) { 557 558 if (ignore) 559 return; 560 561 String content = new String (ch, start, length); 562 564 if (content.trim().length() == 0) { 565 return; 566 } 567 568 StringBuffer buf = new StringBuffer (); 569 int len = content.length(); 570 char character; 571 boolean newline = false; 572 for (int i = 0; i < len; i++) { 573 switch (character = content.charAt(i)) { 574 case ' ': 575 if (!newline) { 576 buf.append(character); 577 } 578 break; 579 case '\n': 580 if (i > 0) { 581 newline = true; 582 buf.append(' '); 583 } 584 break; 585 case '\r': 586 break; 587 case '\t': 588 break; 589 default: 590 newline = false; 591 buf.append(character); 592 } 593 } 594 if (currentChunk == null) { 595 if (bf == null) { 596 currentChunk = new Chunk(buf.toString()); 597 } 598 else { 599 currentChunk = new Chunk(buf.toString(), new Font(this.bf)); 600 } 601 } else { 602 currentChunk.append(buf.toString()); 603 } 604 } 605 606 private BaseFont bf = null; 607 608 612 public void setBaseFont(BaseFont bf) { 613 this.bf = bf; 614 } 615 616 627 628 public void endElement(String uri, String lname, String name) { 629 handleEndingTags(name); 630 } 631 632 638 639 public void handleEndingTags(String name) { 640 641 643 if (ElementTags.IGNORE.equals(name)) { 644 ignore = false; 645 return; 646 } 647 if (ignore) 648 return; 649 if (isNewpage(name) || ElementTags.ANNOTATION.equals(name) || ElementTags.IMAGE.equals(name) 651 || isNewline(name)) { 652 return; 653 } 654 655 try { 656 if (ElementTags.TITLE.equals(name)) { 658 Paragraph current = (Paragraph) stack.pop(); 659 if (currentChunk != null) { 660 current.add(currentChunk); 661 currentChunk = null; 662 } 663 Section previous = (Section) stack.pop(); 664 previous.setTitle(current); 665 stack.push(previous); 666 return; 667 } 668 669 if (currentChunk != null) { 671 TextElementArray current; 672 try { 673 current = (TextElementArray) stack.pop(); 674 } catch (EmptyStackException ese) { 675 current = new Paragraph(); 676 } 677 current.add(currentChunk); 678 stack.push(current); 679 currentChunk = null; 680 } 681 682 if (ElementTags.CHUNK.equals(name)) { 684 return; 685 } 686 687 if (ElementTags.PHRASE.equals(name) || ElementTags.ANCHOR.equals(name) || ElementTags.LIST.equals(name) 689 || ElementTags.PARAGRAPH.equals(name)) { 690 Element current = (Element) stack.pop(); 691 try { 692 TextElementArray previous = (TextElementArray) stack.pop(); 693 previous.add(current); 694 stack.push(previous); 695 } catch (EmptyStackException ese) { 696 document.add(current); 697 } 698 return; 699 } 700 701 if (ElementTags.LISTITEM.equals(name)) { 703 ListItem listItem = (ListItem) stack.pop(); 704 List list = (List ) stack.pop(); 705 list.add(listItem); 706 stack.push(list); 707 } 708 709 if (ElementTags.TABLE.equals(name)) { 711 Table table = (Table) stack.pop(); 712 try { 713 TextElementArray previous = (TextElementArray) stack.pop(); 714 previous.add(table); 715 stack.push(previous); 716 } catch (EmptyStackException ese) { 717 document.add(table); 718 } 719 return; 720 } 721 722 if (ElementTags.ROW.equals(name)) { 724 ArrayList cells = new ArrayList (); 725 int columns = 0; 726 Table table; 727 Cell cell; 728 while (true) { 729 Element element = (Element) stack.pop(); 730 if (element.type() == Element.CELL) { 731 cell = (Cell) element; 732 columns += cell.getColspan(); 733 cells.add(cell); 734 } else { 735 table = (Table) element; 736 break; 737 } 738 } 739 if (table.getColumns() < columns) { 740 table.addColumns(columns - table.getColumns()); 741 } 742 Collections.reverse(cells); 743 String width; 744 float[] cellWidths = new float[columns]; 745 boolean[] cellNulls = new boolean[columns]; 746 for (int i = 0; i < columns; i++) { 747 cellWidths[i] = 0; 748 cellNulls[i] = true; 749 } 750 float total = 0; 751 int j = 0; 752 for (Iterator i = cells.iterator(); i.hasNext();) { 753 cell = (Cell) i.next(); 754 width = cell.getWidthAsString(); 755 if (cell.getWidth() == 0) { 756 if (cell.getColspan() == 1 && cellWidths[j] == 0) { 757 try { 758 cellWidths[j] = 100f / columns; 759 total += cellWidths[j]; 760 } catch (Exception e) { 761 } 763 } else if (cell.getColspan() == 1) { 764 cellNulls[j] = false; 765 } 766 } else if (cell.getColspan() == 1 && width.endsWith("%")) { 767 try { 768 cellWidths[j] = Float.parseFloat( 769 width.substring(0, width.length() - 1) 770 + "f"); 771 total += cellWidths[j]; 772 } catch (Exception e) { 773 } 775 } 776 j += cell.getColspan(); 777 table.addCell(cell); 778 } 779 float widths[] = table.getProportionalWidths(); 780 if (widths.length == columns) { 781 float left = 0.0f; 782 for (int i = 0; i < columns; i++) { 783 if (cellNulls[i] && widths[i] != 0) { 784 left += widths[i]; 785 cellWidths[i] = widths[i]; 786 } 787 } 788 if (100.0 >= total) { 789 for (int i = 0; i < widths.length; i++) { 790 if (cellWidths[i] == 0 && widths[i] != 0) { 791 cellWidths[i] = (widths[i] / left) 792 * (100.0f - total); 793 } 794 } 795 } 796 table.setWidths(cellWidths); 797 } 798 stack.push(table); 799 } 800 801 if (ElementTags.CELL.equals(name)) { 803 return; 804 } 805 806 if (ElementTags.SECTION.equals(name)) { 808 stack.pop(); 809 return; 810 } 811 812 if (ElementTags.CHAPTER.equals(name)) { 814 document.add((Element) stack.pop()); 815 return; 816 } 817 818 if (isDocumentRoot(name)) { 820 try { 821 while (true) { 822 Element element = (Element) stack.pop(); 823 try { 824 TextElementArray previous = (TextElementArray) stack 825 .pop(); 826 previous.add(element); 827 stack.push(previous); 828 } catch (EmptyStackException es) { 829 document.add(element); 830 } 831 } 832 } catch (EmptyStackException ese) { 833 } 835 if (controlOpenClose) 836 document.close(); 837 return; 838 } 839 } catch (DocumentException de) { 840 throw new ExceptionConverter(de); 841 } 842 } 843 844 851 852 private boolean isNewpage(String tag) { 853 return ElementTags.NEWPAGE.equals(tag); 854 } 855 856 863 864 private boolean isNewline(String tag) { 865 return ElementTags.NEWLINE.equals(tag); 866 } 867 868 876 877 protected boolean isDocumentRoot(String tag) { 878 return ElementTags.ITEXT.equals(tag); 879 } 880 } | Popular Tags |