[ 
https://issues.apache.org/jira/browse/WICKET-4930?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13534183#comment-13534183
 ] 

SoulSpirit commented on WICKET-4930:
------------------------------------

Martin, I remember I read that post in the past, but then forgot about it. I 
have to say I don't see at all this verbosity problem, the only thing I see is 
clearer code:

ListView<Person> peopleListView = new ListView<Person>("people", people) {
        protected void populateItem(ListItem<Person> item) {
            item.add(new Link<Person>("editPerson", item.getModel()){
                public void onClick() {
                    Person p = getModelObject();
                    setResponsePage(new EditPersonPage(p));
                }
            });
        }
    };

The example on that post is perfect, and it show exactly what I mean: obviously 
a ListView<Person> has many many advantages over a plain ListView, as a 
List<Person> is in many ways superior to a simple List.

Can't you remember the nightmare it was to mantain legacy code, where is some 
dark corner of some dark project there was that little method taking an Object 
parameter, supposed to be a list, where each of its elements were another List, 
where each of its elements were a different object with a different meaning? 
Haven't you ever dealt with something like this?

private method(Object obj) {
  List list = (List)obj;
  for (int i = 0; i < list.size(); i++) {
    List list2 = (List)list.get(i);
    doSomething(list2.get(0));
    method(list2.get(1));
  }
}

Well, that's a very concise syntax, but it is surely unreadable, unmaintenable 
and error prone.
It's difficult to achieve such uglyness using Wicket, but you can't deny the 
fact that a little type parameter helps in reducing coding errors and makes 
clearer what each Component does. And, if you really want, you can ignore it, 
Java permits that.

One of the best examples to understand this is Panel, because it usually has 
its own .java file and, without the tricks introduced by GenericPanel, would be 
really confusing to manage:
"let's hope this PersonPanel is really bound to a Person object! ... 
(Person)getModelObject() ... compile ... run ... RuntimeException! Mmm, perhaps 
it was a PersonBean object, better to add a breakpoint and check... ".

This is what I'm trying to avoid.
                
> Generified Component and Component.getInputConverter()
> ------------------------------------------------------
>
>                 Key: WICKET-4930
>                 URL: https://issues.apache.org/jira/browse/WICKET-4930
>             Project: Wicket
>          Issue Type: Wish
>          Components: wicket
>    Affects Versions: 6.4.0
>            Reporter: SoulSpirit
>            Priority: Minor
>             Fix For: 7.0
>
>         Attachments: 0001-From-Component-to-Component-T.patch
>
>
> Many years are passed since I first used Wicket and there are 2 things I've 
> never really understood:
> 1. Why Component hasn't been generified (i.e. type parametrized)?
> 2. Why Component.getConverter() takes a Class<C> parameter?
> For the first question, I have the suspect the answser brings to backward 
> compatibilities issues (even if Wicket project hasn't always been so much 
> backward compatible between releases). The recent introduction of 
> IGenericComponent is a hint.
> The answer to the second question came clear after a recent release (I don't 
> remember which) that broke some of my components (I'll explain later why). 
> I've always used Converters to convert the model object to a String, but I've 
> learned that they are also used to convert "other" values related to the 
> Component.
> For example, an AbstractChoice may have a model of type X, and at the same 
> time showing values (the choices) of a different type Y. I never ever had 
> this need, but I understand it's a possibility, and that it should be 
> possible to set a Converter for either type X and Y.
> The problem is that the only tool Component.getConverter() has to choose 
> between the available Converters is the Class<C> of the value we want to 
> convert, and this isn't always enought.
> The recent Wicket release I was speaking about changed the way validation 
> messages are generated, converting every message's variable (${input} and 
> ${label} too) with the Component's Converter.
> If, for example, a custom Component is bound to a IModel<String> that need 
> custom conversion, the same Converter is used to transform that ${label} that 
> compose the validation message. And there's no way to avoid it without 
> re-engineering the custom Component.
> I think is more natural to refer to a "component converter" as something that 
> "converts the model to a string".
> The tipical Component.getConverter() implementation looks like this:
> public <C> IConverter<C> getConverter(final Class<C> type)
>   if (MyType.class.isAssignableFrom(type)){
>     return (IConverter<C>)converter;
>   }else{
>     return super.getConverter(type);
> }
> but I'd like to have something like this, that just converts from/to the type 
> of the component's model:
> public IConverter<MyType> getInputConverter(){
>   return converter;
> }
> Obviously, this syntax requires Component to be defined with a type parameter.
> The patch I've attached introduces the method 
> Component#getInputConverter(Class<T>).
> I haven't removed the Class parameter present in the original #getConverter() 
> method to avoid the use of reflection, but I have introduced 
> FormComponent#getInputConverter() (without parameters) as a shortcut to it.
> Along with these two methods, I changed the declaration of Component to 
> Component<T>, and I updated all the framework to support that type parameter, 
> thus removing IGenericComponent, GenericPanel and GenericWebPage.
> The patch breaks something in the compatibility field, but I've updated all 
> the tests to work correctly, and I've made most of them making use of the new 
> type parameter. I'm open to discuss it in detail if someone is interested.
> Little confusion remains in the project about type parameters related to 
> List<T>, List<? extends T>, ? extends List<? extends T>, Collection<T>, ... , 
> but that sort of confusion was already present and I haven't invested much 
> time trying to fix it.
> This patch isn't fully polished as I haven't checked if all the classes make 
> use of the new type parameter and I haven't tried it with any of my real 
> projects, because I understand it will not be so easily integrated into the 
> main branch. It represents just an idea to demonstrate that such a 
> refactoring is possible, and it is fairly effortless (it took me about 10 
> hours of work).

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to