how to annotate/convert an interface?

11 views
Skip to first unread message

Jon Harley

unread,
Jan 20, 2010, 11:33:00 AM1/20/10
to xmappr
Hi, I'm trying to use xmappr to generate XML for a simple class which
has a field that has an interface type.

It's a bit like this:

@RootElement
public class Bowl {

@Element
private final Fruit pieceOfFruit;

...

where Fruit is an interface and pieceOfFruit contains an instance of a
class that implements it such as Apple or Orange which have their own
private fields which need to be written out to xml.

Does this have to be done with a Converter? The wiki page on
converters says "Xmappr calls this method on all converters at
configuration time to decide which converter can convert the target
class. " But in the case of an interface, it cannot be known at
configuration time what the target class is going to be.

Peter Knego

unread,
Jan 20, 2010, 12:05:06 PM1/20/10
to xma...@googlegroups.com
I suppose you have different XML elements for different types of fruit? Something like this:

<apple>some apple</apple>
<orange>some orange</orange>

This could be mapped via Converter, but not necessarily. A custom Converter in this case would just have to "know" about all implementations of Fruit and handle each appropriately.

Normally you could just do:

@RootElement
public class Bowl {

@Elements({
   @Element(name="apple", targetType=Apple.class)
   @Element(name="orange", targetType=Orange.class)
})
private final Fruit pieceOfFruit;

where classes Apple and Orange both implement Fruit.

Note that if your XML contains both <apple> and <orange> (as subelements on the same level) then field "pieceOfFruit" would be written twice and would only contain Orange, since it comes after <apple> in XML stream.

Peter

Peter Knego

unread,
Jan 20, 2010, 12:08:57 PM1/20/10
to xma...@googlegroups.com
Also note that field pieceOfFruit is final and can only be initialized statically or in constructor. Xmappr currently does not use constructor injection (this is planned) and can not access this field.

Jon Harley

unread,
Jan 20, 2010, 12:27:18 PM1/20/10
to xmappr

Thanks for your quick reply Peter!

On Jan 20, 5:05 pm, Peter Knego <pe...@knego.net> wrote:
> I suppose you have different XML elements for different types of fruit?
> Something like this:
>
> <apple>some apple</apple>
> <orange>some orange</orange>
>
> This could be mapped via Converter, but not necessarily. A custom Converter
> in this case would just have to "know" about all implementations of Fruit
> and handle each appropriately.
>
> Normally you could just do:
>
> @RootElement
> public class Bowl {
>
> @Elements({
>    @Element(name="apple", targetType=Apple.class)
>    @Element(name="orange", targetType=Orange.class)})
>
> private final Fruit pieceOfFruit;
>
> where classes Apple and Orange both implement Fruit.

That kind of sucks. Every time I add a new subtype of the interface,
I'd have to modify every class that uses the interface! That's exactly
what interfaces are supposed to avoid. Even having to modify the
Converter every time I add a new subtype is a pain. Is there no way to
do this just by annotating the classes themselves? I'm guessing not,
if xmappr wants to discover all classes at configuration time.

> Note that if your XML contains both <apple> and <orange> (as subelements on
> the same level) then field "pieceOfFruit" would be written twice and would
> only contain Orange, since it comes after <apple> in XML stream.

I assume you mean when reading. Is that a problem if I have two
variables of the same type at the same level?

> Also note that field pieceOfFruit is final and can only be initialized
> statically or in constructor. Xmappr currently does not use constructor
> injection (this is planned) and can not access this field.

Again, I assume you mean for reading? For writing, I see no reason why
it would need to initialise those fields, surely it only needs to be
able to get them, not set them.

J.

Peter Knego

unread,
Jan 20, 2010, 1:18:16 PM1/20/10
to xma...@googlegroups.com

It would help if you could send me the example XML and classes. I could then suggest the mapping.

I suspect there is a corner case with interfaces where interface defines getters/setters but does not define the field. I'm gonna test this case later today and post the result.

On 20 Jan 2010 18:27, "Jon Harley" <jimb...@gmail.com> wrote:


Thanks for your quick reply Peter!

On Jan 20, 5:05 pm, Peter Knego <pe...@knego.net> wrote: > I suppose you have different XML element...

That kind of sucks. Every time I add a new subtype of the interface,
I'd have to modify every class that uses the interface! That's exactly
what interfaces are supposed to avoid. Even having to modify the
Converter every time I add a new subtype is a pain. Is there no way to
do this just by annotating the classes themselves? I'm guessing not,
if xmappr wants to discover all classes at configuration time.

> Note that if your XML contains both <apple> and <orange> (as subelements on > the same level) the...

I assume you mean when reading. Is that a problem if I have two
variables of the same type at the same level?

> Also note that field pieceOfFruit is final and can only be initialized > statically or in constru...

Reply all
Reply to author
Forward
0 new messages