I'm talking about the same idea. What made me think you were suggesting
something else was your earlier comment:
Reduce the # of classes? Unwrapping *increases* the number of classes ..
each arg becomes a separate class. I must be missing something.
But unwrapping *does* reduce the number of classes involved - in your
example below, the plain doc/lit case has the fooRequest and fooResponse
classes, while these are not needed in the unwrapped case.
So it sounds like we're in basic agreement on how things are supposed to
work. I think we still differ on the details, though. Take your sample
service method:
int foo(float a, Address b)
How do you actually generate the code to call this on the server? You
start with an input OMElement, and need to get back an OMElement as the
response. The input OMElement has child elements with the actual data
for the parameters, and the data binding code needs to handle converting
those child elements into the method parameter values. Likewise, the
data binding code needs to handle converting the return value into the
output OMElement. Are we in agreement so far?
I can think of two reasonable ways to implement this in the code. The
first is to implement separate data binding methods per-parameter and
per-return, so that you have methods like:
float convertFooParamA(OMElement elem) { ... }
Address convertFooParamB(OMElement elem) { ... }
OMElement convertFooResult(int value) { ... }
To use these, the common operation code would need to extract the child
elements from the input OMElement and then pass each one to the
appropriate method. But child elements can be optional (minOccurs="0"),
in which case they may have a default value - so the data binding
conversion method still needs to be called in this case (presumably with
a null instead of an element).
The second is to just turn the service method call generation over to
the data binding code, so that you instead have a single generated
method like:
OMElement processFoo(OMElement elem) { ... }
The drawback as compared to the first approach is that this way the data
binding code generation has more complexity, since it needs to process
each child parameter element and actually call the service method - but
I don't see this as much more difficult than just generating all the
methods separately in the first approach.
I see two important advantages as compared to the first approach. First,
the code generation task is divided more cleanly between the message
receiver xslt and the databinding xslt, making them easier to debug.
Second, data binding frameworks such as XMLBeans which could probably
not work with the first approach (because it wants everything to always
be an object) could work with this one by continuing to use a wrapper
class internally but just taking the values out of the wrapper class in
order to call the service method.
So my preference between the two I've outlined is the second approach.
Is there another approach I'm missing?
- Dennis
Sanjiva Weerawarana wrote:
Hmm. That's *exactly* what Anne, Ajith and I are saying too, I believe.
This is the idea: Suppose you have:
int foo (float a, Address b)
Then the doc/lit (or WSDL 2.0) description of this would have two GEDs
(using a syntax hack):
<fooRequest>
<a @type=xsd:float>
<b @type=x:Address>
</fooRequest>
<fooResponse>
<return @type=xsd:int>
</fooResponse>
Now switch sides to generating stubs and skeletons for an operation that
has these as their in's and out's respectively.
What we do now (*without unwrapping) is to generate exactly one class as
an argument:
fooReqest foo (fooResponse)
where they are beans with properties.
If we had unwrap turned on, what I'd expect to see as the signature of
the stub or the skeleton is:
int foo (float, Address)
The implementation of the stub must "wrap" these arguments into a single
OMElement and use ServiceClient underneath to send the message out. When
the response is received, it must "unwrap" the incoming element to pull
out the child of the <fooRequest> element and get the value of the child
element as an int and return that. The implementation of the message
receiver is the opposite.
To do this, all we have to do is to tell the data binding framework to
data bind all the elements one level below the top level GED
representing the "wrapped" message. Data binding *does not* have to
change. Each such child must be treated as a typed thing that must
become a certain name when serialized, not as an element itself. That's
the way to avoid XMLBeans like class proliferation.
Are you talking about the same idea or something different? If so where
do we differ in our understanding of the problem to be solved and/or the
approach?
Sanjiva.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]