You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Szádeczky-Kardoss Szabolcs (JIRA)" <ji...@apache.org> on 2011/01/26 17:23:45 UTC

[jira] Created: (WICKET-3392) Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)

Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)
---------------------------------------------------------------------------------------

                 Key: WICKET-3392
                 URL: https://issues.apache.org/jira/browse/WICKET-3392
             Project: Wicket
          Issue Type: Bug
          Components: wicket
    Affects Versions: 1.5-RC1
            Reporter: Szádeczky-Kardoss Szabolcs
            Priority: Critical


I think the 3218 issue is really a misunderstanding of the onInitialize concept, as it was a really needed feature. This was the reason I switched to 1.5-M3, and then BANG! in RC1 this is broken. Let me explain how to use it in the right way, and then my use case for which this is much needed. 
USAGE 
As you have pointed out, onInitialize gets called at the first time when a component gets added to the Page, or - if this doesn't happen in the constructor then - in the render phase (internalPrepareForRender method) at latest. Well, if you add any component to the page in the constructor then onInitialize is really not of much use, actually in this case it's better not to use it all. However if you start making pages as I do, then it becomes a joy to work with. 

The solution is simple: Don't add any component to the Page in the constructor, use onInitialize for that purpose. If you advocate this as a best practice then the use cases stated below will be much easier to make than without the onInitialize (and using only constructor). 

The constructor is anyway best suited only for setting up models, performing (some or all of the) service calls and other things needed to ensure that the given Page is the one to show to the user, without going into costly component additions to the Page. 

USE CASES 
- In my current project we have a common base page from which all other pages subclasses and so we share a common layout, some common panels and common functionality in all pages. However once in a while it might be needed to hide or replace one of the common panels in only one page but leave it as common in all of the others. If you only could do this in the constructor then that will be a really pain. The reason in short is that irrespective of whether you use overriden "panel adder methods" or any other solution you are still in object construction phase and that puts quite a few restrictions on variable initialization order. I know, I did it, and there are only hacking workarounds for this. On the other hand, onInitialize is a super elegant way to use overriden methods or any cool OO technique since you are not constrained any more by the "Construction phase". 

- An other use case is that the user is doing stuff on any page, it can be anything. Irrespective of what he/she is doing, something is happening in the background, perhaps by an other user's action. The next time the first user is refreshing this page or going to another page, I want the user to be notified, in a common way, in a common code. This can be also achieved without onInitialize with more or less hacking (especially when we want the user notified when staying on the same page), but with onInitialize this is a much cleaner. The reason is that prepareForRender (which by the way also got final, why?) precedes onInitialize and so it is possible to do this check there. 

FINAL/NON-FINAL :) THOUGHTS 
Sorry for getting so long, my only point is that onInitialize (and prepareForRender) not being final was one of the great achievements of 1.5 (backported into 1.4, or was it the other way around?). There were really use cases for this, especially the avoidance of the Java Object Construction Phase limitations (and the possibility of not having ugly big constructors :)). Sure this can be misused or used wrongly as a lot of other things in Wicket, but this is not a reason to limit the good usage of this. You can put it in the javadoc, that only use onInitialize when you don't do add operations in the constructor. Actually I would also ask what's the point of onInitialize anywhere else than for Pages? At least I could live without it anywhere else, but not for Pages. 
I hope you will change both methods back to non-final. If not, then I will have to revert to 1.4 and possibly never use 1.5 since the above issues are showstoppers for me. This would be a sad thing from such a great framework.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (WICKET-3392) Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)

Posted by "Szádeczky-Kardoss Szabolcs (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/WICKET-3392?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12987195#action_12987195 ] 

Szádeczky-Kardoss Szabolcs commented on WICKET-3392:
----------------------------------------------------

(Same comment as in 3218)
Thanks for the quick reply. The point is yours with my second use case, that's fine with onConfigure. However I have still a problem with onInitialize. If it remains final as in RC1, then for Pages there's no other way to do initialization than in the constructor, right? All other Components can have this nice feature, but not Pages. Why? If you really want to protect users, then a much nicer solution would have been NOT to initialize Pages when components get added, but only before the render phase. I understand that most situations could be solved with a panel replace maybe in onConfigure, but IMHO this is kind of a hack compared to a nice OO solution that actually are very widespread in Wicket elsewhere. And what makes Wicket lightyears ahead of JSP, JSF and Co.

