KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Copyright 2001-2003 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.Reader JavaDoc;
22 import java.io.Writer JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.apache.batik.transcoder.ErrorHandler;
27 import org.apache.batik.transcoder.TranscoderException;
28 import org.apache.batik.util.SVGConstants;
29 import org.apache.batik.xml.LexicalUnits;
30 import org.apache.batik.xml.XMLException;
31 import org.apache.batik.xml.XMLScanner;
32
33 /**
34  * This class represents an SVG source files pretty-printer.
35  *
36  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
37  * @version $Id: PrettyPrinter.java,v 1.9 2005/03/15 11:24:35 deweese Exp $
38  */

39 public class PrettyPrinter {
40
41     // The doctype options.
42
public final static int DOCTYPE_CHANGE = 0;
43     public final static int DOCTYPE_REMOVE = 1;
44     public final static int DOCTYPE_KEEP_UNCHANGED = 2;
45
46     /**
47      * The document scanner.
48      */

49     protected XMLScanner scanner;
50
51     /**
52      * The output manager.
53      */

54     protected OutputManager output;
55
56     /**
57      * The writer used to output the document.
58      */

59     protected Writer JavaDoc writer;
60
61     /**
62      * The error handler.
63      */

64     protected ErrorHandler errorHandler = SVGTranscoder.DEFAULT_ERROR_HANDLER;
65
66     /**
67      * The newline characters.
68      */

69     protected String JavaDoc newline = "\n";
70
71     /**
72      * Whether the output must be formatted.
73      */

74     protected boolean format = true;
75
76     /**
77      * The tabulation width.
78      */

79     protected int tabulationWidth = 4;
80
81     /**
82      * The document width.
83      */

84     protected int documentWidth = 80;
85
86     /**
87      * The doctype option.
88      */

89     protected int doctypeOption = DOCTYPE_KEEP_UNCHANGED;
90
91     /**
92      * The public id.
93      */

94     protected String JavaDoc publicId;
95
96     /**
97      * The system id.
98      */

99     protected String JavaDoc systemId;
100
101     /**
102      * The XML declaration.
103      */

104     protected String JavaDoc xmlDeclaration;
105
106     /**
107      * The type of the current lexical unit.
108      */

109     protected int type;
110
111     /**
112      * Sets the XML declaration text.
113      */

114     public void setXMLDeclaration(String JavaDoc s) {
115         xmlDeclaration = s;
116     }
117
118     /**
119      * Sets the doctype option.
120      */

121     public void setDoctypeOption(int i) {
122         doctypeOption = i;
123     }
124
125     /**
126      * Sets the public ID.
127      */

128     public void setPublicId(String JavaDoc s) {
129         publicId = s;
130     }
131
132     /**
133      * Sets the system ID.
134      */

135     public void setSystemId(String JavaDoc s) {
136         systemId = s;
137     }
138
139     /**
140      * Sets the newline characters.
141      */

142     public void setNewline(String JavaDoc s) {
143         newline = s;
144     }
145
146     /**
147      * Returns the newline characters.
148      */

149     public String JavaDoc getNewline() {
150         return newline;
151     }
152
153     /**
154      * Sets the format attribute.
155      */

156     public void setFormat(boolean b) {
157         format = b;
158     }
159
160     /**
161      * Returns whether the output must be formatted.
162      */

163     public boolean getFormat() {
164         return format;
165     }
166
167     /**
168      * Sets the tabulation width.
169      */

170     public void setTabulationWidth(int i) {
171         tabulationWidth = Math.max(i, 0);
172     }
173
174     /**
175      * Returns whether the tabulation width.
176      */

177     public int getTabulationWidth() {
178         return tabulationWidth;
179     }
180
181     /**
182      * Sets the document width.
183      */

184     public void setDocumentWidth(int i) {
185         documentWidth = Math.max(i, 0);
186     }
187
188     /**
189      * Returns whether the document width.
190      */

191     public int getDocumentWidth() {
192         return documentWidth;
193     }
194
195     /**
196      * Prints an SVG document from the given reader to the given writer.
197      */

198     public void print(Reader JavaDoc r, Writer JavaDoc w) throws TranscoderException,
199                                                  IOException JavaDoc {
200         try {
201             scanner = new XMLScanner(r);
202             output = new OutputManager(this, w);
203             writer = w;
204             type = scanner.next();
205
206             printXMLDecl();
207
208             misc1: for (;;) {
209                 switch (type) {
210                 case LexicalUnits.S:
211                     output.printTopSpaces(getCurrentValue());
212                     scanner.clearBuffer();
213                     type = scanner.next();
214                     break;
215                 case LexicalUnits.COMMENT:
216                     output.printComment(getCurrentValue());
217                     scanner.clearBuffer();
218                     type = scanner.next();
219                     break;
220                 case LexicalUnits.PI_START:
221                     printPI();
222                     break;
223                 default:
224                     break misc1;
225                 }
226             }
227
228             printDoctype();
229
230             misc2: for (;;) {
231                 scanner.clearBuffer();
232                 switch (type) {
233                 case LexicalUnits.S:
234                     output.printTopSpaces(getCurrentValue());
235                     scanner.clearBuffer();
236                     type = scanner.next();
237                     break;
238                 case LexicalUnits.COMMENT:
239                     output.printComment(getCurrentValue());
240                     scanner.clearBuffer();
241                     type = scanner.next();
242                     break;
243                 case LexicalUnits.PI_START:
244                     printPI();
245                     break;
246                 default:
247                     break misc2;
248                 }
249             }
250
251             if (type != LexicalUnits.START_TAG) {
252                 throw fatalError("element", null);
253             }
254             
255             printElement();
256
257             misc3: for (;;) {
258                 switch (type) {
259                 case LexicalUnits.S:
260                     output.printTopSpaces(getCurrentValue());
261                     scanner.clearBuffer();
262                     type = scanner.next();
263                     break;
264                 case LexicalUnits.COMMENT:
265                     output.printComment(getCurrentValue());
266                     scanner.clearBuffer();
267                     type = scanner.next();
268                     break;
269                 case LexicalUnits.PI_START:
270                     printPI();
271                     break;
272                 default:
273                     break misc3;
274                 }
275             }
276         } catch (XMLException e) {
277             errorHandler.fatalError(new TranscoderException(e.getMessage()));
278         }
279     }
280
281     /**
282      * Prints the XML declaration.
283      */

284     protected void printXMLDecl()
285         throws TranscoderException,
286                XMLException,
287                IOException JavaDoc {
288         if (xmlDeclaration == null) {
289             if (type == LexicalUnits.XML_DECL_START) {
290                 if (scanner.next() != LexicalUnits.S) {
291                     throw fatalError("space", null);
292                 }
293                 char[] space1 = getCurrentValue();
294                 
295                 if (scanner.next() != LexicalUnits.VERSION_IDENTIFIER) {
296                     throw fatalError("token", new Object JavaDoc[] { "version" });
297                 }
298                 type = scanner.next();
299             
300                 char[] space2 = null;
301                 if (type == LexicalUnits.S) {
302                     space2 = getCurrentValue();
303                     type = scanner.next();
304                 }
305                 if (type != LexicalUnits.EQ) {
306                     throw fatalError("token", new Object JavaDoc[] { "=" });
307                 }
308                 type = scanner.next();
309                 
310                 char[] space3 = null;
311                 if (type == LexicalUnits.S) {
312                     space3 = getCurrentValue();
313                     type = scanner.next();
314                 }
315                 
316                 if (type != LexicalUnits.STRING) {
317                     throw fatalError("string", null);
318                 }
319
320                 char[] version = getCurrentValue();
321                 char versionDelim = scanner.getStringDelimiter();
322
323                 char[] space4 = null;
324                 char[] space5 = null;
325                 char[] space6 = null;
326                 char[] encoding = null;
327                 char encodingDelim = 0;
328                 char[] space7 = null;
329                 char[] space8 = null;
330                 char[] space9 = null;
331                 char[] standalone = null;
332                 char standaloneDelim = 0;
333                 char[] space10 = null;
334                 
335                 type = scanner.next();
336                 if (type == LexicalUnits.S) {
337                     space4 = getCurrentValue();
338                     type = scanner.next();
339                     
340                     if (type == LexicalUnits.ENCODING_IDENTIFIER) {
341                         type = scanner.next();
342                         if (type == LexicalUnits.S) {
343                             space5 = getCurrentValue();
344                             type = scanner.next();
345                         }
346                         if (type != LexicalUnits.EQ) {
347                             throw fatalError("token", new Object JavaDoc[] { "=" });
348                         }
349                         type = scanner.next();
350                         if (type == LexicalUnits.S) {
351                             space6 = getCurrentValue();
352                             type = scanner.next();
353                         }
354                         if (type != LexicalUnits.STRING) {
355                             throw fatalError("string", null);
356                         }
357
358                         encoding = getCurrentValue();
359                         encodingDelim = scanner.getStringDelimiter();
360
361                         type = scanner.next();
362                         if (type == LexicalUnits.S) {
363                             space7 = getCurrentValue();
364                             type = scanner.next();
365                         }
366                     }
367             
368                     if (type == LexicalUnits.STANDALONE_IDENTIFIER) {
369                         type = scanner.next();
370                         if (type == LexicalUnits.S) {
371                             space8 = getCurrentValue();
372                             type = scanner.next();
373                         }
374                         if (type != LexicalUnits.EQ) {
375                             throw fatalError("token", new Object JavaDoc[] { "=" });
376                         }
377                         type = scanner.next();
378                         if (type == LexicalUnits.S) {
379                             space9 = getCurrentValue();
380                             type = scanner.next();
381                         }
382                         if (type != LexicalUnits.STRING) {
383                             throw fatalError("string", null);
384                         }
385                         
386                         standalone = getCurrentValue();
387                         standaloneDelim = scanner.getStringDelimiter();
388                         
389                         type = scanner.next();
390                         if (type == LexicalUnits.S) {
391                             space10 = getCurrentValue();
392                             type = scanner.next();
393                         }
394                     }
395                 }
396                 if (type != LexicalUnits.PI_END) {
397                     throw fatalError("pi.end", null);
398                 }
399
400                 output.printXMLDecl(space1, space2, space3,
401                                     version, versionDelim,
402                                     space4, space5, space6,
403                                     encoding, encodingDelim,
404                                     space7, space8, space9,
405                                     standalone, standaloneDelim,
406                                     space10);
407
408                 type = scanner.next();
409             }
410         } else {
411             output.printString(xmlDeclaration);
412             output.printNewline();
413
414             if (type == LexicalUnits.XML_DECL_START) {
415                 // Skip the XML declaraction.
416
if (scanner.next() != LexicalUnits.S) {
417                     throw fatalError("space", null);
418                 }
419                 
420                 if (scanner.next() != LexicalUnits.VERSION_IDENTIFIER) {
421                     throw fatalError("token", new Object JavaDoc[] { "version" });
422                 }
423                 type = scanner.next();
424             
425                 if (type == LexicalUnits.S) {
426                     type = scanner.next();
427                 }
428                 if (type != LexicalUnits.EQ) {
429                     throw fatalError("token", new Object JavaDoc[] { "=" });
430                 }
431                 type = scanner.next();
432                 
433                 if (type == LexicalUnits.S) {
434                     type = scanner.next();
435                 }
436                 
437                 if (type != LexicalUnits.STRING) {
438                     throw fatalError("string", null);
439                 }
440
441                 type = scanner.next();
442                 if (type == LexicalUnits.S) {
443                     type = scanner.next();
444                     
445                     if (type == LexicalUnits.ENCODING_IDENTIFIER) {
446                         type = scanner.next();
447                         if (type == LexicalUnits.S) {
448                             type = scanner.next();
449                         }
450                         if (type != LexicalUnits.EQ) {
451                             throw fatalError("token", new Object JavaDoc[] { "=" });
452                         }
453                         type = scanner.next();
454                         if (type == LexicalUnits.S) {
455                             type = scanner.next();
456                         }
457                         if (type != LexicalUnits.STRING) {
458                             throw fatalError("string", null);
459                         }
460
461                         type = scanner.next();
462                         if (type == LexicalUnits.S) {
463                             type = scanner.next();
464                         }
465                     }
466             
467                     if (type == LexicalUnits.STANDALONE_IDENTIFIER) {
468                         type = scanner.next();
469                         if (type == LexicalUnits.S) {
470                             type = scanner.next();
471                         }
472                         if (type != LexicalUnits.EQ) {
473                             throw fatalError("token", new Object JavaDoc[] { "=" });
474                         }
475                         type = scanner.next();
476                         if (type == LexicalUnits.S) {
477                             type = scanner.next();
478                         }
479                         if (type != LexicalUnits.STRING) {
480                             throw fatalError("string", null);
481                         }
482                         
483                         type = scanner.next();
484                         if (type == LexicalUnits.S) {
485                             type = scanner.next();
486                         }
487                     }
488                 }
489                 if (type != LexicalUnits.PI_END) {
490                     throw fatalError("pi.end", null);
491                 }
492
493                 type = scanner.next();
494             }
495         }
496     }
497
498     /**
499      * Prints a processing instruction.
500      */

501     protected void printPI()
502         throws TranscoderException,
503                XMLException,
504                IOException JavaDoc {
505         char[] target = getCurrentValue();
506
507         type = scanner.next();
508         char[] space = {};
509         if (type == LexicalUnits.S) {
510             space = getCurrentValue();
511             type = scanner.next();
512         }
513         if (type != LexicalUnits.PI_DATA) {
514             throw fatalError("pi.data", null);
515         }
516         char[] data = getCurrentValue();
517
518         type = scanner.next();
519         if (type != LexicalUnits.PI_END) {
520             throw fatalError("pi.end", null);
521         }
522
523         output.printPI(target, space, data);
524
525         type = scanner.next();
526     }
527
528     /**
529      * Prints the doctype.
530      */

531     protected void printDoctype()
532         throws TranscoderException,
533                XMLException,
534                IOException JavaDoc {
535         switch (doctypeOption) {
536         default:
537             if (type == LexicalUnits.DOCTYPE_START) {
538                 type = scanner.next();
539
540                 if (type != LexicalUnits.S) {
541                     throw fatalError("space", null);
542                 }
543                 char[] space1 = getCurrentValue();
544                 type = scanner.next();
545                 
546                 if (type != LexicalUnits.NAME) {
547                     throw fatalError("name", null);
548                 }
549
550                 char[] root = getCurrentValue();
551                 char[] space2 = null;
552                 String JavaDoc externalId = null;
553                 char[] space3 = null;
554                 char[] string1 = null;
555                 char string1Delim = 0;
556                 char[] space4 = null;
557                 char[] string2 = null;
558                 char string2Delim = 0;
559                 char[] space5 = null;
560
561                 type = scanner.next();
562                 if (type == LexicalUnits.S) {
563                     space2 = getCurrentValue();
564                     type = scanner.next();
565                     
566                     switch (type) {
567                     case LexicalUnits.PUBLIC_IDENTIFIER:
568                         externalId = "PUBLIC";
569                         
570                         type = scanner.next();
571                         if (type != LexicalUnits.S) {
572                             throw fatalError("space", null);
573                         }
574                         space3 = getCurrentValue();
575                         type = scanner.next();
576                         
577                         if (type != LexicalUnits.STRING) {
578                             throw fatalError("string", null);
579                         }
580                     
581                         string1 = getCurrentValue();
582                         string1Delim = scanner.getStringDelimiter();
583
584                         type = scanner.next();
585                         if (type != LexicalUnits.S) {
586                             throw fatalError("space", null);
587                         }
588                         space4 = getCurrentValue();
589                         type = scanner.next();
590                         
591                         if (type != LexicalUnits.STRING) {
592                             throw fatalError("string", null);
593                         }
594
595                         string2 = getCurrentValue();
596                         string2Delim = scanner.getStringDelimiter();
597
598                         type = scanner.next();
599                         if (type == LexicalUnits.S) {
600                             space5 = getCurrentValue();
601                             type = scanner.next();
602                         }
603                         break;
604                     case LexicalUnits.SYSTEM_IDENTIFIER:
605                         externalId = "SYSTEM";
606                         
607                         type = scanner.next();
608                         if (type != LexicalUnits.S) {
609                             throw fatalError("space", null);
610                         }
611                         space3 = getCurrentValue();
612                         type = scanner.next();
613
614                         if (type != LexicalUnits.STRING) {
615                             throw fatalError("string", null);
616                         }
617
618                         string1 = getCurrentValue();
619                         string1Delim = scanner.getStringDelimiter();
620
621                         type = scanner.next();
622                         if (type == LexicalUnits.S) {
623                             space4 = getCurrentValue();
624                             type = scanner.next();
625                         }
626                     }
627                 }
628
629                 if (doctypeOption == DOCTYPE_CHANGE) {
630                     if (publicId != null) {
631                         externalId = "PUBLIC";
632                         string1 = publicId.toCharArray();
633                         string1Delim = '"';
634                         if (systemId != null) {
635                             string2 = systemId.toCharArray();
636                             string2Delim = '"';
637                         }
638                     } else if (systemId != null) {
639                         externalId = "SYSTEM";
640                         string1 = systemId.toCharArray();
641                         string1Delim = '"';
642                         string2 = null;
643                     }
644                 }
645                 output.printDoctypeStart(space1, root, space2,
646                                          externalId, space3,
647                                          string1, string1Delim,
648                                          space4,
649                                          string2, string2Delim,
650                                          space5);
651
652                 if (type == LexicalUnits.LSQUARE_BRACKET) {
653                     output.printCharacter('[');
654                     type = scanner.next();
655                     
656                     dtd: for (;;) {
657                         switch (type) {
658                         case LexicalUnits.S:
659                             output.printSpaces(getCurrentValue(), true);
660                             scanner.clearBuffer();
661                             type = scanner.next();
662                             break;
663                         case LexicalUnits.COMMENT:
664                             output.printComment(getCurrentValue());
665                             scanner.clearBuffer();
666                             type = scanner.next();
667                             break;
668                         case LexicalUnits.PI_START:
669                             printPI();
670                             break;
671                         case LexicalUnits.PARAMETER_ENTITY_REFERENCE:
672                             output.printParameterEntityReference(getCurrentValue());
673                             scanner.clearBuffer();
674                             type = scanner.next();
675                             break;
676                         case LexicalUnits.ELEMENT_DECLARATION_START:
677                             scanner.clearBuffer();
678                             printElementDeclaration();
679                             break;
680                         case LexicalUnits.ATTLIST_START:
681                             scanner.clearBuffer();
682                             printAttlist();
683                             break;
684                         case LexicalUnits.NOTATION_START:
685                             scanner.clearBuffer();
686                             printNotation();
687                             break;
688                         case LexicalUnits.ENTITY_START:
689                             scanner.clearBuffer();
690                             printEntityDeclaration();
691                             break;
692                         case LexicalUnits.RSQUARE_BRACKET:
693                             output.printCharacter(']');
694                             scanner.clearBuffer();
695                             type = scanner.next();
696                             break dtd;
697                         default:
698                             throw fatalError("xml", null);
699                         }
700                     }
701                 }
702                 char[] endSpace = null;
703                 if (type == LexicalUnits.S) {
704                     endSpace = getCurrentValue();
705                     type = scanner.next();
706                 }
707
708                 if (type != LexicalUnits.END_CHAR) {
709                     throw fatalError("end", null);
710                 }
711                 type = scanner.next();
712                 output.printDoctypeEnd(endSpace);
713             } else {
714                 if (doctypeOption == DOCTYPE_CHANGE) {
715                     String JavaDoc externalId = "PUBLIC";
716                     char[] string1 = SVGConstants.SVG_PUBLIC_ID.toCharArray();
717                     char[] string2 = SVGConstants.SVG_SYSTEM_ID.toCharArray();
718                     if (publicId != null) {
719                         string1 = publicId.toCharArray();
720                         if (systemId != null) {
721                             string2 = systemId.toCharArray();
722                         }
723                     } else if (systemId != null) {
724                         externalId = "SYSTEM";
725                         string1 = systemId.toCharArray();
726                         string2 = null;
727                     }
728                     output.printDoctypeStart(new char[] { ' ' },
729                                              new char[] { 's', 'v', 'g' },
730                                              new char[] { ' ' },
731                                              externalId,
732                                              new char[] { ' ' },
733                                              string1, '"',
734                                              new char[] { ' ' },
735                                              string2, '"',
736                                              null);
737                     output.printDoctypeEnd(null);
738                 }
739             }
740
741             break;
742
743         case DOCTYPE_REMOVE:
744             if (type == LexicalUnits.DOCTYPE_START) {
745                 type = scanner.next();
746
747                 if (type != LexicalUnits.S) {
748                     throw fatalError("space", null);
749                 }
750                 type = scanner.next();
751                 
752                 if (type != LexicalUnits.NAME) {
753                     throw fatalError("name", null);
754                 }
755
756                 type = scanner.next();
757                 if (type == LexicalUnits.S) {
758                     type = scanner.next();
759                     
760                     switch (type) {
761                     case LexicalUnits.PUBLIC_IDENTIFIER:
762                         
763                         type = scanner.next();
764                         if (type != LexicalUnits.S) {
765                             throw fatalError("space", null);
766                         }
767                         type = scanner.next();
768                         
769                         if (type != LexicalUnits.STRING) {
770                             throw fatalError("string", null);
771                         }
772                     
773                         type = scanner.next();
774                         if (type != LexicalUnits.S) {
775                             throw fatalError("space", null);
776                         }
777                         type = scanner.next();
778                         
779                         if (type != LexicalUnits.STRING) {
780                             throw fatalError("string", null);
781                         }
782
783                         type = scanner.next();
784                         if (type == LexicalUnits.S) {
785                             type = scanner.next();
786                         }
787                         break;
788                     case LexicalUnits.SYSTEM_IDENTIFIER:
789                         
790                         type = scanner.next();
791                         if (type != LexicalUnits.S) {
792                             throw fatalError("space", null);
793                         }
794                         type = scanner.next();
795
796                         if (type != LexicalUnits.STRING) {
797                             throw fatalError("string", null);
798                         }
799
800                         type = scanner.next();
801                         if (type == LexicalUnits.S) {
802                             type = scanner.next();
803                         }
804                     }
805                 }
806
807                 if (type == LexicalUnits.LSQUARE_BRACKET) {
808                     do {
809                         type = scanner.next();
810                     } while (type != LexicalUnits.RSQUARE_BRACKET);
811                 }
812                 if (type == LexicalUnits.S) {
813                     type = scanner.next();
814                 }
815
816                 if (type != LexicalUnits.END_CHAR) {
817                     throw fatalError("end", null);
818                 }
819             }
820             type = scanner.next();
821         }
822     }
823
824     /**
825      * Prints an element.
826      */

827     protected String JavaDoc printElement()
828         throws TranscoderException,
829                XMLException,
830                IOException JavaDoc {
831         char[] name = getCurrentValue();
832         String JavaDoc nameStr = new String JavaDoc(name);
833         List JavaDoc attributes = new LinkedList JavaDoc();
834         char[] space = null;
835
836         type = scanner.next();
837         while (type == LexicalUnits.S) {
838             space = getCurrentValue();
839
840             type = scanner.next();
841             if (type == LexicalUnits.NAME) {
842                 char[] attName = getCurrentValue();
843                 char[] space1 = null;
844
845                 type = scanner.next();
846                 if (type == LexicalUnits.S) {
847                     space1 = getCurrentValue();
848                     type = scanner.next();
849                 }
850                 if (type != LexicalUnits.EQ) {
851                     throw fatalError("token", new Object JavaDoc[] { "=" });
852                 }
853                 type = scanner.next();
854
855                 char[] space2 = null;
856                 if (type == LexicalUnits.S) {
857                     space2 = getCurrentValue();
858                     type = scanner.next();
859                 }
860                 if (type != LexicalUnits.STRING &&
861                     type != LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT) {
862                     throw fatalError("string", null);
863                 }
864
865                 char valueDelim = scanner.getStringDelimiter();
866                 boolean hasEntityRef = false;
867
868                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
869                 sb.append(getCurrentValue());
870                 loop: for (;;) {
871                     scanner.clearBuffer();
872                     type = scanner.next();
873                     switch (type) {
874                     case LexicalUnits.STRING:
875                     case LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT:
876                     case LexicalUnits.LAST_ATTRIBUTE_FRAGMENT:
877                     case LexicalUnits.ATTRIBUTE_FRAGMENT:
878                         sb.append(getCurrentValue());
879                         break;
880                     case LexicalUnits.CHARACTER_REFERENCE:
881                         hasEntityRef = true;
882                         sb.append("&#");
883                         sb.append(getCurrentValue());
884                         sb.append(";");
885                         break;
886                     case LexicalUnits.ENTITY_REFERENCE:
887                         hasEntityRef = true;
888                         sb.append("&");
889                         sb.append(getCurrentValue());
890                         sb.append(";");
891                         break;
892                     default:
893                         break loop;
894                     }
895                 }
896
897                 attributes.add(new OutputManager.AttributeInfo(space,
898                                                                attName,
899                                                                space1, space2,
900                                                                new String JavaDoc(sb),
901                                                                valueDelim,
902                                                                hasEntityRef));
903                 space = null;
904             }
905         }
906         output.printElementStart(name, attributes, space);
907         
908         switch (type) {
909         default:
910             throw fatalError("xml", null);
911         case LexicalUnits.EMPTY_ELEMENT_END:
912             output.printElementEnd(null, null);
913             break;
914         case LexicalUnits.END_CHAR:
915             output.printCharacter('>');
916             type = scanner.next();
917             printContent(allowSpaceAtStart(nameStr));
918             if (type != LexicalUnits.END_TAG) {
919                 throw fatalError("end.tag", null);
920             }
921             name = getCurrentValue();
922
923             type = scanner.next();
924             space = null;
925             if (type == LexicalUnits.S) {
926                 space = getCurrentValue();
927                 type = scanner.next();
928             }
929
930             output.printElementEnd(name, space);
931
932             if (type != LexicalUnits.END_CHAR) {
933                 throw fatalError("end", null);
934             }
935         }
936
937         type = scanner.next();
938         return nameStr;
939     }
940
941     boolean allowSpaceAtStart(String JavaDoc tagName) {
942         return true;
943         /**
944          * This would be a real hack for SVG. This should be
945          * driven by a configuration paramater as well as
946          * needing to be really namespace aware...
947          */

948         // return !(tagName.equals("tspan")||
949
// tagName.endsWith(":tspan"));
950
}
951
952     /**
953      * Prints the content of an element.
954      */

955     protected void printContent(boolean spaceAtStart)
956         throws TranscoderException,
957                XMLException,
958                IOException JavaDoc {
959         boolean preceedingSpace = false;
960         content: for (;;) {
961             switch (type) {
962             case LexicalUnits.COMMENT:
963                 output.printComment(getCurrentValue());
964                 scanner.clearBuffer();
965                 type = scanner.next();
966                 preceedingSpace = false;
967                 break;
968             case LexicalUnits.PI_START:
969                 printPI();
970                 preceedingSpace = false;
971                 break;
972             case LexicalUnits.CHARACTER_DATA:
973                 preceedingSpace = output.printCharacterData
974                     (getCurrentValue(), spaceAtStart, preceedingSpace);
975                 scanner.clearBuffer();
976                 type = scanner.next();
977                 spaceAtStart = false;
978                 break;
979             case LexicalUnits.CDATA_START:
980                 type = scanner.next();
981                 if (type != LexicalUnits.CHARACTER_DATA) {
982                     throw fatalError("character.data", null);
983                 }
984                 output.printCDATASection(getCurrentValue());
985                 if (scanner.next() != LexicalUnits.SECTION_END) {
986                     throw fatalError("section.end", null);
987                 }
988                 scanner.clearBuffer();
989                 type = scanner.next();
990                 preceedingSpace = false;
991                 spaceAtStart = false;
992                 break;
993             case LexicalUnits.START_TAG:
994                 String JavaDoc name = printElement();
995                 spaceAtStart = allowSpaceAtStart(name);
996                 break;
997             case LexicalUnits.CHARACTER_REFERENCE:
998                 output.printCharacterEntityReference(getCurrentValue(),
999                                                      spaceAtStart,
1000                                                     preceedingSpace);
1001                scanner.clearBuffer();
1002                type = scanner.next();
1003                spaceAtStart = false;
1004                preceedingSpace = false;
1005                break;
1006            case LexicalUnits.ENTITY_REFERENCE:
1007                output.printEntityReference(getCurrentValue(), spaceAtStart);
1008                scanner.clearBuffer();
1009                type = scanner.next();
1010                spaceAtStart = false;
1011                preceedingSpace = false;
1012                break;
1013            default:
1014                break content;
1015            }
1016        }
1017    }
1018
1019    /**
1020     * Prints a notation declaration.
1021     */

1022    protected void printNotation()
1023        throws TranscoderException,
1024               XMLException,
1025               IOException JavaDoc {
1026        int t = scanner.next();
1027        if (t != LexicalUnits.S) {
1028            throw fatalError("space", null);
1029        }
1030        char[] space1 = getCurrentValue();
1031        t = scanner.next();
1032
1033        if (t != LexicalUnits.NAME) {
1034            throw fatalError("name", null);
1035        }
1036        char[] name = getCurrentValue();
1037        t = scanner.next();
1038
1039        if (t != LexicalUnits.S) {
1040            throw fatalError("space", null);
1041        }
1042        char[] space2 = getCurrentValue();
1043        t = scanner.next();
1044
1045        String JavaDoc externalId = null;
1046        char[] space3 = null;
1047        char[] string1 = null;
1048        char string1Delim = 0;
1049        char[] space4 = null;
1050        char[] string2 = null;
1051        char string2Delim = 0;
1052
1053        switch (t) {
1054        default:
1055            throw fatalError("notation.definition", null);
1056        case LexicalUnits.PUBLIC_IDENTIFIER:
1057            externalId = "PUBLIC";
1058
1059            t = scanner.next();
1060            if (t != LexicalUnits.S) {
1061                throw fatalError("space", null);
1062            }
1063            space3 = getCurrentValue();
1064            t = scanner.next();
1065
1066            if (t != LexicalUnits.STRING) {
1067                throw fatalError("string", null);
1068            }
1069            string1 = getCurrentValue();
1070            string1Delim = scanner.getStringDelimiter();
1071            t = scanner.next();
1072            
1073            if (t == LexicalUnits.S) {
1074                space4 = getCurrentValue();
1075                t = scanner.next();
1076
1077                if (t == LexicalUnits.STRING) {
1078                    string2 = getCurrentValue();
1079                    string2Delim = scanner.getStringDelimiter();
1080                    t = scanner.next();
1081                }
1082            }
1083
1084            break;
1085        case LexicalUnits.SYSTEM_IDENTIFIER:
1086            externalId = "SYSTEM";
1087
1088            t = scanner.next();
1089            if (t != LexicalUnits.S) {
1090                throw fatalError("space", null);
1091            }
1092            space3 = getCurrentValue();
1093            t = scanner.next();
1094
1095            if (t != LexicalUnits.STRING) {
1096                throw fatalError("string", null);
1097            }
1098            string1 = getCurrentValue();
1099            string1Delim = scanner.getStringDelimiter();
1100            t = scanner.next();
1101        }
1102
1103        char[] space5 = null;
1104        if (t == LexicalUnits.S) {
1105            space5 = getCurrentValue();
1106            t = scanner.next();
1107        }
1108        if (t != LexicalUnits.END_CHAR) {
1109            throw fatalError("end", null);
1110        }
1111        output.printNotation(space1, name, space2, externalId, space3,
1112                             string1, string1Delim, space4,
1113                             string2, string2Delim, space5);
1114
1115        scanner.next();
1116    }
1117
1118    /**
1119     * Prints an ATTLIST declaration.
1120     */

1121    protected void printAttlist()
1122        throws TranscoderException,
1123               XMLException,
1124               IOException JavaDoc {
1125        type = scanner.next();
1126        if (type != LexicalUnits.S) {
1127            throw fatalError("space", null);
1128        }
1129        char[] space = getCurrentValue();
1130        type = scanner.next();
1131
1132        if (type != LexicalUnits.NAME) {
1133            throw fatalError("name", null);
1134        }
1135        char[] name = getCurrentValue();
1136        type = scanner.next();
1137
1138        output.printAttlistStart(space, name);
1139
1140        while (type == LexicalUnits.S) {
1141            space = getCurrentValue();
1142            type = scanner.next();
1143            
1144            if (type != LexicalUnits.NAME) {
1145                break;
1146            }
1147            name = getCurrentValue();
1148            type = scanner.next();
1149
1150            if (type != LexicalUnits.S) {
1151                throw fatalError("space", null);
1152            }
1153            char[] space2 = getCurrentValue();
1154            type = scanner.next();
1155
1156            output.printAttName(space, name, space2);
1157
1158            switch (type) {
1159            case LexicalUnits.CDATA_IDENTIFIER:
1160            case LexicalUnits.ID_IDENTIFIER:
1161            case LexicalUnits.IDREF_IDENTIFIER:
1162            case LexicalUnits.IDREFS_IDENTIFIER:
1163            case LexicalUnits.ENTITY_IDENTIFIER:
1164            case LexicalUnits.ENTITIES_IDENTIFIER:
1165            case LexicalUnits.NMTOKEN_IDENTIFIER:
1166            case LexicalUnits.NMTOKENS_IDENTIFIER:
1167                output.printCharacters(getCurrentValue());
1168                type = scanner.next();
1169                break;
1170            case LexicalUnits.NOTATION_IDENTIFIER:
1171                output.printCharacters(getCurrentValue());
1172                type = scanner.next();
1173
1174                if (type != LexicalUnits.S) {
1175                    throw fatalError("space", null);
1176                }
1177                output.printSpaces(getCurrentValue(), false);
1178                type = scanner.next();
1179            
1180                if (type != LexicalUnits.LEFT_BRACE) {
1181                    throw fatalError("left.brace", null);
1182                }
1183                type = scanner.next();
1184
1185                List JavaDoc names = new LinkedList JavaDoc();
1186                space = null;
1187
1188                if (type == LexicalUnits.S) {
1189                    space = getCurrentValue();
1190                    type = scanner.next();
1191                }
1192
1193                if (type != LexicalUnits.NAME) {
1194                    throw fatalError("name", null);
1195                }
1196                name = getCurrentValue();
1197                type = scanner.next();
1198
1199                space2 = null;
1200                if (type == LexicalUnits.S) {
1201                    space2 = getCurrentValue();
1202                    type = scanner.next();
1203                }
1204
1205                names.add(new OutputManager.NameInfo(space, name, space2));
1206
1207                loop: for (;;) {
1208                    switch (type) {
1209                    default:
1210                        break loop;
1211                    case LexicalUnits.PIPE:
1212                        type = scanner.next();
1213                        
1214                        space = null;
1215                        if (type == LexicalUnits.S) {
1216                            space = getCurrentValue();
1217                            type = scanner.next();
1218                        }
1219
1220                        if (type != LexicalUnits.NAME) {
1221                            throw fatalError("name", null);
1222                        }
1223                        name = getCurrentValue();
1224                        type = scanner.next();
1225
1226                        space2 = null;
1227                        if (type == LexicalUnits.S) {
1228                            space2 = getCurrentValue();
1229                            type = scanner.next();
1230                        }
1231                        
1232                        names.add(new OutputManager.NameInfo(space, name, space2));
1233                    }
1234                }
1235                if (type != LexicalUnits.RIGHT_BRACE) {
1236                    throw fatalError("right.brace", null);
1237                }
1238
1239                output.printEnumeration(names);
1240                type = scanner.next();
1241                break;
1242            case LexicalUnits.LEFT_BRACE:
1243                type = scanner.next();
1244
1245                names = new LinkedList JavaDoc();
1246                space = null;
1247
1248                if (type == LexicalUnits.S) {
1249                    space = getCurrentValue();
1250                    type = scanner.next();
1251                }
1252
1253                if (type != LexicalUnits.NMTOKEN) {
1254                    throw fatalError("nmtoken", null);
1255                }
1256                name = getCurrentValue();
1257                type = scanner.next();
1258
1259                space2 = null;
1260                if (type == LexicalUnits.S) {
1261                    space2 = getCurrentValue();
1262                    type = scanner.next();
1263                }
1264
1265                names.add(new OutputManager.NameInfo(space, name, space2));
1266
1267                loop: for (;;) {
1268                    switch (type) {
1269                    default:
1270                        break loop;
1271                    case LexicalUnits.PIPE:
1272                        type = scanner.next();
1273                        
1274                        space = null;
1275                        if (type == LexicalUnits.S) {
1276                            space = getCurrentValue();
1277                            type = scanner.next();
1278                        }
1279
1280                        if (type != LexicalUnits.NMTOKEN) {
1281                            throw fatalError("nmtoken", null);
1282                        }
1283                        name = getCurrentValue();
1284                        type = scanner.next();
1285
1286                        space2 = null;
1287                        if (type == LexicalUnits.S) {
1288                            space2 = getCurrentValue();
1289                            type = scanner.next();
1290                        }
1291                        
1292                        names.add(new OutputManager.NameInfo(space, name, space2));
1293                    }
1294                }
1295                if (type != LexicalUnits.RIGHT_BRACE) {
1296                    throw fatalError("right.brace", null);
1297                }
1298
1299                output.printEnumeration(names);
1300                type = scanner.next();
1301                
1302            }
1303
1304            if (type == LexicalUnits.S) {
1305                output.printSpaces(getCurrentValue(), true);
1306                type = scanner.next();
1307            }
1308
1309            switch (type) {
1310            default:
1311                throw fatalError("default.decl", null);
1312            case LexicalUnits.REQUIRED_IDENTIFIER:
1313            case LexicalUnits.IMPLIED_IDENTIFIER:
1314                output.printCharacters(getCurrentValue());
1315                type = scanner.next();
1316                break;
1317            case LexicalUnits.FIXED_IDENTIFIER:
1318                output.printCharacters(getCurrentValue());
1319                type = scanner.next();
1320                
1321                if (type != LexicalUnits.S) {
1322                    throw fatalError("space", null);
1323                }
1324                output.printSpaces(getCurrentValue(), false);
1325                type = scanner.next();
1326
1327                if (type != LexicalUnits.STRING &&
1328                    type != LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT) {
1329                    throw fatalError("space", null);
1330                }
1331            case LexicalUnits.STRING:
1332            case LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT:
1333                output.printCharacter(scanner.getStringDelimiter());
1334                output.printCharacters(getCurrentValue());
1335                loop: for (;;) {
1336                    type = scanner.next();
1337                    switch (type) {
1338                    case LexicalUnits.STRING:
1339                    case LexicalUnits.ATTRIBUTE_FRAGMENT:
1340                    case LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT:
1341                    case LexicalUnits.LAST_ATTRIBUTE_FRAGMENT:
1342                        output.printCharacters(getCurrentValue());
1343                        break;
1344                    case LexicalUnits.CHARACTER_REFERENCE:
1345                        output.printString("&#");
1346                        output.printCharacters(getCurrentValue());
1347                        output.printCharacter(';');
1348                        break;
1349                    case LexicalUnits.ENTITY_REFERENCE:
1350                        output.printCharacter('&');
1351                        output.printCharacters(getCurrentValue());
1352                        output.printCharacter(';');
1353                        break;
1354                    default:
1355                        break loop;
1356                    }
1357                }
1358                output.printCharacter(scanner.getStringDelimiter());
1359            }
1360            space = null;
1361        }
1362
1363        if (type != LexicalUnits.END_CHAR) {
1364            throw fatalError("end", null);
1365        }
1366        output.printAttlistEnd(space);
1367        type = scanner.next();
1368    }
1369
1370    /**
1371     * Prints an entity declaration.
1372     */

1373    protected void printEntityDeclaration()
1374        throws TranscoderException,
1375               XMLException,
1376               IOException JavaDoc {
1377        writer.write("<!ENTITY");
1378
1379        type = scanner.next();
1380        if (type != LexicalUnits.S) {
1381            throw fatalError("space", null);
1382        }
1383        writer.write(getCurrentValue());
1384        type = scanner.next();
1385
1386        boolean pe = false;
1387
1388        switch (type) {
1389        default:
1390            throw fatalError("xml", null);
1391        case LexicalUnits.NAME:
1392            writer.write(getCurrentValue());
1393            type = scanner.next();
1394            break;
1395        case LexicalUnits.PERCENT:
1396            pe = true;
1397            writer.write('%');
1398            type = scanner.next();
1399
1400            if (type != LexicalUnits.S) {
1401                throw fatalError("space", null);
1402            }
1403            writer.write(getCurrentValue());
1404            type = scanner.next();
1405
1406            if (type != LexicalUnits.NAME) {
1407                throw fatalError("name", null);
1408            }
1409            writer.write(getCurrentValue());
1410            type = scanner.next();
1411        }
1412
1413        if (type != LexicalUnits.S) {
1414            throw fatalError("space", null);
1415        }
1416        writer.write(getCurrentValue());
1417        type = scanner.next();
1418
1419        switch (type) {
1420        case LexicalUnits.STRING:
1421        case LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT:
1422            char sd = scanner.getStringDelimiter();
1423            writer.write(sd);
1424            loop: for (;;) {
1425                switch (type) {
1426                case LexicalUnits.STRING:
1427                case LexicalUnits.ATTRIBUTE_FRAGMENT:
1428                case LexicalUnits.FIRST_ATTRIBUTE_FRAGMENT:
1429                case LexicalUnits.LAST_ATTRIBUTE_FRAGMENT:
1430                    writer.write(getCurrentValue());
1431                    break;
1432                case LexicalUnits.ENTITY_REFERENCE:
1433                    writer.write('&');
1434                    writer.write(getCurrentValue());
1435                    writer.write(';');
1436                    break;
1437                case LexicalUnits.PARAMETER_ENTITY_REFERENCE:
1438                    writer.write('&');
1439                    writer.write(getCurrentValue());
1440                    writer.write(';');
1441                    break;
1442                default:
1443                    break loop;
1444                }
1445                type = scanner.next();
1446            }
1447            writer.write(sd);
1448
1449            if (type == LexicalUnits.S) {
1450                writer.write(getCurrentValue());
1451                type = scanner.next();
1452            }
1453            
1454            if (type != LexicalUnits.END_CHAR) {
1455                throw fatalError("end", null);
1456            }
1457            writer.write(">");
1458            type = scanner.next();
1459            return;
1460        case LexicalUnits.PUBLIC_IDENTIFIER:
1461            writer.write("PUBLIC");
1462            type = scanner.next();
1463            if (type != LexicalUnits.S) {
1464                throw fatalError("space", null);
1465            }
1466            type = scanner.next();
1467            if (type != LexicalUnits.STRING) {
1468                throw fatalError("string", null);
1469            }
1470
1471            writer.write(" \"");
1472            writer.write(getCurrentValue());
1473            writer.write("\" \"");
1474
1475            type = scanner.next();
1476            if (type != LexicalUnits.S) {
1477                throw fatalError("space", null);
1478            }
1479            type = scanner.next();
1480            if (type != LexicalUnits.STRING) {
1481                throw fatalError("string", null);
1482            }
1483
1484            writer.write(getCurrentValue());
1485            writer.write('"');
1486            break;
1487            
1488        case LexicalUnits.SYSTEM_IDENTIFIER:
1489            writer.write("SYSTEM");
1490            type = scanner.next();
1491            if (type != LexicalUnits.S) {
1492                throw fatalError("space", null);
1493            }
1494            type = scanner.next();
1495            if (type != LexicalUnits.STRING) {
1496                throw fatalError("string", null);
1497            }
1498            writer.write(" \"");
1499            writer.write(getCurrentValue());
1500            writer.write('"');
1501        }
1502
1503        type = scanner.next();
1504        if (type == LexicalUnits.S) {
1505            writer.write(getCurrentValue());
1506            type = scanner.next();
1507            if (!pe && type == LexicalUnits.NDATA_IDENTIFIER) {
1508                writer.write("NDATA");
1509                type = scanner.next();
1510                if (type != LexicalUnits.S) {
1511                    throw fatalError("space", null);
1512                }
1513                writer.write(getCurrentValue());
1514                type = scanner.next();
1515                if (type != LexicalUnits.NAME) {
1516                    throw fatalError("name", null);
1517                }
1518                writer.write(getCurrentValue());
1519                type = scanner.next();
1520            }
1521            if (type == LexicalUnits.S) {
1522                writer.write(getCurrentValue());
1523                type = scanner.next();
1524            }
1525        }
1526        
1527        if (type != LexicalUnits.END_CHAR) {
1528            throw fatalError("end", null);
1529        }
1530        writer.write('>');
1531        type = scanner.next();
1532    }
1533
1534    /**
1535     * Prints an element declaration.
1536     */

1537    protected void printElementDeclaration()
1538        throws TranscoderException,
1539               XMLException,
1540               IOException JavaDoc {
1541        writer.write("<!ELEMENT");
1542
1543        type = scanner.next();
1544        if (type != LexicalUnits.S) {
1545            throw fatalError("space", null);
1546        }
1547        writer.write(getCurrentValue());
1548        type = scanner.next();
1549        switch (type) {
1550        default:
1551            throw fatalError("name", null);
1552        case LexicalUnits.NAME:
1553            writer.write(getCurrentValue());
1554        }
1555
1556        type = scanner.next();
1557        if (type != LexicalUnits.S) {
1558            throw fatalError("space", null);
1559        }
1560        writer.write(getCurrentValue());
1561
1562        switch (type = scanner.next()) {
1563        case LexicalUnits.EMPTY_IDENTIFIER:
1564            writer.write("EMPTY");
1565            type = scanner.next();
1566            break;
1567        case LexicalUnits.ANY_IDENTIFIER:
1568            writer.write("ANY");
1569            type = scanner.next();
1570            break;
1571        case LexicalUnits.LEFT_BRACE:
1572            writer.write('(');
1573            type = scanner.next();
1574            if (type == LexicalUnits.S) {
1575                writer.write(getCurrentValue());
1576                type = scanner.next();
1577            }
1578            mixed: switch (type) {
1579            case LexicalUnits.PCDATA_IDENTIFIER:
1580                writer.write("#PCDATA");
1581                type = scanner.next();
1582
1583                for (;;) {
1584                    switch (type) {
1585                    case LexicalUnits.S:
1586                        writer.write(getCurrentValue());
1587                        type = scanner.next();
1588                        break;
1589                    case LexicalUnits.PIPE:
1590                        writer.write('|');
1591                        type = scanner.next();
1592                        if (type == LexicalUnits.S) {
1593                            writer.write(getCurrentValue());
1594                            type = scanner.next();
1595                        }
1596                        if (type != LexicalUnits.NAME) {
1597                            throw fatalError("name", null);
1598                        }
1599                        writer.write(getCurrentValue());
1600                        type = scanner.next();
1601                        break;
1602                    case LexicalUnits.RIGHT_BRACE:
1603                        writer.write(')');
1604                        type = scanner.next();
1605                        break mixed;
1606                    }
1607                }
1608
1609            case LexicalUnits.NAME:
1610            case LexicalUnits.LEFT_BRACE:
1611                printChildren();
1612                if (type != LexicalUnits.RIGHT_BRACE) {
1613                    throw fatalError("right.brace", null);
1614                }
1615                writer.write(')');
1616                type = scanner.next();
1617                if (type == LexicalUnits.S) {
1618                    writer.write(getCurrentValue());
1619                    type = scanner.next();
1620                }
1621                switch (type) {
1622                case LexicalUnits.QUESTION:
1623                    writer.write('?');
1624                    type = scanner.next();
1625                    break;
1626                case LexicalUnits.STAR:
1627                    writer.write('*');
1628                    type = scanner.next();
1629                    break;
1630                case LexicalUnits.PLUS:
1631                    writer.write('+');
1632                    type = scanner.next();
1633                }
1634            }
1635        }
1636        
1637        if (type == LexicalUnits.S) {
1638            writer.write(getCurrentValue());
1639            type = scanner.next();
1640        }
1641
1642        if (type != LexicalUnits.END_CHAR) {
1643            throw fatalError("end", null);
1644        }
1645        writer.write('>');
1646        scanner.next();
1647    }
1648
1649    /**
1650     * Prints the children of an element declaration.
1651     */

1652    protected void printChildren()
1653        throws TranscoderException,
1654               XMLException,
1655               IOException JavaDoc {
1656        int op = 0;
1657        loop: for (;;) {
1658            switch (type) {
1659            default:
1660                throw new RuntimeException JavaDoc("Invalid XML");
1661            case LexicalUnits.NAME:
1662                writer.write(getCurrentValue());
1663                type = scanner.next();
1664                break;
1665            case LexicalUnits.LEFT_BRACE:
1666                writer.write('(');
1667                type = scanner.next();
1668                if (type == LexicalUnits.S) {
1669                    writer.write(getCurrentValue());
1670                    type = scanner.next();
1671                }
1672                printChildren();
1673                if (type != LexicalUnits.RIGHT_BRACE) {
1674                    throw fatalError("right.brace", null);
1675                }
1676                writer.write(')');
1677                type = scanner.next();
1678            }
1679
1680            if (type == LexicalUnits.S) {
1681                writer.write(getCurrentValue());
1682                type = scanner.next();
1683            }
1684
1685            switch (type) {
1686            case LexicalUnits.RIGHT_BRACE:
1687                break loop;
1688            case LexicalUnits.STAR:
1689                writer.write('*');
1690                type = scanner.next();
1691                break;
1692            case LexicalUnits.QUESTION:
1693                writer.write('?');
1694                type = scanner.next();
1695                break;
1696            case LexicalUnits.PLUS:
1697                writer.write('+');
1698                type = scanner.next();
1699                break;
1700            }
1701
1702            if (type == LexicalUnits.S) {
1703                writer.write(getCurrentValue());
1704                type = scanner.next();
1705            }
1706
1707            switch (type) {
1708            case LexicalUnits.PIPE:
1709                if (op != 0 && op != type) {
1710                    throw new RuntimeException JavaDoc("Invalid XML");
1711                }
1712                writer.write('|');
1713                op = type;
1714                type = scanner.next();
1715                break;
1716            case LexicalUnits.COMMA:
1717                if (op != 0 && op != type) {
1718                    throw new RuntimeException JavaDoc("Invalid XML");
1719                }
1720                writer.write(',');
1721                op = type;
1722                type = scanner.next();
1723            }
1724
1725            if (type == LexicalUnits.S) {
1726                writer.write(getCurrentValue());
1727                type = scanner.next();
1728            }
1729        }
1730    }
1731
1732    /**
1733     * Returns the current lexical unit value.
1734     */

1735    protected char[] getCurrentValue() {
1736        int off = scanner.getStart() + scanner.getStartOffset();
1737        int len = scanner.getEnd() + scanner.getEndOffset() - off;
1738        char[] result = new char[len];
1739        char[] buffer = scanner.getBuffer();
1740        for (int i = 0; i < len; i++) {
1741            result[i] = buffer[off + i];
1742        }
1743        return result;
1744    }
1745
1746    /**
1747     * Creates a transcoder exception.
1748     */

1749    protected TranscoderException fatalError(String JavaDoc key, Object JavaDoc[] params)
1750        throws TranscoderException {
1751        TranscoderException result = new TranscoderException(key);
1752        errorHandler.fatalError(result);
1753        return result;
1754    }
1755}
1756
Popular Tags