0

I have generated some Jaxb objects with the XJC tool. These classes extend one common base class. So for example:

Base.java - Hand-written

@XmlTransient
public class Base {
    public void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) {
        //...
    }

    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
        //...
    }

    //...
}

H1.java - Generated from XJC

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "content"
})
@XmlRootElement(name = "h1")
public class H1 extends Base {
    //...
}

I want to override the behavior of a handful of these generated classes through a factory method, but I don't want to change the code that's generated from XJC because I want to keep these classes open for other uses, not just my current project. For example, I'd like to extend the H1 class (we'll call it H1Extended) and add a couple attributes, and each time the H1 tag occurs in the XML, Jaxb would return an instance of H1Extended instead of H1.

I tried placing a factoryClass annotation on the base class like this...

@XmlTransient
@XmlType(factoryClass=MyFactoryClass.class, factoryMethod="create")
public class Base {
    //...
}

... but that didn't work. What I would like is a factory method that creates the class generated by XJC by default, and returns a custom class for the ones I specify.

I don't mind re-generating the Jaxb classes with XJC, but I want them to utilize base classes that the programmer will create, and once they're generated, they cannot be hand-edited.

Is this possible? Thanks.

EDIT: I didn't notice the generated ObjectFactory class. Could this be used to accomplish what I'm looking for?

EDIT #2: I extended the ObjectFactory class and overrode one of the create methods to return H1Extended, but the base H1 class is being returned for some reason.

EDIT #3: I'll shorten my question: if I have a JaxB class H1, how do I have the unmarshaller return H1Extended?

user1428945
  • 339
  • 1
  • 13
  • I wonder how xjc would generate code containing `extends Base` if Base isn't derived from the XML schema. How was this achieved? - Don't expect an element tagged H1 to be unmarshalled into an object of class H1. Element names refer to properties (fields) within a parent class. - I don't see what you are trying to do - only that you are heading for trouble. – laune Oct 02 '15 at 02:09
  • You can use `` to have the generated classes extend a base class. I'm able to unmarshal the XML like this, so long as the fields are marked as `@XmlTransient`. What I want to do is have the unmarshaller return H1Extended rather than H1. – user1428945 Oct 02 '15 at 12:27
  • Well, as I wrote: the type of an element is determined by the type associated with the element in the XML Schema or by an annotation to the field in a class. If `

    ` is associated with class H1, then that's it.

    – laune Oct 02 '15 at 12:35
  • If you want to switch (for element `

    `) from H1 to H1Extended you can edit your XML schema and recompile.

    – laune Oct 02 '15 at 12:41
  • Unfortunately, I can't edit the schema either. [This person](http://stackoverflow.com/questions/619761/jaxb-inheritance-unmarshal-to-subclass-of-marshaled-class) is trying to do the exact same thing as me, but all the answers I've tried so far do not work. – user1428945 Oct 02 '15 at 12:49
  • What happens there is the substitution of a subclass object (ReceiverPerson) for the object JAXB would unmarshal according to the generated classes. But: the additional subclass fields will not be set, and if their elements appear in the XML it'll throw an error. - Again: dynamically substituting a fully working subclass without changing the code isn't something JAXB can do for you. - You can leave the element unmarshalled (`xs:any`) and unmarshal by hand from a DOM node. – laune Oct 02 '15 at 14:16

0 Answers0