If you still insist on the current solution, would it be not possible to add an extra initialize method for Pages that gets called guaranteed only once, and guaranteed not while the constructor is running (probably before the render phase like now)? For me this would be essential, and I can hopefully show another use case of mine for this purpose:
On some pages there might be an important form working with session-bound data that we want to protect even when the user navigates away via some link other than submit or cancel. Imagine a shopping cart page where the user can set the quantities but if he abruptly clicks on a featured product in the sidebar I want to store all the quantity changes he has made in the cart. A very efficient solution can be done with AjaxFormSubmitBehavior, that I add to each link on each panel on such Pages. However each Panel must be made aware of this important form at creation or initialization time. Since my panels get added in my common base Page, without onInitialize the only nice way to pass this form to it is through the super constructor call, however the form is definitely not available in the first line of the constructor where super(...) is. Of course workarounds can be made, as I have made one myself that included an extra Page-managed initialized attribute and some extra glues, but onInitialize was really a super nice solution to this problem. I am open to other suggestions, but probably not leaving Pages as orphans that don't have a chance for nice initialization outside of a Java Constructor would make Wicket more concistent.

> Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)
> ---------------------------------------------------------------------------------------
>
>                 Key: WICKET-3392
>                 URL: https://issues.apache.org/jira/browse/WICKET-3392
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.5-RC1
>            Reporter: Szádeczky-Kardoss Szabolcs
>            Assignee: Igor Vaynberg
>            Priority: Critical
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> I think the 3218 issue is really a misunderstanding of the onInitialize concept, as it was a really needed feature. This was the reason I switched to 1.5-M3, and then BANG! in RC1 this is broken. Let me explain how to use it in the right way, and then my use case for which this is much needed. 
> USAGE 
> As you have pointed out, onInitialize gets called at the first time when a component gets added to the Page, or - if this doesn't happen in the constructor then - in the render phase (internalPrepareForRender method) at latest. Well, if you add any component to the page in the constructor then onInitialize is really not of much use, actually in this case it's better not to use it all. However if you start making pages as I do, then it becomes a joy to work with. 
> The solution is simple: Don't add any component to the Page in the constructor, use onInitialize for that purpose. If you advocate this as a best practice then the use cases stated below will be much easier to make than without the onInitialize (and using only constructor). 
> The constructor is anyway best suited only for setting up models, performing (some or all of the) service calls and other things needed to ensure that the given Page is the one to show to the user, without going into costly component additions to the Page. 
> USE CASES 
> - In my current project we have a common base page from which all other pages subclasses and so we share a common layout, some common panels and common functionality in all pages. However once in a while it might be needed to hide or replace one of the common panels in only one page but leave it as common in all of the others. If you only could do this in the constructor then that will be a really pain. The reason in short is that irrespective of whether you use overriden "panel adder methods" or any other solution you are still in object construction phase and that puts quite a few restrictions on variable initialization order. I know, I did it, and there are only hacking workarounds for this. On the other hand, onInitialize is a super elegant way to use overriden methods or any cool OO technique since you are not constrained any more by the "Construction phase". 
> - An other use case is that the user is doing stuff on any page, it can be anything. Irrespective of what he/she is doing, something is happening in the background, perhaps by an other user's action. The next time the first user is refreshing this page or going to another page, I want the user to be notified, in a common way, in a common code. This can be also achieved without onInitialize with more or less hacking (especially when we want the user notified when staying on the same page), but with onInitialize this is a much cleaner. The reason is that prepareForRender (which by the way also got final, why?) precedes onInitialize and so it is possible to do this check there. 
> FINAL/NON-FINAL :) THOUGHTS 
> Sorry for getting so long, my only point is that onInitialize (and prepareForRender) not being final was one of the great achievements of 1.5 (backported into 1.4, or was it the other way around?). There were really use cases for this, especially the avoidance of the Java Object Construction Phase limitations (and the possibility of not having ugly big constructors :)). Sure this can be misused or used wrongly as a lot of other things in Wicket, but this is not a reason to limit the good usage of this. You can put it in the javadoc, that only use onInitialize when you don't do add operations in the constructor. Actually I would also ask what's the point of onInitialize anywhere else than for Pages? At least I could live without it anywhere else, but not for Pages. 
> I hope you will change both methods back to non-final. If not, then I will have to revert to 1.4 and possibly never use 1.5 since the above issues are showstoppers for me. This would be a sad thing from such a great framework.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (WICKET-3392) Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)

