You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/11/22 16:08:45 UTC

svn commit: r348184 - in /jakarta/tapestry/trunk: ./ framework/src/java/org/apache/tapestry/record/ framework/src/test/org/apache/tapestry/record/

Author: hlship
Date: Tue Nov 22 07:08:38 2005
New Revision: 348184

URL: http://svn.apache.org/viewcvs?rev=348184&view=rev
Log:
TAPESTRY-701: NPE creating a link from pageValidate() when there are client-persistent properties with page scope

Added:
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/ClientPropertyPersistenceStrategyTest.java
      - copied, changed from r345745, jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/TestClientPropertyPersistenceStrategy.java
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/PageClientPropertyPersistenceScopeTest.java
Removed:
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/TestClientPropertyPersistenceStrategy.java
Modified:
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/record/PageClientPropertyPersistenceScope.java
    jakarta/tapestry/trunk/status.xml

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/record/PageClientPropertyPersistenceScope.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/record/PageClientPropertyPersistenceScope.java?rev=348184&r1=348183&r2=348184&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/record/PageClientPropertyPersistenceScope.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/record/PageClientPropertyPersistenceScope.java Tue Nov 22 07:08:38 2005
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.record;
 
+import org.apache.tapestry.IPage;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.engine.ServiceEncoding;
 
