java - JAXB - Composite pattern and @XmlValue -
java - JAXB - Composite pattern and @XmlValue -
following jaxb , composite pattern, managed map:
<precondition> <or> <and> <just><query>foo</query></just> <just><query>bar</query></just> </and> <just><query>baz</query></just> </or> </precondition> but i'd map:
<precondition> <or> <and> <query>foo</query> <query>bar</query> </and> <query>baz</query> </or> </precondition> my jaxb class hierarchy follows:
@xmlrootelement @xmlseealso({simplepreconditionquery.class, compoundandpreconditionquery.class, compoundorpreconditionquery.class}) public abstract class preconditionquery { // jaxb not deal interfaces default >:( } with several kinds of queries:
@xmlseealso(preconditionquery.class) @xmlrootelement(name = "just") public class simplepreconditionquery extends preconditionquery { private string query; @xmlelement(name = "query") public string getquery() { homecoming query; } public void setquery(string query) { this.query = query; } } the compound ones (and/or) similar:
@xmlseealso(preconditionquery.class) @xmlrootelement(name = "and") public class compoundandpreconditionquery extends preconditionquery { private collection<preconditionquery> preconditionqueries = newarraylist(); @xmlelementref(name = "query") public collection<preconditionquery> getpreconditionqueries() { homecoming preconditionqueries; } public void setpreconditionqueries(collection<preconditionquery> preconditionqueries) { this.preconditionqueries = preconditionqueries; } } and enclosing bean:
public class precondition { private preconditionquery query; @xmlelementref(required = true) public preconditionquery getquery() { homecoming query; } public void setquery(preconditionquery query) { this.query = query; } } jaxb won't allow me map @xmlvalue on simplepreconditionquery. why , what's alternative?
the problem
if do:
import javax.xml.bind.annotation.*; @xmlrootelement(name = "query") public class simplepreconditionquery extends preconditionquery { private string query; @xmlvalue public string getquery() { homecoming query; } public void setquery(string query) { this.query = query; } } you next exception because simplepreconditionquery subclasses other java.lang.object.
exception in thread "main" com.sun.xml.internal.bind.v2.runtime.illegalannotationsexception: 1 counts of illegalannotationexceptions @xmlvalue not allowed on class derives class. problem related next location: @ public java.lang.string forum26714143.simplepreconditionquery.getquery() @ forum26714143.simplepreconditionquery @ @javax.xml.bind.annotation.xmlseealso(value=[class forum26714143.simplepreconditionquery, class forum26714143.compoundandpreconditionquery, class forum26714143.compoundorpreconditionquery]) @ public forum26714143.preconditionquery forum26714143.precondition.getquery() @ forum26714143.precondition removing preconditionquery inheritance hierarchy. we can utilize @xmltransient annotation @ class level remove class jaxb. properties super class treated properties of super class.
import javax.xml.bind.annotation.*; @xmlseealso({simplepreconditionquery.class, compoundandpreconditionquery.class, compoundorpreconditionquery.class}) @xmltransient public abstract class preconditionquery { // jaxb not deal interfaces default >:( } now next exception:
exception in thread "main" com.sun.xml.internal.bind.v2.runtime.illegalannotationsexception: 3 counts of illegalannotationexceptions invalid @xmlelementref : type "class forum26714143.preconditionquery" or of subclasses not known context. problem related next location: @ public forum26714143.preconditionquery forum26714143.precondition.getquery() @ forum26714143.precondition making jaxb aware of subclasses now have removed preconditionquery set of classes jaxb cares about, longer benefit @xmlseealso annotation contains. such need create our @xmlelementref annotations more explicit:
precondition
import javax.xml.bind.annotation.*; @xmlrootelement public class precondition { private preconditionquery query; @xmlelementrefs({ @xmlelementref(name="and", type = compoundandpreconditionquery.class), @xmlelementref(name="or", type= compoundorpreconditionquery.class), @xmlelementref(name="query", type=simplepreconditionquery.class) }) public preconditionquery getquery() { homecoming query; } public void setquery(preconditionquery query) { this.query = query; } } compoundandpreconditionquery
you need compoundandpreconditionquery , compoundandpreconditionquery.
import java.util.*; import javax.xml.bind.annotation.*; @xmlrootelement(name = "and") public class compoundandpreconditionquery extends preconditionquery { private collection<preconditionquery> preconditionqueries = new arraylist(); @xmlelementrefs({ @xmlelementref(name="and", type = compoundandpreconditionquery.class), @xmlelementref(name="or", type= compoundorpreconditionquery.class), @xmlelementref(name="query", type=simplepreconditionquery.class) }) public collection<preconditionquery> getpreconditionqueries() { homecoming preconditionqueries; } public void setpreconditionqueries(collection<preconditionquery> preconditionqueries) { this.preconditionqueries = preconditionqueries; } } handling interfaces // jaxb not deal interfaces default >:(
now jaxb no longer aware of precondition query class, create interface if wanted to.
public interface preconditionquery { } java xml jaxb
Comments
Post a Comment