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