You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@xml.apache.org by Jacob Kjome <ho...@visi.com> on 2006/01/31 07:57:24 UTC

[resolver] - XCatalog support not functional in resolver package

Hello,

I'm making an attempt to update XMLC ( http://xmlc.enhydra.org/ ) to 
Xerces2 from Xerces (XMLC has dependencies on the Xerces1 implementation 
classes for various valid reasons that I won't go into here).  Along with 
that move, I lose native Xerces1 support for XCatalogs.  I realize it's the 
old catalog format, but it's been that way forever and XMLC needs to 
continue to support it.  However, as I've found out, XCatalog support in 
the resolver package is less than useful.  Here's a few reasons why.  Enjoy!...

1.  When registered via SAXCatalogReader.setCatalogParser(String, String, 
String), the XCatalogReader will never be successfully instantiated via 
Class.forName() because it doesn't have a default constructor.  You might 
also notice that this is the default way that Catalog.setupReaders() is 
implemented.  OASISXMLCatalogReader has a default constructor and doesn't 
suffer from this problem.

2.  Even if XCatalogReader had a default constructor so it could be 
successfully instantiated via reflection, it would fail to be found as a 
registered catalog parser because of a bad assumption.  In 
Catalog.setupReaders(), the XCatalog parser is setup like this...

saxReader.setCatalogParser(null, "XMLCatalog",
			       "org.apache.xml.resolver.readers.XCatalogReader");

Notice that null is passed for the namespaceURI.  Now, here's the method in 
SAXCatalogReader...

public void setCatalogParser(String namespaceURI,
			       String rootElement,
			       String parserClass) {
     if (namespaceURI == null) {
       namespaceMap.put(rootElement, parserClass);
     } else {
       namespaceMap.put("{"+namespaceURI+"}"+rootElement, parserClass);
     }
   }

So, when null is passed as the namespaceURI, it uses only the rootElement 
as the key in the Map.  The corresponding logic is done in 
getCatalogParser(String, String).  So far, so good.  However, in 
SAXCatalogParser.startElement(String, String, String, Attributes), when the 
parser is being initialized for the first time, it looks up the parser via 
getCatalogParser(String, String) always passing a non-null namespaceURI 
argument (I guess because the XML parser uses an empty string instead of 
null for a missing namespaceURI?).  So, the assumption made in 
set/getCatalogParser() falls flat on its face for XCatalogReader.  It will 
never be found because it was registered in the map with the key 
"XMLCatalog", but when it is looked up, it will always attempt to use the 
key "{}XMLCatalog", which will never exist.

3.  Now lets say both 1 and 2 are fixed.  Well, XCatalogReader assumes a 
root element of "XMLCatalog".  The javadoc says it supports the "XML 
Catalog format developed by John Cowan and supported by Apache".  Well, it 
was supported by Apache in Xerces1.  Except the DTD supplied there defines 
"XCatalog" as the root element, not "XMLCatalog".  This is not good for 
users of that DTD since the document will never validate against what 
XCatalogReader expects.  See the Xerces1 javadoc for XCatalog.java and the 
xcatalog.dtd for proof of this...

http://xerces.apache.org/xerces-j/apiDocs/org/apache/xerces/readers/XCatalog.html

http://svn.apache.org/viewcvs.cgi/xerces/java/branches/xerces_j_1/src/org/apache/xerces/readers/xcatalog.dtd?rev=317487&view=markup


4.  Let's say that 1 and 2 are a lost cause and we'll just ignore 3 by 
changing our root element to "XMLCatalog" in the XML and update the DTD to 
match this... or just stop referencing the DTD altogether to get around 
this problem (BTW, this is not an option for XMLC.  It needs to be 
"XCatalog" so that it matches the DTD which, it seems to me, ought to be 
distributed with resolver.jar just like the other catalog dtd, no?).  We 
just instantiate XCatalogReader directly and add it to the Catalog 
ourselves....

catalog.addReader("application/xml", new XCatalogReader(spf));

Then, we try it out.  Low and behold, it bombs out with a 
NullPointerException in startElement(String, String, String, Attributes) 
after parsing the first child entry of the root "XMLCatalog" element in my 
catalog, which is "Map" (I know this by subclassing XCatalogReader and 
implementing startElement(), doing some debugging, and then passing on 
execution to super.startElement()).  I'm not 100% sure exactly which line 
it blows chunks on because the classes in resovler.jar, distributed with 
Xerces-2.7.1, didn't have have debug enabled when compiling (does the pain 
ever stop?), but it is somewhere in here...

} else if (localName.equals("Map")) {
       entryType = catalog.PUBLIC;
       entryArgs.add(atts.getValue("PublicId"));
       entryArgs.add(atts.getValue("HRef"));

       catalog.getCatalogManager().debug.message(4, "Map",
		    PublicId.normalize(atts.getValue("PublicId")),
		    atts.getValue("HRef"));
} else ....


I suspect that the catalog is null for some reason, although I tried to 
hack it up and set the catalog in my implementation of startElement() 
before passing on execution to super.startElement(), but that didn't seem 
to help?  Maybe someone else can say?


So..... I guess the question is, did anyone actually test the functionality 
of XCatalogReader?  I'll take a wild guess at the 
answer.  No!  Why?  Because it's quite simply impossible for it to have 
passed any test, as I've shown above.

Will this be fixed in the next release?  I think Xerces-2.8.0 is going to 
be shipping in not too long, and it would be ever so nice if resolver.jar 
contained an XCatalogReader actually worked as advertised.  Please forgive 
the sharp tongue.  I tried to keep things relatively lighthearted, but I 
also wanted to convey a hint of bitterness after attempting, on and off, 
for a full day to get this to work, finally figuring out all the issues 
that I detailed above.  In any case, I hope my descriptions are useful in 
mapping out how to fix the existing problems.

thanks!

Jake


---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@xml.apache.org
For additional commands, e-mail: general-help@xml.apache.org