Hi Ajith,
Glad to be part of the project!
I understand the virtual nature of OM. I'd like to take advantage of
that when writing the actual serialized output, so that the OM stays
virtual when used for the output of a databinding operation. It looks
like this should be very easy to implement, though - I assume you're
using the OMNode.serialize() method for actually writing out the data,
right? Then it should be just a matter of implementing a custom
OMElement for each data binding framework, which knows how to serialize
out a saved data object to an XMLStreamWriter when the serialize()
method is called.
Behind the scenes, we'd need to handle actually building an OM tree
representation of the data from the object - but only if needed, since
OM is virtual. This should give us the best possible performance.
The code for this should be very similar between JiBX and JAXB 2.0, so I
should be able to implement these both at the same time (the research
license for JAXB 2.0 gives me some concern on this, but I'd expect that
just implementing and distributing code that uses part of the API is
valid under the terms of the license as long as the JAXB 2.0 API is not
itself exposed or redistributed). I'll start in modifying the JiBX input
and output to work with XMLStreamReader and XMLStreamWriter,
respectively, in about a week from now when I get out the JiBX 1.0
production release. The official support for these will be in a 1.1
build of JiBX. Once I have the basic JiBX changes in place I'll work on
hand-crafting DatabindingSupporter classes for JiBX and JAXB 2.0.
- Dennis
Ajith Ranabahu wrote:
Hello Dennis,
Glad to have you as an Axis committer and guess I should give you some
explanations to why there are toOM(...) and fromOM(...) methods. Seems
I'm a little late on answering but guess I should provide you an
explanation anyway :)
The Axis2 client API depends upon OM and expects and OMElement as the
input to a message being sent. Hence we must have the objects
converted to OM represntations and vice-versa. However building the OM
does not mean that the whole XML stream is parsed and converted into
the Object tree. It's OM and OM builds the Object model when
absolutely necessary :). Inside the databind supporteres what happens
is this conversion, where the pull stream is taken from the object and
fed into the builder(toOM) or the pullstream is taken from the
OMElement and fed into the XMLBeans factory to create the Object
(fromOM). The streaming API gives us the chance to get the events as
late as possible. (There are some problems we need to fix to have this
running smoothely with maximum performance. For starters attemting to
get the events without caching throws out an error with the XBeans
pull stream. Perhaps the object reference needs to be explicitly
maintained through out the process but seems I'll have to dig deep to
solve it. Until then the generated stubs have a 'element.build()'
statement). What I wanted to stress is that OM is virtual by it's
nature :)
You are absolutely right about the pull support in XMLBeans. AFAIK it
is the only known framework that has the capability of interefacing
through StAX. The best solution for doing it with other framworks I
guess is what Eran explained, a 'Push' builder. Push builders create
havoc in serialization (:)) but I guess we can make it work. To keep
the perf figures intact we actually made the builder hang on to the
object and push the events directly to the stream (through a content
handler) if needed. I'm not sure whether this code is still in the
code base but I remember well that we did something similar.
However the generated code is architectured in such a way that the
databind mechanism (may it be push,pull,XMLBeans, JiBX or JAXB) has
nothing to do with the stubs. The seperate databind supporter is the
one that handles the whole thing. Theoreticaly one can modify the
databind supporter and customize how objects are serialized. So If we
figure out how to do the serialization, putting it in shouldn't be a
problem.
Dennis Sosnoski wrote:
I took a look at the XMLBeans data binding implementation for Axis2,
and have got some questions about this. For one thing, it looks like
the toOM() methods actually build the OM representation of the
databound objects, while I thought the idea behind Axis2 was to keep
the OM virtual unless absolutely necessary (for something like signing).
Also, the way in which Axis gets the data out of the databound
objects is by using an XMLStreamReader. AFAIK, XMLBeans is the only
framework which directly supports using a reader to get the XML
representation of the objects. Most frameworks (including JiBX and
JAXB 2.0) only support push-style output, where you tell the
framework to serialize the XML representation to some form of output
interface and it does so before returning. We could write an adapter
to basically store the output from one of these frameworks and make
it readable using an XMLStreamReader, but it would probably have a
substantial impact on performance.
For other data binding frameworks it's probably best to define a
special type of OMElement to hold on to the object and the
corresponding serializer until the serialize() method of the
OMElement is called, then serialize directly to the supplied target.
If we need to instead create a full OM representation, we can use a
builder that implements the XMLStreamWriter interface and supply this
to the binding framework as the target for the marshalling output.
This does make for an all-or-nothing expansion, but this is probably
the best we can do with most data binding frameworks.
There's also the issue of how to link data binding to the MTOM
support, so that a data binding framework can pass off components to
be marshalled as attachments (and likewise access attachments for
unmarshalling). I don't know if XMLBeans has any support for this
yet, but JAXB 2.0 has it and I'll be adding it into JiBX.
- Dennis