Wednesday 10 December 2008

XPath evaluation in Java using Namespaces

Earlier this year I wrote an article on testing Xpath expressions and XSL transformations in Java. This is no that hard if you know how to do it.

What I did not mention there is how to do xpath-queries on documents with namespaces.
Take for example the following xml:



<?xml version="1.0" encoding="UTF-8" ?>
<XSLBatch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.darwin-it.nl/XMLTypes/XSLBatch ../xsd/XSLBatch.xsd"
xmlns="http://www.darwin-it.nl/XMLTypes/XSLBatch">
<XSLTransform>
<Order>1</Order>
<SourceXMLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xml/sos_exportjobs.xml</SourceXMLFile>
<XSLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xsl/CreateObjectType_0.2.xsl</XSLFile>
<DestinationFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/output/sos_exportjobs.tps</DestinationFile>
</XSLTransform>
<XSLTransform>
<Order>2</Order>
<SourceXMLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xml/sos_exportjobs.xml</SourceXMLFile>
<XSLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xsl/CreateObjectTypeBody_0.2.xsl</XSLFile>
<DestinationFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/output/sos_exportjobs.tpb</DestinationFile>
</XSLTransform>
</XSLBatch>


If you want to do a query on all XSLTransforms, you would probably write an Xpath of the form:
/XSLBatch/XSLTransform

But if you try to do that with the statement:

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

then you find out that the NodeList nl would not deliver you any nodes.
This is because the XML document is of namespace: "http://www.darwin-it.nl/XMLTypes/XSLBatch" and this is not taken into account in the xpath expression above.
You could use an expression in the form of:
/xbt:XSLBatch/xbt:XSLTransform

But then: how does the parser know to what Namespace the abbreviation xbt resolves?

You could avoid the problem above with the expression:
/*[local-name()="XSLBatch"]/*[local-name()="XSLTransform"]
This is especially usefull if you have no means of specifying the namespaces you used.
But it makes the expressions very complex and if you need to query on a specific value of an attribute then you're out.

You can resolve this in Java quite easily with a NameSpace resolver. A what? A NameSpace resolver is a class that implements the oracle.xml.parser.v2.NSResolver interface. That is: using the Oracle XML parser.

A sample implementation of the Namespace Resolver is as follows:
package com.m10.xmlfiles;

import java.util.HashMap;

import oracle.xml.parser.v2.NSResolver;

public class XMLNSResolver implements NSResolver{
  private HashMap nsMap = new HashMap();
  
    public XMLNSResolver() {
    }

   public void addNS(String abbrev, String namespace){
       nsMap.put(abbrev, namespace);
   }
    public String resolveNamespacePrefix(String string) {
        return (String)nsMap.get(string);
    }
}

As you can see this implementation is fairly simple. It has a HashMap in which you can store your namespaces with an abbreviation as a key.
Since it inmplements the NSResolver interface it must implement the resolveNamespacePrefix. And that one does exactly what you might expect: it gives the namespace back that belongs to the abbreviation.

So if you do the following:
XMLNSResolver nsRes = new XMLNSResolver();
nsRes.addNS("xbt", "http://www.darwin-it.nl/XMLTypes/XSLBatch");
Then you can do your xpath query as follows:
NodeList nl = this.xmlDoc.selectNodes("/xbt:XSLBatch/xbt:XSLTransform", nsRes);

And that is how this is done.

Friday 5 December 2008

EDA the successor of SOA?


Today I read the remarkable article in the Computable that according to Gardner EDA (Event Driven Architecture) will be the successor of SOA (Service Oriented Architecture). That would suggest that EDA and its technology is newer than SOA or that EDA tools will replace the current SOA-tools. Well, I'm not that into the History of ICT. But about three years ago Oracle introduced their Enterprise Service Bus as part of the SoaSuite. You could consider the ESB as the succesor of Oracle's InterConnect in J2EE technology. Remarkable also is that you can find Oracle Workflow's Business Event System parts in the ESB technology. The Business Event System (the name sais it all) is part of Oracle Workflow since version 2.6, that was introduced in 2001 if I'm right.
Oracle Service Bus (fka. BEA's AquaLogic Service Bus) was introduced in 2005. And there are serveral other service busses maybe with an even longer history.

So Busineess Events could be (and should be) part of our applications since a long time. In fact Enterprise Application Integration (another Three Letter Acronym or TLA), is about firing and receiving business events from applications.

I believe that EDA does not succeed SOA. In fact SOA is about Services and Services on their own are not usefull. Services are triggered with an information object. And this infact is an event. Connecting Services in to a business flow (what we call "orchestration") is about passing Business Events between Services folowing a Business Process. Nowadays we tend to do that using BPEL or BPMN.

Therefore I would state that SOA = EDA + BPM. I must confess that I did not make that up on my own. Since I'm a former Oracle Employee, this is what I've learned from the positioning of Oracle's toolstack onto SOA.

Having a Service Bus is not a replacement of your SOA toolstack but a very valuable addition to it. It's a very good idea to have a Service Bus abstract your services from your Business Process. That makes it easier to do things like aggregating services, replacing services, transformations from Enterprise Business Objects to Application Business Objects, etc. But this article is not about the value of an Service Bus. For that I could write a complete separate article.

Read also this previous article.

Monday 1 December 2008

Unlock SVN Repository for SVN Sync

Lately I've been introduced into the ease of use of subversion. I now use it on my laptop to keep track of my projects. It's surprisingly easy to setup a repository and to use it. Maybe I should do a posting on that in the near future.

I also setup a local synced repository that I use to get a local copy of our central project repository. However, last week I started by accident this repository server twice, and stopped the sync-run by ctrl-c to resolve this. After that I got a:
"Failed to get lock on destination repos, currently held by makker-laptop" message repeatedly.

I got the solution on: http://journal.paul.querna.org/articles/2006/09/14/using-svnsync/.

However the exact command mismatched for me (I don't know how version dependent that is).

What I had to do is to delete the lock by removing a lock-property. The command for this is:

svn propdel svn:sync-lock --revprop -r 0 .

In Pauls blog he suggested the svn-command propdelete, but this should be propdel. And I had to make up that for the repository you have to give in the link to the svnserver that runs the repository.

For example:
svn propdel svn:sync-lock --revprop -r 0 svn://localhost:3904

This worked, and got me syncing my repositories again.