You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Dennis Sosnoski <dm...@sosnoski.com> on 2010/07/21 20:25:01 UTC

JiBX Databinding: databinding interface methods

I've been looking at supplying the information needed by CXF from JiBX
code generation, in particular that represented by the
org.apache.cxf.tools.wsdlto.core.DataBindingProfile interface methods
String getType(QName qn, boolean element) and String
getWrappedElementType(QName wrapperElement, QName item).

I figure these are used to handle adding data to a wrapper bean on the
client side, and extracting data from a wrapper bean on the service
side. But if that's the case, how does the code know which property of
the wrapper bean corresponds to each child element of the wrapper? Does
the CXF code just assume that the element names are identical to
property names?

Also, when using JiBX data binding schema types may be used directly for
child elements of the wrapper, meaning the return from these methods
might be "java.lang.String", "java.lang.Integer", or even just "int" (in
the case of a required element). How will CXF use these types of return
values?

  - Dennis

Re: JiBX Databinding: databinding interface methods

Posted by Daniel Kulp <dk...@apache.org>.
On Saturday 07 August 2010 3:41:15 am Dennis Sosnoski wrote:
> On 07/22/2010 02:16 PM, Daniel Kulp wrote:
> > On Wednesday 21 July 2010 5:19:42 pm Dennis Sosnoski wrote:
> > 
> > ...
> > 
> >> And in
> >> that case I assume the runtime DataBinding object must implement
> >> WrapperCapableDatabinding, right? (Since otherwise I don't see how the
> >> unwrapping could be handled).
> > 
> > Well, yes and no.   It should implement it if possible.    If not, what
> > happens at runtime is that the WrappedInInterceptor would strip off the
> > wrapper element and it would try and call into the databinding to read
> > each individual part directly.   In some cases, this can be a bit slower
> > as the databinding needs to set things up and such for each part instead
> > of for the entire payload at once.
> 
> So as long as the databinding code can efficiently process multiple
> child elements one-at-a-time it's feasible to skip generating classes
> for the wrapper elements and instead just generate the data model? Then
> the WrappedInInterceptor would create a DataReader<T> instance for each
> child element of the wrapper, and call one of the read() methods? 

Yep.  That's how Aegis works.

> So does the WrappedInInterceptor know which type of DataReader<T> to
> create for each child element type by calling (at code generation time)
> the DataBindingProfile String getType(QName qn, boolean element) method?

No.  It passes the MessagePartInfo object into the reader for the part.   From 
there, the Databinding can figure out whatever it needs to do.   If it needs 
to call getType, it can.  If it has other ways to handle it, great.


> It sounds like we could use either approach with JiBX - generate classes
> for the wrapper elements, and support the DataBindingProfile String
> getWrappedElementType(QName wrapperElement, QName item) method call to
> provide code-generation-time information about the child element
> components *and* also generate WrapperHelper classes to get data in and
> out of the wrappers, or only generate the actual data classes and let
> WrappedInInterceptor handle the details. Since generating the
> WrapperHelper classes adds a fair amount of complexity, I'm thinking the
> latter approach might be better.

If it works, then yea.


-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: JiBX Databinding: databinding interface methods

Posted by Dennis Sosnoski <dm...@sosnoski.com>.
On 07/22/2010 02:16 PM, Daniel Kulp wrote:
> On Wednesday 21 July 2010 5:19:42 pm Dennis Sosnoski wrote:
>   
> ...
>> And in
>> that case I assume the runtime DataBinding object must implement
>> WrapperCapableDatabinding, right? (Since otherwise I don't see how the
>> unwrapping could be handled).
>>     
> Well, yes and no.   It should implement it if possible.    If not, what 
> happens at runtime is that the WrappedInInterceptor would strip off the 
> wrapper element and it would try and call into the databinding to read each 
> individual part directly.   In some cases, this can be a bit slower as the 
> databinding needs to set things up and such for each part instead of for the 
> entire payload at once.   
>   

So as long as the databinding code can efficiently process multiple
child elements one-at-a-time it's feasible to skip generating classes
for the wrapper elements and instead just generate the data model? Then
the WrappedInInterceptor would create a DataReader<T> instance for each
child element of the wrapper, and call one of the read() methods?

So does the WrappedInInterceptor know which type of DataReader<T> to
create for each child element type by calling (at code generation time)
the DataBindingProfile String getType(QName qn, boolean element) method?

It sounds like we could use either approach with JiBX - generate classes
for the wrapper elements, and support the DataBindingProfile String
getWrappedElementType(QName wrapperElement, QName item) method call to
provide code-generation-time information about the child element
components *and* also generate WrapperHelper classes to get data in and
out of the wrappers, or only generate the actual data classes and let
WrappedInInterceptor handle the details. Since generating the
WrapperHelper classes adds a fair amount of complexity, I'm thinking the
latter approach might be better.

  - Dennis

Re: JiBX Databinding: databinding interface methods

