Uploaded image for project: 'Axis-C++'
  1. Axis-C++
  2. AXISCPP-977

axiscpp engine & wsdl2ws: In server response, basic array element no namespace prefix added

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.6 Beta
    • None
    • None

    Description

      1. sample WSDL
      ... ...
      <xs:schema elementFormDefault="qualified" targetNamespace="http://www.foo.bar/foo/bar">
      <xs:element name="AddDog"">
      <xs:complexType>
      <xs:sequence>
      <xs:element maxOccurs="unbounded" name="Dog" type="mb:DogRequest"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      <xs:element name="AddDogResponse">
      <xs:complexType>
      <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Dog" type="mb:DogInfo"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      <xs:element name="DeleteDog">
      <xs:complexType>
      <xs:sequence>
      <xs:element maxOccurs="unbounded" name="Dog" type="mb:DogRequest"/>
      <xs:element minOccurs="0" maxOccurs="1" name="Forced" type="xs:boolean" default="false"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      <xs:element name="DeleteDogResponse">
      <xs:complexType>
      <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="DogId" type="xs:string"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      </xs:schema>
      ... ...

      2. I created a c++ server by axiscpp1.6beta and a java client by axisjava1.3

      3. Response from c++ server when do DeleteDog operation from the created java client:
      <ns1:DeleteDogResponse xmlns:ns1="http://www.foo.bar/foo/bar">
      <DogId>1</DogId>
      <DogId>2</DogId>
      </ns1:DeleteDogResponse >

      The client can not recognize the response because the expected response seems should be like the below:
      <ns1:DeleteDogResponse xmlns:ns1="http://www.foo.bar/foo/bar">
      <ns1:DogId>1</ns1:DogId>
      <ns1:DogId>2</ns1:DogId>
      </ns1:DeleteDogResponse >

      The difference is the lack of ns1: prefix.

      4. I've read the related source code of axiscpp and find that the reason is that axiscpp does not pass namespace information when serializing/descrializing basic array parameter.

      5. I have succeeded in the modification to axis-c-1.6beta to improve it to support namespace prefix for basic array element like the below:
      5.1: Add an interface in IWrapperSoapSerializer(include/axis/IWrapperSoapSerializer.hpp)
      //<mxiong debug 2006/6/27 ++
      /* Method used by wrappers to set a to-be-serialized Array of basic types */
      virtual int AXISCALL addOutputBasicArrayParam(const Axis_Array* pArray,
      XSDTYPE nType, const AxisChar* pName, const AxisChar* pNamespace)=0;
      //>mxiong debug 2006/6/27 ++

      5.2: Derive the above interface in class SoapSerializer(src/soap/SoapSerializer.h)
      //<mxiong debug 2006/6/27 ++
      /* Method used by wrappers to set a to-be-serialized Array of basic types */
      int AXISCALL addOutputBasicArrayParam(const Axis_Array* pArray,
      XSDTYPE nType, const AxisChar* pName,
      const AxisChar* pNamespace);
      //>mxiong debug 2006/6/27 ++

      5.3: Implement the above method like the below(src/soap/SoapSerializer.cpp):
      //<mxiong debug 2006/6/27 ++
      int SoapSerializer::addOutputBasicArrayParam( const Axis_Array * pArray,
      XSDTYPE nType,
      const AxisChar * pName,
      const AxisChar* pNamespace)
      {
      //<mxiong debug 2006/5/19 ++
      std::cerr << "SoapSerializer::addOutputBasicArrayParam with namespace, begin, pName=" << pName << std::endl;
      //>mxiong debug 2006/5/19 ++
      #ifdef ENABLE_AXISTRACE
      if (axiscpp::AxisTrace::isTraceOn())
      axiscpp::AxisTrace::traceEntry("SoapSerializer", "addOutputBasicArrayParam", this, 3,
      TRACETYPE_POINTER, sizeof(Axis_Array), ((void*)&pArray),
      TRACETYPE_DATA, sizeof(XSDTYPE), ((void*)&nTrype),
      TRACETYPE_STRING, 0, ((void*)&pName)); /* AUTOINSERTED TRACE */
      #endif

      int iSuccess = AXIS_SUCCESS;
      Axis_Array * pLocalArray = pArray->clone();
      ArrayBean * pAb = makeArrayBean( nType, (void**) (pLocalArray->m_Array));
      pAb->SetDimension(pLocalArray->m_Size);
      /*

      • We're now finished with the local array object, so it can be deleted
      • However, we need to de-couple from the internal array, which is now owned
      • by the ArrayBean.
        */
        pLocalArray->m_Array = NULL;
        pLocalArray->m_Size = 0;
        delete pLocalArray;
        pLocalArray = NULL;
        Param* pParam = new Param();
        if( RPC_ENCODED == m_nStyle) { pAb->SetItemName("item"); pParam->setName(pName); //<mxiong debug 2006/6/27 ++ std::cerr << "SoapSerializer::addOutputBasicArrayParam with namespace, RPC_ENCODED == m_nStyle" << std::endl; pAb->SetUri( pNamespace); //>mxiong debug 2006/6/27 ++ }

        else

        Unknown macro: { pAb->SetItemName(pName); pParam->setName("array"); //<mxiong debug 2006/6/27 ++ std}

      pParam->m_Value.pArray = pAb;
      pParam->m_Type = XSD_ARRAY;
      if( m_pSoapEnvelope && (m_pSoapEnvelope->m_pSoapBody) &&
      (m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod))

      { //<mxiong debug 2006/5/19 ++ std::cerr << "SoapSerializer::addOutputBasicArrayParam, addOutputParam" << std::endl; //>mxiong debug 2006/5/19 ++ m_pSoapEnvelope->m_pSoapBody->m_pSoapMethod->addOutputParam( pParam); }

      //<mxiong debug 2006/5/19 ++
      std::cerr << "SoapSerializer::addOutputBasicArrayParam, end, pName=" << pName << std::endl;
      //>mxiong debug 2006/5/19 ++

      { #ifdef ENABLE_AXISTRACE int traceRet = (iSuccess); if (axiscpp::AxisTrace::isTraceOn()) axiscpp::AxisTrace::traceExit("SoapSerializer", "addOutputBasicArrayParam", this, 0, TRACETYPE_INT, 0, ((void*)&traceRet)); /* AUTOINSERTED TRACE */ return traceRet; #else return iSuccess; #endif }

      // Can it only be successful?
      }
      //>mxiong debug 2006/6/27 ++

      6. For WSDL2WS, src/wsdl/org/apache/axis/wsdl/wsdl2ws/cpp/literal/WrapWriter.java, in method "writeMethodInWrapper", modify it like the below:
      ... ...
      /* set the result */
      if (returntypeissimple)
      {
      if (returntype.isArray())

      { /*parameters that are declared as arrays in the wrapping element.*/ String containedType = CUtils.getclass4qname(retType.getName()); writer.write( "\t\tnStatus = pIWSSZ->addOutputBasicArrayParam(ret, " + CUtils.getXSDTypeForBasicType(containedType) + ", \"" + returnParamName //<mxiong debug 2006/6/27 ++ + "\", \"" + minfo.getOutputMessage().getNamespaceURI() //>mxiong debug 2006/6/27 ++ + "\");\n"); writer.write("\t\tdelete ret;\n"); writer.write("\t\treturn nStatus;\n"); }

      else
      {
      ... ...

      7. I've verified my modification for axis-c-1.6b engine and WSDL2WS tool, it works well.

      Could you please give my report a kindly check ?

      Attachments

        1. axis-c-1.6b-mxiong-20060616.patch
          60 kB
          Michael Xiong

        Activity

          People

            Unassigned Unassigned
            mxiong Michael Xiong
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated: