I've following class hierarchy.
class A {
String id;
@NotEmpty(message="Title can't be empty")
String title;
String description;
String comments;
}
class B extends A {
String manufacturer;
}
class C extends A {
long size;
}
Now I want an editor which reuses editor of A and also works well with values of B and C. So I went ahead with following:
class EditorA extends Composite implements Editor<A> {
@uiField
TextBox id;
@uiField
TextBox title;
@uiField
TextBox description;
// .. constructor etc
}
class EditorB extends Composite implements Editor<B> {
@Path(“”)
@UiField
EditorA editorA;
@UiField
TextBox manufacturer;
public interface Driver extends SimpleBeanEditorDriver<B, EditorB>{}
// .. initialization
}
class EditorC extends Composite implements Editor<C> {
@Path(“”)
@UiField
EditorA editorA;
@UiField
LongBox size;
public interface Driver extends SimpleBeanEditorDriver<C, EditorC>{}
// .. initialization
}
then I choose the editor based on actual type being edited. Driver flushes object correctly. But when I show constraint violations, every violation is duplicated before its sent to widgets e.g.
“Title can’t be empty" “Title can’t be empty”
Worse, if I include multiple such widgets (with @Path("") annotation) in one form, violations keep increasing. so in the setup below, 3 violations are set.
class EditorAFooter extends Composite implements Editor<A> {
@UiField
TextBox comments;
}
class EditorB extends Composite implements Editor<B> {
@Path(“”)
@UiField
EditorA editorA;
@UiField
TextBox manufacturer;
@Path(“”)
@UiField
EditorAFooter editorAFooter;
public interface Driver extends SimpleBeanEditorDriver<B, EditorB>{}
// .. initialization
}
Workaround is not to used EditorA inside EditorB, instead copy all widgets of EditorA and paste into EditorB.ui.xml and then only single violations are set (as expected). However, that’s a lot of code duplication as EditorA is pretty complex in reality.
What’s wrong with this kind of editor setup? I’m essentially following guidelines mentioned here: http://www.gwtproject.org/doc/latest/DevGuideUiEditors.html#Very_large_objects
======Update=======
I debugged it further (no success yet) In SimpleViolation.java, following code is able to find 3 matching delegates for 1 property:
public static void pushViolations(Iterable<SimpleViolation> violations,
EditorDriver<?> driver, KeyMethod keyMethod) {
if (violations == null) {
return;
}
DelegateMap delegateMap = DelegateMap.of(driver, keyMethod);
// For each violation
for (SimpleViolation error : violations) {
Object key = error.getKey();
List<AbstractEditorDelegate<?, ?>> delegateList = delegateMap.get(key);
delegateList above has 2 or 3 editors depending on my configuration. Probable reason is because subType has access to all superType properties so subType editor driver can be considered a delegate for that property. SuperType's editor is a delegate in itself. Since everyone implements Editor everyone is responsible for setting violations. For every editor involved, it pushes violation to same textbox which shows violation multiple times.
Is this expected? If yes, how to correctly use Editor framework for polymorphic types and display ConstraintViolation only once?