1 /* GnomeXMLReader.java -
2    Copyright (C) 2004 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package gnu.xml.libxmlj.sax;
39 
40 import java.io.File;
41 import java.io.FileNotFoundException;
42 import java.io.InputStream;
43 import java.io.IOException;
44 import java.net.MalformedURLException;
45 import java.net.URL;
46 import java.util.Arrays;
47 import java.util.ArrayList;
48 import java.util.Iterator;
49 import java.util.List;
50 
51 import org.xml.sax.Attributes;
52 import org.xml.sax.ContentHandler;
53 import org.xml.sax.DTDHandler;
54 import org.xml.sax.EntityResolver;
55 import org.xml.sax.ErrorHandler;
56 import org.xml.sax.InputSource;
57 import org.xml.sax.Locator;
58 import org.xml.sax.SAXException;
59 import org.xml.sax.SAXNotRecognizedException;
60 import org.xml.sax.SAXNotSupportedException;
61 import org.xml.sax.SAXParseException;
62 import org.xml.sax.XMLReader;
63 import org.xml.sax.ext.DeclHandler;
64 import org.xml.sax.ext.LexicalHandler;
65 
66 import gnu.xml.libxmlj.util.NamedInputStream;
67 import gnu.xml.libxmlj.util.StandaloneLocator;
68 import gnu.xml.libxmlj.util.XMLJ;
69 
70 /**
71  * A SAX2 parser that uses libxml2.
72  *
73  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
74  */
75 public class GnomeXMLReader
76 implements XMLReader
77 {
78 
79   static
80   {
XMLJ.init()81     XMLJ.init ();
82   }
83 
84   private static final String FEATURES_PREFIX =
85     "http://xml.org/sax/features/";
86 
87   private static final List RECOGNIZED_FEATURES =
88     Arrays.asList (new String[]
89                    {
90                    "external-general-entities",
91                    "external-parameter-entities",
92                    "is-standalone",
93                    "lexical-handler/parameter-entities",
94                    "namespaces",
95                    "namespace-prefixes",
96                    "resolve-dtd-uris",
97                    "string-interning",
98                    "use-attributes2",
99                    "use-locator2",
100                    "use-entity-resolver2",
101                    "validation"
102                    });
103 
104   private static final String PROPERTIES_PREFIX =
105     "http://xml.org/sax/properties/";
106 
107   private static final List RECOGNIZED_PROPERTIES =
108     Arrays.asList (new String[]
109                    {
110                    "declaration-handler",
111                    "dom-node",
112                    "lexical-handler",
113                    "xml-string"
114                    });
115 
116   // Features
117 
118   private transient boolean standalone;
119   private boolean namespaces;
120   private boolean namespacePrefixes;
121   private boolean validation;
122 
123   // Callback handlers
124 
125   private ContentHandler contentHandler;
126 
127   private DTDHandler dtdHandler;
128 
129   private EntityResolver entityResolver;
130 
131   private ErrorHandler errorHandler;
132 
133   private DeclHandler declarationHandler;
134 
135   private LexicalHandler lexicalHandler;
136 
137   private GnomeLocator locator;
138 
139   // Namespace helper for handling callbacks
140   private transient Namespaces ns;
141 
142   // If true, do not invoke callback methods except endDocument
143   private transient boolean seenFatalError;
144 
145   private transient boolean seenStartDocument;
146 
147   private transient String base;
148 
GnomeXMLReader()149   public GnomeXMLReader ()
150   {
151     this (true, true);
152   }
153 
GnomeXMLReader(boolean namespaces, boolean validation)154   public GnomeXMLReader (boolean namespaces, boolean validation)
155   {
156     this.namespaces = namespaces;
157     this.validation = validation;
158     ns = new Namespaces ();
159   }
160 
getContentHandler()161   public ContentHandler getContentHandler ()
162   {
163     return contentHandler;
164   }
165 
setContentHandler(ContentHandler handler)166   public void setContentHandler (ContentHandler handler)
167   {
168     contentHandler = handler;
169   }
170 
getDTDHandler()171   public DTDHandler getDTDHandler ()
172   {
173     return dtdHandler;
174   }
175 
setDTDHandler(DTDHandler handler)176   public void setDTDHandler (DTDHandler handler)
177   {
178     dtdHandler = handler;
179   }
180 
getEntityResolver()181   public EntityResolver getEntityResolver ()
182   {
183     return entityResolver;
184   }
185 
setEntityResolver(EntityResolver resolver)186   public void setEntityResolver (EntityResolver resolver)
187   {
188     entityResolver = resolver;
189   }
190 
getErrorHandler()191   public ErrorHandler getErrorHandler ()
192   {
193     return errorHandler;
194   }
195 
setErrorHandler(ErrorHandler handler)196   public void setErrorHandler (ErrorHandler handler)
197   {
198     errorHandler = handler;
199   }
200 
201   // Features
202 
getFeature(String name)203   public boolean getFeature (String name)
204     throws SAXNotRecognizedException, SAXNotSupportedException
205   {
206     checkFeatureName (name);
207     String key = name.substring (FEATURES_PREFIX.length ());
208     if ("external-general-entities".equals (key))
209       {
210         return validation; // TODO check this
211       }
212     else if ("external-parameter-entities".equals (key))
213       {
214         return validation; // TODO check this
215       }
216     else if ("is-standalone".equals (key))
217       {
218         return standalone;
219       }
220     else if ("namespaces".equals (key))
221       {
222         return namespaces;
223       }
224     else if ("namespace-prefixes".equals (key))
225       {
226         return namespacePrefixes;
227       }
228     else if ("resolve-dtd-uris".equals (key))
229       {
230         return true;
231       }
232     else if ("validation".equals (key))
233       {
234         return validation;
235       }
236     else
237       {
238         return false;
239       }
240   }
241 
setFeature(String name, boolean value)242   public void setFeature (String name, boolean value)
243     throws SAXNotRecognizedException, SAXNotSupportedException
244   {
245     checkFeatureName (name);
246     String key = name.substring (FEATURES_PREFIX.length ());
247     if ("namespaces".equals (key))
248       {
249         namespaces = value;
250       }
251     else if ("namespace-prefixes".equals (key))
252       {
253         namespacePrefixes = value;
254       }
255     else if ("validation".equals (key))
256       {
257         validation = value;
258       }
259   }
260 
261   /**
262    * Check that the specified feature name is recognized.
263    */
checkFeatureName(String name)264   static void checkFeatureName (String name)
265     throws SAXNotRecognizedException
266   {
267     if (name == null || !name.startsWith (FEATURES_PREFIX))
268       {
269         throw new SAXNotRecognizedException (name);
270       }
271     String key = name.substring (FEATURES_PREFIX.length ());
272     if (!RECOGNIZED_FEATURES.contains (key))
273       {
274         throw new SAXNotRecognizedException (name);
275       }
276   }
277 
278   // Properties
279 
getProperty(String name)280   public Object getProperty (String name)
281     throws SAXNotRecognizedException, SAXNotSupportedException
282   {
283     checkPropertyName (name);
284     String key = name.substring (PROPERTIES_PREFIX.length ());
285     if ("declaration-handler".equals (key))
286       {
287         return getDeclarationHandler ();
288       }
289     else if ("lexical-handler".equals (key))
290       {
291         return getLexicalHandler ();
292       }
293     else
294       {
295         throw new SAXNotSupportedException (name);
296       }
297   }
298 
setProperty(String name, Object value)299   public void setProperty (String name, Object value)
300     throws SAXNotRecognizedException, SAXNotSupportedException
301   {
302     checkPropertyName (name);
303     String key = name.substring (PROPERTIES_PREFIX.length ());
304     if ("declaration-handler".equals (key))
305       {
306         setDeclarationHandler ((DeclHandler) value);
307       }
308     else if ("lexical-handler".equals (key))
309       {
310         setLexicalHandler ((LexicalHandler) value);
311       }
312   }
313 
getDeclarationHandler()314   public DeclHandler getDeclarationHandler ()
315   {
316     return declarationHandler;
317   }
318 
setDeclarationHandler(DeclHandler declarationHandler)319   public void setDeclarationHandler (DeclHandler declarationHandler)
320   {
321     this.declarationHandler = declarationHandler;
322   }
323 
getLexicalHandler()324   public LexicalHandler getLexicalHandler ()
325   {
326     return lexicalHandler;
327   }
328 
setLexicalHandler(LexicalHandler lexicalHandler)329   public void setLexicalHandler (LexicalHandler lexicalHandler)
330   {
331     this.lexicalHandler = lexicalHandler;
332   }
333 
334   /**
335    * Check that the specified property name is recognized.
336    */
checkPropertyName(String name)337   static void checkPropertyName (String name)
338     throws SAXNotRecognizedException
339   {
340     if (!name.startsWith (PROPERTIES_PREFIX))
341       {
342         throw new SAXNotRecognizedException (name);
343       }
344     String key = name.substring (PROPERTIES_PREFIX.length ());
345     if (!RECOGNIZED_PROPERTIES.contains (key))
346       {
347         throw new SAXNotRecognizedException (name);
348       }
349   }
350 
351   // Parse
352 
parse(String systemId)353   public void parse (String systemId)
354     throws IOException, SAXException
355   {
356     URL url = null;
357     try
358       {
359         url = new URL (systemId);
360       }
361     catch (MalformedURLException e)
362       {
363         File file = new File(systemId);
364         if (!file.exists ())
365           {
366             throw new FileNotFoundException (systemId);
367           }
368         String path  = file.getAbsolutePath();
369         if (File.separatorChar != '/')
370           {
371             path = path.replace (File.separatorChar, '/');
372           }
373         if (!path.startsWith ("/"))
374           {
375             path = "/" + path;
376           }
377         if (!path.endsWith ("/") && file.isDirectory ())
378           {
379             path = path + "/";
380           }
381         url = new URL ("file:" + path);
382       }
383     InputSource source = new InputSource(url.toString ());
384     source.setByteStream (url.openStream ());
385     parse (source);
386   }
387 
parse(InputSource input)388   public synchronized void parse (InputSource input)
389     throws IOException, SAXException
390   {
391     NamedInputStream in = XMLJ.getInputStream (input);
392     byte[] detectBuffer = in.getDetectBuffer ();
393     String publicId = input.getPublicId ();
394     String systemId = input.getSystemId ();
395     base = XMLJ.getBaseURI (systemId);
396     // Reset state
397     standalone = false;
398     seenFatalError = false;
399     seenStartDocument = false;
400     if (systemId != null)
401       {
402         int lsi = systemId.lastIndexOf ('/');
403         if (lsi != -1)
404           {
405             base = systemId.substring (0, lsi + 1);
406           }
407       }
408     // Handle zero-length document
409     if (detectBuffer == null)
410       {
411         startDocument (true);
412         fatalError ("No document element", 0, 0, publicId, systemId);
413         endDocument ();
414         return;
415       }
416     // Parse
417     parseStream(in,
418                 detectBuffer,
419                 publicId,
420                 systemId,
421                 base,
422                 validation,
423                 contentHandler != null,
424                 dtdHandler != null,
425                 entityResolver != null,
426                 errorHandler != null,
427                 declarationHandler != null,
428                 lexicalHandler != null);
429     in.close ();
430   }
431 
parseStream(InputStream in, byte[] detectBuffer, String publicId, String systemId, String base, boolean validate, boolean contentHandler, boolean dtdHandler, boolean entityResolver, boolean errorHandler, boolean declarationHandler, boolean lexicalHandler)432   native void parseStream (InputStream in,
433                            byte[] detectBuffer,
434                            String publicId,
435                            String systemId,
436                            String base,
437                            boolean validate,
438                            boolean contentHandler,
439                            boolean dtdHandler,
440                            boolean entityResolver,
441                            boolean errorHandler,
442                            boolean declarationHandler,
443                            boolean lexicalHandler)
444     throws IOException, SAXException;
445 
getURI(String prefix)446   String getURI (String prefix)
447   {
448     if (!namespaces)
449       {
450         return null;
451       }
452     return ns.getURI (prefix);
453   }
454 
455   // Callbacks from libxmlj
456 
startDTD(String name, String publicId, String systemId)457   private void startDTD (String name, String publicId, String systemId)
458     throws SAXException
459   {
460     if (seenFatalError || lexicalHandler == null)
461       {
462         return;
463       }
464     try
465       {
466         systemId = XMLJ.getAbsoluteURI (base, systemId);
467         lexicalHandler.startDTD (name, publicId, systemId);
468       }
469     catch (Exception e)
470       {
471         if (e instanceof SAXException)
472           {
473             throw (SAXException) e;
474           }
475         else
476           {
477             throw new SAXException (e);
478           }
479       }
480   }
481 
externalEntityDecl(String name, String publicId, String systemId)482   private void externalEntityDecl (String name, String publicId,
483                                    String systemId)
484     throws SAXException
485   {
486     if (seenFatalError || declarationHandler == null)
487       {
488         return;
489       }
490     try
491       {
492         systemId = XMLJ.getAbsoluteURI (base, systemId);
493         declarationHandler.externalEntityDecl (name, publicId, systemId);
494       }
495     catch (Exception e)
496       {
497         if (e instanceof SAXException)
498           {
499             throw (SAXException) e;
500           }
501         else
502           {
503             throw new SAXException (e);
504           }
505       }
506   }
507 
internalEntityDecl(String name, String value)508   private void internalEntityDecl (String name, String value)
509     throws SAXException
510   {
511     if (seenFatalError || declarationHandler == null)
512       {
513         return;
514       }
515     try
516       {
517         declarationHandler.internalEntityDecl (name, value);
518       }
519     catch (Exception e)
520       {
521         if (e instanceof SAXException)
522           {
523             throw (SAXException) e;
524           }
525         else
526           {
527             throw new SAXException (e);
528           }
529       }
530   }
531 
resolveEntity(String publicId, String systemId)532   private InputStream resolveEntity (String publicId, String systemId)
533     throws SAXException, IOException
534   {
535     if (entityResolver == null)
536       {
537         return null;
538       }
539     try
540       {
541         systemId = XMLJ.getAbsoluteURI (base, systemId);
542         InputSource source = entityResolver.resolveEntity (publicId, systemId);
543         return (source == null) ? null : XMLJ.getInputStream (source);
544       }
545     catch (Exception e)
546       {
547         if (e instanceof SAXException)
548           {
549             throw (SAXException) e;
550           }
551         else
552           {
553             throw new SAXException (e);
554           }
555       }
556   }
557 
notationDecl(String name, String publicId, String systemId)558   private void notationDecl (String name, String publicId, String systemId)
559     throws SAXException
560   {
561     if (seenFatalError || dtdHandler == null)
562       {
563         return;
564       }
565     try
566       {
567         systemId = XMLJ.getAbsoluteURI (base, systemId);
568         dtdHandler.notationDecl (name, publicId, systemId);
569       }
570     catch (Exception e)
571       {
572         if (e instanceof SAXException)
573           {
574             throw (SAXException) e;
575           }
576         else
577           {
578             throw new SAXException (e);
579           }
580       }
581   }
582 
attributeDecl(String eName, String aName, String type, String mode, String value)583   private void attributeDecl (String eName, String aName, String type,
584                               String mode, String value)
585     throws SAXException
586   {
587     if (seenFatalError || declarationHandler == null)
588       {
589         return;
590       }
591     try
592       {
593         declarationHandler.attributeDecl (eName, aName, type, mode, value);
594       }
595     catch (Exception e)
596       {
597         if (e instanceof SAXException)
598           {
599             throw (SAXException) e;
600           }
601         else
602           {
603             throw new SAXException (e);
604           }
605       }
606   }
607 
elementDecl(String name, String model)608   private void elementDecl (String name, String model)
609     throws SAXException
610   {
611     if (seenFatalError || declarationHandler == null)
612       {
613         return;
614       }
615     try
616       {
617         declarationHandler.elementDecl (name, model);
618       }
619     catch (Exception e)
620       {
621         if (e instanceof SAXException)
622           {
623             throw (SAXException) e;
624           }
625         else
626           {
627             throw new SAXException (e);
628           }
629       }
630   }
631 
unparsedEntityDecl(String name, String publicId, String systemId, String notationName)632   private void unparsedEntityDecl (String name, String publicId,
633                                    String systemId, String notationName)
634     throws SAXException
635   {
636     if (seenFatalError || dtdHandler == null)
637       {
638         return;
639       }
640     try
641       {
642         systemId = XMLJ.getAbsoluteURI (base, systemId);
643         dtdHandler.unparsedEntityDecl (name, publicId, systemId,
644                                        notationName);
645       }
646     catch (Exception e)
647       {
648         if (e instanceof SAXException)
649           {
650             throw (SAXException) e;
651           }
652         else
653           {
654             throw new SAXException (e);
655           }
656       }
657   }
658 
setDocumentLocator(Object ctx, Object loc)659   private void setDocumentLocator (Object ctx, Object loc)
660   {
661     locator = new GnomeLocator (ctx, loc);
662     if (seenFatalError || contentHandler == null)
663       {
664         return;
665       }
666     try
667       {
668         contentHandler.setDocumentLocator (locator);
669       }
670     catch (Exception e)
671       {
672       }
673   }
674 
startDocument(boolean standalone)675   private void startDocument (boolean standalone)
676     throws SAXException
677   {
678     this.standalone = standalone;
679     seenStartDocument = true;
680     if (contentHandler == null)
681       {
682         return;
683       }
684     try
685       {
686         contentHandler.startDocument ();
687       }
688     catch (Exception e)
689       {
690         if (e instanceof SAXException)
691           {
692             throw (SAXException) e;
693           }
694         else
695           {
696             throw new SAXException (e);
697           }
698       }
699   }
700 
endDocument()701   private void endDocument ()
702     throws SAXException
703   {
704     if (contentHandler == null)
705       {
706         return;
707       }
708     try
709       {
710         contentHandler.endDocument();
711       }
712     catch (Exception e)
713       {
714         if (e instanceof SAXException)
715           {
716             throw (SAXException) e;
717           }
718         else
719           {
720             throw new SAXException (e);
721           }
722       }
723   }
724 
startElement(String name, String[] attrs)725   private void startElement(String name, String[] attrs)
726     throws SAXException
727   {
728     if (seenFatalError || contentHandler == null)
729       {
730         return;
731       }
732     try
733       {
734         XMLName xName = new XMLName (this, name);
735         if (namespaces)
736           {
737             // Handle defined namespaces
738             ns.push ();
739             int len = (attrs == null) ? 0 : attrs.length;
740             if (len > 0)
741               {
742                 ArrayList filtered = new ArrayList (len);
743                 for (int i = 0; i < len; i += 2)
744                   {
745                     String attName = attrs[i];
746                     String attValue = attrs[i + 1];
747                     if (attName.equals ("xmlns"))
748                       {
749                         startPrefixMapping ("", attValue);
750                       }
751                     else if (attName.startsWith ("xmlns:"))
752                       {
753                         startPrefixMapping (attName.substring (6), attValue);
754                       }
755                     else
756                       {
757                         filtered.add (attName);
758                         filtered.add (attValue);
759                       }
760                   }
761                 // Remove xmlns attributes
762                 attrs = new String[filtered.size ()];
763                 filtered.toArray (attrs);
764               }
765           }
766         // Construct attributes
767         Attributes atts = new StringArrayAttributes (this, attrs);
768         contentHandler.startElement (xName.uri, xName.localName, xName.qName,
769                                      atts);
770       }
771     catch (Exception e)
772       {
773         if (e instanceof SAXException)
774           {
775             throw (SAXException) e;
776           }
777         else
778           {
779             throw new SAXException (e);
780           }
781       }
782   }
783 
endElement(String name)784   private void endElement (String name)
785     throws SAXException
786   {
787     if (seenFatalError || contentHandler == null)
788       {
789         return;
790       }
791     try
792       {
793         XMLName xName = new XMLName (this, name);
794         String uri = (xName.uri == null) ? "" : xName.uri;
795         contentHandler.endElement (uri, xName.localName, xName.qName);
796         // Handle undefining namespaces
797         if (namespaces)
798           {
799             for (Iterator i = ns.currentPrefixes (); i.hasNext (); )
800               {
801                 endPrefixMapping ((String) i.next ());
802               }
803             ns.pop (); // releases current depth
804           }
805       }
806     catch (Exception e)
807       {
808         if (e instanceof SAXException)
809           {
810             throw (SAXException) e;
811           }
812         else
813           {
814             throw new SAXException (e);
815           }
816       }
817   }
818 
startPrefixMapping(String prefix, String uri)819   private void startPrefixMapping (String prefix, String uri)
820     throws SAXException
821   {
822     if (seenFatalError || contentHandler == null)
823       {
824         return;
825       }
826     ns.define (prefix, uri);
827     contentHandler.startPrefixMapping (prefix, uri);
828   }
829 
endPrefixMapping(String prefix)830   private void endPrefixMapping (String prefix)
831     throws SAXException
832   {
833     if (seenFatalError || contentHandler == null)
834       {
835         return;
836       }
837     contentHandler.endPrefixMapping (prefix);
838   }
839 
characters(String text)840   private void characters (String text)
841     throws SAXException
842   {
843     if (seenFatalError || contentHandler == null || text == null)
844       {
845         return;
846       }
847     try
848       {
849         char[] ch = text.toCharArray ();
850         contentHandler.characters (ch, 0, ch.length);
851       }
852     catch (Exception e)
853       {
854         if (e instanceof SAXException)
855           {
856             throw (SAXException) e;
857           }
858         else
859           {
860             throw new SAXException (e);
861           }
862       }
863   }
864 
ignorableWhitespace(String text)865   private void ignorableWhitespace (String text)
866     throws SAXException
867   {
868     if (seenFatalError || contentHandler == null || text == null)
869       {
870         return;
871       }
872     try
873       {
874         char[] ch = text.toCharArray ();
875         contentHandler.ignorableWhitespace (ch, 0, ch.length);
876       }
877     catch (Exception e)
878       {
879         if (e instanceof SAXException)
880           {
881             throw (SAXException) e;
882           }
883         else
884           {
885             throw new SAXException (e);
886           }
887       }
888   }
889 
processingInstruction(String target, String data)890   private void processingInstruction (String target, String data)
891     throws SAXException
892   {
893     if (seenFatalError || contentHandler == null)
894       {
895         return;
896       }
897     try
898       {
899         if (data == null)
900           {
901             data = "";
902           }
903         contentHandler.processingInstruction (target, data);
904       }
905     catch (Exception e)
906       {
907         if (e instanceof SAXException)
908           {
909             throw (SAXException) e;
910           }
911         else
912           {
913             throw new SAXException (e);
914           }
915       }
916   }
917 
comment(String text)918   private void comment (String text)
919     throws SAXException
920   {
921     if (seenFatalError || lexicalHandler == null || text == null)
922       {
923         return;
924       }
925     try
926       {
927         char[] ch = text.toCharArray ();
928         lexicalHandler.comment (ch, 0, ch.length);
929       }
930     catch (Exception e)
931       {
932         if (e instanceof SAXException)
933           {
934             throw (SAXException) e;
935           }
936         else
937           {
938             throw new SAXException (e);
939           }
940       }
941   }
942 
cdataBlock(String text)943   private void cdataBlock (String text)
944     throws SAXException
945   {
946     if (seenFatalError || text == null)
947       {
948         return;
949       }
950     try
951       {
952         if (lexicalHandler == null)
953           {
954             characters(text);
955           }
956         else
957           {
958             lexicalHandler.startCDATA();
959             characters(text);
960             lexicalHandler.endCDATA();
961           }
962       }
963     catch (Exception e)
964       {
965         if (e instanceof SAXException)
966           {
967             throw (SAXException) e;
968           }
969         else
970           {
971             throw new SAXException (e);
972           }
973       }
974   }
975 
warning(String message, int lineNumber, int columnNumber, String publicId, String systemId)976   private void warning (String message,
977                         int lineNumber, int columnNumber,
978                         String publicId, String systemId)
979     throws SAXException
980   {
981     if (seenFatalError || errorHandler == null)
982       {
983         return;
984       }
985     try
986       {
987         Locator l = new StandaloneLocator (lineNumber, columnNumber,
988                                            publicId, systemId);
989         errorHandler.warning (new SAXParseException (message, l));
990       }
991     catch (Exception e)
992       {
993         if (e instanceof SAXException)
994           {
995             throw (SAXException) e;
996           }
997         else
998           {
999             throw new SAXException (e);
1000           }
1001       }
1002   }
1003 
error(String message, int lineNumber, int columnNumber, String publicId, String systemId)1004   private void error (String message,
1005                       int lineNumber, int columnNumber,
1006                       String publicId, String systemId)
1007     throws SAXException
1008   {
1009     if (seenFatalError || errorHandler == null)
1010       {
1011         return;
1012       }
1013     try
1014       {
1015         Locator l = new StandaloneLocator (lineNumber, columnNumber,
1016                                            publicId, systemId);
1017         errorHandler.error (new SAXParseException (message, l));
1018       }
1019     catch (Exception e)
1020       {
1021         if (e instanceof SAXException)
1022           {
1023             throw (SAXException) e;
1024           }
1025         else
1026           {
1027             throw new SAXException (e);
1028           }
1029       }
1030   }
1031 
fatalError(String message, int lineNumber, int columnNumber, String publicId, String systemId)1032   private void fatalError (String message,
1033                            int lineNumber, int columnNumber,
1034                            String publicId, String systemId)
1035     throws SAXException
1036   {
1037     if (seenFatalError || errorHandler == null)
1038       {
1039         return;
1040       }
1041     try
1042       {
1043         if (!seenStartDocument)
1044           {
1045             startDocument (false);
1046           }
1047         seenFatalError = true;
1048         Locator l = new StandaloneLocator (lineNumber, columnNumber,
1049                                            publicId, systemId);
1050         errorHandler.fatalError (new SAXParseException (message, l));
1051       }
1052     catch (Exception e)
1053       {
1054         if (e instanceof SAXException)
1055           {
1056             throw (SAXException) e;
1057           }
1058         else
1059           {
1060             throw new SAXException (e);
1061           }
1062       }
1063   }
1064 
1065 }
1066