users@jaxb.java.net

Re: How to map Java enum to XML element (not #PCDATA) body?

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Tue, 15 Dec 2009 20:15:13 +0100

What you want is a unique instance of E for each of the unique settings of
its fields v1, v2,... with a unique instance of V1, V2,..., respectively.

Since you are not compiling the Java classes from the XML schema, you could
write all setters of fields of type E so that

public void setE( E e ){
    this.e = E.getSingleton( e );
}

E.getSingleton() would have to determine which of e's fields v1, v2,... is
not null and return the corresponding E.V_1, E.V_2,...

-W


On Tue, Dec 15, 2009 at 5:58 PM, Markus Karg <markus.karg_at_gmx.net> wrote:

> Using @XmlEnumValue it is possible to map Java enums to XML elements,
> like in this example>
>
>
>
> @XmlRootElement
>
> *public* *enum* E {
>
> @XmlEnumValue("v1") *V_1*,
>
> @XmlEnumValue("v2") *V_2*,
>
> …
>
> }
>
>
>
> While this is working fine in case of #PCDATA values, I now am experiencing
> the problem that I need to map values that are not #PCDATA but in fact are
> XML elements:
>
>
>
> For example,
>
>
>
> <e><v1/></e>
>
>
>
> shall result in the same Java enum instance than
>
>
>
> <e>
>
> <v1>
>
> </v1>
>
> </e>
>
>
>
> and so on.
>
>
>
> That means, I cannot write
>
>
>
> @XmlEnumValue("<v1/>") *V_1*,
>
> @XmlEnumValue("<v2/>") *V_2*,
>
>
>
> in Java, because that would not result in an instance of B when
> unmarshalling a formatted XML file.
>
>
>
> Can anybody tell me a solution working in JAXB 2.1 that will solve this
> problem?
>
>
>
> I started with a rather complex workaround like this one (derived from the
> singleton pattern):
>
>
>
> @XmlAccessorType(*FIELD*)
>
> @XmlRootElement
>
> *public* *class* E {
>
> * public* *static* *final* E *V_1* = *new* E(*new* V1());
>
> * public* *static* *final* E *V_2* = *new* E(*new* V2());
>
> * private* V1 v1;
>
> * private* V2 v2;
>
> * private* E() { }
>
> * private* E(V1 v1) { *this*.v1 = v1; }
>
> * private* E(V2 v2) { *this*.v2 = v2; }
>
> }
>
>
>
> @XmlRootElement
>
> *public* *final* *class* V1 { }
>
>
>
> @XmlRootElement
>
> *public* *final* *class* V2 { }
>
>
>
> This perfectly unmarshalls any kind of formatting and whitespacing of
> <e><v1/></e> and I am really happy with it so far, BUT it does not produce
> singletongs. Instead, I am getting another instance of E and V1 each time.
> This is rather bad, since I now must use the equals operator to compare
> them, while it would be certainly great to in fact have the same instances
> to be able to compare references:
>
>
>
> if (unmarshalledObject == E.V1)
>
>
>
> So my questions are:
>
>
>
> * How can I get singletons, i. e. always the same instance of E.V1 and E.V2
> instead of new copies for each reference?
>
>
>
> * Ain't there a simpler way to get enums with dynamically formatted and
> whitespaced XML element bodies?
>
>
>
> BTW, since the XML schema is far out of my control, I am sorry, no, I
> cannot change the fact that the body is not a #PCDATA but an XML element.
>
>
>
> Thanks a lot!
>
> Markus
>