[Engine-devel] Introducing generics to UiCommon

Tomas Jelinek tjelinek at redhat.com
Mon Aug 5 07:41:29 UTC 2013


Hey all,

as we have passed the oVirt feature freeze I would like to celebrate it with a little bit of cleanup :)

A good candidate for this is to introduce generics into uicommonweb project. The fact that it is not generic
brings quite some hidden expectations into our code, makes it unreadable and error prone.

Also, the gwt-common and both webadmin and userportal are mostly prepared to be generic but because the uicommonweb is not, we have code like:

new ListModelListBoxEditor<Object>(new NullSafeRenderer<Object>() {
            @Override
            public String renderNullSafe(Object object) 
                return ((Version) object).getValue();
            }
        });

which is quite ugly and error prone.

So I have prepared two patches, one [1] which introduces the generic infrastructure (and prepares one widget for it, more about this below) and one [2] which uses it and refactors the DataCenterModel
to use it (I have chosen this model because it is big enough to show how to do it and what the benefits are but small enough to be quickly review-able).

The infrastructure change:
- changes the ListModel and EntityModel to be genreic
- adjusts the UiCommonEditorDriverGenerator to work with generics (e.g. to make it aware that ListModel<String> is indeed a ListModel, same for EntityModel)
- created a String version of EntityModelTextBox

The reason why the String EntityModelTextBox had to be created is that the EntityModelTextBox is an EditorWidget<Object, ...> so it can work only with EntityModel<Object>. I saw 2 ways how to make this work with EntityModel<String>:
1: Create a String version of this editor inside the .generic sub-package, incrementally replace the usage of the non-generic EntityModelTextBox and when the non-generic will be completely replaced, delete it and move the generic one 
   out from the generic sub-package

2: Change the EditorWidget<Object, ...> to EditorWidget<T, ...> and replace each usage of the "EntityModelTextBox someWidget" by "EntityModelTextBox<Object> someWidget" and than incrementally replace the <Object> to <String> as the 
   underlying models will be refactored. After the last one will be refactored, change the EditorWidget<T, ...> to EditorWidget<String, ...> and replace all "EntityModelTextBox<Object> someWidget" by "EntityModelTextBox someWidget"

I have chosen the first option because:
- much less classes touched at once (e.g. much more safe)
- the EntityModelTextBox<T> invites to use something like EntityModelTextBox<VM> which is not correct and fails on class cast exceptions

But at the same time I see the disadvantages of this approach (mostly that we have two versions of the same class). Please note that far not all the widgets will need two versions, only the ones editing only Strings which
are declared as EditorWidget<Object> which are:
- EntityModelLabel
- EntityModelTextAreaLabel (used only in couple of places - can be refactored together without the need to have two versions)
- EntityModelTextBox (already in the [1])
- EntityModelPasswordBox
- EntityModelTextArea
- ListModelSuggestBox (used only in couple of places - can be refactored together without the need to have two versions)

The rest of the widgets should be already prepared to be used in generic environment.

Please let me know what do you think about it,

have a nice day,
Tomas

[1]: http://gerrit.ovirt.org/#/c/17604/
[2]: http://gerrit.ovirt.org/#/c/17605/




More information about the Engine-devel mailing list