You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Glen Daniels <gd...@macromedia.com> on 2001/05/29 05:45:58 UTC

Compromise on streaming

OK, after thinking a bunch about the proposed new design for
Handlers/Deserializers, I came up with what I think is a reasonable
compromise which gets us in the region without going all the way into a
full-streaming architecture.  I would like to propose the following:

1) Introduce a new Handler method:

   public void registerDeserializers(DeserializationContext ctx);

   The purpose of this is to allow Handlers/Chains to register themselves as
SAX handlers for particular elements (esp. headers), and also any specific
type mappings they want to enable for deserialization.

2) AxisServer.invoke() will, before invoke()ing any Handlers, create a
DeserializationContext and allow all Handlers we know about (i.e. Transport
Input, Global Input) to register deserializers as described in (1).

3) Whenever the service is determined (i.e. as a result of calling
MessageContext.setTargetService()), we will ask the service Handler to
register its deserializers and any type mappings into the
DeserializationContext.  This will often happen before the parse starts (in
a transport-specific dispatch handler like the URLMapper or
HTTPActionHandler).

4) If the service has NOT been determined by the time the SOAPSAXHandler
arrives at the first <Body> element, it will attempt to set the service in
the MessageContext based on the QName of that element.  This will result in
calling the logic in (3) and therefore registering any service-specific type
mappings.

So basically, we have what we've got now.  Handlers are invoke()d down the
chain until someone triggers the parse by asking for a Header/Body element.
The difference is that at that point, some of the Handlers on the processing
chain MAY have registered themselves as the "ElementHandlers" for particular
headers - this lets developers choose to write a single class that both
deserializes and processes headers.  And also, service specific type
mappings will be engaged as soon as we figure out what the service is -
which MAY now happen during the parse when we get to the 1st body element.
This solves the problem Sam had with not registering all the type mappers
before doing the parse.

This model will parse the entire message as soon as someone asks for a
Header/Body element.  It does NOT provide for "streaming processing" (we
still rely on the AxisServer to walk the chain of invoke()s), but I believe
it solves some of the problems that streaming solves, and it will be pretty
simple to add to the current code, and won't necessarily change the way
Handlers are written now.

Once I get commit access again, I can probably implement this in a day or
two.

Thoughts?

--Glen



Re: Compromise on streaming

Posted by Simon Fell <so...@zaks.demon.co.uk>.
That would probably work (need to double check with the spec), ideally
you'd look for the root='1' attribute but (a) my reading of the spec
says its optional and (b) i can't think of a single toolkit that
currently includes it when serializing multi-refs.

But, this leads to the problem that you've de-serialized part of the
message before you can work out what you're mapping it to, so if you
need to register additional de-serializers and/or type mappings (e.g.
add element name -> type mappings based on reflection data for the
method) its potentially too late (this is the problem i'm currently
looking at)

Cheers
Simon

On Tue, 29 May 2001 00:40:43 -0400, in soap you wrote:

>Hi Simon!
>
>Yep - so maybe change that to "the first Body element with no ID attribute".
>Will that take care of it?  Is it possible to have a "main" body element
>which itself has an ID?  Not using section-5 encoding, I don't think....
>
>--Glen
>
>----- Original Message -----
>From: "Simon Fell" <so...@zaks.demon.co.uk>
>To: <ax...@xml.apache.org>
>Sent: Tuesday, May 29, 2001 12:15 AM
>Subject: Re: Compromise on streaming
>
>
>On Mon, 28 May 2001 23:45:58 -0400, in soap you wrote:
>
>[snip]
>>4) If the service has NOT been determined by the time the SOAPSAXHandler
>>arrives at the first <Body> element, it will attempt to set the service in
>>the MessageContext based on the QName of that element.  This will result in
>>calling the logic in (3) and therefore registering any service-specific
>type
>>mappings.
>
>I've been working on my own streaming de-serializer model, so have
>been keeping on eye on what you're upto :) apologies in advance if i'm
>way off here, but doesn't this mean that this approach will fail to
>deserialize this correctly ?
>
><s:Envelope ....>
><s:Body>
><item id="ref-3">
><areacode>415</areacode>
><exchange>343</exchange>
><number>3077</number>
></item>
><item id="ref-2">
><state>CA</state>
><streetName>Spear Street</streetName>
><phoneNumber href="#ref-3"/>
><zip>94107</zip>
><city>San Francisco</city>
><streetNum>1</streetNum>
></item>
><item id="ref-4">
><state>NY</state>
><streetName>5th Ave</streetName>
><phoneNumber href="#ref-3" />
><zip>123437</zip>
><city>New York</city>
><streetNum'>12</streetNum>
></item>
><n1:addEntry id="ref-1" e:root="1">
><addresses xsi:type='e:Array' e:arrayType="n1:address[3]">
><address href="#ref-2"   />
><address href="#ref-4"   />
><address href="#ref-2"   />
></addresses>
><AddressToRegister>Simon Fell</AddressToRegister>
></n1:addEntry>
></s:Body>
></s:Envelope>
>
>Cheers
>Simon
>


Re: Compromise on streaming

Posted by Glen Daniels <gd...@macromedia.com>.
Hi Simon!

Yep - so maybe change that to "the first Body element with no ID attribute".
Will that take care of it?  Is it possible to have a "main" body element
which itself has an ID?  Not using section-5 encoding, I don't think....

--Glen

----- Original Message -----
From: "Simon Fell" <so...@zaks.demon.co.uk>
To: <ax...@xml.apache.org>
Sent: Tuesday, May 29, 2001 12:15 AM
Subject: Re: Compromise on streaming


On Mon, 28 May 2001 23:45:58 -0400, in soap you wrote:

[snip]
>4) If the service has NOT been determined by the time the SOAPSAXHandler
>arrives at the first <Body> element, it will attempt to set the service in
>the MessageContext based on the QName of that element.  This will result in
>calling the logic in (3) and therefore registering any service-specific
type
>mappings.

I've been working on my own streaming de-serializer model, so have
been keeping on eye on what you're upto :) apologies in advance if i'm
way off here, but doesn't this mean that this approach will fail to
deserialize this correctly ?

<s:Envelope ....>
<s:Body>
<item id="ref-3">
<areacode>415</areacode>
<exchange>343</exchange>
<number>3077</number>
</item>
<item id="ref-2">
<state>CA</state>
<streetName>Spear Street</streetName>
<phoneNumber href="#ref-3"/>
<zip>94107</zip>
<city>San Francisco</city>
<streetNum>1</streetNum>
</item>
<item id="ref-4">
<state>NY</state>
<streetName>5th Ave</streetName>
<phoneNumber href="#ref-3" />
<zip>123437</zip>
<city>New York</city>
<streetNum'>12</streetNum>
</item>
<n1:addEntry id="ref-1" e:root="1">
<addresses xsi:type='e:Array' e:arrayType="n1:address[3]">
<address href="#ref-2"   />
<address href="#ref-4"   />
<address href="#ref-2"   />
</addresses>
<AddressToRegister>Simon Fell</AddressToRegister>
</n1:addEntry>
</s:Body>
</s:Envelope>

Cheers
Simon



Re: Compromise on streaming

Posted by Simon Fell <so...@zaks.demon.co.uk>.
On Mon, 28 May 2001 23:45:58 -0400, in soap you wrote:

[snip]
>4) If the service has NOT been determined by the time the SOAPSAXHandler
>arrives at the first <Body> element, it will attempt to set the service in
>the MessageContext based on the QName of that element.  This will result in
>calling the logic in (3) and therefore registering any service-specific type
>mappings.

I've been working on my own streaming de-serializer model, so have
been keeping on eye on what you're upto :) apologies in advance if i'm
way off here, but doesn't this mean that this approach will fail to
deserialize this correctly ?

<s:Envelope ....>
<s:Body>
	<item id="ref-3">
		<areacode>415</areacode>
		<exchange>343</exchange>
		<number>3077</number>
	</item>
	<item id="ref-2">
		<state>CA</state>
		<streetName>Spear Street</streetName>
		<phoneNumber href="#ref-3"/>
		<zip>94107</zip>
		<city>San Francisco</city>
		<streetNum>1</streetNum>
	</item>
	<item id="ref-4">
		<state>NY</state>
		<streetName>5th Ave</streetName>
		<phoneNumber href="#ref-3" />
		<zip>123437</zip>
		<city>New York</city>
		<streetNum'>12</streetNum>
	</item>
	<n1:addEntry id="ref-1" e:root="1">
		<addresses xsi:type='e:Array' e:arrayType="n1:address[3]">
			<address href="#ref-2"   />
			<address href="#ref-4"   />
			<address href="#ref-2"   />
		</addresses>
		<AddressToRegister>Simon Fell</AddressToRegister>
	</n1:addEntry>
</s:Body>
</s:Envelope>

Cheers
Simon

Re: Compromise on streaming

Posted by Glen Daniels <gd...@macromedia.com>.
Oh, two other things:

1) Note that if you use Handlers to do SAX based deserialization, we want to
make sure that at least those specific Handlers are NOT shared, but rather
created and destroyed for each request, as they'll likely have state.

2) If Handlers are going to be deserializing headers into more compact
forms, we may also want to keep around a "master recording" of the entire
SAX stream (which gets us back to James' model of the big array), which will
allow us to recreate the original message in a byte-for-byte manner.  This
may be expensive (i.e. it forces us to keep the whole message in memory), so
we may selectively allow services to opt out of or in to this functionality,
otherwise throwing away SAX events after any registered element handlers
have a go at them.

--Glen