On Thu, Jan 23, 2014 at 8:53 AM, Martin Grigorov <mgrigo...@apache.org> wrote: > On Thu, Jan 23, 2014 at 6:36 PM, Igor Vaynberg <igor.vaynb...@gmail.com>wrote: > >> On Thu, Jan 23, 2014 at 8:20 AM, Martin Grigorov <mgrigo...@apache.org> >> wrote: >> > Once the markup driven construction is done (just before onInitialize()) >> > the application will have to use the old good add()/addOrReplace(). >> >> yeah, but onInitialize() is there to partially replace the constructor >> as a place to add components. >> > > It is perfectly fine to add components later. > If markup-driven construction cannot find a component it doesn't blow > immediately. > It just ignores the rest of the markup stream below the missing component. > If there is a missing component during rendering then an exception is > thrown. > > >> >> > The components are already in the MarkupContainer#children data >> structure. >> > So each field will add extra 8 bytes on 64bit machine (or 4 bytes with >> > CompressedOops enabled). >> >> yes, thats the 8 bytes i was talking about. considering some pages >> have easily over a hundred components that adds up. >> >> > Serialization is the same - the object is written once, with several >> > pointers. >> >> no, serialization will suffer from the same 8 bytes per component >> reference issue. that means thats a bunch more bytes to shuffle to and >> from disk and also across network when clustered. >> > > Well, I see no other way to find a reference to a component :-/ > If a page has 1000 components then this is 8k more. > 1000 components is a lot. Most pages have much less. > I have to check again but recently while working on Memcached based > IDataStore I think a pretty simple page serialized was about 60k. > > >> >> > I am also not fully sure in the approach but I am experimenting and so >> far >> > it works well. >> > And it is configurable, by default disabled. >> > We can advertise it as experimental ?! >> >> something like this cannot be enabled/disabled. if a component library >> uses it then it will fail on applications where this is disabled. >> > > yes, this is true > a "workaround" here is each MarkupContainer can declare whether it supports > markup-driven tree by overriding > org.apache.wicket.MarkupContainer#isMarkupDrivenComponentTreeEnabled > i.e. the library component can always return true > > >> >> also, what happens in situations where ids are not unique? then those >> cannot be put into the hierarchy? >> >> its common to have structure like this: >> >> <a wicket:id="remove"><span wicket:id="label"></span></a><a >> wicket:id="add"><span wicket:id="label"></a> >> > > This should work fine at the moment. > Each MarkupContainer instance resolves its own fields/components. > I'll add test tomorrow to verify.
not sure what you mean by works fine. @Auto WebMarkupContainer a,b,c,d; a=new Link("remove"); b=new Label("label", "remove"); c=new Link("add"); d=new Label("label", "add"); how does wicket know the difference between b and d? this will get worse with subclasses as now you have to be aware to not add any component with the same id used in the class hierarchy... -igor > > >> >> another exception is the repeater, unless you create a custom subclass >> of Item which no one ever does. >> > > another test to add ! > > >> >> seems to me there are too many gotchas for all but the most trivial >> cases. couple this together with the fact that it has to be enabled as >> mentioned above would put me at -0.5 for this for now. >> >> -igor >> >> > I will add more use cases/tests soon. >> > And caching for the reflection stuff. >> > >> > >> > On Thu, Jan 23, 2014 at 6:09 PM, Igor Vaynberg <igor.vaynb...@gmail.com >> >wrote: >> > >> >> what about components added in onInitialize() or on onConfigure()? >> >> >> >> this will also lead to a higher memory/serialization space usage since >> >> by default you need a field to store the component ref. >> >> >> >> not sure its worth doing it this way... >> >> >> >> -igor >> >> >> >> >> >> On Wed, Jan 22, 2014 at 12:12 PM, Martin Grigorov <mgrigo...@apache.org >> > >> >> wrote: >> >> > Hi, >> >> > >> >> > Recently Fridolin Jackstadt shared his approach to "autowire" >> components >> >> - >> >> > https://github.com/wicket-acc/wicket-autowire. >> >> > >> >> > I believe this approach can solve two issues: >> >> > - duplicate construction of the component tree - once in the markup >> and >> >> > second time in Java code >> >> > - auto components available only in the render phase >> >> > >> >> > Here is how I see it: >> >> > >> >> > Any MarkupContainer that wants to use markup-driven-tree must declare >> the >> >> > components as member fields: >> >> > >> >> > private SomeComponent aComponent; >> >> > >> >> > These fields will be instantiated like any other component in Wicket: >> >> > >> >> > aComponent = new SomeComponent(id, ...); >> >> > >> >> > The new thing is that they *won't* be added to a parent component >> >> > explicitly/manually. >> >> > >> >> > On Page#onInitialize() the first thing to do it to walk over the >> >> component >> >> > tree from the page's markup (just like the walk in the rendering >> related >> >> > code) and resolve the missing bits. >> >> > I.e. while walking thru the markup tree we will check the Java >> component >> >> > tree (container.get(tagId)). If there is a miss then we search for a >> >> member >> >> > field that is a component with the same id in the current >> >> MarkupContainer, >> >> > its (Java) super classes and finally in its (Wicket) parent classes. >> >> > >> >> > This will solve issue #1 (identical trees in Java and markup) >> >> > (P.S. Fridolin's code uses @AutoComponent annotation that facilitates >> >> > searching by component id, but will duplicate the declaration of the >> id - >> >> > once in the annotation and second time in 'new MyComponent(ID). This >> is >> >> an >> >> > implementation detail.) >> >> > >> >> > >> >> > The second part is not less hard - during the walk over the markup >> tree >> >> > when an autocomponent (e.g. enclosure) is seen Wicket will use the >> >> > registered IComponentResolvers to create the Java component and >> insert it >> >> > in the Java tree. >> >> > The tricky part here is that any manually added components (like in >> >> Wicket >> >> > 6.x) to the parent of the autocomponent should be moved into the >> >> > autocomponent. >> >> > For example: >> >> > >> >> > <div wicket:id="a"> >> >> > <wicket:enclosure child="b"> >> >> > <span wicket:id="b"></span> >> >> > <span wicket:id="c"></span> >> >> > </wicket:enclosure> >> >> > </div> >> >> > >> >> > If 'b' and 'c' are added manually to 'a' in the application's Java >> code: >> >> > (a (b,c)) >> >> > >> >> > then after the "resolving phase" the tree will be: >> >> > >> >> > a (enclosure(b, c)) >> >> > >> >> > so b.getParent() in onInitialize() and later will return the >> Enclosure, >> >> not >> >> > 'a'. >> >> > >> >> > >> >> > I don't know very well the MarkupStream APIs but I think all this >> should >> >> be >> >> > possible. >> >> > >> >> > WDYT about this approach ? >> >> > >> >> > >> >> > Martin Grigorov >> >> > Wicket Training and Consulting >> >> >>