GWT Editor Framework for polymorphic types
Asked Answered
W

0

11

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?

Wessling answered 30/10, 2014 at 14:58 Comment(8)
I was in a similar situation a while back and someone gave me a great answer. It's here: #13346808Fieldsman
Do you have getters for the EditorWidgets in the class. This may be causing the problem. You can try using @Editor.Ignore on your getter methods or on the fields. This will tell the editor framework to ignore this editor.Lastex
@Fieldsman Were you displaying ConstraintViolations in your code? Were they correctly showing up (i.e. not appearing x2 or x3 times as I explained above)?Wessling
@Fieldsman I did try the example you mentioned. ConstraintViolations are still published multiple times (even though driver only generates single violation). Let me know if you used that example to publish violations as well.Wessling
@ChrisHinshaw No getters, editor fields are of default scope and are annotated with @ UiField. I didn't quite understand where you're telling to put @ IgnoreWessling
The editor framework will look for any exposed package or public methods or getters that return a type of Editor. If you have for example a public TextBox getSomeEntityProperty() in your editor the editor framework will also see these and look for the entity field someEntityProperty. The @ UiField does nothing in the editor framework. It looks for fields and methods with either @Editor.Path or if the object/method inherits from Editor. Hope this clears it up.Lastex
I understand that Editor framework doesnt' care about @ UiField. What I meant to say is that these are UI fields (package private with no getters/setters) and there are no duplicate fields for which I could see double violations.Wessling
Just encountered the same issue; were you able to solve/work around it somehow? If you post a self-answer I'm happy to award you the bounty; otherwise I hope one of the GWT devs will be along to provide an answer.Evelyne

© 2022 - 2024 — McMap. All rights reserved.