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. > > 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 > >> >