1 18 package org.apache.batik.transcoder.svg2svg; 19 20 import java.io.IOException ; 21 import java.io.Writer ; 22 import java.util.Iterator ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 26 import org.apache.batik.xml.XMLUtilities; 27 28 34 public class OutputManager { 35 36 39 protected PrettyPrinter prettyPrinter; 40 41 44 protected Writer writer; 45 46 49 protected int level; 50 51 54 protected StringBuffer margin = new StringBuffer (); 55 56 59 protected int line = 1; 60 61 64 protected int column; 65 66 69 protected List xmlSpace = new LinkedList (); 70 { 71 xmlSpace.add(Boolean.FALSE); 72 } 73 74 77 protected boolean canIndent = true; 78 79 82 protected List startingLines = new LinkedList (); 83 84 87 protected boolean lineAttributes = false; 88 89 94 public OutputManager(PrettyPrinter pp, Writer w) { 95 prettyPrinter = pp; 96 writer = w; 97 } 98 99 102 public void printCharacter(char c) throws IOException { 103 if (c == 10) { 104 printNewline(); 105 } else { 106 column++; 107 writer.write(c); 108 } 109 } 110 111 114 public void printNewline() throws IOException { 115 String nl = prettyPrinter.getNewline(); 116 for (int i = 0; i < nl.length(); i++) { 117 writer.write(nl.charAt(i)); 118 } 119 column = 0; 120 line++; 121 } 122 123 126 public void printString(String s) throws IOException { 127 for (int i = 0; i < s.length(); i++) { 128 printCharacter(s.charAt(i)); 129 } 130 } 131 132 135 public void printCharacters(char[] ca) throws IOException { 136 for (int i = 0; i < ca.length; i++) { 137 printCharacter(ca[i]); 138 } 139 } 140 141 146 public void printSpaces(char[] text, boolean opt) throws IOException { 147 if (prettyPrinter.getFormat()) { 148 if (!opt) { 149 printCharacter(' '); 150 } 151 } else { 152 printCharacters(text); 153 } 154 } 155 156 160 public void printTopSpaces(char[] text) throws IOException { 161 if (prettyPrinter.getFormat()) { 162 int nl = newlines(text); 163 for (int i = 0; i < nl; i++) { 164 printNewline(); 165 } 166 } else { 167 printCharacters(text); 168 } 169 } 170 171 175 public void printComment(char[] text) throws IOException { 176 if (prettyPrinter.getFormat()) { 177 if (canIndent) { 178 printNewline(); 179 printString(margin.toString()); 180 } 181 printString("<!--"); 182 if (column + text.length + 3 < prettyPrinter.getDocumentWidth()) { 183 printCharacters(text); 184 } else { 185 formatText(text, margin.toString(), false); 186 printCharacter(' '); 187 } 188 if (column + 3 > prettyPrinter.getDocumentWidth()) { 189 printNewline(); 190 printString(margin.toString()); 191 } 192 printString("-->"); 193 } else { 194 printString("<!--"); 195 printCharacters(text); 196 printString("-->"); 197 } 198 } 199 200 203 public void printXMLDecl(char[] space1, 204 char[] space2, 205 char[] space3, 206 char[] version, char versionDelim, 207 char[] space4, 208 char[] space5, 209 char[] space6, 210 char[] encoding, char encodingDelim, 211 char[] space7, 212 char[] space8, 213 char[] space9, 214 char[] standalone, char standaloneDelim, 215 char[] space10) 216 throws IOException { 217 printString("<?xml"); 218 219 printSpaces(space1, false); 220 221 printString("version"); 222 223 if (space2 != null) { 224 printSpaces(space2, true); 225 } 226 227 printCharacter('='); 228 229 if (space3 != null) { 230 printSpaces(space3, true); 231 } 232 233 printCharacter(versionDelim); 234 printCharacters(version); 235 printCharacter(versionDelim); 236 237 if (space4 != null) { 238 printSpaces(space4, false); 239 240 if (encoding != null) { 241 printString("encoding"); 242 243 if (space5 != null) { 244 printSpaces(space5, true); 245 } 246 247 printCharacter('='); 248 249 if (space6 != null) { 250 printSpaces(space6, true); 251 } 252 253 printCharacter(encodingDelim); 254 printCharacters(encoding); 255 printCharacter(encodingDelim); 256 257 if (space7 != null) { 258 printSpaces(space7, standalone == null); 259 } 260 } 261 262 if (standalone != null) { 263 printString("standalone"); 264 265 if (space8 != null) { 266 printSpaces(space8, true); 267 } 268 269 printCharacter('='); 270 271 if (space9 != null) { 272 printSpaces(space9, true); 273 } 274 275 printCharacter(standaloneDelim); 276 printCharacters(standalone); 277 printCharacter(standaloneDelim); 278 279 if (space10 != null) { 280 printSpaces(space10, true); 281 } 282 } 283 } 284 285 printString("?>"); 286 } 287 288 291 public void printPI(char[] target, char[] space, char[] data) throws IOException { 292 if (prettyPrinter.getFormat()) { 293 if (canIndent) { 294 printNewline(); 295 printString(margin.toString()); 296 } 297 } 298 printString("<?"); 299 printCharacters(target); 300 printSpaces(space, false); 301 printCharacters(data); 302 printString("?>"); 303 } 304 305 308 public void printDoctypeStart(char[] space1, 309 char[] root, 310 char[] space2, 311 String externalId, 312 char[] space3, 313 char[] string1, char string1Delim, 314 char[] space4, 315 char[] string2, char string2Delim, 316 char[] space5) throws IOException { 317 if (prettyPrinter.getFormat()) { 318 printString("<!DOCTYPE"); 319 320 printCharacter(' '); 321 printCharacters(root); 322 323 if (space2 != null) { 324 printCharacter(' '); 325 printString(externalId); 326 printCharacter(' '); 327 328 printCharacter(string1Delim); 329 printCharacters(string1); 330 printCharacter(string1Delim); 331 332 if (space4 != null) { 333 if (string2 != null) { 334 if (column + string2.length + 3 > 335 prettyPrinter.getDocumentWidth()) { 336 printNewline(); 337 for (int i = 0; 338 i < prettyPrinter.getTabulationWidth(); 339 i++) { 340 printCharacter(' '); 341 } 342 } else { 343 printCharacter(' '); 344 } 345 printCharacter(string2Delim); 346 printCharacters(string2); 347 printCharacter(string2Delim); 348 printCharacter(' '); 349 } 350 } 351 } 352 } else { 353 printString("<!DOCTYPE"); 354 355 printSpaces(space1, false); 356 printCharacters(root); 357 358 if (space2 != null) { 359 printSpaces(space2, false); 360 printString(externalId); 361 printSpaces(space3, false); 362 363 printCharacter(string1Delim); 364 printCharacters(string1); 365 printCharacter(string1Delim); 366 367 if (space4 != null) { 368 printSpaces(space4, string2 == null); 369 370 if (string2 != null) { 371 printCharacter(string2Delim); 372 printCharacters(string2); 373 printCharacter(string2Delim); 374 375 if (space5 != null) { 376 printSpaces(space5, true); 377 } 378 } 379 } 380 } 381 } 382 } 383 384 387 public void printDoctypeEnd(char[] space) throws IOException { 388 if (space != null) { 389 printSpaces(space, true); 390 } 391 printCharacter('>'); 392 } 393 394 397 public void printParameterEntityReference(char[] name) throws IOException { 398 printCharacter('%'); 399 printCharacters(name); 400 printCharacter(';'); 401 } 402 403 406 public void printEntityReference(char[] name, 407 boolean first) throws IOException { 408 if ((prettyPrinter.getFormat()) && 409 (xmlSpace.get(0) != Boolean.TRUE) && 410 first) { 411 printNewline(); 412 printString(margin.toString()); 413 } 414 printCharacter('&'); 415 printCharacters(name); 416 printCharacter(';'); 417 } 418 419 422 public void printCharacterEntityReference 423 (char[] code, boolean first, boolean preceedingSpace) 424 throws IOException { 425 if ((prettyPrinter.getFormat()) && 426 (xmlSpace.get(0) != Boolean.TRUE)) { 427 428 if (first) { 429 printNewline(); 430 printString(margin.toString()); 431 } else if (preceedingSpace) { 432 int endCol = column + code.length + 3; 433 if (endCol > prettyPrinter.getDocumentWidth()){ 434 printNewline(); 435 printString(margin.toString()); 436 } else { 437 printCharacter(' '); 438 } 439 } 440 } 441 printString("&#"); 442 printCharacters(code); 443 printCharacter(';'); 444 } 445 446 449 public void printElementStart(char[] name, List attributes, char[] space) 450 throws IOException { 451 xmlSpace.add(0, xmlSpace.get(0)); 452 453 startingLines.add(0, new Integer (line)); 454 455 if (prettyPrinter.getFormat()) { 456 if (canIndent) { 457 printNewline(); 458 printString(margin.toString()); 459 } 460 } 461 printCharacter('<'); 462 printCharacters(name); 463 464 if (prettyPrinter.getFormat()) { 465 Iterator it = attributes.iterator(); 466 if (it.hasNext()) { 467 AttributeInfo ai = (AttributeInfo)it.next(); 468 469 if (ai.isAttribute("xml:space")) { 470 xmlSpace.set(0, (ai.value.equals("preserve") 471 ? Boolean.TRUE 472 : Boolean.FALSE)); 473 } 474 475 printCharacter(' '); 476 printCharacters(ai.name); 477 printCharacter('='); 478 printCharacter(ai.delimiter); 479 printString(ai.value); 480 printCharacter(ai.delimiter); 481 } 482 while (it.hasNext()) { 483 AttributeInfo ai = (AttributeInfo)it.next(); 484 485 if (ai.isAttribute("xml:space")) { 486 xmlSpace.set(0, (ai.value.equals("preserve") 487 ? Boolean.TRUE 488 : Boolean.FALSE)); 489 } 490 491 int len = ai.name.length + ai.value.length() + 4; 492 if (lineAttributes || 493 len + column > prettyPrinter.getDocumentWidth()) { 494 printNewline(); 495 printString(margin.toString()); 496 for (int i = 0; i < name.length + 2; i++) { 497 printCharacter(' '); 498 } 499 } else { 500 printCharacter(' '); 501 } 502 printCharacters(ai.name); 503 printCharacter('='); 504 printCharacter(ai.delimiter); 505 printString(ai.value); 506 printCharacter(ai.delimiter); 507 } 508 } else { 509 Iterator it = attributes.iterator(); 510 while (it.hasNext()) { 511 AttributeInfo ai = (AttributeInfo)it.next(); 512 513 if (ai.isAttribute("xml:space")) { 514 xmlSpace.set(0, (ai.value.equals("preserve") 515 ? Boolean.TRUE 516 : Boolean.FALSE)); 517 } 518 519 printSpaces(ai.space, false); 520 printCharacters(ai.name); 521 522 if (ai.space1 != null) { 523 printSpaces(ai.space1, true); 524 } 525 printCharacter('='); 526 if (ai.space2 != null) { 527 printSpaces(ai.space2, true); 528 } 529 530 printCharacter(ai.delimiter); 531 printString(ai.value); 532 printCharacter(ai.delimiter); 533 } 534 } 535 536 if (space != null) { 537 printSpaces(space, true); 538 } 539 level++; 540 for (int i = 0; i < prettyPrinter.getTabulationWidth(); i++) { 541 margin.append(' '); 542 } 543 canIndent = true; 544 } 545 546 549 public void printElementEnd(char[] name, char[] space) throws IOException { 550 for (int i = 0; i < prettyPrinter.getTabulationWidth(); i++) { 551 margin.deleteCharAt(0); 552 } 553 level--; 554 if (name != null) { 555 if (prettyPrinter.getFormat()) { 556 if (xmlSpace.get(0) != Boolean.TRUE && 557 (line != ((Integer )startingLines.get(0)).intValue() || 558 column + name.length + 3 >= prettyPrinter.getDocumentWidth())) { 559 printNewline(); 560 printString(margin.toString()); 561 } 562 } 563 printString("</"); 564 printCharacters(name); 565 if (space != null) { 566 printSpaces(space, true); 567 } 568 printCharacter('>'); 569 } else { 570 printString("/>"); 571 } 572 startingLines.remove(0); 573 xmlSpace.remove(0); 574 } 575 576 579 public boolean printCharacterData(char[] data, 580 boolean first, 581 boolean preceedingSpace) 582 throws IOException { 583 if (!prettyPrinter.getFormat()) { 584 printCharacters(data); 585 return false; 586 } 587 588 canIndent = true; 589 if (isWhiteSpace(data)) { 590 int nl = newlines(data); 591 for (int i = 0; i < nl - 1; i++) { 592 printNewline(); 593 } 594 return true; 595 } 596 597 if (xmlSpace.get(0) == Boolean.TRUE) { 598 printCharacters(data); 599 canIndent = false; 600 return false; 601 } 602 603 if (first) { 604 printNewline(); 605 printString(margin.toString()); 606 } 607 return formatText(data, margin.toString(), preceedingSpace); 608 } 609 610 613 public void printCDATASection(char[] data) throws IOException { 614 printString("<![CDATA["); 615 printCharacters(data); 616 printString("]]>"); 617 } 618 619 622 public void printNotation(char[] space1, 623 char[] name, 624 char[] space2, 625 String externalId, 626 char[] space3, 627 char[] string1, char string1Delim, 628 char[] space4, 629 char[] string2, char string2Delim, 630 char[] space5) 631 throws IOException { 632 writer.write("<!NOTATION"); 633 printSpaces(space1, false); 634 writer.write(name); 635 printSpaces(space2, false); 636 writer.write(externalId); 637 printSpaces(space3, false); 638 639 writer.write(string1Delim); 640 writer.write(string1); 641 writer.write(string1Delim); 642 643 if (space4 != null) { 644 printSpaces(space4, false); 645 646 if (string2 != null) { 647 writer.write(string2Delim); 648 writer.write(string2); 649 writer.write(string2Delim); 650 } 651 } 652 if (space5 != null) { 653 printSpaces(space5, true); 654 } 655 writer.write('>'); 656 } 657 658 661 public void printAttlistStart(char[] space, char[] name) throws IOException { 662 writer.write("<!ATTLIST"); 663 printSpaces(space, false); 664 writer.write(name); 665 } 666 667 670 public void printAttlistEnd(char[] space) throws IOException { 671 if (space != null) { 672 printSpaces(space, false); 673 } 674 writer.write('>'); 675 } 676 677 680 public void printAttName(char[] space1, char[] name, char[] space2) 681 throws IOException { 682 printSpaces(space1, false); 683 writer.write(name); 684 printSpaces(space2, false); 685 } 686 687 690 public void printEnumeration(List names) throws IOException { 691 writer.write('('); 692 693 Iterator it = names.iterator(); 694 NameInfo ni = (NameInfo)it.next(); 695 if (ni.space1 != null) { 696 printSpaces(ni.space1, true); 697 } 698 699 writer.write(ni.name); 700 701 if (ni.space2 != null) { 702 printSpaces(ni.space2, true); 703 } 704 while (it.hasNext()) { 705 writer.write('|'); 706 707 ni = (NameInfo)it.next(); 708 if (ni.space1 != null) { 709 printSpaces(ni.space1, true); 710 } 711 712 writer.write(ni.name); 713 714 if (ni.space2 != null) { 715 printSpaces(ni.space2, true); 716 } 717 } 718 719 writer.write(')'); 720 } 721 722 725 protected int newlines(char[] text) { 726 int result = 0; 727 for (int i = 0; i < text.length; i++) { 728 if (text[i] == 10) { 729 result++; 730 } 731 } 732 return result; 733 } 734 735 738 protected boolean isWhiteSpace(char[] text) { 739 for (int i = 0; i < text.length; i++) { 740 if (!XMLUtilities.isXMLSpace(text[i])) { 741 return false; 742 } 743 } 744 return true; 745 } 746 747 750 protected boolean formatText(char[] text, String margin, 751 boolean preceedingSpace) throws IOException { 752 int i = 0; 753 boolean startsWithSpace = preceedingSpace; 754 loop: while (i < text.length) { 755 for (;;) { 756 if (i >= text.length) { 757 break loop; 758 } 759 if (!XMLUtilities.isXMLSpace(text[i])) { 760 break; 761 } 762 startsWithSpace = true; 763 i++; 764 } 765 StringBuffer sb = new StringBuffer (); 766 for (;;) { 767 if (i >= text.length || XMLUtilities.isXMLSpace(text[i])) { 768 break; 769 } 770 sb.append(text[i++]); 771 } 772 if (sb.length() == 0) { 773 return startsWithSpace; 774 } 775 if (startsWithSpace) { 776 int endCol = column + sb.length(); 778 if ((endCol >= prettyPrinter.getDocumentWidth() - 1) && 779 ((margin.length() + sb.length() < 780 prettyPrinter.getDocumentWidth() - 1) || 781 (margin.length() < column))) { 782 printNewline(); 783 printString(margin); 784 } else if (column > margin.length()) { 785 printCharacter(' '); 787 } 788 } 789 printString(sb.toString()); 790 startsWithSpace = false; 791 } 792 return startsWithSpace; 793 } 794 795 798 public static class NameInfo { 799 800 803 public char[] space1; 804 805 808 public char[] name; 809 810 813 public char[] space2; 814 815 818 public NameInfo(char[] sp1, char[] nm, char[] sp2) { 819 space1 = sp1; 820 name = nm; 821 space2 = sp2; 822 } 823 } 824 825 828 public static class AttributeInfo { 829 830 833 public char[] space; 834 835 838 public char[] name; 839 840 843 public char[] space1; 844 845 848 public char[] space2; 849 850 853 public String value; 854 855 858 public char delimiter; 859 860 863 public boolean entityReferences; 864 865 868 public AttributeInfo(char[] sp, char[] n, char[] sp1, char[] sp2, 869 String val, char delim, boolean entity) { 870 space = sp; 871 name = n; 872 space1 = sp1; 873 space2 = sp2; 874 value = val; 875 delimiter = delim; 876 entityReferences = entity; 877 } 878 879 883 public boolean isAttribute(String s) { 884 if (name.length == s.length()) { 885 for (int i = 0; i < name.length; i++) { 886 if (name[i] != s.charAt(i)) { 887 return false; 888 } 889 } 890 return true; 891 } 892 return false; 893 } 894 } 895 } 896 | Popular Tags |