cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dennis Sosnoski <...@sosnoski.com>
Subject Re: JiBX databinding implementation
Date Sat, 29 May 2010 03:26:20 GMT
Nilupa Bandara wrote:
> Hello Everyone,
>
> The code that I've written so far is available at[1], [2] and it for simple
> data types. I've used the Axis2 JiBX implementation as guide and now I am
> working on implementing the complex data type support.
>   

I haven't had a chance to look at this in any detail, but I suspect you 
may be going off track. The Axis2 support uses code generation of the 
actual stub code called by the client to access the server, and the 
message receiver code on the server side which calls the service method. 
The simple data type support comes in when unwrapping a request message 
from the WSDL to pass the child elements as method parameters.

 From what I understand of CXF's implementation it always uses a wrapper 
class that matches the actual request or response message element (which 
is the content of the SOAP Body element), and handles converting this 
into method parameters with shared logic. So you shouldn't need to work 
with the simple data types at all.

What I'd think you would need to work on would be handling the actual 
JiBX conversions to and from the SOAP Body. I've tried taking a look at 
the XMLBeans support in CXF to see if I could get a handle on how this 
needs to be done, but I find the code hard to follow with the only 
comments brief one-liners on interface method definitions. So here's my 
take on how I think this should work, and perhaps Dan or someone else 
can help match this up with the CXF structure.

To start with, you need to have some sort of configuration which tells 
you how to access the JiBX binding factory. JiBX is very flexible in how 
it handles bindings, including allowing multiple bindings of the same 
class to different XML representations. Each binding has an associated 
factory class used to work with that binding at runtime. You load a 
binding factory using the methods in org.jibx.runtime.BindingDirectory, 
which work with several variations of parameters:

   1. by the binding name and base Java package in the binding
   2. by the binding name and one of the classes mapped in that binding
   3. by one of the classes mapped in the binding (if that class is only
      involved in one binding).

You can pass a classloader to the first two variations, to specify where 
the classes can be found. If you don't supply a classloader, the 
BindingDirectory does its best to find things using the classloader 
which loaded the class you pass in (if using a class) or the classloader 
which loaded the BindingDirectory class (if using package name lookup). 
Binding factories are thread-safe and can be cached once you've found them.

When handling input, you need to start with the XMLStreamReader 
positioned at the start tag of the message element (the child of the 
SOAP Body element). You create an unmarshalling context instance from 
the binding factory which you'll use for unmarshalling the data. This is 
an interface, but for your purposes you'll need to cast it to the actual 
implementation class org.jibx.runtime.impl.UnmarshallingContext and use 
the setDocument() method which takes an IXMLReader instance. You create 
the IXMLReader instance from your existing XMLStreamReader using the 
org.jibx.runtime.impl.StAXReaderWrapper constructor. You should be able 
to just call the unmarshalElement() method of the unmarshalling context 
and get back the unmarshalled instance.

It looks like you've figured out much of this, but I wanted to spell it 
out to help you understand the sequence. From your stack trace it 
appears you're calling parseElementText(), which is definitely not what 
you want to use - this just returns text content for an element with no 
child elements.

Handling output is a little different You first create a marshalling 
context, then a org.jibx.runtime.impl.StAXWriter using the constructor 
which takes an XMLStreamWriter (for the namespace URIs, just pass an 
array with the two required values listed in the method JavaDocs), and 
set the StAXWriter on the marshalling context. Then cast the object 
you're going to marshal to the org.jibx.runtime.IMarshallable interface 
(which is added to each mapped class by the JiBX binding compiler) and 
call the marshal() method defined by this interface.

Hope this gets you further. Keep us posted on this list and I'll try to 
provide pointers whenever you run into problems.

Once the basic JiBX runtime support is working we can discuss how to 
integrate JiBX code generation from schema, but I think the basic 
runtime support is the most important step.

  - Dennis


Mime
View raw message