Posted by Daniel Kulp <dk...@apache.org>.
On Wednesday 21 July 2010 5:19:42 pm Dennis Sosnoski wrote:
> On 07/22/2010 06:42 AM, Daniel Kulp wrote:
> > ...
> > Well, no.  It's ONLY used for code generation.   Not used for runtime at
> > all. It's mostly for filling in things like the classname attribute of
> > @RequestWrapper as well as for the types for the params at code
> > generation time.
> > 
> > 
> > ..
> > Well, runtime is different story.   For the most part, yes.  However, if
> > the runtime DataBinding object implements the WrapperCapableDatabinding,
> > then it provides the WrapperHelper object that would be used to set/get
> > the params in/out of the wrapper object.    Thus, it can do whatever
> > mapping it needs to do.   For example, JAXB will look at the @XmlElement
> > annotations and such as well to map the names.
> 
> The "types for the params at code generation time" mentioned in the
> first quote only applies if the interface is unwrapped, right?

Correct.   If the databinding doesn't support unwrapping at runtime, then it 
should just return null and the code generator would keep things wrapped.   

> And in
> that case I assume the runtime DataBinding object must implement
> WrapperCapableDatabinding, right? (Since otherwise I don't see how the
> unwrapping could be handled).

Well, yes and no.   It should implement it if possible.    If not, what 
happens at runtime is that the WrappedInInterceptor would strip off the 
wrapper element and it would try and call into the databinding to read each 
individual part directly.   In some cases, this can be a bit slower as the 
databinding needs to set things up and such for each part instead of for the 
entire payload at once.   

For example, the Aegis databinding doesn't implement it as it doesn't 
support/generate types for the wrappers.    Then again, there isn't a code 
generator for Aegis.   :-)

On a historical note: when doing java first wrapped doc/lit,  CXF 2.0.x didn't 
really support using ASM to generate in-memory wrapper objects.   Thus, it did 
each part individually like that.  (and actually, with 2.2, if asm isn't 
avail, it tries as well).   However, with JAX-WS 2.1 (and more so with 2.2), 
certain JAXB annotations are allowed on the jaxws methods/params so doing it 
part by part like that requires digging deap into JAXB implementation "bridge" 
classes to get it to work.   In some cases, that still doesn't work which is 
why with 2.2, asm is now not marked optional for jaxws.

> So if I understand this correctly the JiBX DataBindingProfile code would
> need to generate a class to support returning a WrapperHelper at runtime
> to actually implement the wrapped support (since the JiBX code
> generation details won't otherwise be available at runtime).

Or it would need to be able to read/write the individual parts themselves.   


-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: JiBX Databinding: databinding interface methods

Posted by Dennis Sosnoski <dm...@sosnoski.com>.
On 07/22/2010 06:42 AM, Daniel Kulp wrote:
> ...
> Well, no.  It's ONLY used for code generation.   Not used for runtime at all.   
> It's mostly for filling in things like the classname attribute of 
> @RequestWrapper as well as for the types for the params at code generation 
> time.
>   

> ..
> Well, runtime is different story.   For the most part, yes.  However, if the 
> runtime DataBinding object implements the WrapperCapableDatabinding, then it 
> provides the WrapperHelper object that would be used to set/get the params 
> in/out of the wrapper object.    Thus, it can do whatever mapping it needs to 
> do.   For example, JAXB will look at the @XmlElement annotations and such as 
> well to map the names. 
>   

The "types for the params at code generation time" mentioned in the
first quote only applies if the interface is unwrapped, right? And in
that case I assume the runtime DataBinding object must implement
WrapperCapableDatabinding, right? (Since otherwise I don't see how the
unwrapping could be handled).

So if I understand this correctly the JiBX DataBindingProfile code would
need to generate a class to support returning a WrapperHelper at runtime
to actually implement the wrapped support (since the JiBX code
generation details won't otherwise be available at runtime).

  - Dennis

Re: JiBX Databinding: databinding interface methods

Posted by Daniel Kulp <dk...@apache.org>.
On Wednesday 21 July 2010 2:25:01 pm Dennis Sosnoski wrote:
> I've been looking at supplying the information needed by CXF from JiBX
> code generation, in particular that represented by the
> org.apache.cxf.tools.wsdlto.core.DataBindingProfile interface methods
> String getType(QName qn, boolean element) and String
> getWrappedElementType(QName wrapperElement, QName item).
> 
> I figure these are used to handle adding data to a wrapper bean on the
> client side, and extracting data from a wrapper bean on the service
> side.

Well, no.  It's ONLY used for code generation.   Not used for runtime at all.   
It's mostly for filling in things like the classname attribute of 
@RequestWrapper as well as for the types for the params at code generation 
time.

> But if that's the case, how does the code know which property of
> the wrapper bean corresponds to each child element of the wrapper? Does
> the CXF code just assume that the element names are identical to
> property names?

Well, runtime is different story.   For the most part, yes.  However, if the 
runtime DataBinding object implements the WrapperCapableDatabinding, then it 
provides the WrapperHelper object that would be used to set/get the params 
in/out of the wrapper object.    Thus, it can do whatever mapping it needs to 
do.   For example, JAXB will look at the @XmlElement annotations and such as 
well to map the names. 

 
> Also, when using JiBX data binding schema types may be used directly for
> child elements of the wrapper, meaning the return from these methods
> might be "java.lang.String", "java.lang.Integer", or even just "int" (in
> the case of a required element). How will CXF use these types of return
> values?

Just fine.   That would be the same for JAXB.


-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog