FYI, I have now written the code I describe below. It does not break any of my existing code in the case where polymorphism is *not* specified. I have to come up with some tests of the polymorphism before I commit the code.
Also, this lays the groundwork for polymorphic serialization in general (i.e. on the client). Scott Nichol ----- Original Message ----- From: "Scott Nichol" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, December 04, 2002 10:28 AM Subject: Re: passing interfaces instead of classes > Right now, it will fail because [de-]serializers are found by exact type > match only (or a default if one is defined, but this is typically > useless). I did not take the time to change the [de-]serializer lookup, > because I am not sure what the right way is to implement polymorphic > return values. > > One issue is, how will a client know what different types it can receive > if the return value is polymorphic? In your example, a client who > thinks the contract is A getA() may always expect to deserialize an A. > Receiving a B would be an error: the client does not even know what a B > is! This is a place where WSDL would be a big help. > > You have raised the other major issue: should the service have to map > all of the concrete types that may be returned? > > I am thinking that to address the first issue, I should make return > value polymorphism an option in the deployment descriptor, so that the > service implementor will have to explicitly enable it for the service. > It would then be up to the implementor to document the possible return > types for client implementors. > > For the second issue, I would walk the inheritance chain looking for a > serializer, then check implemented interfaces for one. This really is > not too big of a deal. > > Scott Nichol > > ----- Original Message ----- > From: "Alex Dovlecel" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Wednesday, December 04, 2002 9:42 AM > Subject: Re: passing interfaces instead of classes > > > > Have some questions about it (I have not read the changed code). > > > > If I have a method with the following signature: > > > > A getA ( ) ; > > > > and B extends A. > > > > I have mapped the A class into the SOAP engine, but the B class is not > mapped > > (no QName and serializer associated). > > > > If the getA( ) will return a B, what SOAP will do ? Will fail because > could > > not find (de)serializer for type B, or will try to find the closest > mapped > > type and use the serializer for that type? (in that case, will > serialize the > > B as an A object) > > > > pls answer me, > > Tx > > dovle > > > > > > > > > > I have just committed a change so that the return value of a service > > > method is serialized using its actual class rather than its declared > > > one, assuming the declared one is not a primitive type. This > feature > > > will be available in future nightly builds, which are accessed at > > > http://cvs.apache.org/dist/soap/nightly/. > > > > > > Scott Nichol > > > > > > ----- Original Message ----- > > > From: "Scott Nichol" <[EMAIL PROTECTED]> > > > To: <[EMAIL PROTECTED]> > > > Sent: Monday, December 02, 2002 5:12 PM > > > Subject: Re: passing interfaces instead of classes > > > > > > > Without looking at the code, my guess would be that Apache SOAP > > > > serializes the return value based on the declared type of the > > > > > > function, > > > > > > > not the actual type returned. I will have to look at this later. > > > > > > > > Scott Nichol > > > > > > > > ----- Original Message ----- > > > > From: "Chris Kelly" <[EMAIL PROTECTED]> > > > > To: <[EMAIL PROTECTED]> > > > > Sent: Monday, December 02, 2002 5:26 PM > > > > Subject: Re: passing interfaces instead of classes > > > > > > > > > The problem I had is that my service actually looks like this: > > > > > > > > > > class SoapService { > > > > > public IData doSomething( IData data ) {...} > > > > > } > > > > > > > > > > When I tried to send a ComplexData or SimpleData concrete class > > > > > > back, > > > > > > > it > > > > > > > > > didn't work. Are you saying that was just a config or similar > > > > > > problem? > > > > > > > > Currently, I use a return type mapping when one of the service > > > > > > methods > > > > > > > > returns an array. Do I need to set up a return type mapping, as > > > > > > shown > > > > > > > in > > > > > > > > > the following code, or will the return be handled automatically > and > > > > > > I > > > > > > > just > > > > > > > > > had something set wrong? > > > > > > > > > > SOAPMappingRegistry smr; > > > > > ... > > > > > smr.mapTypes( > > > > > Constants.NS_URI_SOAP_ENC, > > > > > new QName( uri, "return" ), > > > > > null, > > > > > ???, ??? ); > > > > > ... > > > > > call.setSOAPMappingRegistry( smr ); > > > > > > > > > > At 09:09 AM 12/2/02 -0500, Scott Nichol wrote: > > > > > >It is up to you when you define your mappings and/or write your > > > > > >serializers whether the classes implementing interfaces will be > > > > > >serialized with just information for the interface or for the > > > > > > actual > > > > > > > > >class. I personally prefer to have separate mappings for each > > > > > > > > concrete > > > > > > > > > >class. I don't like to have one serializer for an interface > that > > > > > >internally actually knows how to serialize each class that > > > > > > implements > > > > > > > > >the interface. Big switch statements or multiple if/else > branches > > > > > > > > don't > > > > > > > > > >feel right to me in the O-O world. > > > > > > > > > > > >Anyway, in your case this means I would write serializers (and > > > > > >deserializers) for SimpleData and ComplexData, then map each > type > > > > > > to > > > > > > > the > > > > > > > > > >corresponding [de-]serializer. The server will correctly > resolve > > > > > > > > these > > > > > > > > > >types as parameters to the doSomething method. > > > > > > > > > > > >----- Original Message ----- > > > > > >From: "Chris Kelly" <[EMAIL PROTECTED]> > > > > > >To: <[EMAIL PROTECTED]> > > > > > >Sent: Sunday, December 01, 2002 7:48 PM > > > > > >Subject: passing interfaces instead of classes > > > > > > > > > > > >> Consider: > > > > > >> > > > > > >> interface IData { > > > > > >> int getValue(); > > > > > >> } > > > > > >> > > > > > >> class SimpleData implements IData { > > > > > >> int value; > > > > > >> public SimpleData( int v ) { value = v; } > > > > > >> public int getValue() { return value; } > > > > > >> } > > > > > >> > > > > > >> class ComplexData implements IData { > > > > > >> float value, multiplier; > > > > > >> public SimpleData( float v, float m; ) { > > > > > >> value = v; > > > > > >> multiplier = m; > > > > > >> } > > > > > >> public int getValue() { > > > > > >> return (int) ( multiplier * value ); > > > > > >> } > > > > > >> } > > > > > >> > > > > > >> Then, consider a service that accepts an IData object: > > > > > >> > > > > > >> class SoapService { > > > > > >> public doSomething( IData data ) {...} > > > > > >> } > > > > > >> > > > > > >> If I pass an IData object in a bean-like fashion, only the > > > > > > 'value' > > > > > > > > >will be > > > > > > > > > > > >> sent in the XML, not the 'multiplier' if the IData object I'm > > > > > > > > sending > > > > > > > > > >is a > > > > > > > > > > > >> ComplexData object. > > > > > >> > > > > > >> If I change SoapService.doSomething to accept either a > SimpleData > > > > > > > > or a > > > > > > > > > >> ComplexData, then the other class can't be sent. > > > > > >> > > > > > >> So, am I missing something, or is it difficult to represent > > > > > > passed > > > > > > > > >objects > > > > > > > > > > > >> as interfaces? Must they be represented as classes? > > > > > >> > > > > > >> One way around this would be to pass IData objects as the > name in > > > > > > > > the > > > > > > > > > >XML, > > > > > > > > > > > >> and include the name of the implementing class in the XML as > > > > > > well. > > > > > > > An > > > > > > > > > >IData > > > > > > > > > > > >> de/serializer would then determine the implementing class, > and > > > > > > call > > > > > > > a > > > > > > > > > >> de/serializer specific to that implementing class. Is there > an > > > > > > > > > > > >automatic > > > > > > > > > > > >> way to do this? > > > > > >> > > > > > >> > > > > > >> -- > > > > > >> To unsubscribe, e-mail: > > > > > > > > > > > ><mailto:[EMAIL PROTECTED]> > > > > > > > > > > > >> For additional commands, e-mail: > > > > > > > > > > > ><mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >-- > > > > > >To unsubscribe, e-mail: > > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > >For additional commands, e-mail: > > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > -- > > > > > To unsubscribe, e-mail: > > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > For additional commands, e-mail: > > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > > > > > > > > > -- > > > > To unsubscribe, e-mail: > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > For additional commands, e-mail: > > > > > > <mailto:[EMAIL PROTECTED]> > > > > -- > > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>