Document loading via XMPP

Firstly I added the loading code to the overridden setURI, and put a trap in the ActionListener added to the location bar. This didn't work:

One option was to implement the stream connection in an extension of one of the ParsedURL classes, ParsedURLProtocolHandler, but that class is too deep within Batik to reach any references to an XMPPConnection, let alone one connection of many - tricks with static variables or Maps with Threads as keys wouldn't work.

The chosen solution was to extend DocumentLoader.

The extended document loader requires a reference to the XMPPConnection which won't exist if the client isn't connected. If the client is not connected, then a normal DocumentLoader is created.

The extended document loader is called GradientDocumentLoader. It's an abstract class, with one protected abstract method, "setNextDocInfo". This method is implemented when the GradientDocumentLoader is instantiated as an anonymous inner class within GradientSVGCanvas. The method is used as a callback to update the canvas info that governs packet routing, as well as doing some pre-loading magic too (see Preloaded document packet queuing.). Since this info governs stanza routing, and therefore should be controlled carefully, creating a setThreadID() method with access of anything other than private or protected is a bad idea.

The GradientDocumentLoader instance will de-register the canvas from the PacketRouter if the document being loaded does not specify a thread.

Documents that specify an alternate location using the "src" attribute of the document response IQ are also handled correctly.

The canvas is only registered or re-registered with the packet router within the managerStopped method, which is an SVGDocumentLoaderListener event.

There are several places where a DocumentLoader is constructed, but only two that we care about for now:

To allow the setURLObject(URL) to be called on SVGOMDocument with a Gradient URL, a new URLStreamHandler implementation has to be created and its enclosing namespace registered via the java.protocol.handler.pkgs system property. This is done, but URLStreamHandler.openConnection merely throws an IOException, since Gradient connections have a lot of state to set up before making a request, and openConnection is best suited for protocols such as HTTP, and cannot be passed any information other than the target URL - and we also need an XMPPConnection to request it with.

The next issue is that the user information is removed from the URL before it is passed to the document handler. This is because the URL is loaded into a ParsedURL, which doesn't normally record user info, before being reserialised into a String. To fix this I patched ParsedURLData and ParsedURLDataProtocolHandler to record the user info.

Q: Why is setURI still being called twice?
A: I don't know.

© 2006. Some rights reserved. Author: Ian Sollars.