Search code examples
javasoapjaxbjax-ws

Can you cast an object to have a specific function?


I'm using the jaxb/jaxws libraries to handle Soap messages. When a soap fault occurs, I have to cast it to one of the message types. That is, I do something like this:

if(exceptionObject instanceof Message1Data){
     Integer errorCode = ((Message1ExceptionData) exceptionObject).
                           getExceptionData().getErrorCode();
}
if(exceptionObject instanceof Message2Data){
     Integer errorCode = ((Message2ExceptionData) exceptionObject).
                           getExceptionData().getErrorCode();
}
//...

For a bunch of different types of messages. All of which have the function getErrorCode() but are auto generated so there isn't any kind of class inheritance.

So this turns into a long series of if statements to just get the errorCode out, which always exists. Is there a way to tell the compiler that its OK to call this function on the object, similar how I would cast an object in order to access certain functions. So instead of doing a bunch of if statements I can remove it and do something like

Integer errorCode = exceptionObject.getExceptionData().getErrorCode();

once, instead of the same code for each type of message? Or is there an option in jaxb/jaxws to tell it that each of these classes implement an interface? (Short of writing a custom library that allows this)


Solution

  • JAXB2 Inheritance Plugin allows you to make your classes implement a given interface or extends a certain class.

    Customization directly in the schema:

    <xs:complexType name="WillBeMadeCloneableType">
        <xs:annotation>
            <xs:appinfo>
                <inheritance:implements>java.lang.Cloneable</inheritance:implements>
            </xs:appinfo>
        </xs:annotation>
        <!-- ... -->
    </xs:complexType>
    

    Or in an external binding file:

    <jaxb:bindings node="xsd:simpleType[@name='MyType']">
         <inheritance:implements>java.lang.Cloneable</inheritance:implements>
     </jaxb:bindings>
    

    You can also use generics.

    Customizing WSDLs is a bit trickier, but is also possible.

    Disclosure: I am the author of the JAXB2 Inheritance plugin which is the part of the JAXB2 Basics package.

    Documentation is currently being moved to GitHub. Please check the following links: