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

Reply via email to