Anybody having an idea how to solve this?
From: Markus Karg [mailto:markus.karg_at_gmx.net]
Sent: Dienstag, 15. Dezember 2009 21:33
To: 'users_at_jaxb.dev.java.net'
Subject: RE: How to map Java enum to XML element (not #PCDATA) body?
Wolfgang,
your proposed solution unfortunately does not work! :-(
You are assuming that I know locations of any code that is using my enum.
But this is not the case. I am writing a library that anybody can use. The
job of providing a singleton has to be done *inside* my library (i. e. JAXB
itself must know that an instance has to be replaced by another instance
*before* providing the reference to a using instance), not *outside* (not in
the caller's class). Otherwise each user would have to know about the
singleton problem and take care of it, what is very, very error prone.
I need a solution that works *within* my library. Somethink like an
"Unmarshal Resolver". I know I can register unmarshal listeners, but how to
tell in that's event handler that the outcome is a *different* instance?
Thanks!
Markus
From: Wolfgang Laun [mailto:wolfgang.laun_at_gmail.com]
Sent: Dienstag, 15. Dezember 2009 20:15
To: users_at_jaxb.dev.java.net
Subject: Re: How to map Java enum to XML element (not #PCDATA) body?
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