You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by Thomas Baier <th...@gmx.net> on 2009/12/27 09:55:08 UTC

adb and loosely typed parameters

Hi,

I've created a service based on a WSDL (generated sources with "WSDL2C
-ss -sd -d adb -u -f -uri") and it seems to work fine for parameters and
return values with fixed type.

Some of my functions can take any parameters, e.g. from my WSDL:

  ...
  <wsdl:types>
  ...
      <s:element name="SetSymbol">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="pName"
type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="pData" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="SetSymbolResponse">
        <s:complexType />
      </s:element>
  ...
  </wsdl:types>
  ...
  <wsdl:message name="SetSymbolSoapIn">
    <wsdl:part name="parameters" element="tns:SetSymbol" />
  </wsdl:message>
  <wsdl:message name="SetSymbolSoapOut">
    <wsdl:part name="parameters" element="tns:SetSymbolResponse" />
  </wsdl:message>
  ...
  <wsdl:portType name="StatConnectorSoap">
  ...
    <wsdl:operation name="SetSymbol">
      <wsdl:input message="tns:SetSymbolSoapIn" />
      <wsdl:output message="tns:SetSymbolSoapOut" />
    </wsdl:operation>
  ...
  </wsdl:portType>
  ...
  <wsdl:binding name="StatConnectorSoap" type="tns:StatConnectorSoap">
  ...
    <wsdl:operation name="SetSymbol">
      <soap:operation
soapAction="http://www.statconn.com/StatConnector/SetSymbol"
style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  ...
  </wsdl:binding>
  <wsdl:binding name="StatConnectorSoap12" type="tns:StatConnectorSoap">
  ...
    <wsdl:operation name="SetSymbol">
      <soap12:operation
soapAction="http://www.statconn.com/StatConnector/SetSymbol"
style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  ...
  </wsdl:binding>
  ...

The generated function signature is

	adb_SetSymbolResponse_t* axis2_skel_StatConnector_SetSymbol(const
axutil_env_t *env,adb_SetSymbol_t* _setSymbol );

and adb_SetSymbol.h contains the following accessor functions:

        axis2_char_t* AXIS2_CALL
        adb_SetSymbol_get_pName(
            adb_SetSymbol_t* _SetSymbol,
            const axutil_env_t *env);
        axiom_node_t* AXIS2_CALL
        adb_SetSymbol_get_pData(
            adb_SetSymbol_t* _SetSymbol,
            const axutil_env_t *env);

The SOAP payload from the request message sent from my test application
(done in C#) is:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <SetSymbol xmlns="http://www.statconn.com/StatConnector">
         <pName>myvar</pName>
         <pData xsi:type="ArrayOfAnyType">
            <anyType xsi:type="xsd:double">3.14</anyType>
            <anyType xsi:type="xsd:int">815</anyType>
            <anyType xsi:type="xsd:string">My String</anyType>
         </pData>
      </SetSymbol>
   </soap:Body>
</soap:Envelope>

When now calling adb_SetSymbol_get_pData(), I expected to get access to
all elements of pData. So I wrote a simple recursive tracing functions
showing the data I got:

int iterateNodes(axiom_node_t* pNode,axutil_env_t const* pEnv,int pLevel)
{
  axiom_node_t* lNode;
  printf("MyFun#%d: node <%s> is of type %d\n",pLevel,
	 axiom_node_to_string(pNode,pEnv),
	 axiom_node_get_node_type(pNode,pEnv));
  lNode = axiom_node_get_first_child(pNode,pEnv);
  if(lNode) {
    iterateNodes(lNode,pEnv,pLevel+1);
  }
  lNode = axiom_node_get_next_sibling(pNode,pEnv);
  if(lNode) {
    iterateNodes(lNode,pEnv,pLevel);
  }
  return 0;
}

And this function gets called from axis2_skel_StatConnector_SetSymbol()
like this:

  iterateNodes(adb_SetSymbol_get_pData(_setSymbol,env),env,0);

Unexpectedly the stdout shows:

	MyFun#0: node <<anyType
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:double">3.14</anyType>> is of type 2
	MyFun#1: node <3.14> is of type 8

axiom_node_get_next_sibling for adb_SetSymbol_get_pData(_setSymbol,env)
returns NULL.

I'm quite sure this is a misunderstanding in the way I'm using the
adb-functions, but I just can't find the problem.

Additionally, if sending not an array, but just a simple scalar:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <SetSymbol xmlns="http://www.statconn.com/StatConnector">
         <pName>myvar</pName>
         <pData xsi:type="xsd:double">3.1415</pData>
      </SetSymbol>
   </soap:Body>
</soap:Envelope>

the traces show

	MyFun#0: node <3.1415> is of type 8

Is there any way to find out the type informatino (xsd:double in this
case) from adb_SetSymbol_get_pData()?

Best,
Thomas


Re: adb and loosely typed parameters

Posted by Dimuthu Gamage <di...@gmail.com>.
Hi,
yea look like it is a bug in wsdl2c. I think having the condition check
<xsl:when test="@any or not(@type)"> should solve the issue. Please raise a
jira for this.
Dimuthu

On Mon, Dec 28, 2009 at 11:29 PM, Thomas Baier <th...@gmx.net> wrote:

> Hi Dimuthu,
>
> Dimuthu Gamage schrieb:
> > Can you try change your wsdl to  <s:element minOccurs="0" maxOccurs="1"
> > name="pData" *type="s:anyType"* />  and regenerate the code and see
> > whether you getting the correct result?
>
> Thanks for this tip. It works fine now. Unfortunately I have spent the
> better half of a day in parsing the message myself without adb, but at
> least I now seem to understand a few things ;-)
>
> The WSDL itself is generated by Visual Studio 2008, so unfortunately
> this seems to be a fairly common problem when using some WSDL from a
> VS.NET Webservice.
>
> Thanks again,
> Thomas
>
>


