A Confluence GUI Client in 200 Lines of Code

by Charles Miller on February 5, 2004

One of the features due to be rolled out in Confluence RC1 is the remote API. It comes in XML-RPC and SOAP flavours for your remote-editing pleasure. The only way to really test such a feature is to build a of client around it. Until you've built a client, you can't really know if your API is any good.

If you're designing an API, read the last sentence of that paragraph again. Keep reading it until it is embedded in your psyche.

Anyway, the first attempt at a client was written in Swing. we're a Java shop, after all, and you go with the tool that's most familiar first. And to Swing's credit, Mike had a Swing client up and running pretty quickly using IDEA's GUI-building tool.

The problem turned out to be HTML. The killer feature of the client: the one that would make people go "ooh, what a neat demo" instead of "yawn, its just a couple of list-boxes" was going to be the side-by-side editing. You write your page in Wiki-notation, and when you flip to the Preview pane, the client asks Confluence to convert it into nice shiny HTML for you to view. Unfortunately, Swing's HTML component still lives somewhere in the deep recesses of HTML3.2, so that was about as far as that client went.

This limited our options somewhat. If you want a decent HTML engine, your choices narrow quite considerably, especially if nobody owns up to knowing XUL or C, or wanting to program anything for Windows. :)

Apple's WebKit to the rescue. WebKit is so insanely easy to use that I'm amazed every OS X application doesn't do it somewhere, just for the fun of it. Maybe they do.

[[webView mainFrame] loadHTMLString:renderedContent baseUrl:pageBaseUrl];

That's basically... it. The entirety of the interaction you need to have with WebKit to render some HTML1.

By the end of the day we had about 200 lines of source-code, and a client that could drill down the spaces and pages in a Confluence site, view its unrendered and rendered content side-by-side, and preview changes in the HTML pane. About 70 lines of that code was the controller class, the other 130 were my painfully ugly and naive attempts to get XML-RPC working properly under Objective-C.

Ah yes, Objective-C. It took about four hours of on-off pairing to write those 200 lines of code. Despite my oft-stated affection for Cocoa, I only get to use it about once every six months, so while I have some vague notion of the syntax and how the pieces fit together, pretty much everything has to be looked up in the reference documentation first.

I might have been better off with PyObjC or RubyCocoa, especially as far as that line-number count is concerned: both scripting languages have powerful and simple interfaces to XML-RPC. Unfortunately, OS X only ships with Ruby 1.6, which doesn't include the XML-RPC libraries (1.8 does. Grr, Apple. Get up to date), and as much as I admire Python, I know even less about it than I do Objective-C, and coming to grips with Python and PyObjC and Cocoa at the same time would have been just that little bit too much.

Hopefully, we'll be able to polish the client (and its code) up in the next day or two so we can put the source-code up somewhere.

1 Well, the only programmatic interaction. You still, obviously, need to drag the WebView component onto the canvas in Interface Builder, and draw a line between it and the controller class. But that doesn't really count.

Previously: Spamwords

Next: The Java Seige Mentality