[
http://jira.codehaus.org/browse/XFIRE-868?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_94768
]
Tom Lambrechts commented on XFIRE-868:
--------------------------------------
Dan,
There three issue that prevent inheritance from working.
The inherited types are not included in the WSDL.
The package containing the overriding types should be added by
means of the property "jaxb.search.packages".
But the overriding types should also be added to the list of
OVERRIDING_TYPES in the WSDL builder.
This can be done manual by setting the OVERRIDE_TYPES_KEY property
on the ServiceBean. The AegisBindingProvider will get this list from the
service properties and build a new list WSDLBuilder.OVERRIDING_TYPES and set it
on the service properties. (see also the initialize(Service service) method in
the AegisBindingProvider)
We then would get the following config:
<bean class="org.codehaus.xfire.spring.ServiceBean">
<property name="serviceClass"
value="be.telindus.util.soa.ws.xfire.inheritance.MyService" />
<property name="properties">
<map>
<entry key="jaxb.search.packages">
<list>
<value>be.telindus.util.soa.ws.xfire.inheritance</value>
</list>
</entry>
<entry key="overrideTypesList">
<list>
<value>be.telindus.util.soa.ws.xfire.inheritance.MyObject</value>
<value>be.telindus.util.soa.ws.xfire.inheritance.YourObject</value>
</list>
</entry>
</map>
</property>
<property name="serviceBean">
<ref bean="myService" />
</property>
</bean>
This would work if the AegisBindingProvider would also add
JaxbTypes from the list OVERRIDE_TYPES_KEY to the list
WSDLBuilder.OVERRIDING_TYPES. But he only adds BeanTypes.
public void initialize(Service service)
{
List classes = (List) service.getProperty(OVERRIDE_TYPES_KEY);
if (classes != null)
{
List types = new ArrayList();
TypeMapping tm = getTypeMapping(service);
for (Iterator it = classes.iterator(); it.hasNext();)
{
String typeName = (String) it.next();
Class c;
try
{
c = ClassLoaderUtils.loadClass(typeName,
AegisBindingProvider.class);
}
catch (ClassNotFoundException e)
{
throw new XFireRuntimeException("Could not find override
type class: " + typeName, e);
}
Type t = tm.getType(c);
if (t == null)
{
t = tm.getTypeCreator().createType(c);
tm.register(t);
}
if (t instanceof BeanType)
{
BeanType bt = (BeanType) t;
bt.getTypeInfo().setExtension(true);
types.add(bt);
}else if (t instanceof JaxbType)
{
//TODO BUG BIX
//also add Jaxbtypes to the overriding types to pass to the
wsdl builder
//warning: circular depencancy of aegis on jaxb2.0. Maybe
consider to write a JaxbBindingProvider
JaxbType bt = (JaxbType) t;
types.add(bt);
}
}
service.setProperty(WSDLBuilder.OVERRIDING_TYPES, types);
}
super.initialize(service);
}
Voila now all the overriding types are correctly added in the WSDL.
Now we go to the next level of marshalling and unmarshalling.
The inherited types are not marshalled correctly.
The problem is that when marshalling the message parts that for override type
the xsi:type should be included. If not the other side does not know what type
to use.
Example of an response of a type
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<getObjectResponse
xmlns="http://inheritance.xfire.ws.soa.util.telindus.be">
<out>
<id>id</id>
<description>description</description>
</out>
</getObjectResponse>
</soap:Body>
</soap:Envelope>
The out element should carry the type of the overrideType:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<getObjectResponse
xmlns="http://inheritance.xfire.ws.soa.util.telindus.be">
<out xsi:type="MyObject">
<id>id</id>
<description>description</description>
</out>
</getObjectResponse>
</soap:Body>
</soap:Envelope>
This can be achived by changing the JAXBType write method:
if (isAbstract())
{
MessagePartInfo part = (MessagePartInfo)
context.getProperty(AegisBindingProvider.CURRENT_MESSAGE_PART);
//TODO dirty fix to force jaxb to write the xsi:type
//object = new JAXBElement(part.getName(), getClassType(),
object);
object = new JAXBElement(part.getName(), Object.class, object);
}
By setting the declaring type to Object.class it will defere from the
Value and the xsi:type attribute is added.
The inherited types are not UNmarshalled correctly.
It seems that the jaxb unmarshal ignores the xs:type. But actually
correct jaxbType is already resolved and therefore we know the actualType of
the element.
//TODO: fix this
// if (isAbstract() &&
reader.getAttributeReader(XSI_TYPE).getValue() == null)
if (isAbstract())
o = u.unmarshal(reader.getXMLStreamReader(),
actualTypeClass);
else
o = u.unmarshal(reader.getXMLStreamReader());
This should do the trick. I'm not sure that the proposed fixes are close to a
generic solution? Feel free to contact me for more information if necessary. My
googleTalk chat is [EMAIL PROTECTED]
Regards,
Tom
> JAXB inheritance not working on 1.2.4
> -------------------------------------
>
> Key: XFIRE-868
> URL: http://jira.codehaus.org/browse/XFIRE-868
> Project: XFire
> Issue Type: Bug
> Components: JAXB 2.0
> Affects Versions: 1.2.4
> Environment: Windows XP, Tomcat 5.5.20
> Reporter: Michael Coughlan
> Assignee: Dan Diephouse
> Fix For: 1.2.6
>
>
> Hi,
> I am writing a web service in Xfire, which has a parameter , that requires
> the use of Inherited classes.
> I configured the service using JAXB, following the instructions on
> http://xfire.codehaus.org/JAXB+2.0 , specifically, the JAXB inheritance
> section. This involved adding a section to my services.xml file which looked
> like this:
> <property xmlns="" name="properties">
> <map xmlns="">
> <entry xmlns="" key="jaxb.search.packages">
> <value xmlns="">
> <list xmlns="">
> <value xmlns="">com.mysubclass</value>
> </list>
> </value>
> </entry>
> </map>
> </property>
> The problem however, is that the runtime WSDL generated by XFire, has no
> reference to the subclass as it is not listed as a "complexType". The parent
> class, which "mysubclass" extends, however is decribed within the runtime
> WSDL. This impacts my webservice in that, the object passed into the web
> service method (an instanceof the "mysubclass" ) appears as a instance of the
> parent class internally.
> Can anyone help with this issue ?
> Thanks
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email