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

axis-c engine: nillable problem: when minOccurs="0" and nillable="false", the serailization does NOT follow W3C schema standard

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Critical
    • Resolution: Unresolved
    • 1.6 Beta
    • None
    • None

    Description

      [Introduction]:
      Maybe you have known that, the axis-c-1.5final's "nillable" dealing is completely wrong.
      I found that axis-c-1.6beta has taken some improvement on this area, it's good.
      But after really verify axis-c-1.6beta, I found axis-c-1.6beta seems has NOT resolved the old nillable issue correctly.
      At first, the design of "nillable" is too strange and hard-for-maintain in axis-c-1.6beta.
      The W3C's standard set default of "nillable" to "false", but axis-c-1.6beta set it's default to "true" in related constructor.
      Anyway, if axis-c-1.6beta can deal with "nillable" carefully & correctly in inner logic, there will has no problem.
      But after verify, I found that axis-c-1.6beta seems does not deal with "nillable" correctly in case of minOccurs="0".
      This problem occurred in nearly all XSD types.
      The below is a sample which has been verified by me, which indicate that axis-c-1.6beta has problem to deal with "nillable" in case of minOccurs="0".

      [Error Statement]:
      The below is a piece of WSDL which used by me:
      ... ...
      <xs:element name="TestingResponse">
      <xs:complexType>
      <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="testcase" type="xs:string"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      ... ...

      I created server code by axis-c-1.6beta on this WSDL, wrote the related code logic(demo purpose only) inside server module like the below:
      xsd_string_Array * MyTesting::Testing(xsdstring Value0,xsdstring Value1,xsd_string Value2)
      {
      //<mxiong debug 2006/5/19
      xsd_string_Array* pIDs = new xsd_string_Array();
      xsd_string* p = new xsd_string[3];
      p[0] = strdup("");
      p[1] = strdup("");
      p[2] = strdup("2");
      pIDs->set(p,3);
      return pIDs;
      //>mxiong debug 2006/5/19
      }

      I build my server module and run, **TESTING IT BY A CLIENT APPLICATION WHICH SPEAK THE SAME WSDL**, the response looks like this:
      ... ...
      <TestingResponse xmlns="... ...">;
      <testcase xsi:nil="true"></testcase>
      <testcase xsi:nil="true"></testcase>
      <testcase>2</testcase>
      </TestingResponse>
      ... ...

      You can found that the response xsi:nil="true" is wrong.(because my schema does not allow xsi:nil="true", my schema means xsi:nil="false" indeed for it's the default setting according to W3C's standard )
      That will cause my client application to decline the response since it does not follow contracted schema.

      [My Solution]:
      After analyzing and debug to axis-c-1.6beta code, I modified soap/xsd/String.cpp, it became OK.
      The correct response looks like the below:
      ... ...
      <TestingResponse xmlns="... ...">;
      <testcase></testcase>
      <testcase></testcase>
      <testcase>2</testcase>
      </TestingResponse>
      ... ...

      Thus my client application can accept the response correctly and succeed to complete the whole session.

      My detail modification is like the below:
      String::String(const xsd__string value)
      {
      #ifdef ENABLE_AXISTRACE
      if (axiscpp::AxisTrace::isTraceOn())
      axiscpp::AxisTrace::traceEntry("String", "String", this, 1,
      TRACETYPE_STRING, 0, ((void*)&value)); /* AUTOINSERTED TRACE */
      #endif

      //<mxiong debug 2006/5/19
      // if (value)
      //

      { setNil(false); serialize(value); // }

      //>mxiong debug 2006/5/19
      {
      #ifdef ENABLE_AXISTRACE
      if (axiscpp::AxisTrace::isTraceOn())
      axiscpp::AxisTrace::traceExit("String", "String", this, 0); /* AUTOINSERTED TRACE */
      #endif
      return;
      }
      }

      AxisChar* String::serialize(const xsd__string value) throw (AxisSoapException)
      {
      #ifdef ENABLE_AXISTRACE
      if (axiscpp::AxisTrace::isTraceOn())
      axiscpp::AxisTrace::traceEntry("String", "serialize", this, 1,
      TRACETYPE_STRING, 0, ((void*)&value)); /* AUTOINSERTED TRACE */
      #endif

      MinLength* minLength= getMinLength();
      //<mxiong debug 2006/5/19
      unsigned int nLen = 0;
      //>mxiong debug 2006/5/19
      if (minLength->isSet())
      {
      //<mxiong debug 2006/5/19
      if (NULL != value)
      {
      nLen = strlen(value);
      }
      if (nLen < (unsigned int) minLength->getMinLength())
      //>mxiong debug 2006/5/19
      // if (strlen(value) < (unsigned int) minLength->getMinLength())

      { AxisString exceptionMessage = "Length of value to be serialized is shorter than MinLength specified for this type. Minlength = "; AxisChar* length = new AxisChar[10]; sprintf(length, "%d", minLength->getMinLength()); exceptionMessage += length; exceptionMessage += ", Length of value = "; sprintf(length, "%d", strlen(value)); exceptionMessage += length; exceptionMessage += "."; delete [] length; throw AxisSoapException(CLIENT_SOAP_SOAP_CONTENT_ERROR, const_cast<AxisChar*>(exceptionMessage.c_str())); }

      }
      delete minLength;

      MaxLength* maxLength = getMaxLength();
      if (maxLength->isSet())
      {
      //<mxiong debug 2006/5/19
      // if (strlen(value) > (unsigned int) maxLength->getMaxLength())
      if (nLen > (unsigned int) maxLength->getMaxLength())
      //>mxiong debug 2006/5/19

      { AxisString exceptionMessage = "Length of value to be serialized is longer than MaxLength specified for this type. Maxlength = "; AxisChar* length = new AxisChar[10]; sprintf(length, "%d", maxLength->getMaxLength()); exceptionMessage += length; exceptionMessage += ", Length of value = "; sprintf(length, "%d", strlen(value)); exceptionMessage += length; exceptionMessage += "."; delete [] length; throw AxisSoapException(CLIENT_SOAP_SOAP_CONTENT_ERROR, const_cast<AxisChar*>(exceptionMessage.c_str())); }

      }
      delete maxLength;
      Length* length = getLength();
      if (length->isSet())
      {
      //<mxiong debug 2006/5/19
      if (nLen != (unsigned int) length->getLength())
      //>mxiong debug 2006/5/19
      // if (strlen(value) != (unsigned int) length->getLength())

      { AxisString exceptionMessage = "Length of value to be serialized is not the same as Length specified for this type. Length = "; AxisChar* lengthAsString = new AxisChar[10]; sprintf(lengthAsString, "%d", length->getLength()); exceptionMessage += lengthAsString; exceptionMessage += ", Length of value = "; sprintf(lengthAsString, "%d", strlen(value)); exceptionMessage += lengthAsString; exceptionMessage += "."; delete [] lengthAsString; throw AxisSoapException(CLIENT_SOAP_SOAP_CONTENT_ERROR, const_cast<AxisChar*>(exceptionMessage.c_str())); }

      }
      delete length;

      //<mxiong debug 2006/5/19
      AxisString valueAsString;
      if (NULL != value)
      {
      valueAsString = value;
      } else
      {
      valueAsString = "";
      }
      //>mxiong debug 2006/5/19
      // AxisString valueAsString = value;
      AxisChar* serializedValue = (AxisChar*) replaceReservedCharacters(valueAsString).c_str();
      IAnySimpleType::serialize(serializedValue);

      { #ifdef ENABLE_AXISTRACE AxisChar* traceRet = (m_Buf); if (axiscpp::AxisTrace::isTraceOn()) axiscpp::AxisTrace::traceExit("String", "serialize", this, 0, TRACETYPE_STRING, 0, ((void*)&traceRet)); /* AUTOINSERTED TRACE */ return traceRet; #else return m_Buf; #endif } }

      So I think axis-c-1.6beta has bug in dealing with "nillable" for nearly all the XSD types, especially for String type(but not only for String type, but also other types) as my sample indicated.

      [My Suggestion]
      Would you like to give it a careful check to correct this problem in axis-c-1.6beta?
      My code modification may be regarded as a candicate solution for you to resolve this problem, but I think there may has some better detail design for axis-c-1.6beta on "nillable" area.

      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated: