[ 
https://issues.apache.org/jira/browse/AXIS2-1938?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bo Xie updated AXIS2-1938:
--------------------------

    Attachment: XMLBeanBinding.zip

> [axis2] WSDL2JAVA with XMLBean binding does not create instance of the 
> derived type or ignore xsi:type in the xml
> -----------------------------------------------------------------------------------------------------------------
>
>                 Key: AXIS2-1938
>                 URL: https://issues.apache.org/jira/browse/AXIS2-1938
>             Project: Apache Axis 2.0 (Axis2)
>          Issue Type: Bug
>          Components: databinding
>    Affects Versions: 1.1
>         Environment: Windows XP, tomcat 5.5, Axis2 1.1
>            Reporter: Bo Xie
>         Attachments: XMLBeanBinding.zip
>
>
> There are basically two issues.
> 1. The java objects created does not use the xsi:type in the XML. In my case, 
> the xsi:type is for derived type, but the object created is still of base 
> type.
> 2. The XML string generated from the client side has the xsi:type for Address 
> object, so the service see it but did not generate the derived type according 
> to the xsi:type(this is the issue reported above). But the server side 
> generated XML string does not have the xsi:type for the objects, so the 
> object XML string does not have xsi:type when the message received on the 
> client side. Why the xsi:type is missing in this case? In both cases, I used 
> types derived from the Address type. The client and service code are based on 
> the XMLBean quickstart sample.
> Attached are 
> 1. the WSDL file. 
> 2.The build file that you can check if the WSDL2JAVA is proper for my case.
> 3. The client code
> 4. The server code.
> Below are the email exchange with Ajith Ranabahu.
> Subject: [axis2] WSDL2JAVA with XMLBean binding does not create instance of 
> the derived type
> ------------------------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Tue, Jan 2, 2007 at 7:45 PM
> Hi there,
>   I am new to axis2 with XMLBean data binding, please help me with the 
> following issue.
>   I modified the quickstart sample XMLBean program to try a WSDL with the 
> following types. The type US-Address is a derived from type Address. I would 
> like to create a service operation updateAddresses to change addresses of a 
> company based on a symbol. The addresses is an array that can take either 
> Address or USAddress instances.
>           <xs:complexType name="Address">
>                 <xs:sequence>
>                     <xs:element name="name" type="xs:string" minOccurs="0"/>
>                     <xs:element name="street" type="xs:string"/>
>                     <xs:element name="city" type="xs:string"/>
>                 </xs:sequence>
>             </xs:complexType>
>          
>        
>             <xs:complexType name="US-Address">
>                 <xs:complexContent>
>                     <xs:extension base="ipo:Address">
>                         <xs:sequence>
>                             <xs:element name="state" type="ipo:US-State"/>
>                             <xs:element name="zip" type="xs:positiveInteger"/>
>                         </xs:sequence>
>                     </xs:extension>
>                 </xs:complexContent>
>             </xs:complexType>
>          <xs:element name="updateAddresses">
>                 <xs:complexType>
>                     <xs:sequence>
>                         <xs:element name="symbol" type="xs:string" 
> nillable="true"/>
>                         <xs:element name="addresses" type="ipo:Address" 
> maxOccurs="unbounded"/>
>                     </xs:sequence>
>                 </xs:complexType>
>       I used WSDL2JAVA with XMLBean data binding to generate the skeleton and 
> stub code. All looks great and the SOAP exchange looks fine too.
>       In the client code, I created one instance if USAddress and one 
> instance of Address and put them into the addresses list. In the SOAP request 
> message, the instances are as  shown as follows below. Note, xsi-type for the 
> instance indicate the correct types which is nice.
>     <soapenv:Body>
>     <updateAddresses xmlns="http://quickstart.samples/xsd";>
>       
>         <symbol>XYZ</symbol>      
>         <addresses xmlns:xsi="http;//www.w3.org/2001/XMLSchema-instance" 
> xmlns:xsd="
> http://quickstart.samples/xsd"; xsi:type="xsd:US-Address">
>         <name>company name</name>
>         <city>Sunnyvale</city>
>         <state>CA</state>
>         <zip>94087</zip>
>        </addresses>
>        <addresses xmlns:xsi="http;//www.w3.org/2001/XMLSchema-instance" 
> xmlns:xsd="http://quickstart.samples/xsd
> " xsi:type="xsd:Address">
>         <name>company name</name>
>         <city>Hong Kong</city>
>        </addresses>
>     </updateAddresses>
>   </soapenv:Body>
>    The problem is when the XML object mapped into java object on the service 
> side, all the XML address object passed to the skeleton are all of Address 
> type. I would expect one instance be Address type, another be USAddress type. 
> Since xsi-type in the SOAP message has the right type, why the XMLBean object 
> is not created as the derived type? Is there any option in WSDL2JAVA to make 
> this work?
>    From the XMLBean Address java object, how can I access the xsi-type 
> attribute that was available in the XML string?
>    If I am not heading the right direction, can anyone suggest some 
> alternatives?
> Thanks for your time!
> -Bo
>  
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 5:16 AM
> Hi,
> The reason here is that you have set the type of the addresses element
> to be 'Address' rather than USAddress (the code generator would put
> the reference for the Address rather than the USAddress). However
> since the xsi:type attribute is present the deserializer should create
> the right object and you can just use a type cast to get to the right
> object.
> HTH
> Ajith
> [Quoted text hidden]
> --
> Ajith Ranabahu
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 7:55 AM
> Thanks Ajith for the quick response.
> I have tried to use the instanceof to test if the instance is USAddress,
> but the test returns false. Without that, the type cast is not safe as
> the Address list can have items of either Address or USAddress. My
> question here is should the java instance created from XML be of type
> USAddress even though the signature is Address. Is there anyway to make
> this happen?
> Thanks,
> -Bo
> [Quoted text hidden]
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 8:20 AM
> Hi,
> Since the xsi:type attribute is present and points to the USAddress,
> the generated object should be of  type USAddress. Perhaps the problem
> is the way you check the instanceof. I mean XMLBeans should have
> generated a getAddresses method to updateAddress ? (It's a little bit
> weird how XMLBeans treats these schemas but I'm guessing)
> If you can use a debugger and go through the object hierarchy at
> runtime you should be able to figure this out
> Ajith
> [Quoted text hidden]
> --
> Ajith Ranabahu
> [Quoted text hidden]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 10:19 AM
> Thanks Ajith. Could you be more specific on how to figure out the right type 
> of the instance? Here is the code snippet and the output on the service side.
> The getAddressArray indeed returns Address[] which is good. But the 
> instanceof always returns Address even for USAddress instance. The 
> interesting thing is the toString output of the addr variable. It includes 
> the correct xsi-type for each instance. So how can I do the correct 
> instanceof to figure the right type to cast in this case?
> Thanks,
> -Bo
> ----Code snippet----
> public  void 
> updateAddresses(samples.quickstart.service.xmlbeans.xsd.UpdateAddressesDocument
>  param3)
>     {
>         //Todo fill this with the necessary business logic
>         String symbol = param3.getUpdateAddresses().getSymbol();
>         System.err.println(getCurrentTime()+"- Update Symbol:" + symbol);
>        
>         Address[] addrs = param3.getUpdateAddresses ().getAddressesArray();
>         for (int i = 0; i < addrs.length; i++) {
>             Address addr = addrs[i];
>             if(addr instanceof USAddress) System.err.println("USAddress 
> instance");
>             if(addr instanceof Address) System.err.println("Address 
> instance");
>             System.err.println(addr.getClass().getName()+":"+addr);
>         }
>    ...}
>  ----Output from the code ----
> Address instance
> samples.quickstart.service.xmlbeans.xsd.impl.AddressImpl: <xml-fragment 
> xsi:type="xsd:US-Address" 
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:xsd=" 
> http://quickstart.samples/xsd"; 
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";>
>   <name xmlns=" http://quickstart.samples/xsd";>company name</name>
>   <city xmlns="http://quickstart.samples/xsd";>Sunnyvale</city>
>   <state xmlns=" http://quickstart.samples/xsd";>CA</state>
>   <zip xmlns="http://quickstart.samples/xsd";>94087</zip>
> </xml-fragment>
> Address instance
> samples.quickstart.service.xmlbeans.xsd.impl.AddressImpl:<xml-fragment 
> xsi:type="xsd:Address" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"; 
> xmlns:ns1="http://quickstart.samples/xsd"; 
> xmlns:xsd="http://quickstart.samples/xsd " 
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";>
>   <name xmlns="http://quickstart.samples/xsd ">company</name>
>   <city xmlns="http://quickstart.samples/xsd";>Hong Kong</city>
> </xml-fragment>
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 5:16 PM
> Hi,
> It seems to me that you have to go one level deep. See whether there
> is a getAddress method in the Address class.
> XMLBeans generates a lot of classes and things are a bit confusing
> specially when types and elements have similar names. AFAIK XMLBeans
> generates a class per type and element. So there would be a class
> generated for the address type and also for the address element. My
> guess is you have to check the address type object instead of the
> address element object.
> Ajith
> [Quoted text hidden]
> --
> [Quoted text hidden]
> --------
> From: Ramesh Gurunathan <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 8:32 PM
> Hi,
> What you are trying to achieve is the value inheritance in XML. I
> think, unfortunately, the web services / XML / SOAP community is
> paying less attention to this topic. I encountered the same issue with
> XMLBeans binding. It forced me to change the XML schema. I introduced
> a new complex type with a 'choice'
> <complexType name="Address">
>  <choice>
>    <element name="USAddress" type="USAddress"/>
>    <element name="OtherAddress" type="OtherAddress"/>
>  </choice>
> </complexType>
> <xs:complexType name="OtherAddress">
>  <xs:sequence>
>    <xs:element name="name" type="xs:string" minOccurs="0"/>
>    <xs:element name="street" type="xs:string"/>
>    <xs:element name="city" type="xs:string"/>
>  </xs:sequence>
> </xs:complexType>
> <xs:complexType name="USAddress">
>  <xs:complexContent>
>    <xs:extension base="ipo:OtherAddress">
>      <xs:sequence>
>        <xs:element name="state" type="ipo:US-State"/>
>        <xs:element name="zip" type="xs:positiveInteger"/>
>      </xs:sequence>
>   </xs:extension>
>  </xs:complexContent>
> </xs:complexType>
> <xs:element name="updateAddresses">
>  <xs:complexType>
>    <xs:sequence>
>      <xs:element name="symbol" type="xs:string" nillable="true"/>
>      <xs:element name="addresses" type="Address" maxOccurs="unbounded"/>
>    </xs:sequence>
>  </xs:complexType>
> </element>
> If you generate XML beans types with above changes, it will generate a
> Address type object which will have methods to check whether USAddress
> is set or the Other Address. No need of instanceof check. Do take a
> look at the generated method signatures of the Address XML type
> object, it should give you an idea to play with it.
> That said, this is just an another way of handling inheritance. I
> would like to see XML beans to inherantly support the polymorphism.
> Ramesh
> [Quoted text hidden]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 10:50 PM
> Hi Ajith,
>    The Address class only has getter and setter for name, city etc. No 
> getAddress. Do you see this ignoring of xsi:type in creating instance as a 
> bug?
>    Besides using choice option as Ramesh suggested, do we run out of luck 
> here? I am a little hesitate to use choice as in my case, the choice list 
> changes quite fast. Keeping track of the exhaustive list of all the choices 
> is a challenge.
> Thanks,
> -Bo
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Thu, Jan 4, 2007 at 5:08 AM
> Hi,
> > Hi Ajith,
> >
> >    The Address class only has getter and setter for name, city etc. No
> > getAddress. Do you see this ignoring of xsi:type in creating instance as a
> > bug?
> Yep. It is a bug. But AFAIK it was reported to be working. In any case
> you can file a Jira with your schema.
> Ajith

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to