Jeremy Haile wrote:
> Could I possibly make use of the XmlAdapter and @XmlJavaTypeAdapter
> mechanism to work around this problem? (solution #1) For example, the
> XmlAdapter could hand my AppleAdapter the string "myFruit". The
> AppleAdapter would know to retrieve the appropriate Apple object and
> return it.
Yes, that's the natural direction to go.
You first need to list up Apple objects that are unmarshalled. Today I
guess you do that by implementing ObjectLifeCycle interface by Apple
objects and use afterUnmarshalling hook to register itself to a Map.
class Apple implements ObjectLifeCycle {
void afterUnmarshalling(Unmarshaller u,Object parent) {
// register
AppleAdapter.tls.get().put(this.id,this);
}
}
class AppleAdapter extends XmlAdapter {
// this map needs to be set to a new one every time you unmarshal.
static ThreadLocal<Map<String,Apple>> tls = new ...;
...
}
> This isn't exactly ideal - in the example I gave previously the Apple
> object may not have been constructed by the time the XmlAdapter is
> invoked - therefore I would have to carefully load my objects in the
> appropriate order and there would still be limitations.
Right, there's a forward-reference problem. One way to work around this
is to resolve tokens to object lazily, perhaps like this:
interface Ref<T> {
T resolve();
}
class AppleAdapter extends XmlAdapter {
...
public Ref<Apple> unmarshal(final String s) {
return new Ref<Apple>() {
Map<String,Apple> map = tls.get();
Apple resolve() {
return map.get(s);
}
}
}
}
So I guess it's possible today (except that it requires a lot of code.)
I think making this easier/shorter is the right direction to go.
> What would be ideal (solution #2) for my situation would be if JAXB
> basically kept a mapping from <class type, ID> to the object being
> constructed. Then if it was setting a property like setApple( Apple
> myApple ), it would know to only look in IDREF list under <Apple.class,
> "myFruit"> Of course, this doesn't exactly follow the ID/IDREF
> semantics, but other than the idea mentioned above I don't have many
> good ideas.
The problem with this is that it's too specific to your needs. It's not
general purpose enough.
> I guess another solution (solution #3) would be to build up an
> XML-specific tree and then convert that into a domain-specific tree.
> (as you mentioned) But this requires a separate processing layer in
> between the XML binding and application layer - a post-XML binding
> layer.
Right. You'd except a data-binding tool to do this.
--
Kohsuke Kawaguchi
Sun Microsystems kohsuke.kawaguchi_at_sun.com