KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > transcoder > svg2svg > OutputManager


1 /*
2
3    Copyright 2001-2002 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    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
17  */

18 package org.apache.batik.transcoder.svg2svg;
19
20 import java.io.IOException JavaDoc;
21 import java.io.Writer JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.apache.batik.xml.XMLUtilities;
27
28 /**
29  * This class is responsible of the output of XML constructs.
30  *
31  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
32  * @version $Id: OutputManager.java,v 1.10 2005/03/27 08:58:36 cam Exp $
33  */

34 public class OutputManager {
35
36     /**
37      * The pretty printer.
38      */

39     protected PrettyPrinter prettyPrinter;
40
41     /**
42      * The writer used to output the tokens.
43      */

44     protected Writer JavaDoc writer;
45
46     /**
47      * The indentation level.
48      */

49     protected int level;
50
51     /**
52      * The margin.
53      */

54     protected StringBuffer JavaDoc margin = new StringBuffer JavaDoc();
55
56     /**
57      * The current line.
58      */

59     protected int line = 1;
60
61     /**
62      * The current column.
63      */

64     protected int column;
65
66     /**
67      * The xml:space values.
68      */

69     protected List JavaDoc xmlSpace = new LinkedList JavaDoc();
70     {
71         xmlSpace.add(Boolean.FALSE);
72     }
73
74     /**
75      * Whether the next markup can be indented.
76      */

77     protected boolean canIndent = true;
78
79     /**
80      * The elements starting lines.
81      */

82     protected List JavaDoc startingLines = new LinkedList JavaDoc();
83
84     /**
85      * Whether the attribute layout must be done on a single line.
86      */

87     protected boolean lineAttributes = false;
88
89     /**
90      * Creates a new output manager.
91      * @param pp The PrettyPrinter used for formatting the output.
92      * @param w The Writer to write the output to.
93      */

94     public OutputManager(PrettyPrinter pp, Writer JavaDoc w) {
95         prettyPrinter = pp;
96         writer = w;
97     }
98
99     /**
100      * Prints a single character.
101      */

102     public void printCharacter(char c) throws IOException JavaDoc {
103         if (c == 10) {
104             printNewline();
105         } else {
106             column++;
107             writer.write(c);
108         }
109     }
110
111     /**
112      * Prints a newline.
113      */

114     public void printNewline() throws IOException JavaDoc {
115         String JavaDoc 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     /**
124      * Prints a string.
125      */

126     public void printString(String JavaDoc s) throws IOException JavaDoc {
127         for (int i = 0; i < s.length(); i++) {
128             printCharacter(s.charAt(i));
129         }
130     }
131
132     /**
133      * Prints a char array.
134      */

135     public void printCharacters(char[] ca) throws IOException JavaDoc {
136         for (int i = 0; i < ca.length; i++) {
137             printCharacter(ca[i]);
138         }
139     }
140
141     /**
142      * Prints white spaces.
143      * @param text The space text.
144      * @param opt whether the space is optional.
145      */

146     public void printSpaces(char[] text, boolean opt) throws IOException JavaDoc {
147         if (prettyPrinter.getFormat()) {
148             if (!opt) {
149                 printCharacter(' ');
150             }
151         } else {
152             printCharacters(text);
153         }
154     }
155
156     /**
157      * Prints top level white spaces.
158      * @param text The space text.
159      */

160     public void printTopSpaces(char[] text) throws IOException JavaDoc {
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     /**
172      * Prints a comment.
173      * @param text The comment text.
174      */

175     public void printComment(char[] text) throws IOException JavaDoc {
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     /**
201      * Prints an XML declaration.
202      */

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 JavaDoc {
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     /**
289      * Prints a processing instruction.
290      */

291     public void printPI(char[] target, char[] space, char[] data) throws IOException JavaDoc {
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     /**
306      * Prints the portion of the doctype before '['.
307      */

308     public void printDoctypeStart(char[] space1,
309                                   char[] root,
310                                   char[] space2,
311                                   String JavaDoc externalId,
312                                   char[] space3,
313                                   char[] string1, char string1Delim,
314                                   char[] space4,
315                                   char[] string2, char string2Delim,
316                                   char[] space5) throws IOException JavaDoc {
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     /**
385      * Prints the portion of the doctype after ']'.
386      */

387     public void printDoctypeEnd(char[] space) throws IOException JavaDoc {
388         if (space != null) {
389             printSpaces(space, true);
390         }
391         printCharacter('>');
392     }
393
394     /**
395      * Prints a parameter entity reference.
396      */

397     public void printParameterEntityReference(char[] name) throws IOException JavaDoc {
398         printCharacter('%');
399         printCharacters(name);
400         printCharacter(';');
401     }
402
403     /**
404      * Prints an entity reference.
405      */

406     public void printEntityReference(char[] name,
407                                      boolean first) throws IOException JavaDoc {
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     /**
420      * Prints a character entity reference.
421      */

422     public void printCharacterEntityReference
423         (char[] code, boolean first, boolean preceedingSpace)
424         throws IOException JavaDoc {
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     /**
447      * Prints the start of an element.
448      */

449     public void printElementStart(char[] name, List JavaDoc attributes, char[] space)
450         throws IOException JavaDoc {
451         xmlSpace.add(0, xmlSpace.get(0));
452
453         startingLines.add(0, new Integer JavaDoc(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 JavaDoc 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 JavaDoc 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     /**
547      * Prints the end of an element.
548      */

549     public void printElementEnd(char[] name, char[] space) throws IOException JavaDoc {
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 JavaDoc)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     /**
577      * Prints the character data of an element content.
578      */

579     public boolean printCharacterData(char[] data,
580                                       boolean first,
581                                       boolean preceedingSpace)
582         throws IOException JavaDoc {
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     /**
611      * Prints a CDATA section.
612      */

613     public void printCDATASection(char[] data) throws IOException JavaDoc {
614         printString("<![CDATA[");
615         printCharacters(data);
616         printString("]]>");
617     }
618
619     /**
620      * Prints a notation declaration.
621      */

622     public void printNotation(char[] space1,
623                               char[] name,
624                               char[] space2,
625                               String JavaDoc externalId,
626                               char[] space3,
627                               char[] string1, char string1Delim,
628                               char[] space4,
629                               char[] string2, char string2Delim,
630                               char[] space5)
631         throws IOException JavaDoc {
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     /**
659      * Prints an attribute list declaration start.
660      */

661     public void printAttlistStart(char[] space, char[] name) throws IOException JavaDoc {
662         writer.write("<!ATTLIST");
663         printSpaces(space, false);
664         writer.write(name);
665     }
666
667     /**
668      * Prints an attribute list declaration end.
669      */

670     public void printAttlistEnd(char[] space) throws IOException JavaDoc {
671         if (space != null) {
672             printSpaces(space, false);
673         }
674         writer.write('>');
675     }
676
677     /**
678      * Prints an attribute declaration start.
679      */

680     public void printAttName(char[] space1, char[] name, char[] space2)
681         throws IOException JavaDoc {
682         printSpaces(space1, false);
683         writer.write(name);
684         printSpaces(space2, false);
685     }
686
687     /**
688      * Prints an enumeration.
689      */

690     public void printEnumeration(List JavaDoc names) throws IOException JavaDoc {
691         writer.write('(');
692
693         Iterator JavaDoc 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     /**
723      * Returns the number of newlines in the given char array.
724      */

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     /**
736      * Tells whether the given character represents white spaces.
737      */

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     /**
748      * Formats the given text.
749      */

750     protected boolean formatText(char[] text, String JavaDoc margin,
751                                  boolean preceedingSpace) throws IOException JavaDoc {
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 JavaDoc sb = new StringBuffer JavaDoc();
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                 // Consider reformatting ws so things look nicer.
777
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                     // Don't print space at start of new line.
786
printCharacter(' ');
787                 }
788             }
789             printString(sb.toString());
790             startsWithSpace = false;
791         }
792         return startsWithSpace;
793     }
794
795     /**
796      * To store the informations about a name.
797      */

798     public static class NameInfo {
799         
800         /**
801          * The space before the name.
802          */

803         public char[] space1;
804
805         /**
806          * The name.
807          */

808         public char[] name;
809
810         /**
811          * The space after the name
812          */

813         public char[] space2;
814
815         /**
816          * Creates a new NameInfo.
817          */

818         public NameInfo(char[] sp1, char[] nm, char[] sp2) {
819             space1 = sp1;
820             name = nm;
821             space2 = sp2;
822         }
823     }
824
825     /**
826      * To store the informations about an attribute.
827      */

828     public static class AttributeInfo {
829
830         /**
831          * The space before the name.
832          */

833         public char[] space;
834
835         /**
836          * The attribute name.
837          */

838         public char[] name;
839
840         /**
841          * The space before '='.
842          */

843         public char[] space1;
844
845         /**
846          * The space after '='.
847          */

848         public char[] space2;
849
850         /**
851          * The attribute value.
852          */

853         public String JavaDoc value;
854
855         /**
856          * The attribute value delimiter.
857          */

858         public char delimiter;
859
860         /**
861          * Whether the attribute value contains entity references.
862          */

863         public boolean entityReferences;
864
865         /**
866          * Creates a new AttributeInfo.
867          */

868         public AttributeInfo(char[] sp, char[] n, char[] sp1, char[] sp2,
869                              String JavaDoc 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         /**
880          * Tells whether the name of the attribute represented by this class
881          * equals the given string.
882          */

883         public boolean isAttribute(String JavaDoc 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