axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "McLay, Tony" <Tony.Mc...@COGNOS.com>
Subject Derivation by restriction (of a restriction)
Date Thu, 20 May 2004 16:35:28 GMT

A recent schema change to a web service resulted in an ArrayStoreException. My initial reaction
was that it was a simple bug, so I started by constructing a simple test service (see wsdl
below). I now think that aligning the xml schema restriction mechanism with OO programming
is a much deeper issue. 

Consider:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="badservice.axistests.com" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="badservice.axistests.com" xmlns:intf="badservice.axistests.com"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<wsdl:types>
		<schema targetNamespace="badservice.axistests.com" xmlns="http://www.w3.org/2001/XMLSchema">
			<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
			<simpleType name="BaseType">
				<restriction base="xsd:string"/>
			</simpleType>
			<simpleType name="DerivedType">
				<restriction base="impl:BaseType"/>
			</simpleType>
			<complexType name="ArrayOfBaseType">
				<complexContent>
					<restriction base="soapenc:Array">
						<attribute ref="soapenc:arrayType" wsdl:arrayType="impl:BaseType[]"/>
					</restriction>
				</complexContent>
			</complexType>
		</schema>
	</wsdl:types>
	<wsdl:message name="setTypesResponse">
	</wsdl:message>
	<wsdl:message name="setTypesRequest">
		<wsdl:part name="in0" type="impl:ArrayOfBaseType"/>
	</wsdl:message>
	<wsdl:message name="getTypesResponse">
		<wsdl:part name="getTypesReturn" type="impl:ArrayOfBaseType"/>
	</wsdl:message>
	<wsdl:message name="getTypesRequest">
   </wsdl:message>
	<wsdl:portType name="BadService">
		<wsdl:operation name="setTypes" parameterOrder="in0">
			<wsdl:input message="impl:setTypesRequest" name="setTypesRequest"/>
			<wsdl:output message="impl:setTypesResponse" name="setTypesResponse"/>
		</wsdl:operation>
		<wsdl:operation name="getTypes">
			<wsdl:input message="impl:getTypesRequest" name="getTypesRequest"/>
			<wsdl:output message="impl:getTypesResponse" name="getTypesResponse"/>
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="BadServiceSoapBinding" type="impl:BadService">
		<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
		<wsdl:operation name="setTypes">
			<wsdlsoap:operation soapAction=""/>
			<wsdl:input name="setTypesRequest">
				<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="badservice.axistests.com"
use="encoded"/>
			</wsdl:input>
			<wsdl:output name="setTypesResponse">
				<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="badservice.axistests.com"
use="encoded"/>
			</wsdl:output>
		</wsdl:operation>
		<wsdl:operation name="getTypes">
			<wsdlsoap:operation soapAction=""/>
			<wsdl:input name="getTypesRequest">
				<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="badservice.axistests.com"
use="encoded"/>
			</wsdl:input>
			<wsdl:output name="getTypesResponse">
				<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="badservice.axistests.com"
use="encoded"/>
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="BadServiceService">
		<wsdl:port binding="impl:BadServiceSoapBinding" name="BadService">
			<wsdlsoap:address location="http://localhost:9300/axis/services/BadService"/>
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>


The schema will allow me to enter the DerivedType into an ArrayOfBaseType (validates according
to xml schema). However, generating the server code (and client test case) does not allow
this use. In fact in the generated java code, BaseType does not extend String (can't anyway
- its final), and DerivedType does not extend BaseType. The service methods are defined in
terms of the BaseType: e.g. 
	public void setTypes(BaseType[] in0) throws RemoteException;
	public BaseType[] getTypes() RemoteException;

and so there is no way to pass in an array of DerivedType's.

Likewise, the generated client testcase uses the BaseType, and I cannot write something like
the following:
	DerivedType derivedType = new DerivedType();
	...
	binding.setTypes(new com.axistests.badservice.BaseType[]{derivedType});//WRONG - CAN'T DO
THIS

The ArrayStoreException surfaces if you don't use the generated service api, but create your
own axis service, create a MessageContext and Message using the derived type, and invoke the
service directly with the context - falls over in JavaUtils, when an Attempt is made to store
a DerivedType into an array of BaseType (basically the same 'type' problem).

I've been through the mailing lists, and not found anything that has specifically touched
this issue (apologies if there is, I am useless at formulating appropriate search expressions).
Trawling the internet, it seems that xml schema's derivation by restriction is a bit of a
thorny issue in the OO world ('impedance mismatch', 'derivation does not align with inheritance',
'restriction is not a natural concept to OO' etc. etc.). I'm not convinced that one can even
draw a parallel between inheritance and derivation in this respect (but xml schema states
that subtyping rules apply, and validation backs this up).

So the questions: - is this a bug? is it by design? an executive decision? or am I missing
something obvious?

Thanks
Tony 
  
       This message may contain privileged and/or confidential information.  If you have received
this e-mail in error or are not the intended recipient, you may not use, copy, disseminate
or distribute it; do not open any attachments, delete it immediately from your system and
notify the sender promptly by e-mail that you have done so.  Thank you. 
 

Mime
View raw message