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

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -