Wicket
  1. Wicket
  2. WICKET-3335

Component Queueing (extract hierarchy information from markup)

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 7.0.0-M1
    • Component/s: wicket
    • Labels:
      None

      Description

      Doubly defined hierarhices are redundant.
      Server-side hierarchy can be automatically deduced from markup hierarchy.
      Use queue method in MarkupContainer to add components and extract hierarchy information from markup.
      Discussed here: http://apache-wicket.1842946.n4.nabble.com/Free-wicket-from-component-hierarchy-hell-td3027705.html
      Implementation of queue method on branch 1.4.x : https://github.com/koutsoub/wicket/tree/component-queuing

      1. wicket-3335.patch
        11 kB
        Juergen Donnerstag
      2. 0001-component-queuing.patch
        33 kB
        Giannis Koutsoubos

        Issue Links

          Activity

          Giannis Koutsoubos created issue -
          Hide
          Giannis Koutsoubos added a comment -

          patch that provides component queuing support on wicket-1.4.x branch

          Show
          Giannis Koutsoubos added a comment - patch that provides component queuing support on wicket-1.4.x branch
          Giannis Koutsoubos made changes -
          Field Original Value New Value
          Attachment 0001-component-queuing.patch [ 12468382 ]
          Hide
          Martin Makundi added a comment -

          I vote
          +1 for adding it to 1.4.x

          because this feature does not compromise anything, it is just an alternate way of adding components.

          Show
          Martin Makundi added a comment - I vote +1 for adding it to 1.4.x because this feature does not compromise anything, it is just an alternate way of adding components.
          Show
          Giannis Koutsoubos added a comment - support for 1.5 https://github.com/koutsoub/wicket/tree/component_queuing_1.5
          Igor Vaynberg made changes -
          Link This issue relates to WICKET-3673 [ WICKET-3673 ]
          Hide
          Juergen Donnerstag added a comment -

          Another way to solve it (we actually had that in 1.2 or so) is to extend/replace the component resolution process.

          Show
          Juergen Donnerstag added a comment - Another way to solve it (we actually had that in 1.2 or so) is to extend/replace the component resolution process.
          Hide
          Igor Vaynberg added a comment - - edited

          @Juergen: i dont like doing that. the hierarchical information defined in java/markup is very important and i would not want to do lose that...

          Show
          Igor Vaynberg added a comment - - edited @Juergen: i dont like doing that. the hierarchical information defined in java/markup is very important and i would not want to do lose that...
          Hide
          Ondra Žižka added a comment -

          A note to http://apache-wicket.1842946.n4.nabble.com/Free-wicket-from-component-hierarchy-hell-tp3027705p3028177.html :
          Perhaps hierarchy ambiguities could be solved by introducing a concept of "component tree path", e.g. instead of

          add("form1").add("input");
          add("form2").add("input")

          we could have (while keeping backwards compatibility):

          add("form1")
          add("form1.input")
          add("form2")
          add("form2.input")

          (Which might be what Juergen meant by "extending component resolution process".)

          Pro: More flat code
          Con: Less semantical code, performance drawback

          I'm not really sure what would I prefer. But it would fit with PropertyModel.

          Show
          Ondra Žižka added a comment - A note to http://apache-wicket.1842946.n4.nabble.com/Free-wicket-from-component-hierarchy-hell-tp3027705p3028177.html : Perhaps hierarchy ambiguities could be solved by introducing a concept of "component tree path", e.g. instead of add("form1").add("input"); add("form2").add("input") we could have (while keeping backwards compatibility): add("form1") add("form1.input") add("form2") add("form2.input") (Which might be what Juergen meant by "extending component resolution process".) Pro: More flat code Con: Less semantical code, performance drawback I'm not really sure what would I prefer. But it would fit with PropertyModel.
          Hide
          Igor Vaynberg added a comment -

          there shouldnt be any ambiguities because all containers support queuing.

          so if you have two components with the same id and you want to queue them both you have to queue them under a parent that will not cause ambiguities, eg

          lets say you have
          c1->input
          c1->c2->input

          the following code should obviously not work
          queue(new Container("c1"));
          queue(new Container("c2"));
          queue(new Input("input"));
          queue(new Input("input"));

          because the page does not know how to resolve which input goes where, but - the following

          Container c2;
          queue(new Container("c1"));
          queue(c2=new Container("c2"));
          queue(new Input("input"));
          c2.queue(new Input("input"));

          should work because we have removed the ambiguity.

          Show
          Igor Vaynberg added a comment - there shouldnt be any ambiguities because all containers support queuing. so if you have two components with the same id and you want to queue them both you have to queue them under a parent that will not cause ambiguities, eg lets say you have c1->input c1->c2->input the following code should obviously not work queue(new Container("c1")); queue(new Container("c2")); queue(new Input("input")); queue(new Input("input")); because the page does not know how to resolve which input goes where, but - the following Container c2; queue(new Container("c1")); queue(c2=new Container("c2")); queue(new Input("input")); c2.queue(new Input("input")); should work because we have removed the ambiguity.
          Hide
          Ondra Žižka added a comment -

          ..which leads me to another idea - jQuery-like components selectors:

          getComponents("Form#form1 WebMarkupContainer.holder input"); // CSS-like syntax

          That would traverse this component's tree and return a collection of matching components.
          Components could have CSS-like classes for this purpose.
          Or with a collection proxy able to change the component...

          getComponents("Form#form1 WebMarkupContainer.holder input").setVisible(false)

          Was something like that proposed?
          Maybe this could bring some fresh air to solutions for things like group of checkboxes etc.

          Show
          Ondra Žižka added a comment - ..which leads me to another idea - jQuery-like components selectors: getComponents("Form#form1 WebMarkupContainer.holder input"); // CSS-like syntax That would traverse this component's tree and return a collection of matching components. Components could have CSS-like classes for this purpose. Or with a collection proxy able to change the component... getComponents("Form#form1 WebMarkupContainer.holder input").setVisible(false) Was something like that proposed? Maybe this could bring some fresh air to solutions for things like group of checkboxes etc.
          Hide
          Igor Vaynberg added a comment -

          yes, something like this was proposed, but does not seem very useful. how often do you use a visitor to do something in wicket? which is what this is, a shorthand for visitors.

          Show
          Igor Vaynberg added a comment - yes, something like this was proposed, but does not seem very useful. how often do you use a visitor to do something in wicket? which is what this is, a shorthand for visitors.
          Hide
          Juergen Donnerstag added a comment -

          What shall be the resolution logic in the example below

          c1->input
          c1->c2->input

          Container c2;
          queue(new Container("c1"));
          queue(c2=new Container("c2"));
          queue(new Input("input"));
          c2.queue(new Input("input"));

          I assume:
          queue(new Container("c1")); will immediately be executed because we don't need to wait for anything
          queue(c2=new Container("c2")); same; invoke add() immediately
          queue(new Input("input")); can be added to c1 or c2. Shall that request be stalled until later? Until when? Or shall it be added to the first occassion it finds (without a warning)?
          c2.queue(new Input("input")); can be executed immediately without ambiguity. Should we retry the postponed entry now? In that case queue can only do add but no replace (IMO not a heavy limitation).

          Show
          Juergen Donnerstag added a comment - What shall be the resolution logic in the example below c1->input c1->c2->input Container c2; queue(new Container("c1")); queue(c2=new Container("c2")); queue(new Input("input")); c2.queue(new Input("input")); I assume: queue(new Container("c1")); will immediately be executed because we don't need to wait for anything queue(c2=new Container("c2")); same; invoke add() immediately queue(new Input("input")); can be added to c1 or c2. Shall that request be stalled until later? Until when? Or shall it be added to the first occassion it finds (without a warning)? c2.queue(new Input("input")); can be executed immediately without ambiguity. Should we retry the postponed entry now? In that case queue can only do add but no replace (IMO not a heavy limitation).
          Hide
          Igor Vaynberg added a comment -

          its not exactly how it works. queue(new Container("c1")) will not be immediately executed, none of them will. unqueueing happens after/before? the initialization of the component when the markup is available.

          when dequeuing we try to find a queued child closest to the container, so in the example above it will work like this:

          resolving c1, found and dequeued
          resolving c1->input. look in c1, not found. look in parent, found and dequeued
          resolving c2. look in c1, not found. look in parent, found and dequeued
          resolving c2->input: look in c2, found and dequeued

          also i now think queue is too cumberson to type, we should probably rename it to "push"

          Show
          Igor Vaynberg added a comment - its not exactly how it works. queue(new Container("c1")) will not be immediately executed, none of them will. unqueueing happens after/before? the initialization of the component when the markup is available. when dequeuing we try to find a queued child closest to the container, so in the example above it will work like this: resolving c1, found and dequeued resolving c1->input. look in c1, not found. look in parent, found and dequeued resolving c2. look in c1, not found. look in parent, found and dequeued resolving c2->input: look in c2, found and dequeued also i now think queue is too cumberson to type, we should probably rename it to "push"
          Hide
          Juergen Donnerstag added a comment -

          Find attached my little attempt to implement queuing. Feel free add more test cases, review or comment

          Show
          Juergen Donnerstag added a comment - Find attached my little attempt to implement queuing. Feel free add more test cases, review or comment
          Juergen Donnerstag made changes -
          Attachment wicket-3335.patch [ 12485777 ]
          Igor Vaynberg made changes -
          Assignee Igor Vaynberg [ ivaynberg ]
          Igor Vaynberg made changes -
          Fix Version/s 1.6.0 [ 12315431 ]
          Hide
          Igor Vaynberg added a comment -

          @Juergen, right now your tests only test for rendering, but they should also test that before queued component's oninitialize is called the component is already a child of the correct parent.

          Show
          Igor Vaynberg added a comment - @Juergen, right now your tests only test for rendering, but they should also test that before queued component's oninitialize is called the component is already a child of the correct parent.
          Hide
          Juergen Donnerstag added a comment -

          It's now available on github as well https://github.com/jdonnerstag/wicket/tree/queuing

          Show
          Juergen Donnerstag added a comment - It's now available on github as well https://github.com/jdonnerstag/wicket/tree/queuing
          Hide
          Juergen Donnerstag added a comment -

          @Igor not sure I understand. I thought that for all components (queued or not) onInitialize gets called in any case after it was added and it's markup is available. onInitialize will never be called for queued components while still waiting to be added. During unqueuing the component gets added and because it's markup is guaranteed to be available, onInitialize gets called. Did I misunderstand your question?

          Show
          Juergen Donnerstag added a comment - @Igor not sure I understand. I thought that for all components (queued or not) onInitialize gets called in any case after it was added and it's markup is available. onInitialize will never be called for queued components while still waiting to be added. During unqueuing the component gets added and because it's markup is guaranteed to be available, onInitialize gets called. Did I misunderstand your question?
          Hide
          Igor Vaynberg added a comment -

          @Juergen
          i simply stated that there should be tests that check the hierarchy in a queued component's oninitialize method. eg, to make sure oninitialize is not called on queue, but rather after dequeue.

          Show
          Igor Vaynberg added a comment - @Juergen i simply stated that there should be tests that check the hierarchy in a queued component's oninitialize method. eg, to make sure oninitialize is not called on queue, but rather after dequeue.
          Martin Grigorov made changes -
          Fix Version/s 6.0.0-RC1 [ 12320343 ]
          Fix Version/s 6.0.0-beta1 [ 12315431 ]
          Igor Vaynberg made changes -
          Fix Version/s 6.0.0-RC1 [ 12320343 ]
          Hide
          Igor Vaynberg added a comment -

          this is a much more complex problem that i thought initially, mainly because it has to work with auto resolved tags which "pollute" nesting information in markup.

          some unfinished attempts at this are in the origin/sandbox/component-queueing and origin/sandbox/hierarchy-completion branches.

          Show
          Igor Vaynberg added a comment - this is a much more complex problem that i thought initially, mainly because it has to work with auto resolved tags which "pollute" nesting information in markup. some unfinished attempts at this are in the origin/sandbox/component-queueing and origin/sandbox/hierarchy-completion branches.
          Hide
          Martin Grigorov added a comment -

          Branch 'markup-driven-component-tree' contains alternative solution that is described at http://markmail.org/message/kx3ujbsi4p36je2t
          It is not finished yet but any comments and use cases are welcome!

          Diff against master can be seen at https://github.com/apache/wicket/compare/markup-driven-component-tree (Note: GitHub is a bit behind Apache Git!).

          Show
          Martin Grigorov added a comment - Branch 'markup-driven-component-tree' contains alternative solution that is described at http://markmail.org/message/kx3ujbsi4p36je2t It is not finished yet but any comments and use cases are welcome! Diff against master can be seen at https://github.com/apache/wicket/compare/markup-driven-component-tree (Note: GitHub is a bit behind Apache Git!).
          Hide
          Igor Vaynberg added a comment -

          new implementation in sandbox/component-queueing-2

          Show
          Igor Vaynberg added a comment - new implementation in sandbox/component-queueing-2
          Show
          Igor Vaynberg added a comment - http://markmail.org/message/jzotleixyjxhgn5m
          Igor Vaynberg made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Fix Version/s 7.0.0 [ 12322958 ]
          Resolution Fixed [ 1 ]
          Igor Vaynberg made changes -
          Summary Component Queuing (extract hierarchy information from markup) Component Queueing (extract hierarchy information from markup)
          Hide
          Igor Vaynberg added a comment -
          Show
          Igor Vaynberg added a comment - user description of the implementation: https://www.42lines.net/2014/02/28/component-queueing-in-wicket-7/
          Martin Grigorov made changes -
          Link This issue relates to WICKET-5479 [ WICKET-5479 ]
          Martin Grigorov made changes -
          Link This issue is related to WICKET-5543 [ WICKET-5543 ]

            People

            • Assignee:
              Igor Vaynberg
              Reporter:
              Giannis Koutsoubos
            • Votes:
              4 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development