I got a lot more done today, but I didn't finish the exclude code as I'd expected. I started out by realizing that the
ConstraintNegationTuples has a second constructor that I hadn't noticed before, and this one accepts the parameters I'm interested in. After that, it was a matter of only 2 methods and it would be a full
Resolution object, so I copied it over my earlier work and modified it.
Of course things never go quite as smoothly as planned. The semantics of the statement store are slightly different, so I had to update a few things. Then when I ran the code I discovered that this inverted resolution class wasn't even being created. Quite a bit of debugging later, and I discovered that the
Constraint object I was being given was not a
ConstraintNegation. I was also able to log the fact that a
ConstraintNegation was being created by the client, and received by the server. So somewhere after that I was losing the information that the constraint was inverted.
It doesn't sound like a lot, but the last two paragraphs were actually quite a bit of work. Certainly more effort than over the last two days.
Tonight I tried to continue the debugging at home, but that led to its own problem. I've installed Java 1.5 at home, but this doesn't support Kowari yet. So I could either go back to the old compiler, setting up the environment variables, etc, or else I could try and get Kowari to compile under 1.5.
Since it was after hours, I figured I could do the more enjoyable thing and had a go at porting. :-)
The first class to have problems was
PIErrorHandler. This includes the class
WrappedRuntimeException, which is an internal class from the Apache XML support library in Java 1.4. Speaking with KA I've learned that he was intent to obtain the source of all exceptions. Since this class can be thrown, it is necessary to pull out the wrapped exception to find out the real source of the problem. The best way to do this seemed to be to use reflection to find the
getException method. This matched up nicely with a method of the same name in the
SAXException class which can also be shown.
The next problem was with another "1.4 only" class called
SAXSourceLocator. Again, this is an internal class for XML which is not included in Java 1.5. However, this time it meets a publicly available interface:
javax.xml.transform.SourceLocator. There is no public implementation for this interface, but there is an identical interface,
org.xml.sax.Locator which does have a public implementation called
org.xml.sax.helpers.LocatorImpl. With identical methods, all I needed to do was merge the two into a class which extended
SourceLocator. I liked the way this worked, as it didn't borrowed the implementing methods from
LocatorImpl for the unrelated
SourceLocator interface, and it required no code to do it. It made sense to me, as the interfaces were created for the same reasons. Maybe they should have been merged already.
The next problems come from the changes to Xalan in the latest JVM. This is due to the need to implement XSLT extensions. Reading the online documentation, this requires the use of
org.apache.xalan.templates.ElemExtensionCall. Unfortunately, Java 1.4 never made these classes publicly available, and the version of Xalan that comes with 1.5 doesn't include them.
I've been looking online for the latest way to implement XSL element extensions, but the only examples I can find are for the previous version of Xalan. The latest version of Xalan includes the new XSLT Extensions library, which is an example of this, but I've yet to find any documentation on how it was done. At this point I'm thinking that I will need to find the source code for this library in order to find out how it is done. After that I'll be trying to work out how to do a portable implementation that will work with both versions.
Wednesday, November 10, 2004