Think about this question from the other way around - same interfaces, but
now look at the data itself, the JSON:
{name:foo, shape:bar}
What is that? Is it a Binterface with its other properties null? Is it a
Cinterface with its other properties null?
{name:foo, radius:100, height:200}
What is that? Is it a Binterface with a useless extra radius property, or a
Cinterface with a useless extra height property?
The problem is that JSON doesn't have any built-in type information (by
design), so AutoBeans can't magically decide what you meant. All of the
cases above are legal, though annoying, but thats the nature of the beast.
Generally, when I'm solving this, I have additional type information in the
parent (i.e. the containing object, in this case Dinterface), or I know
what type I expect based on context. Then, you can refer to that property
as a Splittable (i.e. the raw data), and encode with any new information
you get:
public interface Dinterface {
Splittable getA();
void setA(Splittable a);
}
Dinterface outer = ...;
if (isC(outer)) {
Cinterface inner = AutoBeanCodex.decode(factory, Cinterface.class,
outer.getA());
//...
} else if (isB(outer)) {
Binterface inner = AutoBeanCodex.decode(factory, Binterface.class,
outer.getA());
//...
} else {
//unsupported data type, decide what to do now
}
This could clearly be rewritten to have some getType(outer) method that
returns Cinterface.class or Binterface.class - the idea is the same, just a
different way to write it. Note too that if the inner data has some
property you need to read to check that type, you can get it out of the
splittable directly - something like outer.getA().get(typeData).
I wrote a quick experiment to see if the @PropertyName annotation could be
used in the outer interface to let it read the same property in two
different ways - turns out this doesn't work:
interface Dinterface { //DOES NOT WORK, DO NOT DO THIS
@PropertyName(a)
Binterface getB();
@PropertyName(a)
Cinterface getC();
}
I haven't dug too much deeper, but I suspect it is because when you invoke
one of these methods, it looks for what type it has been told that a is,
and decodes it as such. It doesn't pick the specific method you called, as
it only wants to decode once (this stores it in the
AbstractAutoBean.reified map) for cheaper subsequent lookups. Giving it two
different types confuses it. So stick with Splittable as a property, decide
what type you really want, and then decode that object. Or pick a tool
other than JSON to solve your problem.
On Friday, January 18, 2013 12:10:34 PM UTC-6, vb8...@gmail.com wrote:
Did you get solution to this problem?
On Tuesday, July 31, 2012 3:20:21 AM UTC-4, rkulisas wrote:
Hi,
I have 4 interfaces:
public interface Ainterface{
getName()/setName();
getShape()/setShape();
}
public interface Binterface extends Ainterface{
getWidth()/setWidth();
getHeight()/setHeight();
...
}
public interface Cinterface extends Ainterface{
getRadius()/setRadius();
...
}
public interface Dinterface {
Ainterface getA();
void setA(Ainterface a);
...
}
I have included all interfaces in my AutoBeanFactory.
Question: when I decode/encode Dinterface, how do I know if Ainterface is
extended by Binterface or Cinterface? How does AutoBean support
polymorphism?
To make it easier, I can add a variable (for ex, shape) in Ainterface to
indicate which Binterface or Cinterface I have and then cast Ainterface to
Binterface/Cinterface. However, I run into ClassCastException. Should I
have separate interfaces; one that consists Binterface and one consists
Cinterface? Is there other solution to this problem?
Thank you,
--
You received this message because you are subscribed to the Google Groups
Google Web Toolkit group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-web-toolkit/-/sjjAHvm7C8oJ.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.