JAXB - Composite Template and @XmlValue

After JAXB and the composite template, I managed to display:

<precondition>
    <or>
        <and>
            <just><query>foo</query></just>
            <just><query>bar</query></just>
        </and>
        <just><query>baz</query></just>
    </or>
</precondition>

But I would like to display:

<precondition>
    <or>
        <and>
            <query>foo</query>
            <query>bar</query>
        </and>
        <query>baz</query>
    </or>
</precondition>

The JAXB class hierarchy is as follows:

@XmlRootElement
@XmlSeeAlso({SimplePreconditionQuery.class, CompoundAndPreconditionQuery.class, CompoundOrPreconditionQuery.class})
public abstract class PreconditionQuery {
    // JAXB does not deal with interfaces by default >:(
}

With several types of queries:

@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "just")
public class SimplePreconditionQuery extends PreconditionQuery {

    private String query;

    @XmlElement(name = "query")
    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }
}

Compound (AND / OR) are very similar:

@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "and")
public class CompoundAndPreconditionQuery extends PreconditionQuery {

    private Collection<PreconditionQuery> preconditionQueries = newArrayList();

    @XmlElementRef(name = "query")
    public Collection<PreconditionQuery> getPreconditionQueries() {
        return preconditionQueries;
    }

    public void setPreconditionQueries(Collection<PreconditionQuery> preconditionQueries) {
        this.preconditionQueries = preconditionQueries;
    }
}

And the attached bean:

public class Precondition {

    private PreconditionQuery query;

    @XmlElementRef(required = true)
    public PreconditionQuery getQuery() {
        return query;
    }

    public void setQuery(PreconditionQuery query) {
        this.query = query;
    }
}

JAXB won't let me just draw a @XmlValueon SimplePreconditionQuery. Why and what is an alternative?

+4
source share
1 answer

Problem

If you just do:

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "query")
public class SimplePreconditionQuery extends PreconditionQuery {

    private String query;

    @XmlValue
    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

}

You will get the following exception because it SimplePreconditionQuerysubclasses something other than java.lang.Object.

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
@XmlValue is not allowed on a class that derives another class.
    this problem is related to the following location:
        at public java.lang.String forum26714143.SimplePreconditionQuery.getQuery()
        at forum26714143.SimplePreconditionQuery
        at @javax.xml.bind.annotation.XmlSeeAlso(value=[class forum26714143.SimplePreconditionQuery, class forum26714143.CompoundAndPreconditionQuery, class forum26714143.CompoundOrPreconditionQuery])
        at public forum26714143.PreconditionQuery forum26714143.Precondition.getQuery()
        at forum26714143.Precondition

Removing PreconditionQueryfrom inheritance hierarchy.

@XmlTransient , JAXB. .

import javax.xml.bind.annotation.*;

@XmlSeeAlso({SimplePreconditionQuery.class, CompoundAndPreconditionQuery.class, CompoundOrPreconditionQuery.class})
@XmlTransient
public abstract class PreconditionQuery {
    // JAXB does not deal with interfaces by default >:(
}

:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
Invalid @XmlElementRef : Type "class forum26714143.PreconditionQuery" or any of its subclasses are not known to this context.
    this problem is related to the following location:
        at public forum26714143.PreconditionQuery forum26714143.Precondition.getQuery()
        at forum26714143.Precondition

JAXB

, PreconditionQuery , JAXB, @XmlSeeAlso, . @XmlElementRef :

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() {
        return query;
    }

    public void setQuery(PreconditionQuery query) {
        this.query = query;
    }

}

CompoundAndPreconditionQuery

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() {
        return preconditionQueries;
    }

    public void setPreconditionQueries(Collection<PreconditionQuery> preconditionQueries) {
        this.preconditionQueries = preconditionQueries;
    }

}

//JAXB > : (

, JAXB Precondition, , .

public interface PreconditionQuery {

}
+4

All Articles