Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / gnu / xml / libxmlj / sax / GnomeXMLReader.java
blob846015a1c31f14ac3c71a87ea88b2adf6f7fe4e8
1 /* GnomeXMLReader.java -
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
38 package gnu.xml.libxmlj.sax;
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;
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;
66 import gnu.xml.libxmlj.util.NamedInputStream;
67 import gnu.xml.libxmlj.util.StandaloneLocator;
68 import gnu.xml.libxmlj.util.XMLJ;
70 /**
71 * A SAX2 parser that uses libxml2.
73 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
75 public class GnomeXMLReader
76 implements XMLReader
79 static
81 XMLJ.init ();
84 private static final String FEATURES_PREFIX =
85 "http://xml.org/sax/features/";
87 private static final List RECOGNIZED_FEATURES =
88 Arrays.asList (new String[]
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"
104 private static final String PROPERTIES_PREFIX =
105 "http://xml.org/sax/properties/";
107 private static final List RECOGNIZED_PROPERTIES =
108 Arrays.asList (new String[]
110 "declaration-handler",
111 "dom-node",
112 "lexical-handler",
113 "xml-string"
116 // Features
118 private transient boolean standalone;
119 private boolean namespaces;
120 private boolean namespacePrefixes;
121 private boolean validation;
123 // Callback handlers
125 private ContentHandler contentHandler;
127 private DTDHandler dtdHandler;
129 private EntityResolver entityResolver;
131 private ErrorHandler errorHandler;
133 private DeclHandler declarationHandler;
135 private LexicalHandler lexicalHandler;
137 private GnomeLocator locator;
139 // Namespace helper for handling callbacks
140 private transient Namespaces ns;
142 // If true, do not invoke callback methods except endDocument
143 private transient boolean seenFatalError;
145 private transient boolean seenStartDocument;
147 private transient String base;
149 public GnomeXMLReader ()
151 this (true, true);
154 public GnomeXMLReader (boolean namespaces, boolean validation)
156 this.namespaces = namespaces;
157 this.validation = validation;
158 ns = new Namespaces ();
161 public ContentHandler getContentHandler ()
163 return contentHandler;
166 public void setContentHandler (ContentHandler handler)
168 contentHandler = handler;
171 public DTDHandler getDTDHandler ()
173 return dtdHandler;
176 public void setDTDHandler (DTDHandler handler)
178 dtdHandler = handler;
181 public EntityResolver getEntityResolver ()
183 return entityResolver;
186 public void setEntityResolver (EntityResolver resolver)
188 entityResolver = resolver;
191 public ErrorHandler getErrorHandler ()
193 return errorHandler;
196 public void setErrorHandler (ErrorHandler handler)
198 errorHandler = handler;
201 // Features
203 public boolean getFeature (String name)
204 throws SAXNotRecognizedException, SAXNotSupportedException
206 checkFeatureName (name);
207 String key = name.substring (FEATURES_PREFIX.length ());
208 if ("external-general-entities".equals (key))
210 return validation; // TODO check this
212 else if ("external-parameter-entities".equals (key))
214 return validation; // TODO check this
216 else if ("is-standalone".equals (key))
218 return standalone;
220 else if ("namespaces".equals (key))
222 return namespaces;
224 else if ("namespace-prefixes".equals (key))
226 return namespacePrefixes;
228 else if ("resolve-dtd-uris".equals (key))
230 return true;
232 else if ("validation".equals (key))
234 return validation;
236 else
238 return false;
242 public void setFeature (String name, boolean value)
243 throws SAXNotRecognizedException, SAXNotSupportedException
245 checkFeatureName (name);
246 String key = name.substring (FEATURES_PREFIX.length ());
247 if ("namespaces".equals (key))
249 namespaces = value;
251 else if ("namespace-prefixes".equals (key))
253 namespacePrefixes = value;
255 else if ("validation".equals (key))
257 validation = value;
262 * Check that the specified feature name is recognized.
264 static void checkFeatureName (String name)
265 throws SAXNotRecognizedException
267 if (name == null || !name.startsWith (FEATURES_PREFIX))
269 throw new SAXNotRecognizedException (name);
271 String key = name.substring (FEATURES_PREFIX.length ());
272 if (!RECOGNIZED_FEATURES.contains (key))
274 throw new SAXNotRecognizedException (name);
278 // Properties
280 public Object getProperty (String name)
281 throws SAXNotRecognizedException, SAXNotSupportedException
283 checkPropertyName (name);
284 String key = name.substring (PROPERTIES_PREFIX.length ());
285 if ("declaration-handler".equals (key))
287 return getDeclarationHandler ();
289 else if ("lexical-handler".equals (key))
291 return getLexicalHandler ();
293 else
295 throw new SAXNotSupportedException (name);
299 public void setProperty (String name, Object value)
300 throws SAXNotRecognizedException, SAXNotSupportedException
302 checkPropertyName (name);
303 String key = name.substring (PROPERTIES_PREFIX.length ());
304 if ("declaration-handler".equals (key))
306 setDeclarationHandler ((DeclHandler) value);
308 else if ("lexical-handler".equals (key))
310 setLexicalHandler ((LexicalHandler) value);
314 public DeclHandler getDeclarationHandler ()
316 return declarationHandler;
319 public void setDeclarationHandler (DeclHandler declarationHandler)
321 this.declarationHandler = declarationHandler;
324 public LexicalHandler getLexicalHandler ()
326 return lexicalHandler;
329 public void setLexicalHandler (LexicalHandler lexicalHandler)
331 this.lexicalHandler = lexicalHandler;
335 * Check that the specified property name is recognized.
337 static void checkPropertyName (String name)
338 throws SAXNotRecognizedException
340 if (!name.startsWith (PROPERTIES_PREFIX))
342 throw new SAXNotRecognizedException (name);
344 String key = name.substring (PROPERTIES_PREFIX.length ());
345 if (!RECOGNIZED_PROPERTIES.contains (key))
347 throw new SAXNotRecognizedException (name);
351 // Parse
353 public void parse (String systemId)
354 throws IOException, SAXException
356 URL url = null;
359 url = new URL (systemId);
361 catch (MalformedURLException e)
363 File file = new File(systemId);
364 if (!file.exists ())
366 throw new FileNotFoundException (systemId);
368 String path = file.getAbsolutePath();
369 if (File.separatorChar != '/')
371 path = path.replace (File.separatorChar, '/');
373 if (!path.startsWith ("/"))
375 path = "/" + path;
377 if (!path.endsWith ("/") && file.isDirectory ())
379 path = path + "/";
381 url = new URL ("file:" + path);
383 InputSource source = new InputSource(url.toString ());
384 source.setByteStream (url.openStream ());
385 parse (source);
388 public synchronized void parse (InputSource input)
389 throws IOException, SAXException
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)
402 int lsi = systemId.lastIndexOf ('/');
403 if (lsi != -1)
405 base = systemId.substring (0, lsi + 1);
408 // Handle zero-length document
409 if (detectBuffer == null)
411 startDocument (true);
412 fatalError ("No document element", 0, 0, publicId, systemId);
413 endDocument ();
414 return;
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 ();
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;
446 String getURI (String prefix)
448 if (!namespaces)
450 return null;
452 return ns.getURI (prefix);
455 // Callbacks from libxmlj
457 private void startDTD (String name, String publicId, String systemId)
458 throws SAXException
460 if (seenFatalError || lexicalHandler == null)
462 return;
466 systemId = XMLJ.getAbsoluteURI (base, systemId);
467 lexicalHandler.startDTD (name, publicId, systemId);
469 catch (Exception e)
471 if (e instanceof SAXException)
473 throw (SAXException) e;
475 else
477 throw new SAXException (e);
482 private void externalEntityDecl (String name, String publicId,
483 String systemId)
484 throws SAXException
486 if (seenFatalError || declarationHandler == null)
488 return;
492 systemId = XMLJ.getAbsoluteURI (base, systemId);
493 declarationHandler.externalEntityDecl (name, publicId, systemId);
495 catch (Exception e)
497 if (e instanceof SAXException)
499 throw (SAXException) e;
501 else
503 throw new SAXException (e);
508 private void internalEntityDecl (String name, String value)
509 throws SAXException
511 if (seenFatalError || declarationHandler == null)
513 return;
517 declarationHandler.internalEntityDecl (name, value);
519 catch (Exception e)
521 if (e instanceof SAXException)
523 throw (SAXException) e;
525 else
527 throw new SAXException (e);
532 private InputStream resolveEntity (String publicId, String systemId)
533 throws SAXException, IOException
535 if (entityResolver == null)
537 return null;
541 systemId = XMLJ.getAbsoluteURI (base, systemId);
542 InputSource source = entityResolver.resolveEntity (publicId, systemId);
543 return (source == null) ? null : XMLJ.getInputStream (source);
545 catch (Exception e)
547 if (e instanceof SAXException)
549 throw (SAXException) e;
551 else
553 throw new SAXException (e);
558 private void notationDecl (String name, String publicId, String systemId)
559 throws SAXException
561 if (seenFatalError || dtdHandler == null)
563 return;
567 systemId = XMLJ.getAbsoluteURI (base, systemId);
568 dtdHandler.notationDecl (name, publicId, systemId);
570 catch (Exception e)
572 if (e instanceof SAXException)
574 throw (SAXException) e;
576 else
578 throw new SAXException (e);
583 private void attributeDecl (String eName, String aName, String type,
584 String mode, String value)
585 throws SAXException
587 if (seenFatalError || declarationHandler == null)
589 return;
593 declarationHandler.attributeDecl (eName, aName, type, mode, value);
595 catch (Exception e)
597 if (e instanceof SAXException)
599 throw (SAXException) e;
601 else
603 throw new SAXException (e);
608 private void elementDecl (String name, String model)
609 throws SAXException
611 if (seenFatalError || declarationHandler == null)
613 return;
617 declarationHandler.elementDecl (name, model);
619 catch (Exception e)
621 if (e instanceof SAXException)
623 throw (SAXException) e;
625 else
627 throw new SAXException (e);
632 private void unparsedEntityDecl (String name, String publicId,
633 String systemId, String notationName)
634 throws SAXException
636 if (seenFatalError || dtdHandler == null)
638 return;
642 systemId = XMLJ.getAbsoluteURI (base, systemId);
643 dtdHandler.unparsedEntityDecl (name, publicId, systemId,
644 notationName);
646 catch (Exception e)
648 if (e instanceof SAXException)
650 throw (SAXException) e;
652 else
654 throw new SAXException (e);
659 private void setDocumentLocator (Object ctx, Object loc)
661 locator = new GnomeLocator (ctx, loc);
662 if (seenFatalError || contentHandler == null)
664 return;
668 contentHandler.setDocumentLocator (locator);
670 catch (Exception e)
675 private void startDocument (boolean standalone)
676 throws SAXException
678 this.standalone = standalone;
679 seenStartDocument = true;
680 if (contentHandler == null)
682 return;
686 contentHandler.startDocument ();
688 catch (Exception e)
690 if (e instanceof SAXException)
692 throw (SAXException) e;
694 else
696 throw new SAXException (e);
701 private void endDocument ()
702 throws SAXException
704 if (contentHandler == null)
706 return;
710 contentHandler.endDocument();
712 catch (Exception e)
714 if (e instanceof SAXException)
716 throw (SAXException) e;
718 else
720 throw new SAXException (e);
725 private void startElement(String name, String[] attrs)
726 throws SAXException
728 if (seenFatalError || contentHandler == null)
730 return;
734 XMLName xName = new XMLName (this, name);
735 if (namespaces)
737 // Handle defined namespaces
738 ns.push ();
739 int len = (attrs == null) ? 0 : attrs.length;
740 if (len > 0)
742 ArrayList filtered = new ArrayList (len);
743 for (int i = 0; i < len; i += 2)
745 String attName = attrs[i];
746 String attValue = attrs[i + 1];
747 if (attName.equals ("xmlns"))
749 startPrefixMapping ("", attValue);
751 else if (attName.startsWith ("xmlns:"))
753 startPrefixMapping (attName.substring (6), attValue);
755 else
757 filtered.add (attName);
758 filtered.add (attValue);
761 // Remove xmlns attributes
762 attrs = new String[filtered.size ()];
763 filtered.toArray (attrs);
766 // Construct attributes
767 Attributes atts = new StringArrayAttributes (this, attrs);
768 contentHandler.startElement (xName.uri, xName.localName, xName.qName,
769 atts);
771 catch (Exception e)
773 if (e instanceof SAXException)
775 throw (SAXException) e;
777 else
779 throw new SAXException (e);
784 private void endElement (String name)
785 throws SAXException
787 if (seenFatalError || contentHandler == null)
789 return;
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)
799 for (Iterator i = ns.currentPrefixes (); i.hasNext (); )
801 endPrefixMapping ((String) i.next ());
803 ns.pop (); // releases current depth
806 catch (Exception e)
808 if (e instanceof SAXException)
810 throw (SAXException) e;
812 else
814 throw new SAXException (e);
819 private void startPrefixMapping (String prefix, String uri)
820 throws SAXException
822 if (seenFatalError || contentHandler == null)
824 return;
826 ns.define (prefix, uri);
827 contentHandler.startPrefixMapping (prefix, uri);
830 private void endPrefixMapping (String prefix)
831 throws SAXException
833 if (seenFatalError || contentHandler == null)
835 return;
837 contentHandler.endPrefixMapping (prefix);
840 private void characters (String text)
841 throws SAXException
843 if (seenFatalError || contentHandler == null || text == null)
845 return;
849 char[] ch = text.toCharArray ();
850 contentHandler.characters (ch, 0, ch.length);
852 catch (Exception e)
854 if (e instanceof SAXException)
856 throw (SAXException) e;
858 else
860 throw new SAXException (e);
865 private void ignorableWhitespace (String text)
866 throws SAXException
868 if (seenFatalError || contentHandler == null || text == null)
870 return;
874 char[] ch = text.toCharArray ();
875 contentHandler.ignorableWhitespace (ch, 0, ch.length);
877 catch (Exception e)
879 if (e instanceof SAXException)
881 throw (SAXException) e;
883 else
885 throw new SAXException (e);
890 private void processingInstruction (String target, String data)
891 throws SAXException
893 if (seenFatalError || contentHandler == null)
895 return;
899 if (data == null)
901 data = "";
903 contentHandler.processingInstruction (target, data);
905 catch (Exception e)
907 if (e instanceof SAXException)
909 throw (SAXException) e;
911 else
913 throw new SAXException (e);
918 private void comment (String text)
919 throws SAXException
921 if (seenFatalError || lexicalHandler == null || text == null)
923 return;
927 char[] ch = text.toCharArray ();
928 lexicalHandler.comment (ch, 0, ch.length);
930 catch (Exception e)
932 if (e instanceof SAXException)
934 throw (SAXException) e;
936 else
938 throw new SAXException (e);
943 private void cdataBlock (String text)
944 throws SAXException
946 if (seenFatalError || text == null)
948 return;
952 if (lexicalHandler == null)
954 characters(text);
956 else
958 lexicalHandler.startCDATA();
959 characters(text);
960 lexicalHandler.endCDATA();
963 catch (Exception e)
965 if (e instanceof SAXException)
967 throw (SAXException) e;
969 else
971 throw new SAXException (e);
976 private void warning (String message,
977 int lineNumber, int columnNumber,
978 String publicId, String systemId)
979 throws SAXException
981 if (seenFatalError || errorHandler == null)
983 return;
987 Locator l = new StandaloneLocator (lineNumber, columnNumber,
988 publicId, systemId);
989 errorHandler.warning (new SAXParseException (message, l));
991 catch (Exception e)
993 if (e instanceof SAXException)
995 throw (SAXException) e;
997 else
999 throw new SAXException (e);
1004 private void error (String message,
1005 int lineNumber, int columnNumber,
1006 String publicId, String systemId)
1007 throws SAXException
1009 if (seenFatalError || errorHandler == null)
1011 return;
1015 Locator l = new StandaloneLocator (lineNumber, columnNumber,
1016 publicId, systemId);
1017 errorHandler.error (new SAXParseException (message, l));
1019 catch (Exception e)
1021 if (e instanceof SAXException)
1023 throw (SAXException) e;
1025 else
1027 throw new SAXException (e);
1032 private void fatalError (String message,
1033 int lineNumber, int columnNumber,
1034 String publicId, String systemId)
1035 throws SAXException
1037 if (seenFatalError || errorHandler == null)
1039 return;
1043 if (!seenStartDocument)
1045 startDocument (false);
1047 seenFatalError = true;
1048 Locator l = new StandaloneLocator (lineNumber, columnNumber,
1049 publicId, systemId);
1050 errorHandler.fatalError (new SAXParseException (message, l));
1052 catch (Exception e)
1054 if (e instanceof SAXException)
1056 throw (SAXException) e;
1058 else
1060 throw new SAXException (e);