Thursday 26 June 2008

Testing XSL and Xpath with Java Swing

This week I finished a first version of a little java application that I created to build and test xpath expressions and xslt stylesheets.

I was very charmed with the little tool XTrans( http://www.simxtech.com/users/zc2/xtrans/). This smart tool is extreemly small (only a few KB) and enables you to edit xslt's, load xml files and transform them with the created xslt. Unfortunately for me is that it is a windows application, based on the MSXML parser. And I've not found a counterpart on Linux yet. Oh, of course you could do a lot of that with jDeveloper or XMLSpy. Maybe even better. But XTrans is so small and if you're working with xslt's, sometimes the only thing you need is a good ascii-editor and an xmlparser. And a little driver application that helps you with driving your xml and xslt trough the xmlparser.

So I found it usefull to create my own Xsl and xpath tester application.

Besides the arguments above it was also a nice excersise to play a little with the xmlparser (I used the Oracle parser shipped with jDeveloper). Although I have experience with xml, xslt and xpath, I mainly used it from Xtrans, jDeveloper or the Oracle Database (from Pl/Sql). Not directly in Java. And it is very usefull to be able do that. For example when you need to create a custom method within an ADF application, embedded Java or Java WSIF binding in BPEL.

Last year I created two little applications to test-drive messages into Integration B2b and into Axway Cyclone (another B2B product). These little applications help you to send messages with these products based on their configuration (repository or cpa). For these applications I had to parse a CPA (Collaboration Protocol Agreement) to populate the different pop-lists. Back then I did it just by browsing through the NodeLists. I created a few wrapper classes to help me with that. But I couldn't find the proper method to execute a xpath-expression. Also that turns out to be simple, when you know how:

...
private XMLDocument xmlDoc;
...
public NodeList selectNodes(String xpath) throws XSLException {
NodeList nl = this.xmlDoc.selectNodes(xpath);
return nl;
}


Another nice side effect of these little apps is that I got me to play a little with Java Swing. Nowadays people create enterprise applications using frameworks like Oracle Java ADF, JSF, JSP, ADF Components for Java, etc. But for lots of things you don't need and thus don't want the large footprint of a Application Server. And then Java Swing is very nice. It brought me back memories of Oracle Forms, with it's triggers and so on. Also it looked very familiar, thinking back, to Borland Delphi. But that's not strange: jDeveloper originated years ago from Borland jBuilder. Back then Borland used to create smart IDE's for Turbo Pascal/Delphi, C/C++ and Java. And they were in fact all the same. Oh, how much fun I had with Turbo Pascal 5.5. You could build the world with an IDE that fitted on a single floppy.

jDeveloper enables you to 'paint' your frames and panels. And double clicking on a button creates an ActionListener that you only have to fill with a call to an appropriate method.

The two B2B-applications I created last year were my first Swing apps after years. I had to re-invent how to build up an application using Swing-components and containers. When you create a Swing project in jDeveloper it gives you an application and a class that is an extension of JFrame. That's fine if you're building a one-screen application. But if you want a multi-screen application with the different screens changeable from a menu from the same main-frame, that turns out to be unhandy.

What I did was to abstract the menu and the toolbar to separate classes to maintain. In Oracle Forms the menu is also a separate module. It's a pity that there is no graphical method to build up the menu.

Also the panels became separate classes that are extensions of JPanel. I created a little method in the main-frame, that replaces the central-content-pane with one of these panels. This method I can call from the menu.

Then I created a "resize sub-components" method in the main frame class:
private void resizeSubComponents() {
int width = this.getWidth();
int height = this.getHeight();
xmlFilePanel.resizeComponents(width, height);
xpathTestPanel.resizeComponents(width, height);
xsltTestPanel.resizeComponents(width, height);
}

that is called from the Frame's component-listener:
this.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent componentEvent) {
resizeSubComponents();
}

public void componentMoved(ComponentEvent componentEvent) {
}

public void componentShown(ComponentEvent componentEvent) {
}

public void componentHidden(ComponentEvent componentEvent) {
}
});

This method calls the resize methods in the different panels. When the mainframe is resized or maximized the different panels get resized also. Since I have several textareas with the xml-files in it, it is handy that they grow and shrink with the main frame, maximizing the available screen area.

What I have to check out is the use of inner-frames. I read about it. I want to give each panel it's own frame within the mainframe. then you have an application that is like Oracle forms, with it's different modules within the main-window. Something like a wordprocessor that can have multiple documents open.

So Swing is very nice and very powerfull to create small applications that run everywhere. But you have to find yourself a way to split up your application in smart components that are separatly maintainable. jDeveloper does not help you much with that.

I uploaded my tool on http://www.darwin-it.nl/downloads/xmltester_v0.1.zip. Just unzip it, and then change the xmltester.sh or xmltester.bat file. In the file you see a parameter "JAVA_BASE". You should change the file path to the proper location of jour Java JRE or SDK.

No comments :