For some reason I still don't receive mail notification about the revert. https://git-wip-us.apache.org/repos/asf/wicket/repo?p=wicket.git;a=commit;h=af890025eb8fd12459600cf2cf93bc78661589f4
On Tue, Mar 12, 2013 at 1:46 PM, Martin Grigorov <[email protected]>wrote: > > > > On Tue, Mar 12, 2013 at 1:43 PM, Martin Grigorov <[email protected]>wrote: > >> Everything seems to be OK with this additional patch here. >> I've tested our app (which is mostly stateful), and all stateless >> examples in wicket-examples. >> Additionally I ran 'mvn clean test" on wicketstuff-core. >> >> I think Martijn will cut 6.7.0 this Friday. Since this improvement is not >> something urgent I'll revert it now and apply it again when 6.8.0-SNAPSHOT >> is available. This way we will have almost a month to test it before 6.9.0. >> > > I meant "before 6.8.0". > > >> >> >> On Tue, Mar 12, 2013 at 1:15 PM, Martin Grigorov <[email protected]>wrote: >> >>> Thanks, Sven ! >>> >>> I'm investigating what will break if the check for stateless is removed >>> from org.apache.wicket.page.AbstractPageManager#touchPage: >>> --- >>> i/wicket-core/src/main/java/org/apache/wicket/page/AbstractPageManager.java >>> +++ >>> w/wicket-core/src/main/java/org/apache/wicket/page/AbstractPageManager.java >>> @@ -127,10 +127,6 @@ public abstract class AbstractPageManager >>> implements IPageManager >>> @Override >>> public void touchPage(IManageablePage page) >>> { >>> - if (!page.isPageStateless()) >>> - { >>> - getContext().bind(); >>> - } >>> getRequestAdapter().touch(page); >>> >>> >>> The session is being bound at org.apache.wicket.Page#onAfterRender when >>> needed. >>> >>> So far with this additional patch no tests fail and wicket-examples >>> seems to work. >>> I'll test our application with this change and then I'll either commit >>> this change or revert the previous one. >>> >>> >>> On Tue, Mar 12, 2013 at 12:41 PM, Sven Meier <[email protected]> wrote: >>> >>>> Hi Martin, >>>> >>>> >>>> --- a/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>> +++ b/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>> @@ -450,6 +450,8 @@ public abstract class Page extends MarkupContainer >>>> implements IRedirectListener, >>>> if (stateless == null) >>>> { >>>> + internalInitialize(); >>>> + >>>> if (isStateless() == false) >>>> { >>>> stateless = Boolean.FALSE; >>>> >>>> problem is that calling internaltInitialize() here will trigger >>>> initialization of the page from the constructor: >>>> >>>> Thread [qtp400269449-16] (Suspended) >>>> OtherPage.onInitialize() line: 23 >>>> OtherPage(Component).**fireInitialize() line: 863 >>>> OtherPage(MarkupContainer).**internalInitialize() line: 955 >>>> OtherPage(Page).**isPageStateless() line: 453 >>>> PageStoreManager(**AbstractPageManager).**touchPage(IManageablePage) >>>> line: 130 >>>> PageAccessSynchronizer$2(**PageManagerDecorator).**touchPage(IManageablePage) >>>> line: 59 >>>> PageAccessSynchronizer$2.**touchPage(IManageablePage) line: 273 >>>> OtherPage(Page).dirty(boolean) line: 289 >>>> OtherPage(WebPage).dirty(**boolean) line: 324 >>>> OtherPage(Page).init() line: 713 >>>> OtherPage(Page).<init>(**PageParameters, IModel<?>) line: 178 >>>> OtherPage(Page).<init>() line: 132 >>>> OtherPage(WebPage).<init>() line: 75 >>>> OtherPage.<init>() line: 13 >>>> >>>> #onInitialize() is assumed to be called *after* the constructor :(. >>>> >>>> Regards >>>> Sven >>>> >>>> >>>> >>>> On 03/12/2013 11:46 AM, [email protected] wrote: >>>> >>>>> Updated Branches: >>>>> refs/heads/master 62fe0a96e -> beee594d9 >>>>> >>>>> >>>>> WICKET-5083 Page#isPageStateless() may return wrong value >>>>> >>>>> >>>>> Project: >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/repo<http://git-wip-us.apache.org/repos/asf/wicket/repo> >>>>> Commit: http://git-wip-us.apache.org/**repos/asf/wicket/commit/** >>>>> beee594d<http://git-wip-us.apache.org/repos/asf/wicket/commit/beee594d> >>>>> Tree: >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/tree/beee594d<http://git-wip-us.apache.org/repos/asf/wicket/tree/beee594d> >>>>> Diff: >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/diff/beee594d<http://git-wip-us.apache.org/repos/asf/wicket/diff/beee594d> >>>>> >>>>> Branch: refs/heads/master >>>>> Commit: beee594d98f82d1bf8b59c3c69dbe3**3eb1743091 >>>>> Parents: 62fe0a9 >>>>> Author: Martin Tzvetanov Grigorov <[email protected]> >>>>> Authored: Tue Mar 12 11:45:55 2013 +0100 >>>>> Committer: Martin Tzvetanov Grigorov <[email protected]> >>>>> Committed: Tue Mar 12 11:45:55 2013 +0100 >>>>> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> .../src/main/java/org/apache/**wicket/Page.java | 2 + >>>>> .../html/ajaxLink/**AjaxLinkPageExpectedResult.**html | 2 +- >>>>> .../**AjaxLinkWithBorderPageExpected**Result.html | 2 +- >>>>> .../html/ajaxLink/AjaxPage2_**ExpectedResult.html | 2 +- >>>>> .../html/basic/**SimplePageExpectedResult_13.**html | 2 +- >>>>> .../border/HideableBorderPage_**ExpectedResult.html | 2 +- >>>>> .../panel/**InlinePanelPageExpectedResult_**7.html | 2 +- >>>>> .../panel/**InlinePanelPageExpectedResult_**8.html | 2 +- >>>>> .../apache/wicket/page/**PageStatelessnessTest.java | 54 >>>>> +++++++++++++++ >>>>> 9 files changed, 63 insertions(+), 7 deletions(-) >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/main/**java/org/apache/wicket/Page.**java<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/main/java/org/apache/wicket/Page.java> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>>> b/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>>> index 1467798..86c0472 100644 >>>>> --- a/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>>> +++ b/wicket-core/src/main/java/**org/apache/wicket/Page.java >>>>> @@ -450,6 +450,8 @@ public abstract class Page extends MarkupContainer >>>>> implements IRedirectListener, >>>>> if (stateless == null) >>>>> { >>>>> + internalInitialize(); >>>>> + >>>>> if (isStateless() == false) >>>>> { >>>>> stateless = Boolean.FALSE; >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/ajax/** >>>>> markup/html/ajaxLink/**AjaxLinkPageExpectedResult.**html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/ajaxLink/AjaxLinkPageExpectedResult.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/ajax/markup/**html/ajaxLink/** >>>>> AjaxLinkPageExpectedResult.**html b/wicket-core/src/test/java/** >>>>> org/apache/wicket/ajax/markup/**html/ajaxLink/** >>>>> AjaxLinkPageExpectedResult.**html >>>>> index 147a640..5cae1da 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/**AjaxLinkPageExpectedResult.**html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/**AjaxLinkPageExpectedResult.**html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.AjaxLinkPage"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.AjaxLinkPage?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/ajax/** >>>>> markup/html/ajaxLink/**AjaxLinkWithBorderPageExpected**Result.html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/ajaxLink/AjaxLinkWithBorderPageExpectedResult.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/ajax/markup/**html/ajaxLink/** >>>>> AjaxLinkWithBorderPageExpected**Result.html >>>>> b/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/**AjaxLinkWithBorderPageExpected**Result.html >>>>> index 1316cbc..aed0fb7 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/**AjaxLinkWithBorderPageExpected**Result.html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/**AjaxLinkWithBorderPageExpected**Result.html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.**AjaxLinkWithBorderPage"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.**AjaxLinkWithBorderPage?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/ajax/** >>>>> markup/html/ajaxLink/**AjaxPage2_ExpectedResult.html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/ajaxLink/AjaxPage2_ExpectedResult.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/ajax/markup/**html/ajaxLink/AjaxPage2_**ExpectedResult.html >>>>> b/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/AjaxPage2_**ExpectedResult.html >>>>> index 1d0a909..1a0da1e 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/AjaxPage2_**ExpectedResult.html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/ajax/markup/** >>>>> html/ajaxLink/AjaxPage2_**ExpectedResult.html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.AjaxPage2"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.ajax.markup.html.**ajaxLink.AjaxPage2?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/markup/** >>>>> html/basic/**SimplePageExpectedResult_13.**html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/markup/html/basic/SimplePageExpectedResult_13.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/markup/html/**basic/**SimplePageExpectedResult_13.**html >>>>> b/wicket-core/src/test/java/**org/apache/wicket/markup/html/**basic/** >>>>> SimplePageExpectedResult_13.**html >>>>> index 15cea8a..0639e2e 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> basic/**SimplePageExpectedResult_13.**html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> basic/**SimplePageExpectedResult_13.**html >>>>> @@ -13,7 +13,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.basic.**SimplePage_13"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.basic.**SimplePage_13?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <link rel="stylesheet" type="text/css" href="../../BasePage.css" /> >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/markup/** >>>>> html/border/**HideableBorderPage_**ExpectedResult.html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/markup/html/border/HideableBorderPage_ExpectedResult.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/markup/html/**border/HideableBorderPage_**ExpectedResult.html >>>>> b/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> border/HideableBorderPage_**ExpectedResult.html >>>>> index b227b6e..4745897 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> border/HideableBorderPage_**ExpectedResult.html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> border/HideableBorderPage_**ExpectedResult.html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.border.**HideableBorderPage"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.border.**HideableBorderPage?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/markup/** >>>>> html/panel/**InlinePanelPageExpectedResult_**7.html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPageExpectedResult_7.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/markup/html/**panel/**InlinePanelPageExpectedResult_ >>>>> **7.html b/wicket-core/src/test/java/**org/apache/wicket/markup/html/* >>>>> *panel/**InlinePanelPageExpectedResult_**7.html >>>>> index 26eb4e7..76e3382 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> panel/**InlinePanelPageExpectedResult_**7.html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> panel/**InlinePanelPageExpectedResult_**7.html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.panel.**InlinePanelPage_7"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.panel.**InlinePanelPage_7?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/markup/** >>>>> html/panel/**InlinePanelPageExpectedResult_**8.html<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPageExpectedResult_8.html> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git a/wicket-core/src/test/java/** >>>>> org/apache/wicket/markup/html/**panel/**InlinePanelPageExpectedResult_ >>>>> **8.html b/wicket-core/src/test/java/**org/apache/wicket/markup/html/* >>>>> *panel/**InlinePanelPageExpectedResult_**8.html >>>>> index b6d33ec..6c6238f 100644 >>>>> --- a/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> panel/**InlinePanelPageExpectedResult_**8.html >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/markup/html/** >>>>> panel/**InlinePanelPageExpectedResult_**8.html >>>>> @@ -10,7 +10,7 @@ Wicket.Ajax.DebugWindow.**enabled=true; >>>>> </script> >>>>> <script type="text/javascript" id="wicket-ajax-base-url"> >>>>> /*<![CDATA[*/ >>>>> -Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.panel.**InlinePanelPage_8"; >>>>> +Wicket.Ajax.baseUrl="wicket/**bookmarkable/org.apache.** >>>>> wicket.markup.html.panel.**InlinePanelPage_8?0"; >>>>> /*]]>*/ >>>>> </script> >>>>> <script type="text/javascript" > >>>>> >>>>> http://git-wip-us.apache.org/**repos/asf/wicket/blob/** >>>>> beee594d/wicket-core/src/test/**java/org/apache/wicket/page/** >>>>> PageStatelessnessTest.java<http://git-wip-us.apache.org/repos/asf/wicket/blob/beee594d/wicket-core/src/test/java/org/apache/wicket/page/PageStatelessnessTest.java> >>>>> ------------------------------**------------------------------** >>>>> ---------- >>>>> diff --git >>>>> a/wicket-core/src/test/java/**org/apache/wicket/page/**PageStatelessnessTest.java >>>>> b/wicket-core/src/test/java/**org/apache/wicket/page/** >>>>> PageStatelessnessTest.java >>>>> new file mode 100644 >>>>> index 0000000..0340a95 >>>>> --- /dev/null >>>>> +++ b/wicket-core/src/test/java/**org/apache/wicket/page/** >>>>> PageStatelessnessTest.java >>>>> @@ -0,0 +1,54 @@ >>>>> +/* >>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more >>>>> + * contributor license agreements. See the NOTICE file distributed >>>>> with >>>>> + * this work for additional information regarding copyright ownership. >>>>> + * The ASF licenses this file to You under the Apache License, >>>>> Version 2.0 >>>>> + * (the "License"); you may not use this file except in compliance >>>>> with >>>>> + * the License. You may obtain a copy of the License at >>>>> + * >>>>> + * >>>>> http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0> >>>>> + * >>>>> + * Unless required by applicable law or agreed to in writing, software >>>>> + * distributed under the License is distributed on an "AS IS" BASIS, >>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>>> implied. >>>>> + * See the License for the specific language governing permissions and >>>>> + * limitations under the License. >>>>> + */ >>>>> +package org.apache.wicket.page; >>>>> + >>>>> +import org.apache.wicket.Page; >>>>> +import org.apache.wicket.**WicketTestCase; >>>>> +import org.apache.wicket.markup.html.**WebPage; >>>>> +import org.junit.Test; >>>>> + >>>>> +/** >>>>> + * Tests for Page#isPageStateless >>>>> + */ >>>>> +public class PageStatelessnessTest extends WicketTestCase >>>>> +{ >>>>> + /** >>>>> + * Tests that a page is not stateless if it adds stateful >>>>> components in #onInitialize() >>>>> + * >>>>> https://issues.apache.org/**jira/browse/WICKET-5083<https://issues.apache.org/jira/browse/WICKET-5083> >>>>> + */ >>>>> + @Test >>>>> + public void isPageStatelessWithOnInitializ**e() >>>>> + { >>>>> + Page page = new TestPage(); >>>>> + assertFalse(page.**isPageStateless()); >>>>> + } >>>>> + >>>>> + public static class TestPage extends WebPage >>>>> + { >>>>> + >>>>> + public TestPage() >>>>> + { >>>>> + } >>>>> + >>>>> + @Override >>>>> + protected void onInitialize() { >>>>> + super.onInitialize(); >>>>> + >>>>> + setStatelessHint(false); >>>>> + } >>>>> + } >>>>> +} >>>>> >>>>> >>>> >>> >>> >>> -- >>> Martin Grigorov >>> jWeekend >>> Training, Consulting, Development >>> http://jWeekend.com <http://jweekend.com/> >>> >> >> >> >> -- >> Martin Grigorov >> jWeekend >> Training, Consulting, Development >> http://jWeekend.com <http://jweekend.com/> >> > > > > -- > Martin Grigorov > jWeekend > Training, Consulting, Development > http://jWeekend.com <http://jweekend.com/> > -- Martin Grigorov jWeekend Training, Consulting, Development http://jWeekend.com <http://jweekend.com/>