@@ -29,7 +30,7 @@
         AbstractPrefixedClientPropertyPersistenceScope
 {
     private IRequestCycle _requestCycle;
-    
+
     public PageClientPropertyPersistenceScope()
     {
         super("state:");
@@ -43,7 +44,18 @@
     public boolean shouldEncodeState(ServiceEncoding encoding, String pageName,
             PersistentPropertyData data)
     {
-        return pageName.equals(_requestCycle.getPage().getPageName());
+        IPage page = _requestCycle.getPage();
+
+        // TAPESTRY-701: if you try to generate a link using, say, page or external service,
+        // from inside PageValidateListener.pageValidate(), then there may not be an active
+        // page yet. Seems like the right thing to do is hold onto any properties until
+        // we know what the active page is.  I know this one is going to cause a fight
+        // since its not clear whether keeping or discarding is the right way to go.
+        
+        if (page == null)
+            return true;
+
+        return pageName.equals(page.getPageName());
     }
 
     public void setRequestCycle(IRequestCycle requestCycle)

Copied: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/ClientPropertyPersistenceStrategyTest.java (from r345745, jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/TestClientPropertyPersistenceStrategy.java)
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/ClientPropertyPersistenceStrategyTest.java?p2=jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/ClientPropertyPersistenceStrategyTest.java&p1=jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/TestClientPropertyPersistenceStrategy.java&r1=345745&r2=348184&rev=348184&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/TestClientPropertyPersistenceStrategy.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/ClientPropertyPersistenceStrategyTest.java Tue Nov 22 07:08:38 2005
@@ -23,7 +23,6 @@
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.engine.ServiceEncoding;
 import org.apache.tapestry.web.WebRequest;
-import org.easymock.MockControl;
 
 /**
  * Tests for {@link org.apache.tapestry.record.ClientPropertyPersistenceStrategy}.
@@ -31,50 +30,59 @@
  * @author Howard M. Lewis Ship
  * @since 4.0
  */
-public class TestClientPropertyPersistenceStrategy extends HiveMindTestCase
+public class ClientPropertyPersistenceStrategyTest extends HiveMindTestCase
 {
-    public void testInitialize()
+    private IRequestCycle newCycle()
     {
-        MockControl requestc = newControl(WebRequest.class);
-        WebRequest request = (WebRequest) requestc.getMock();
+        return (IRequestCycle) newMock(IRequestCycle.class);
+    }
 
-        request.getParameterNames();
-        requestc.setReturnValue(Arrays.asList(new Object[]
-        { "foo", "state:MyPage" }));
+    private PersistentPropertyDataEncoder newEncoder()
+    {
+        PersistentPropertyDataEncoderImpl encoder = new PersistentPropertyDataEncoderImpl();
+        encoder.setClassResolver(getClassResolver());
 
-        MockControl scopec = newControl(ClientPropertyPersistenceScope.class);
-        ClientPropertyPersistenceScope scope = (ClientPropertyPersistenceScope) scopec.getMock();
+        return encoder;
+    }
 
-        scope.isParameterForScope("foo");
-        scopec.setReturnValue(false);
+    private IPage newPage()
+    {
+        return (IPage) newMock(IPage.class);
+    }
+
+    private WebRequest newRequest()
+    {
+        return (WebRequest) newMock(WebRequest.class);
+    }
 
-        scope.isParameterForScope("state:MyPage");
-        scopec.setReturnValue(true);
+    private ClientPropertyPersistenceScope newScope()
+    {
+        return (ClientPropertyPersistenceScope) newMock(ClientPropertyPersistenceScope.class);
+    }
 
-        scope.extractPageName("state:MyPage");
-        scopec.setReturnValue("MyPage");
+    public void testAddParametersForPersistentProperties()
+    {
+        WebRequest request = newRequest();
 
-        request.getParameterValue("state:MyPage");
-        requestc.setReturnValue("ENCODED");
+        ServiceEncoding encoding = (ServiceEncoding) newMock(ServiceEncoding.class);
 
-        MockControl encoderc = newControl(PersistentPropertyDataEncoder.class);
-        PersistentPropertyDataEncoder encoder = (PersistentPropertyDataEncoder) encoderc.getMock();
+        trainGetParameterNames(request, new String[]
+        { "bar", "appstate:MyPage" });
 
-        List changes = Collections.singletonList(new PropertyChangeImpl("foo", "bar", "baz"));
+        trainGetParameterValue(request, "appstate:MyPage", "ENCODED");
 
-        encoder.decodePageChanges("ENCODED");
-        encoderc.setReturnValue(changes);
+        encoding.setParameterValue("appstate:MyPage", "ENCODED");
 
         replayControls();
 
         ClientPropertyPersistenceStrategy strategy = new ClientPropertyPersistenceStrategy();
         strategy.setRequest(request);
-        strategy.setScope(scope);
-        strategy.setEncoder(encoder);
+        strategy.setScope(new AppClientPropertyPersistenceScope());
+        strategy.setEncoder(newEncoder());
 
         strategy.initializeService();
 
-        assertSame(changes, strategy.getStoredChanges("MyPage"));
+        strategy.addParametersForPersistentProperties(encoding, false);
 
         verifyControls();
     }
@@ -86,96 +94,62 @@
         assertTrue(strategy.getStoredChanges("UnknownPage").isEmpty());
     }
 
-    public void testStoreAndRetrieve()
+    public void testInitialize()
     {
-        PropertyChange pc = new PropertyChangeImpl("foo", "bar", "baz");
-
-        ClientPropertyPersistenceStrategy strategy = new ClientPropertyPersistenceStrategy();
-        strategy.setEncoder(newEncoder());
-
-        strategy.store("MyPage", "foo", "bar", "baz");
+        WebRequest request = newRequest();
+        ClientPropertyPersistenceScope scope = newScope();
+        PersistentPropertyDataEncoder encoder = (PersistentPropertyDataEncoder) newMock(PersistentPropertyDataEncoder.class);
 
-        assertEquals(Collections.singletonList(pc), strategy.getStoredChanges("MyPage"));
+        trainGetParameterNames(request, new String[]
+        { "foo", "state:MyPage" });
 
-        strategy.discardStoredChanges("MyPage");
+        trainIsParameterForScope(scope, "foo", false);
+        trainIsParameterForScope(scope, "state:MyPage", true);
 
-        assertEquals(Collections.EMPTY_LIST, strategy.getStoredChanges("MyPage"));
-    }
+        trainExtractPageName(scope, "state:MyPage", "MyPage");
 
-    public void testAddParametersForPersistentProperties()
-    {
-        MockControl requestc = newControl(WebRequest.class);
-        WebRequest request = (WebRequest) requestc.getMock();
+        trainGetParameterValue(request, "state:MyPage", "ENCODED");
 
-        ServiceEncoding encoding = (ServiceEncoding) newMock(ServiceEncoding.class);
-
-        request.getParameterNames();
-        requestc.setReturnValue(Arrays.asList(new Object[]
-        { "bar", "appstate:MyPage" }));
+        List changes = Collections.singletonList(new PropertyChangeImpl("foo", "bar", "baz"));
 
-        request.getParameterValue("appstate:MyPage");
-        requestc.setReturnValue("ENCODED");
-
-        encoding.setParameterValue("appstate:MyPage", "ENCODED");
+        trainDecodePageChanges(encoder, "ENCODED", changes);
 
         replayControls();
 
         ClientPropertyPersistenceStrategy strategy = new ClientPropertyPersistenceStrategy();
         strategy.setRequest(request);
-        strategy.setScope(new AppClientPropertyPersistenceScope());
-        strategy.setEncoder(newEncoder());
+        strategy.setScope(scope);
+        strategy.setEncoder(encoder);
 
         strategy.initializeService();
 
-        strategy.addParametersForPersistentProperties(encoding, false);
+        assertSame(changes, strategy.getStoredChanges("MyPage"));
 
         verifyControls();
     }
 
-    private PersistentPropertyDataEncoder newEncoder()
-    {
-        PersistentPropertyDataEncoderImpl encoder = new PersistentPropertyDataEncoderImpl();
-        encoder.setClassResolver(getClassResolver());
-
-        return encoder;
-    }
-
     public void testPageScope()
     {
-        MockControl requestc = newControl(WebRequest.class);
-        WebRequest request = (WebRequest) requestc.getMock();
-
-        MockControl cyclec = newControl(IRequestCycle.class);
-        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
-
-        MockControl pagec = newControl(IPage.class);
-        IPage page = (IPage) pagec.getMock();
+        WebRequest request = newRequest();
+        IRequestCycle cycle = newCycle();
+        IPage page = newPage();
 
         ServiceEncoding encoding = (ServiceEncoding) newMock(ServiceEncoding.class);
 
-        cycle.getPage();
-        cyclec.setReturnValue(page);
-
-        cycle.getPage();
-        cyclec.setReturnValue(page);
+        trainGetPage(cycle, page);
 
-        page.getPageName();
-        pagec.setReturnValue("MyPage");
-
-        page.getPageName();
-        pagec.setReturnValue("MyPage");
+        trainGetPageName(page, "MyPage");
 
-        request.getParameterNames();
-        requestc.setReturnValue(Arrays.asList(new Object[]
-        { "foo", "state:MyPage", "state:OtherPage" }));
+        trainGetPage(cycle, page);
+        trainGetPageName(page, "MyPage");
 
-        request.getParameterValue("state:MyPage");
-        requestc.setReturnValue("ENCODED");
+        trainGetParameterNames(request, new String[]
+        { "foo", "state:MyPage", "state:OtherPage" });
 
-        request.getParameterValue("state:OtherPage");
-        requestc.setReturnValue("ENCODED");
+        trainGetParameterValue(request, "state:MyPage", "ENCODED1");
+        trainGetParameterValue(request, "state:OtherPage", "ENCODED2");
 
-        encoding.setParameterValue("state:MyPage", "ENCODED");
+        encoding.setParameterValue("state:MyPage", "ENCODED1");
 
         replayControls();
 
@@ -193,5 +167,66 @@
 
         verifyControls();
 
+    }
+
+    public void testStoreAndRetrieve()
+    {
+        PropertyChange pc = new PropertyChangeImpl("foo", "bar", "baz");
+
+        ClientPropertyPersistenceStrategy strategy = new ClientPropertyPersistenceStrategy();
+        strategy.setEncoder(newEncoder());
+
+        strategy.store("MyPage", "foo", "bar", "baz");
+
+        assertEquals(Collections.singletonList(pc), strategy.getStoredChanges("MyPage"));
+
+        strategy.discardStoredChanges("MyPage");
+
+        assertEquals(Collections.EMPTY_LIST, strategy.getStoredChanges("MyPage"));
+    }
+
+    private void trainDecodePageChanges(PersistentPropertyDataEncoder encoder, String encoded,
+            List changes)
+    {
+        encoder.decodePageChanges(encoded);
+        setReturnValue(encoder, changes);
+    }
+
+    private void trainExtractPageName(ClientPropertyPersistenceScope scope, String parameterName,
+            String pageName)
+    {
+        scope.extractPageName(parameterName);
+        setReturnValue(scope, pageName);
+    }
+
+    private void trainGetPage(IRequestCycle cycle, IPage page)
+    {
+        cycle.getPage();
+        setReturnValue(cycle, page);
+    }
+
+    private void trainGetPageName(IPage page, String pageName)
+    {
+        page.getPageName();
+        setReturnValue(page, pageName);
+    }
+
+    private void trainGetParameterNames(WebRequest request, String[] names)
+    {
+        request.getParameterNames();
+        setReturnValue(request, Arrays.asList(names));
+    }
+
+    private void trainGetParameterValue(WebRequest request, String parameterName, String value)
+    {
+        request.getParameterValue(parameterName);
+        setReturnValue(request, value);
+    }
+
+    private void trainIsParameterForScope(ClientPropertyPersistenceScope scope,
+            String parameterName, boolean result)
+    {
+        scope.isParameterForScope(parameterName);
+        setReturnValue(scope, result);
     }
 }

Added: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/PageClientPropertyPersistenceScopeTest.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/PageClientPropertyPersistenceScopeTest.java?rev=348184&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/PageClientPropertyPersistenceScopeTest.java (added)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/record/PageClientPropertyPersistenceScopeTest.java Tue Nov 22 07:08:38 2005
@@ -0,0 +1,128 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed 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
+//
+// 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.tapestry.record;
+
+import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.tapestry.IPage;
+import org.apache.tapestry.IRequestCycle;
+
+/**
+ * Tests for {@link org.apache.tapestry.record.PageClientPropertyPersistenceScope}.
+ * 
+ * @author Howard M. Lewis Ship
+ * @since 4.0
+ */
+public class PageClientPropertyPersistenceScopeTest extends HiveMindTestCase
+{
+    protected IRequestCycle newCycle()
+    {
+        return (IRequestCycle) newMock(IRequestCycle.class);
+    }
+
+    protected IPage newPage()
+    {
+        return (IPage) newMock(IPage.class);
+    }
+
+    public void testConstructParameterName()
+    {
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        assertEquals("state:MyPage", scope.constructParameterName("MyPage"));
+    }
+
+    public void testIsParameterForScope()
+    {
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        assertEquals(true, scope.isParameterForScope("state:MyPage"));
+        assertEquals(false, scope.isParameterForScope("foo"));
+        assertEquals(false, scope.isParameterForScope("appstate:Foo"));
+    }
+
+    public void testExtractPageName()
+    {
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        assertEquals("MyPage", scope.extractPageName("state:MyPage"));
+    }
+
+    public void testShouldEncodeState()
+    {
+        IRequestCycle cycle = newCycle();
+        IPage page = newPage();
+
+        trainGetPage(cycle, page);
+        trainGetPageName(page, "MyPage");
+
+        replayControls();
+
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        scope.setRequestCycle(cycle);
+
+        assertEquals(true, scope.shouldEncodeState(null, "MyPage", null));
+
+        verifyControls();
+    }
+
+    public void testShouldEncodeStateDifferentPage()
+    {
+        IRequestCycle cycle = newCycle();
+        IPage page = newPage();
+
+        trainGetPage(cycle, page);
+        trainGetPageName(page, "MyPage");
+
+        replayControls();
+
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        scope.setRequestCycle(cycle);
+
+        assertEquals(false, scope.shouldEncodeState(null, "OtherPage", null));
+
+        verifyControls();
+    }
+
+    public void testShouldEncodeStateNoActivePage()
+    {
+        IRequestCycle cycle = newCycle();
+
+        trainGetPage(cycle, null);
+
+        replayControls();
+
+        PageClientPropertyPersistenceScope scope = new PageClientPropertyPersistenceScope();
+
+        scope.setRequestCycle(cycle);
+
+        assertEquals(true, scope.shouldEncodeState(null, "MyPage", null));
+
+        verifyControls();
+    }
+
+    private void trainGetPageName(IPage page, String pageName)
+    {
+        page.getPageName();
+        setReturnValue(page, pageName);
+    }
+
+    private void trainGetPage(IRequestCycle cycle, IPage page)
+    {
+        cycle.getPage();
+        setReturnValue(cycle, page);
+    }
+}

Modified: jakarta/tapestry/trunk/status.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/status.xml?rev=348184&r1=348183&r2=348184&view=diff
==============================================================================
--- jakarta/tapestry/trunk/status.xml (original)
+++ jakarta/tapestry/trunk/status.xml Tue Nov 22 07:08:38 2005
@@ -67,6 +67,7 @@
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-769">StateBinding doesn't override isInvariant()</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-768">FormMessages class has typo in message key for fieldAlreadyPrerendered()</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-275" due-to="Igor Grimaylo">Single quotes in a localization of DatePicker strings causes a failure</action>
+      <action type="fix" dev="HLS" fixes-bug="TAPESTRY-701">NPE creating a link from pageValidate() when there are client-persistent properties with page scope</action>
     </release>
     <release version="4.0-beta-13" date="Nov 12 2005">
       <action type="update" dev="HLS">Switch to HiveMind 1.1 (final)</action>



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org