You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2011/09/15 12:46:26 UTC

svn commit: r1171044 - in /wicket/trunk/wicket-core/src: main/java/org/apache/wicket/request/handler/ test/java/org/apache/wicket/ test/java/org/apache/wicket/request/handler/ test/java/org/apache/wicket/request/mapper/

Author: mgrigorov
Date: Thu Sep 15 10:46:26 2011
New Revision: 1171044

URL: http://svn.apache.org/viewvc?rev=1171044&view=rev
Log:
WICKET-4046 Touch pages only when they are returned from the data stores

Apply Pedro's patch + Enond's -2 patch.
-3 breaks some tests.


Modified:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/request/handler/PageProvider.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/WicketTestCase.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/handler/PageProviderTest.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/mapper/TestMapperContext.java

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/request/handler/PageProvider.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/request/handler/PageProvider.java?rev=1171044&r1=1171043&r2=1171044&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/request/handler/PageProvider.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/request/handler/PageProvider.java Thu Sep 15 10:46:26 2011
@@ -18,6 +18,7 @@ package org.apache.wicket.request.handle
 
 import org.apache.wicket.Application;
 import org.apache.wicket.page.IPageManager;
+import org.apache.wicket.pageStore.IPageStore;
 import org.apache.wicket.protocol.http.PageExpiredException;
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.IRequestMapper;
@@ -46,7 +47,9 @@ import org.apache.wicket.util.lang.Args;
  */
 public class PageProvider implements IPageProvider
 {
-	private Integer renderCount;
+	private final Integer renderCount;
+
+	private final Integer pageId;
 
 	private IPageSource pageSource;
 
@@ -54,8 +57,6 @@ public class PageProvider implements IPa
 
 	private Class<? extends IRequestablePage> pageClass;
 
-	private Integer pageId;
-
 	private PageParameters pageParameters;
 
 	/**
@@ -123,6 +124,8 @@ public class PageProvider implements IPa
 		{
 			setPageParameters(pageParameters);
 		}
+		pageId = null;
+		renderCount = null;
 	}
 
 	/**
@@ -187,10 +190,25 @@ public class PageProvider implements IPa
 		}
 	}
 
+	/**
+	 * The page instance is new only if there is no cached instance or the data stores doesn't have
+	 * a page with that id with the same {@linkplain #pageClass}.
+	 * 
+	 * @see org.apache.wicket.request.handler.IPageProvider#isNewPageInstance()
+	 */
 	public boolean isNewPageInstance()
 	{
-		return pageInstance == null &&
-			(pageId == null || getPageSource().getPageInstance(pageId) == null);
+		boolean isNew = pageInstance == null;
+		if (isNew && pageId != null)
+		{
+			IRequestablePage storedPageInstance = getStoredPage(pageId);
+			if (storedPageInstance != null)
+			{
+				pageInstance = storedPageInstance;
+				isNew = false;
+			}
+		}
+		return isNew;
 	}
 
 	/**
@@ -235,16 +253,9 @@ public class PageProvider implements IPa
 
 		if (pageId != null)
 		{
-			page = getPageSource().getPageInstance(pageId);
-			if (page != null && pageClass != null && page.getClass().equals(pageClass) == false)
-			{
-				page = null;
-			}
-			else if (page != null && pageParameters != null)
-			{
-				page.getPageParameters().overwriteWith(pageParameters);
-			}
+			page = getStoredPage(pageId);
 		}
+
 		if (page == null)
 		{
 			if (pageClass != null)
@@ -266,6 +277,32 @@ public class PageProvider implements IPa
 	}
 
 	/**
+	 * Looks up a page by id from the {@link IPageStore}. <br/>
+	 * If {@linkplain #pageClass} is specified then compares it against the stored instance class
+	 * and returns the found instance only if they match.
+	 * 
+	 * @param pageId
+	 *            the id of the page to look for.
+	 * @return the found page instance by id.
+	 */
+	private IRequestablePage getStoredPage(final int pageId)
+	{
+		IRequestablePage storedPageInstance = getPageSource().getPageInstance(pageId);
+		if (storedPageInstance != null &&
+			(pageClass == null || pageClass.equals(storedPageInstance.getClass())))
+		{
+			pageInstance = storedPageInstance;
+
+			if (pageParameters != null)
+			{
+				storedPageInstance.getPageParameters().overwriteWith(pageParameters);
+			}
+
+		}
+		return storedPageInstance;
+	}
+
+	/**
 	 * Detaches the page if it has been loaded (that means either
 	 * {@link #PageProvider(IRequestablePage)} constructor has been used or
 	 * {@link #getPageInstance()} has been called).

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/WicketTestCase.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/WicketTestCase.java?rev=1171044&r1=1171043&r2=1171044&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/WicketTestCase.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/WicketTestCase.java Thu Sep 15 10:46:26 2011
@@ -65,6 +65,9 @@ public abstract class WicketTestCase ext
 	@Override
 	protected void setUp() throws Exception
 	{
+		// make sure no leaked threadlocals are present
+		ThreadContext.detach();
+
 		WebApplication application = newApplication();
 		tester = newWicketTester(application);
 	}

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/handler/PageProviderTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/handler/PageProviderTest.java?rev=1171044&r1=1171043&r2=1171044&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/handler/PageProviderTest.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/handler/PageProviderTest.java Thu Sep 15 10:46:26 2011
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.text.ParseException;
 
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.MockPage;
 import org.apache.wicket.RestartResponseAtInterceptPageException;
 import org.apache.wicket.WicketTestCase;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -29,15 +30,64 @@ import org.apache.wicket.markup.html.Web
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.request.Url;
 import org.apache.wicket.request.mapper.StalePageException;
+import org.apache.wicket.request.mapper.TestMapperContext;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
 import org.apache.wicket.util.resource.StringResourceStream;
+import org.junit.Test;
 
 /**
  * @author pedro
  */
 public class PageProviderTest extends WicketTestCase
 {
+
+	/**
+	 * <a href="https://issues.apache.org/jira/browse/WICKET-4046">WICKET-4046</a>
+	 */
+	@Test
+	public void pageProviderDontDeserializeOnePageTwice()
+	{
+		int oldState = 0;
+		int newState = 1;
+
+		StatefullMockPage testPage = new StatefullMockPage();
+		testPage.state = oldState;
+
+		// storing test page
+		TestMapperContext mapperContext = new TestMapperContext();
+		mapperContext.getPageManager().touchPage(testPage);
+		mapperContext.getPageManager().commitRequest();
+
+		// by cleaning session cache we make sure of not being testing the same in-memory instance
+		mapperContext.cleanSessionCache();
+
+		PageProvider pageProvider = mapperContext.new TestPageProvider(testPage.getPageId(), 0);
+
+		// simulation an test call to isNewPageInstance
+		boolean isNewPageInstance = pageProvider.isNewPageInstance();
+		assertFalse("test page is already stored", isNewPageInstance);
+
+		// changing some sate
+		StatefullMockPage providedPage = (StatefullMockPage)pageProvider.getPageInstance();
+		providedPage.state = newState;
+		mapperContext.getPageManager().touchPage(providedPage);
+		mapperContext.getPageManager().commitRequest();
+
+
+		mapperContext.cleanSessionCache();
+
+		StatefullMockPage restauredPageAfterStateChage = (StatefullMockPage)mapperContext.getPageInstance(testPage.getPageId());
+
+		// OK, if the correct page got touched/stores its change will be visible now
+		assertEquals(newState, restauredPageAfterStateChage.state);
+	}
+
+	private static class StatefullMockPage extends MockPage
+	{
+		int state = 0;
+	}
+
 	/**
 	 * @see <a href="https://issues.apache.org/jira/browse/WICKET-3252">WICKET-3252</a>
 	 * */

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/mapper/TestMapperContext.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/mapper/TestMapperContext.java?rev=1171044&r1=1171043&r2=1171044&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/mapper/TestMapperContext.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/request/mapper/TestMapperContext.java Thu Sep 15 10:46:26 2011
@@ -20,11 +20,20 @@ import org.apache.wicket.MockPage;
 import org.apache.wicket.RequestListenerInterface;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.MarkupParser;
+import org.apache.wicket.page.IPageManagerContext;
+import org.apache.wicket.page.PageStoreManager;
+import org.apache.wicket.pageStore.DefaultPageStore;
+import org.apache.wicket.pageStore.IDataStore;
+import org.apache.wicket.pageStore.IPageStore;
+import org.apache.wicket.pageStore.memory.DummyPageManagerContext;
 import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.handler.PageProvider;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.request.resource.ResourceReference.Key;
 import org.apache.wicket.request.resource.ResourceReferenceRegistry;
+import org.apache.wicket.serialize.java.JavaSerializer;
+import org.apache.wicket.versioning.InMemoryPageStore;
 
 /**
  * Simple {@link EncoderContext} implementation for testing purposes
@@ -33,12 +42,45 @@ import org.apache.wicket.request.resourc
  */
 public class TestMapperContext implements IMapperContext
 {
+	private static final String APP_NAME = "test_app";
+	private static int count;
+	IDataStore dataStore;
+	IPageStore pageStore;
+	IPageManagerContext pageManagerContext;
+	PageStoreManager pageManager;
+	private String appName;
+	private boolean createMockPageIfInstanceNotFound = true;
 
 	/**
 	 * Construct.
 	 */
 	public TestMapperContext()
 	{
+		appName = APP_NAME + count++;
+		dataStore = new InMemoryPageStore();
+		pageStore = new DefaultPageStore(new JavaSerializer(appName), dataStore, 4);
+		pageManagerContext = new DummyPageManagerContext();
+		pageManager = new PageStoreManager(appName, pageStore, pageManagerContext);
+	}
+
+	/**
+	 * just making sure the session cache will be empty by simulating an intermezzo request
+	 */
+	public void cleanSessionCache()
+	{
+		getPageManager().getContext().setRequestData(null);
+		MockPage other = new MockPage();
+		other.setPageId(Integer.MAX_VALUE);
+		getPageManager().touchPage(other);
+		getPageManager().commitRequest();
+	}
+
+	/**
+	 * @return pageManager
+	 */
+	public PageStoreManager getPageManager()
+	{
+		return pageManager;
 	}
 
 	public String getBookmarkableIdentifier()
@@ -113,12 +155,19 @@ public class TestMapperContext implement
 
 	public IRequestablePage getPageInstance(int pageId)
 	{
-		MockPage page = new MockPage();
-		page.setPageId(pageId);
-		page.setBookmarkable(bookmarkable);
-		page.setCreatedBookmarkable(createdBookmarkable);
-		page.setRenderCount(nextPageRenderCount);
-		return page;
+
+		IRequestablePage requestablePage = (IRequestablePage)pageManager.getPage(pageId);
+		if (requestablePage == null && createMockPageIfInstanceNotFound)
+		{
+			MockPage page = new MockPage();
+			page.setPageId(pageId);
+			page.setBookmarkable(bookmarkable);
+			page.setCreatedBookmarkable(createdBookmarkable);
+			page.setRenderCount(nextPageRenderCount);
+			requestablePage = page;
+		}
+		return requestablePage;
+
 	}
 
 	int idCounter = 0;
@@ -160,4 +209,31 @@ public class TestMapperContext implement
 		return MockPage.class;
 	}
 
+	/**
+	 * 
+	 * Adapts {@link PageProvider} to this {@link IMapperContext}
+	 * 
+	 * @author Pedro Santos
+	 */
+	public class TestPageProvider extends PageProvider
+	{
+
+		/**
+		 * Construct.
+		 * 
+		 * @param pageId
+		 * @param renderCount
+		 */
+		public TestPageProvider(int pageId, Integer renderCount)
+		{
+			super(pageId, renderCount);
+		}
+
+		@Override
+		protected IPageSource getPageSource()
+		{
+			return TestMapperContext.this;
+		}
+	}
+
 }