axis-c-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Michael Xiong (JIRA)" <axis-c-...@ws.apache.org>
Subject [jira] Commented: (AXISCPP-970) axis-c engine: nillable problem: when minOccurs="0" and nillable="false", the serailization does NOT follow W3C schema standard
Date Sat, 20 May 2006 02:31:30 GMT
    [ http://issues.apache.org/jira/browse/AXISCPP-970?page=comments#action_12412618 ] 

Michael Xiong commented on AXISCPP-970:
---------------------------------------

//Sorry, the previous one is still has some minor points not clear and correct, so please
follow the below version:
//change point: (mainly in my demo code: p[2] = strdup(""); --> p[2] = strdup("2");)

 [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(xsd__string Value0,xsd__string 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 xsi:nil="true">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.

> axis-c engine: nillable problem: when minOccurs="0" and nillable="false", the serailization
does NOT follow W3C schema standard
> -------------------------------------------------------------------------------------------------------------------------------
>
>          Key: AXISCPP-970
>          URL: http://issues.apache.org/jira/browse/AXISCPP-970
>      Project: Axis-C++
>         Type: Bug

>   Components: Serialization, Server - Apache module, Server - Engine, SOAP, XSD Types
>     Versions:  1.6 Beta
>  Environment:   	    Platform:
>         Linux fedora 3.0
> Axis version:
>         Server-side Axis C++ 1.6Beta
> XML Parser Lib:
> xersesc 2.6
> WSDL2ws tool by using axis java 1.3
> Client-side version Axis java 1.3
> Http Server Version:
> Apache 2.0.53
> Tomcat 2.0.58
>     Reporter: Michael Xiong
>     Priority: Critical

>
>  [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>
> ... ...
> When I create server code by axis-c-1.6beta on this WSDL, build it and run, the response
looks like this:
> <TestingResponse xmlns="... ...">;
> <testcase xsi:nil="true"></testcase>
> <testcase xsi:nil="true"></testcase>
> <testcase xsi:nil="true"></testcase>
> </TestingResponse>
> I wrote the related code logic(demo purpose only) in server module is like the below:
> xsd__string_Array * MyTesting::Testing(xsd__string Value0,xsd__string 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("");
> 	pIDs->set(p,3);	
> 	return pIDs;
> //>mxiong debug 2006/5/19
> }
> You can found that the response xsi:nil="true" is wrong.
> That will cause my client application rejecting to accept this response for 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.
> My 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 any XSD types,
especially for String type as my sample indicated.
> [Suggestion]
> Would you like to give it a careful check to correct this problem in axis-c-1.6beta?

> My modification may be regarded as a candicate solution for you to resolve this problem,
but I wish maybe a better detail design for axis-c-1.6beta on "nillable" area may be better.

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


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-dev-help@ws.apache.org


Mime
View raw message