-- 
Thanks,
Dimuthu Gamage

http://www.dimuthu.org
http://www.wso2.org

Re: adb and loosely typed parameters

Posted by Thomas Baier <th...@gmx.net>.
Hi Dimuthu,

Dimuthu Gamage schrieb:
> Can you try change your wsdl to  <s:element minOccurs="0" maxOccurs="1"
> name="pData" *type="s:anyType"* />  and regenerate the code and see
> whether you getting the correct result?

Thanks for this tip. It works fine now. Unfortunately I have spent the
better half of a day in parsing the message myself without adb, but at
least I now seem to understand a few things ;-)

The WSDL itself is generated by Visual Studio 2008, so unfortunately
this seems to be a fairly common problem when using some WSDL from a
VS.NET Webservice.

Thanks again,
Thomas


Re: adb and loosely typed parameters

Posted by Dimuthu Gamage <di...@gmail.com>.
Hi,

Can you try change your wsdl to  <s:element minOccurs="0" maxOccurs="1"
name="pData" *type="s:anyType"* />  and regenerate the code and see whether
you getting the correct result?


The template code for axiom_node_t type is

                                    <xsl:when
test="$nativePropertyType='axiom_node_t*'">
                                      text_value = NULL; /* just to avoid
warning */
                                      <xsl:choose>
                                        <xsl:when test="@any">
                                        {
                                          axiom_node_t
*current_property_node = current_node;
                                          current_node =
axiom_node_get_next_sibling(current_node, env);

axiom_node_detach(current_property_node, env);
                                          status = <xsl:value-of
select="$axis2_name"/>_set_<xsl:value-of select="$CName"/>(<xsl:value-of
select="$name"/>, env,

current_property_node);
                                        }
                                        </xsl:when>
                                        <xsl:otherwise>

if(axiom_node_get_first_child(current_node, env))
                                          {
                                              axiom_node_t
*current_property_node = axiom_node_get_first_child(current_node, env);

axiom_node_detach(current_property_node, env);
                                              status = <xsl:value-of
select="$axis2_name"/>_set_<xsl:value-of select="$CName"/>(<xsl:value-of
select="$name"/>, env,

current_property_node);
                                          }
                                          else
                                          {
                                              status = <xsl:value-of
select="$axis2_name"/>_set_<xsl:value-of select="$CName"/>(<xsl:value-of
select="$name"/>, env,

NULL);
                                          }
                                        </xsl:otherwise>
                                      </xsl:choose>
                                    </xsl:when>

Looking at the results of your code, I think what has generated here is the
code inside the <xsl:otherwise> tag (mean <xsl:when test="@any"> is false).
So explictly setting the anyType should correct your problem.


Thanks
Dimuthu



On Sun, Dec 27, 2009 at 2:25 PM, Thomas Baier <th...@gmx.net> wrote:

> Hi,
>
> I've created a service based on a WSDL (generated sources with "WSDL2C
> -ss -sd -d adb -u -f -uri") and it seems to work fine for parameters and
> return values with fixed type.
>
> Some of my functions can take any parameters, e.g. from my WSDL:
>
>  ...
>  <wsdl:types>
>  ...
>      <s:element name="SetSymbol">
>        <s:complexType>
>          <s:sequence>
>            <s:element minOccurs="0" maxOccurs="1" name="pName"
> type="s:string" />
>            <s:element minOccurs="0" maxOccurs="1" name="pData" />
>          </s:sequence>
>        </s:complexType>
>      </s:element>
>      <s:element name="SetSymbolResponse">
>        <s:complexType />
>      </s:element>
>  ...
>  </wsdl:types>
>  ...
>  <wsdl:message name="SetSymbolSoapIn">
>    <wsdl:part name="parameters" element="tns:SetSymbol" />
>  </wsdl:message>
>  <wsdl:message name="SetSymbolSoapOut">
>    <wsdl:part name="parameters" element="tns:SetSymbolResponse" />
>  </wsdl:message>
>  ...
>  <wsdl:portType name="StatConnectorSoap">
>  ...
>    <wsdl:operation name="SetSymbol">
>      <wsdl:input message="tns:SetSymbolSoapIn" />
>      <wsdl:output message="tns:SetSymbolSoapOut" />
>    </wsdl:operation>
>  ...
>  </wsdl:portType>
>  ...
>  <wsdl:binding name="StatConnectorSoap" type="tns:StatConnectorSoap">
>  ...
>    <wsdl:operation name="SetSymbol">
>      <soap:operation
> soapAction="http://www.statconn.com/StatConnector/SetSymbol"
> style="document" />
>      <wsdl:input>
>        <soap:body use="literal" />
>      </wsdl:input>
>      <wsdl:output>
>        <soap:body use="literal" />
>      </wsdl:output>
>    </wsdl:operation>
>  ...
>  </wsdl:binding>
>  <wsdl:binding name="StatConnectorSoap12" type="tns:StatConnectorSoap">
>  ...
>    <wsdl:operation name="SetSymbol">
>      <soap12:operation
> soapAction="http://www.statconn.com/StatConnector/SetSymbol"
> style="document" />
>      <wsdl:input>
>        <soap12:body use="literal" />
>      </wsdl:input>
>      <wsdl:output>
>        <soap12:body use="literal" />
>      </wsdl:output>
>    </wsdl:operation>
>  ...
>  </wsdl:binding>
>  ...
>
> The generated function signature is
>
>        adb_SetSymbolResponse_t* axis2_skel_StatConnector_SetSymbol(const
> axutil_env_t *env,adb_SetSymbol_t* _setSymbol );
>
> and adb_SetSymbol.h contains the following accessor functions:
>
>        axis2_char_t* AXIS2_CALL
>        adb_SetSymbol_get_pName(
>            adb_SetSymbol_t* _SetSymbol,
>            const axutil_env_t *env);
>        axiom_node_t* AXIS2_CALL
>        adb_SetSymbol_get_pData(
>            adb_SetSymbol_t* _SetSymbol,
>            const axutil_env_t *env);
>
> The SOAP payload from the request message sent from my test application
> (done in C#) is:
>
> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>   <soap:Body>
>      <SetSymbol xmlns="http://www.statconn.com/StatConnector">
>         <pName>myvar</pName>
>         <pData xsi:type="ArrayOfAnyType">
>            <anyType xsi:type="xsd:double">3.14</anyType>
>            <anyType xsi:type="xsd:int">815</anyType>
>            <anyType xsi:type="xsd:string">My String</anyType>
>         </pData>
>      </SetSymbol>
>   </soap:Body>
> </soap:Envelope>
>
> When now calling adb_SetSymbol_get_pData(), I expected to get access to
> all elements of pData. So I wrote a simple recursive tracing functions
> showing the data I got:
>
> int iterateNodes(axiom_node_t* pNode,axutil_env_t const* pEnv,int pLevel)
> {
>  axiom_node_t* lNode;
>  printf("MyFun#%d: node <%s> is of type %d\n",pLevel,
>         axiom_node_to_string(pNode,pEnv),
>         axiom_node_get_node_type(pNode,pEnv));
>  lNode = axiom_node_get_first_child(pNode,pEnv);
>  if(lNode) {
>    iterateNodes(lNode,pEnv,pLevel+1);
>  }
>  lNode = axiom_node_get_next_sibling(pNode,pEnv);
>  if(lNode) {
>    iterateNodes(lNode,pEnv,pLevel);
>  }
>  return 0;
> }
>
> And this function gets called from axis2_skel_StatConnector_SetSymbol()
> like this:
>
>  iterateNodes(adb_SetSymbol_get_pData(_setSymbol,env),env,0);
>
> Unexpectedly the stdout shows:
>
>        MyFun#0: node <<anyType
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:type="xsd:double">3.14</anyType>> is of type 2
>        MyFun#1: node <3.14> is of type 8
>
> axiom_node_get_next_sibling for adb_SetSymbol_get_pData(_setSymbol,env)
> returns NULL.
>
> I'm quite sure this is a misunderstanding in the way I'm using the
> adb-functions, but I just can't find the problem.
>
> Additionally, if sending not an array, but just a simple scalar:
>
> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>   <soap:Body>
>      <SetSymbol xmlns="http://www.statconn.com/StatConnector">
>         <pName>myvar</pName>
>         <pData xsi:type="xsd:double">3.1415</pData>
>      </SetSymbol>
>   </soap:Body>
> </soap:Envelope>
>
> the traces show
>
>        MyFun#0: node <3.1415> is of type 8
>
> Is there any way to find out the type informatino (xsd:double in this
> case) from adb_SetSymbol_get_pData()?
>
> Best,
> Thomas
>
>


-- 
Thanks,
Dimuthu Gamage

http://www.dimuthu.org
http://www.wso2.org