XMLReaderFactory.createXMLReader()

Elliotte Harold <[email protected]> Sun, 25 Apr 2004 11:42:01 -0400
Newsgroups gmane.text.xml.sax.devel
Message-ID <[email protected]>
The failure of the no-args version of XMLReaderFactory.createXMLReader() 
has long been a problem for users. Parser vendors are supposed to 
rewrite this method so that it works with their parser. In practice they 
don't. This patch fixes that problem in two ways:

1. It modifies the JavaDoc to make it blindingly obvious that parser 
vendors are expected to rewrite this method and rewrite the class.

2. It changes the default implementation so that if the parser vendor 
does not rewrite this method, and none of the usual mechanisms for 
finding parsers succeed, then it attempts to load one of nine known 
parser classes whose names are hard coded into the source. If the user 
has some common parser somewhere in their classpath, this method will 
now find it, even if no META-INFO or system properties have been set.

--
Elliotte Rusty Harold
factory.patch (text/plain, 3.2 KB)
Index: src/org/xml/sax/helpers/XMLReaderFactory.java
===================================================================
RCS file: /cvsroot/sax/sax2/src/org/xml/sax/helpers/XMLReaderFactory.java,v
retrieving revision 1.10
diff -u -r1.10 XMLReaderFactory.java
--- src/org/xml/sax/helpers/XMLReaderFactory.java	22 Apr 2002 01:00:13 -0000	1.10
+++ src/org/xml/sax/helpers/XMLReaderFactory.java	25 Apr 2004 15:23:45 -0000
@@ -74,7 +74,11 @@
      *
      * <li> SAX parser distributions are strongly encouraged to provide
      * a default XMLReader class name that will take effect only when
-     * previous options (on this list) are not successful.</li>
+     * previous options (on this list) are not successful.
+     * This requires modifying the source code for this class.
+     * This will not work if you ship the default sax2.jar archive.</li>
+     *
+     * <li> The classpath is searched for any of several known parsers.</li>
      *
      * <li>Finally, if {@link ParserFactory#makeParser()} can
      * return a system default SAX1 parser, that parser is wrapped in
@@ -96,9 +100,9 @@
      * environments, with less robust implementations of this method.
      * </p>
      *
-     * @return A new XMLReader.
-     * @exception org.xml.sax.SAXException If no default XMLReader class
-     *            can be identified and instantiated.
+     * @return a new XMLReader
+     * @throws org.xml.sax.SAXException if no default XMLReader class
+     *            can be identified and instantiated
      * @see #createXMLReader(java.lang.String)
      */
     public static XMLReader createXMLReader ()
@@ -148,7 +152,17 @@
 	if (className != null)
 	    return loadClass (loader, className);
 
-	// 4. panic -- adapt any SAX1 parser
+	// 4. panic -- use any SAX2 parser we can find
+    for (int i = 0; i < parsers.length; i++) {
+        try { 
+            return XMLReaderFactory.createXMLReader(parsers[i]);
+        }
+        catch (SAXException ex) {
+            // try the next one 
+        }       
+    }
+    
+	// 5. panic -- adapt any SAX1 parser
 	try {
 	    return new ParserAdapter (ParserFactory.makeParser ());
 	} catch (Exception e) {
@@ -158,6 +172,19 @@
     }
 
 
+    private static String[] parsers = {
+        "org.apache.xerces.parsers.SAXParser",
+        "gnu.xml.aelfred2.XmlReader",
+        "org.apache.crimson.parser.XMLReaderImpl",
+        "com.bluecast.xml.Piccolo",
+        "oracle.xml.parser.v2.SAXParser",
+        "com.jclark.xml.sax.SAX2Driver",
+        "net.sf.saxon.aelfred.SAXDriver",
+        "com.icl.saxon.aelfred.SAXDriver",
+        "org.dom4j.io.aelfred.SAXDriver"
+    };    
+    
+    
     /**
      * Attempt to create an XML reader from a class name.
      *
@@ -168,9 +195,9 @@
      * the caller (perhaps an applet) is not permitted to load classes
      * dynamically.</p>
      *
-     * @return A new XML reader.
-     * @exception org.xml.sax.SAXException If the class cannot be
-     *            loaded, instantiated, and cast to XMLReader.
+     * @return a new XML reader
+     * @throws org.xml.sax.SAXException if the class cannot be
+     *            loaded, instantiated, and cast to XMLReader
      * @see #createXMLReader()
      */
     public static XMLReader createXMLReader (String className)