I still have one error: when AbstractTextComponent tries to get the object class from IObjectClassAwareModel and it returns null, it calls model.toString() to log a warning message. This triggers LazyModel.getPath(), that also uses Generics.getClass(type), thus throwing the same IllegalArgumentException.
But I'm intrigued... has nobody ever hit this problem? This happened to me the first time I tried to use it! I thought my wicket code was good, but now I think I must be doing something very wrong... On Fri, Jun 14, 2013 at 6:10 PM, Sven Meier <[email protected]> wrote: > Hi, > > I gave it another try, there should now be less exceptions thrown. > > I'd be interested to see your usecase if you find something else missing. > > Thanks > Sven > > > > On 06/14/2013 09:18 PM, tetsuo wrote: > >> This change kind of works (I had to change getPath() too), but then for >> every component I use LazyModel this way (every textfield in my case), I >> get three exceptions thrown, then ignored (2 at getObjectClass() and 1 at >> getPath()). >> >> I guess using exceptions to flow control isn't very efficient, too... :) >> >> Could Generics.getClass(type) be changed to not throw >> IllegalArgumentException when it can't resolve the class? Maybe return >> null >> and let callers deal with it? >> >> >> >> >> >> >> >> On Fri, Jun 14, 2013 at 2:52 AM, Sven Meier <[email protected]> wrote: >> >> Hi Tetsuo, >>> >>> I stand corrected: >>> For #getObjectClass() the model had to be bound to something revealing >>> its >>> type. >>> >>> We cannot hold a reference to the type because this could lead to all >>> sorts of class loading problems (see Wicket's IClassResolver). >>> Furthermore >>> it would unnecessarily increase the size of LazyModel in most cases (if >>> everything is properly typed). >>> >>> I improved LazyModel to behave like PropertyModel, i.e. return the result >>> object's type as fallback or just return null if everything fails. >>> >>> Sven >>> >>> >>> On 06/14/2013 02:24 AM, tetsuo wrote: >>> >>> I made the changes to make it work, added a test case, and sent a pull >>>> request on github. >>>> Now it works when you create an unbound model from a class, and then >>>> bind >>>> it to a plain model. >>>> >>>> >>>> On Thu, Jun 13, 2013 at 6:39 PM, tetsuo <[email protected]> >>>> wrote: >>>> >>>> Well, you were the one who said that if I created the unbound model >>>> >>>>> (from(A.class)) then I could bind it to a plain IModel, without the >>>>> extra >>>>> type information :) >>>>> >>>>> I just assumed that it would keep the 'A.class' information passed in >>>>> the >>>>> beginning and use it at runtime. >>>>> >>>>> It seems that the Evaluation holds the initial 'from' type, but it >>>>> isn't >>>>> passed down to LazyModel when it is created (it only receives target >>>>> and >>>>> stack), so it has to try to discover the type by itself, and fails. >>>>> >>>>> I'll try to do some experiments here... >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Thu, Jun 13, 2013 at 6:21 PM, Sven Meier <[email protected]> wrote: >>>>> >>>>> Well, here again LazyModel needs the type of the bound target at >>>>> >>>>>> runtime. >>>>>> Without any runtime information about the model's object type, >>>>>> LazyModel >>>>>> cannot derive the type of the evaluation result. >>>>>> >>>>>> Sven >>>>>> >>>>>> >>>>>> On 06/13/2013 10:55 PM, tetsuo wrote: >>>>>> >>>>>> this test also passes here, but >>>>>> >>>>>>> assertEquals(B.class, ((IObjectClassAwareModel<B>) >>>>>>> model.bind(a)).getObjectClass(******)); >>>>>>> >>>>>>> assertEquals(B.class, ((IObjectClassAwareModel<B>) >>>>>>> model.bind(Model.of(a))).******getObjectClass()); >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> While the first assert passes, but the second one doesn't. >>>>>>> >>>>>>> The exception is thrown not when getting the object, but the object >>>>>>> class >>>>>>> (the AbstractTextComponent class calls this before rendering and >>>>>>> while >>>>>>> converting input). >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Jun 13, 2013 at 5:40 PM, Sven Meier <[email protected]> wrote: >>>>>>> >>>>>>> Strange, works fine here: >>>>>>> >>>>>>> @Test >>>>>>>> public void bindToModelAndGet() { >>>>>>>> LazyModel<B> model = model(from(A.class).getB()); >>>>>>>> >>>>>>>> final A a = new A(); >>>>>>>> a.b = new B(); >>>>>>>> >>>>>>>> assertEquals(a.b, model.bind(Model.of(a)).****** >>>>>>>> >>>>>>>> getObject()); >>>>>>>> >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> Sven >>>>>>>> >>>>>>>> >>>>>>>> On 06/13/2013 10:23 PM, tetsuo wrote: >>>>>>>> >>>>>>>> Thanks for the response! >>>>>>>> >>>>>>>> If I use an object instance, it works, but if I do as your third >>>>>>>>> example >>>>>>>>> (create a model from the class, then bind to a >>>>>>>>> non-IObjectClassAwareModel-********model), >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> it doesn't: >>>>>>>>> >>>>>>>>> public class TestPage extends WebPage { >>>>>>>>> >>>>>>>>> private String text; >>>>>>>>> >>>>>>>>> public TestPage(final PageParameters parameters) { >>>>>>>>> >>>>>>>>> super(parameters); >>>>>>>>> >>>>>>>>> add(new Form<Void>("form") >>>>>>>>> >>>>>>>>> .add(new TextField<String>("text", >>>>>>>>> model(from(TestPage.class >>>>>>>>> ).getText()).bind(Model.of(********this))))); >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> } >>>>>>>>> >>>>>>>>> public String getText() { return text; } >>>>>>>>> >>>>>>>>> public void setText(String text) { this.text = text; } >>>>>>>>> >>>>>>>>> } >>>>>>>>> >>>>>>>>> >>>>>>>>> If I change 'Model.of(this)' to 'this' or an IObjectClassAwareModel >>>>>>>>> implementation, it works: >>>>>>>>> >>>>>>>>> >>>>>>>>> class TestPageModel extends AbstractReadOnlyModel<****** >>>>>>>>> TestPage> >>>>>>>>> >>>>>>>>> implements IObjectClassAwareModel<********TestPage> { >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> public TestPage getObject() { return TestPage.this; } >>>>>>>>> >>>>>>>>> public Class<TestPage> getObjectClass() { return >>>>>>>>> TestPage.class; >>>>>>>>> } >>>>>>>>> >>>>>>>>> } >>>>>>>>> >>>>>>>>> >>>>>>>>> Is this a bug? I could create some wrapper models to make it work, >>>>>>>>> but >>>>>>>>> if >>>>>>>>> this is a bug, I'd prefer to wait for a corrected version. >>>>>>>>> >>>>>>>>> >>>>>>>>> Thanks again >>>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, Jun 13, 2013 at 4:52 PM, Sven Meier <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> LazyModel needs to know the type of the model object to return an >>>>>>>>> >>>>>>>>>> appropriate proxy: >>>>>>>>>> >>>>>>>>>> model(from(a).getB()); // works >>>>>>>>>> model(from(aModel).getB()); // aModel must be an >>>>>>>>>> IObjectClassAwareModel >>>>>>>>>> model(from(A.class).getB()).**********bind(aModel); // >>>>>>>>>> works >>>>>>>>>> >>>>>>>>>> even if >>>>>>>>>> >>>>>>>>>> aModel >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> does not reveal its object class >>>>>>>>>> >>>>>>>>>> Sven >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On 06/13/2013 09:35 PM, tetsuo wrote: >>>>>>>>>> >>>>>>>>>> wait, wait, do you actually do something like >>>>>>>>>> >>>>>>>>>> new TextField<String>("name", new IModel<String>(){ >>>>>>>>>> >>>>>>>>>>> public String getObject() { >>>>>>>>>>> return entity.getName(); >>>>>>>>>>> } >>>>>>>>>>> public void setObject(String value) { >>>>>>>>>>> entity.setName(value); >>>>>>>>>>> } >>>>>>>>>>> public void detach(){} >>>>>>>>>>> }); >>>>>>>>>>> >>>>>>>>>>> for every single field in your system, or you use LazyModel? >>>>>>>>>>> >>>>>>>>>>> Well, I've been trying to use LazyModel, but with it I have to >>>>>>>>>>> pass >>>>>>>>>>> the >>>>>>>>>>> type of every field (the last arg of TextField's constructor) >>>>>>>>>>> because >>>>>>>>>>> if I >>>>>>>>>>> don't, this exception is thrown: >>>>>>>>>>> >>>>>>>>>>> Caused by: java.lang.**********IllegalArgumentException: T is >>>>>>>>>>> not a >>>>>>>>>>> class or >>>>>>>>>>> parameterizedType >>>>>>>>>>> >>>>>>>>>>> at org.wicketstuff.lazymodel.****** >>>>>>>>>>> ****reflect.Generics.getClass(**** >>>>>>>>>>> Generics.java:78) >>>>>>>>>>> >>>>>>>>>>> at org.wicketstuff.lazymodel.****** >>>>>>>>>>> ****LazyModel.getObjectType(** >>>>>>>>>>> LazyModel.java:139) >>>>>>>>>>> >>>>>>>>>>> at org.wicketstuff.lazymodel.****** >>>>>>>>>>> ****LazyModel.getObjectClass(**** >>>>>>>>>>> LazyModel.java:124) >>>>>>>>>>> >>>>>>>>>>> at org.apache.wicket.markup.html.**********form.** >>>>>>>>>>> AbstractTextComponent.**** >>>>>>>>>>> getModelType( >>>>>>>>>>> AbstractTextComponent.java:**********167) >>>>>>>>>>> >>>>>>>>>>> at org.apache.wicket.markup.html.**********form.** >>>>>>>>>>> AbstractTextComponent.**** >>>>>>>>>>> resolveType( >>>>>>>>>>> AbstractTextComponent.java:**********152) >>>>>>>>>>> >>>>>>>>>>> at org.apache.wicket.markup.html.**********form.** >>>>>>>>>>> AbstractTextComponent.**** >>>>>>>>>>> onBeforeRender( >>>>>>>>>>> AbstractTextComponent.java:**********142) >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Any thoughts? >>>>>>>>>>> >>>>>>>>>>> I guess I'll just go back to CompoundPropertyModel... (sigh) >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> (and no, I don't spend that much time debugging property models. >>>>>>>>>>> I >>>>>>>>>>> usually >>>>>>>>>>> don't rename properties that often, and when I have to do some >>>>>>>>>>> refactoring, >>>>>>>>>>> usually the structure changes, and I have to revise all pages >>>>>>>>>>> anyway...) >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Fri, May 31, 2013 at 10:49 AM, Martin Grigorov < >>>>>>>>>>> [email protected] >>>>>>>>>>> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> On Fri, May 31, 2013 at 4:24 PM, tetsuo < >>>>>>>>>>>> >>>>>>>>>>>> [email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Black magic, or code generation? hard choice... :) >>>>>>>>>>> >>>>>>>>>>> I think I'll try the black magic, let's see how it goes :) >>>>>>>>>>>> >>>>>>>>>>>> I personally prefer writing the boilerplate of custom >>>>>>>>>>>>> Model >>>>>>>>>>>>> per >>>>>>>>>>>>> field. >>>>>>>>>>>>> >>>>>>>>>>>>> It is a boring work but it gives me: >>>>>>>>>>>>> >>>>>>>>>>>>> * type safety >>>>>>>>>>>> * the fastest read/write access possible >>>>>>>>>>>> * easier debugging >>>>>>>>>>>> >>>>>>>>>>>> (who knows - maybe I've spent less time to write such models >>>>>>>>>>>> than >>>>>>>>>>>> you've >>>>>>>>>>>> spent to debug your issues with property model after >>>>>>>>>>>> refactoring) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, May 30, 2013 at 8:16 PM, Igor Vaynberg < >>>>>>>>>>>> >>>>>>>>>>>> [email protected] >>>>>>>>>>>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, May 30, 2013 at 12:37 PM, tetsuo < >>>>>>>>>>>>> >>>>>>>>>>>>>> [email protected] >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> -1000! >>>>>>>>>>>>>> >>>>>>>>>>>>> This will be horrible! Even with the current API, most >>>>>>>>>>>>> generics >>>>>>>>>>>>> >>>>>>>>>>>>>> I >>>>>>>>>>>>>> >>>>>>>>>>>>>> have >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>> >>>>>>>>>>>>>> declare in my code don't add anything to type safety. For >>>>>>>>>>>>> example: >>>>>>>>>>>>> >>>>>>>>>>>>> while i am also not a fan of having component generified i do >>>>>>>>>>>>> >>>>>>>>>>>>>> believe >>>>>>>>>>>>>> the example below is a bit contrived. >>>>>>>>>>>>>> >>>>>>>>>>>>>> first, i hope most people do not use PropertyModels because >>>>>>>>>>>>>> they >>>>>>>>>>>>>> are >>>>>>>>>>>>>> not compile-time-safe. there are plenty of project that >>>>>>>>>>>>>> implement >>>>>>>>>>>>>> compile-time-safe models, personally i prefer >>>>>>>>>>>>>> https://github.com/42Lines/**********metagen<https://github.com/42Lines/********metagen> >>>>>>>>>>>>>> <https://github.**com/42Lines/******metagen<https://github.com/42Lines/******metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/**42Lines/******metagen<https://github.com/**42Lines/****metagen> >>>>>>>>>>>>>> <https://github.**com/42Lines/****metagen<https://github.com/42Lines/****metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/**42Lines/******metagen<https://github.com/**42Lines/****metagen> >>>>>>>>>>>>>> <https://github.**com/**42Lines/**metagen<https://github.com/**42Lines/**metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/**42Lines/****metagen<https://github.com/**42Lines/**metagen> >>>>>>>>>>>>>> <https://github.com/**42Lines/**metagen<https://github.com/42Lines/**metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/**42Lines/******metagen<https://github.com/**42Lines/****metagen> >>>>>>>>>>>>>> <https://github.**com/**42Lines/**metagen<https://github.com/**42Lines/**metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/******42Lines/metagen<https://github.com/****42Lines/metagen> >>>>>>>>>>>>>> <https://**github.com/**42Lines/metagen<https://github.com/**42Lines/metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>>> <https://github.com/**42Lines/****metagen<https://github.com/**42Lines/**metagen> >>>>>>>>>>>>>> <https://github.com/****42Lines/metagen<https://github.com/**42Lines/metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> <https://github.com/**42Lines/**metagen<https://github.com/**42Lines/metagen> >>>>>>>>>>>>>> <https://github.com/**42Lines/metagen<https://github.com/42Lines/metagen> >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>> using proxy-based solutions. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> further, i hope even less people use compound property models. >>>>>>>>>>>>>> they >>>>>>>>>>>>>> are even more unsafe then property models and make your code >>>>>>>>>>>>>> even >>>>>>>>>>>>>> more >>>>>>>>>>>>>> fragile. i would hate to refactor code that uses CPMs. >>>>>>>>>>>>>> >>>>>>>>>>>>>> add(new Form<Person>("form", new >>>>>>>>>>>>>> CompoundPropertyModel<Person>( >>>>>>>>>>>>>> **** >>>>>>>>>>>>>> >>>>>>>>>>>>>> new >>>>>>>>>>>>>> >>>>>>>>>>>>>> PropertyModel<Person>(this, "person"))) >>>>>>>>>>>>>> >>>>>>>>>>>>>>> .add(new TextField<String>("name")) >>>>>>>>>>>>>>> .add(new TextField<Integer>("age")) >>>>>>>>>>>>>>> .add(new TextField<Double>("salary")) >>>>>>>>>>>>>>> .add(new Button("save", new >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> PropertyModel<Person>(this,"**********person")){ >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> public void onSubmit() { >>>>>>>>>>>>>>> >>>>>>>>>>>>>> repository.save((Person)**********getForm().**** >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> getDefaultModelObject()); >>>>>>>>>>>>>> >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> }); >>>>>>>>>>>>>> >>>>>>>>>>>>>> In my experience, this kind of code is fairly common in >>>>>>>>>>>>>> Wicket >>>>>>>>>>>>>> >>>>>>>>>>>>>>> applications. Every form component must be declared with a >>>>>>>>>>>>>>> type, >>>>>>>>>>>>>>> but >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> none >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> has *any* kind of type safety gain. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> but how often do you declare a form component without adding >>>>>>>>>>>>>> any >>>>>>>>>>>>>> validators to it? the generic type of component also makes >>>>>>>>>>>>>> sure >>>>>>>>>>>>>> you >>>>>>>>>>>>>> add the correct validator. for example it wont let you add a >>>>>>>>>>>>>> validator >>>>>>>>>>>>>> that expects strings to a component that produces integers. >>>>>>>>>>>>>> >>>>>>>>>>>>>> also, not sure why you are replicating the model in Button. >>>>>>>>>>>>>> first, >>>>>>>>>>>>>> the >>>>>>>>>>>>>> Button uses its model to fill its label; secondly, in real >>>>>>>>>>>>>> code >>>>>>>>>>>>>> the >>>>>>>>>>>>>> model would be in a final var or field that things like >>>>>>>>>>>>>> onsubmit >>>>>>>>>>>>>> can >>>>>>>>>>>>>> access easily. >>>>>>>>>>>>>> >>>>>>>>>>>>>> -igor >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> - The property model uses reflection, so its type can't >>>>>>>>>>>>>> be >>>>>>>>>>>>>> verified >>>>>>>>>>>>>> by >>>>>>>>>>>>>> >>>>>>>>>>>>>> the >>>>>>>>>>>>>> >>>>>>>>>>>>>> compiler (this.person could be anything, not just a >>>>>>>>>>>>> Person). >>>>>>>>>>>>> >>>>>>>>>>>>> - Generics will guarantee that the form model will be of type >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Person, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> but >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> since it's all declared inline, and the real model isn't >>>>>>>>>>>>>>> >>>>>>>>>>>>>> verifiable, >>>>>>>>>>>>>> it >>>>>>>>>>>>>> >>>>>>>>>>>>>> just adds lots of verbosity without any real gain. >>>>>>>>>>>>>> >>>>>>>>>>>>>> - Most form components use the implicit model, that also >>>>>>>>>>>>> uses >>>>>>>>>>>>> >>>>>>>>>>>>> reflection, >>>>>>>>>>>>>> >>>>>>>>>>>>>>> and also can't verify the actual type of the underlying >>>>>>>>>>>>>>> >>>>>>>>>>>>>> property, >>>>>>>>>>>>>> at >>>>>>>>>>>>>> >>>>>>>>>>>>>> compilation time. Even in runtime, *the type information is >>>>>>>>>>>>>> lost >>>>>>>>>>>>>> >>>>>>>>>>>>>> due >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> erasure >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *, so it can't use it to do any additional verification. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> *- Worse, you can even declare the "name" TextField as >>>>>>>>>>>>>> >>>>>>>>>>>>>>> <Integer> >>>>>>>>>>>>>>> or >>>>>>>>>>>>>>> <Double> (while maintaining the 'text' attribute as String), >>>>>>>>>>>>>>> and >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> since >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> there is no type information at runtime, it doesn't >>>>>>>>>>>>>>> matter. It >>>>>>>>>>>>>>> >>>>>>>>>>>>>> won't >>>>>>>>>>>>> >>>>>>>>>>>>> even >>>>>>>>>>>>> >>>>>>>>>>>>> throw an exception (it will just work normally).* In this >>>>>>>>>>>>>> case, >>>>>>>>>>>>>> the >>>>>>>>>>>>>> type >>>>>>>>>>>>>> declaration is simply a lie. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Just pain, no gain. In my code, I sometimes just add a >>>>>>>>>>>>>> >>>>>>>>>>>>>> @SuppressWarnings( >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> "rawtypes") to the class, and remove all useless generic >>>>>>>>>>>>>>> type >>>>>>>>>>>>>>> >>>>>>>>>>>>>> declarations. >>>>>>>>>>>>>> >>>>>>>>>>>>>> If everything will be required to declare them, I will >>>>>>>>>>>>>> have >>>>>>>>>>>>>> do >>>>>>>>>>>>>> it >>>>>>>>>>>>>> >>>>>>>>>>>>>> more >>>>>>>>>>>>>> >>>>>>>>>>>>>>> frequently. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> That said, repeater components benefit greatly from >>>>>>>>>>>>> generics. >>>>>>>>>>>>> So >>>>>>>>>>>>> >>>>>>>>>>>>> do >>>>>>>>>>>>>> >>>>>>>>>>>>>> custom >>>>>>>>>>>>>> >>>>>>>>>>>>>>> models, validators, and converters. Or the rare cases >>>>>>>>>>>>>>> that >>>>>>>>>>>>>>> >>>>>>>>>>>>>> we >>>>>>>>>>>>>> >>>>>>>>>>>>>> explicitly >>>>>>>>>>>>>> >>>>>>>>>>>>>>> declare the form component model. But forcing everything >>>>>>>>>>>>>>> to be >>>>>>>>>>>>>>> >>>>>>>>>>>>>> generic-typed will just make Wicket extremely verbose to >>>>>>>>>>>>>> use, >>>>>>>>>>>>>> >>>>>>>>>>>>>> with >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> very >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> little benefit. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, May 30, 2013 at 4:00 AM, Martin Grigorov < >>>>>>>>>>>>> >>>>>>>>>>>>>> [email protected] >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Hi, >>>>>>>>>>>>> >>>>>>>>>>>>> I just pushed some initial work for [1] and [2] in >>>>>>>>>>>>>> >>>>>>>>>>>>>>> branch generified-component-4930. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> So far it doesn't look nice. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> The added generics break somehow setMetaData/getMetaData >>>>>>>>>>>>>>>> methods - >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> you >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> can >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> see compilation errors in Component and Page classes. I >>>>>>>>>>>>>> think it >>>>>>>>>>>>>> is >>>>>>>>>>>>>> >>>>>>>>>>>>>> caused >>>>>>>>>>>>>> >>>>>>>>>>>>>>> by the anonymous instance of MetaDataKey ( new >>>>>>>>>>>>>>> MetaDataKey<T>(type) >>>>>>>>>>>>>>> {} >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> ). >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Also the visit*** methods do not compile at the moment, but >>>>>>>>>>>>>> even >>>>>>>>>>>>>> if >>>>>>>>>>>>>> >>>>>>>>>>>>>> we >>>>>>>>>>>>>> >>>>>>>>>>>>>>> find >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> a way to fix their signature I think writing a visitor will >>>>>>>>>>>>>> become >>>>>>>>>>>>>> >>>>>>>>>>>>>> quite >>>>>>>>>>>>>> >>>>>>>>>>>>>>> cumbersome. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> At the moment we have IVisitor >>>>>>>>>>>>>> >>>>>>>>>>>>>> and org.apache.wicket.util.**********iterator.**** >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> AbstractHierarchyIterator >>>>>>>>>>>>>>>> which >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> same job. The Iterator API is supposed to be simpler to write >>>>>>>>>>>>>> for >>>>>>>>>>>>>> >>>>>>>>>>>>>> the >>>>>>>>>>>>>> >>>>>>>>>>>>>>> users. Maybe we can drop IVisitor ... ?! >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I'd like to ask for help with this task. It is supposed >>>>>>>>>>>>>> to be >>>>>>>>>>>>>> the >>>>>>>>>>>>>> >>>>>>>>>>>>>> biggest >>>>>>>>>>>>>> >>>>>>>>>>>>>>> API break for Wicket 7.0. My current feeling is that the end >>>>>>>>>>>>>>> result >>>>>>>>>>>>>>> won't >>>>>>>>>>>>>>> be very pleasant for the user-land code. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> For example the application code will have to do something >>>>>>>>>>>>>>> like: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> WebMarkupContainer<Void> wmc = new >>>>>>>>>>>>>>>> WebMarkupContainer<>("id") >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It is not that much but we have to decide whether we want >>>>>>>>>>>>>>>> it. >>>>>>>>>>>>>>>> But first let's try to fix the compilation problems. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 1. https://issues.apache.org/****** >>>>>>>>>>>>>>>> ****jira/browse/WICKET-4930<https://issues.apache.org/********jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> <ht**tps://issues.apache.org/******** >>>>>>>>>>>>>>>> jira/browse/WICKET-4930<https://issues.apache.org/******jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <http**s://issues.apache.org/*** >>>>>>>>>>>>>>>> *****jira/browse/WICKET-4930<http://issues.apache.org/******jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> <h**ttps://issues.apache.org/******jira/browse/WICKET-4930<https://issues.apache.org/****jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <https:**//issues.apache.org/*** >>>>>>>>>>>>>>>> ***jira/**browse/WICKET-4930<http://issues.apache.org/****jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> <h**ttp://issues.apache.org/****jira/**browse/WICKET-4930<http://issues.apache.org/**jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <htt**ps://issues.apache.org/****jira/**browse/WICKET-4930<http://issues.apache.org/**jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> <htt**ps://issues.apache.org/**jira/**browse/WICKET-4930<https://issues.apache.org/**jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <https:**//issues.apache.org/*** >>>>>>>>>>>>>>>> ***jira/**browse/WICKET-4930<http://issues.apache.org/****jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> <h**ttp://issues.apache.org/****jira/**browse/WICKET-4930<http://issues.apache.org/**jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <htt**p://issues.apache.org/**jira/****browse/WICKET-4930<http://issues.apache.org/jira/****browse/WICKET-4930> >>>>>>>>>>>>>>>> <ht**tp://issues.apache.org/jira/****browse/WICKET-4930<http://issues.apache.org/jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <http**s://issues.apache.org/****jira/**browse/WICKET-4930<http://issues.apache.org/**jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> <htt**p://issues.apache.org/jira/****browse/WICKET-4930<http://issues.apache.org/jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> <http**s://issues.apache.org/**jira/**browse/WICKET-4930<http://issues.apache.org/jira/**browse/WICKET-4930> >>>>>>>>>>>>>>>> <http**s://issues.apache.org/jira/**browse/WICKET-4930<https://issues.apache.org/jira/browse/WICKET-4930> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> (Add >>>>>>>>>>>>>>>>> generics >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> o.a.w.Component) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> 2. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> https://cwiki.apache.org/*********<https://cwiki.apache.org/*******> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> *confluence/display/WICKET/**<** >>>>>>>>>>>>>>>> https://cwiki.apache.org/******* >>>>>>>>>>>>>>>> *confluence/display/WICKET/**<https://cwiki.apache.org/******confluence/display/WICKET/**> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <**https://cwiki.apache.org/********<https://cwiki.apache.org/******> >>>>>>>>>>>>>>>> confluence/display/WICKET/**<h** >>>>>>>>>>>>>>>> ttps://cwiki.apache.org/******confluence/display/WICKET/**<https://cwiki.apache.org/****confluence/display/WICKET/**> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> <h**ttps://cwiki.apache.org/******<http://cwiki.apache.org/****> >>>>>>>>>>>>>>>> **confluence/display/WICKET/****< >>>>>>>>>>>>>>>> http://cwiki.apache.org/******confluence/display/WICKET/**<http://cwiki.apache.org/****confluence/display/WICKET/**> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> **<https://cwiki.apache.org/**** >>>>>>>>>>>>>>>> **confluence/display/WICKET/**<https://cwiki.apache.org/****confluence/display/WICKET/**> >>>>>>>>>>>>>>>> **<https://cwiki.apache.org/**** >>>>>>>>>>>>>>>> confluence/display/WICKET/**<https://cwiki.apache.org/**confluence/display/WICKET/**> >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> Wicket+7.0+Roadmap#Wicket7.******* >>>>>>>>>>>>>>>> ***0Roadmap-Genericsfororg.** >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> apache.wicket.Component<https:********// >>>>>>>>>>>>>>> cwiki.apache.org/** >>>>>>>>>>>>>>> >>>>>>>>>>>>>> confluence/** >>>>>>>>>>>>>> <http://cwiki.apache.org/****confluence/**<http://cwiki.apache.org/**confluence/**> >>>>>>>>>>>>> <http://cwiki.**apache.org/confluence/**<http://cwiki.apache.org/confluence/**> >>>>>>>>>>>>> > >>>>>>>>>>>>> >>>>>>>>>>>>> display/WICKET/Wicket+7.0+********Roadmap#Wicket7.0Roadmap-** >>>>>>>>>>>> Genericsfororg.apache.wicket.********Component<https://cwiki.** >>>>>>>>>>>> ** >>>>>>>>>>>> apache.org/confluence/display/******WICKET/Wicket+7.0+Roadmap#* >>>>>>>>>>>> ***<http://apache.org/confluence/display/****WICKET/Wicket+7.0+Roadmap#**> >>>>>>>>>>>> <http://apache.org/**confluence/display/**WICKET/** >>>>>>>>>>>> Wicket+7.0+Roadmap#**<http://apache.org/confluence/display/**WICKET/Wicket+7.0+Roadmap#**> >>>>>>>>>>>> > >>>>>>>>>>>> Wicket7.0Roadmap-******Genericsfororg.apache.wicket.*** >>>>>>>>>>>> ***Component< >>>>>>>>>>>> >>>>>>>>>>>> https://cwiki.**apache.org/**confluence/display/**<http://apache.org/confluence/display/**> >>>>>>>>>>>> WICKET/Wicket+7.0+Roadmap#****Wicket7.0Roadmap-** >>>>>>>>>>>> Genericsfororg.apache.wicket.****Component<https://cwiki.** >>>>>>>>>>>> apache.org/confluence/display/**WICKET/Wicket+7.0+Roadmap#** >>>>>>>>>>>> Wicket7.0Roadmap-**Genericsfororg.apache.wicket.**Component<https://cwiki.apache.org/confluence/display/WICKET/Wicket+7.0+Roadmap#Wicket7.0Roadmap-Genericsfororg.apache.wicket.Component> >>>>>>>>>>>> > >>>>>>>>>>>> >>>>>>>>>>>> >