Posted by "Igor Vaynberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/WICKET-3392?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Igor Vaynberg resolved WICKET-3392.
-----------------------------------

    Resolution: Duplicate
      Assignee: Igor Vaynberg

i have answered your comments in 3128

> Page#onInitialize (and prepareForRender) is now broken as it is final (see Wicket-3218)
> ---------------------------------------------------------------------------------------
>
>                 Key: WICKET-3392
>                 URL: https://issues.apache.org/jira/browse/WICKET-3392
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.5-RC1
>            Reporter: Szádeczky-Kardoss Szabolcs
>            Assignee: Igor Vaynberg
>            Priority: Critical
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> I think the 3218 issue is really a misunderstanding of the onInitialize concept, as it was a really needed feature. This was the reason I switched to 1.5-M3, and then BANG! in RC1 this is broken. Let me explain how to use it in the right way, and then my use case for which this is much needed. 
> USAGE 
> As you have pointed out, onInitialize gets called at the first time when a component gets added to the Page, or - if this doesn't happen in the constructor then - in the render phase (internalPrepareForRender method) at latest. Well, if you add any component to the page in the constructor then onInitialize is really not of much use, actually in this case it's better not to use it all. However if you start making pages as I do, then it becomes a joy to work with. 
> The solution is simple: Don't add any component to the Page in the constructor, use onInitialize for that purpose. If you advocate this as a best practice then the use cases stated below will be much easier to make than without the onInitialize (and using only constructor). 
> The constructor is anyway best suited only for setting up models, performing (some or all of the) service calls and other things needed to ensure that the given Page is the one to show to the user, without going into costly component additions to the Page. 
> USE CASES 
> - In my current project we have a common base page from which all other pages subclasses and so we share a common layout, some common panels and common functionality in all pages. However once in a while it might be needed to hide or replace one of the common panels in only one page but leave it as common in all of the others. If you only could do this in the constructor then that will be a really pain. The reason in short is that irrespective of whether you use overriden "panel adder methods" or any other solution you are still in object construction phase and that puts quite a few restrictions on variable initialization order. I know, I did it, and there are only hacking workarounds for this. On the other hand, onInitialize is a super elegant way to use overriden methods or any cool OO technique since you are not constrained any more by the "Construction phase". 
> - An other use case is that the user is doing stuff on any page, it can be anything. Irrespective of what he/she is doing, something is happening in the background, perhaps by an other user's action. The next time the first user is refreshing this page or going to another page, I want the user to be notified, in a common way, in a common code. This can be also achieved without onInitialize with more or less hacking (especially when we want the user notified when staying on the same page), but with onInitialize this is a much cleaner. The reason is that prepareForRender (which by the way also got final, why?) precedes onInitialize and so it is possible to do this check there. 
> FINAL/NON-FINAL :) THOUGHTS 
> Sorry for getting so long, my only point is that onInitialize (and prepareForRender) not being final was one of the great achievements of 1.5 (backported into 1.4, or was it the other way around?). There were really use cases for this, especially the avoidance of the Java Object Construction Phase limitations (and the possibility of not having ugly big constructors :)). Sure this can be misused or used wrongly as a lot of other things in Wicket, but this is not a reason to limit the good usage of this. You can put it in the javadoc, that only use onInitialize when you don't do add operations in the constructor. Actually I would also ask what's the point of onInitialize anywhere else than for Pages? At least I could live without it anywhere else, but not for Pages. 
> I hope you will change both methods back to non-final. If not, then I will have to revert to 1.4 and possibly never use 1.5 since the above issues are showstoppers for me. This would be a sad thing from such a great framework.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.